#include "cubes.h" #include "gen.h" #include "inv.h" #include "linmath.h" #include int is_space; int collision(struct chunk chunk, vec3 pos, vec3 dir_temp, int col, int n) { vec3 closestVert = {floor(pos[0]), floor(pos[1] + 0.5), floor(pos[2])}; if (col) { double xd = dir_temp[0] / (closestVert[0] - (pos[0] - 0.5)); double yd = dir_temp[1] / (closestVert[1] - (pos[1])); double zd = dir_temp[2] / (closestVert[2] - (pos[2] - 0.5)); if (xd < 0 && n == 0) { dir_temp[0] = 0; pos[0] = closestVert[0] + 0.5; return 1; } if (yd < 0 && n == 1) { dir_temp[1] = 0.015; pos[1] = closestVert[1]; return 1; } if (zd < 0 && n == 2) { dir_temp[2] = 0; pos[2] = closestVert[2] + 0.5; return 1; } } return 0; } struct v3f control_handler(double cx, double cy, vec3 pos, vec3 dir_temp, GLFWwindow *window, struct chunk chunk) { double delta = glfwGetTime(); if (delta > 1/60.0) delta = 1/60.0; glfwSetTime(0); delta *= 30; vec3 direction = {cosf(cy) * sinf(cx), sinf(cy), cosf(cy) * cosf(cx)}; vec3 right = {sinf(cx - 3.14f / 2.0f) * 0.015 * delta, 0, cosf(cx - 3.14f / 2.0f) * 0.015 * delta}; vec3 front = {sinf(cx) * 0.015 * delta, 0, cosf(cx) * 0.015 * delta}; vec3 pos_temp = {0, 0, 0}; vec3_dup(pos_temp, pos); if (glfwGetKey(window, GLFW_KEY_S) == GLFW_PRESS) { vec3_sub(dir_temp, dir_temp, front); } if (glfwGetKey(window, GLFW_KEY_W) == GLFW_PRESS) { vec3_add(dir_temp, dir_temp, front); } if (glfwGetKey(window, GLFW_KEY_D) == GLFW_PRESS) { vec3_add(dir_temp, dir_temp, right); } if (glfwGetKey(window, GLFW_KEY_A) == GLFW_PRESS) { vec3_sub(dir_temp, dir_temp, right); } vec3_scale(dir_temp, dir_temp, pow(0.9,delta)); vec3 off = {0, 0, 0}; int col = 0; for (int a = -2; a < 0; a++) { off[1] = a; for (int b = -1; b < 1; b++) { off[0] = (b + 0.5) * 0.95; for (int c = -1; c < 1; c++) { off[2] = (c + 0.5) * 0.95; col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], chunk, 0, -1); } } } vec3_add(pos, pos, dir_temp); dir_temp[1] -= 0.03 * delta; if (collision(chunk, pos, dir_temp, col, 1)) { col = 0; off[1] = -2; for (int b = -1; b < 1; b++) { off[0] = (b + 0.5) * 0.95; for (int c = -1; c < 1; c++) { off[2] = (c + 0.5) * 0.95; col = col || gen_cube(pos[0] + off[0], pos[1] + off[1], pos[2] + off[2], chunk, 0, -1); } } if (glfwGetKey(window, GLFW_KEY_SPACE) == GLFW_PRESS) { dir_temp[1] = 0.5 * delta; } } collision(chunk, pos, dir_temp, col, 0); collision(chunk, pos, dir_temp, col, 2); struct v3f dirOut; vec3_dup(dirOut.pos, direction); return dirOut; } struct v3f control_rtrace(double cx, double cy, vec3 pos, int mode) { struct chunk placeChunk; vec3 direction = {cosf(cy) * sinf(cx) * 0.1, sinf(cy) * 0.1, cosf(cy) * cosf(cx) * 0.1}; vec3 temp_pos; vec3 temp_dir; vec3_dup(temp_pos, pos); for (int i = 0; i < CHUNK_LENGTH * 4; i++) { double xd = fabs(direction[0]) / (((direction[0] > 0) ? (1.0 - fmod(temp_pos[0], 1)) : fmod(temp_pos[0], 1)) + 0.01); double yd = fabs(direction[1]) / (((direction[1] > 0) ? (1.0 - fmod(temp_pos[1], 1)) : fmod(temp_pos[1], 1)) + 0.01); double zd = fabs(direction[2]) / (((direction[2] > 0) ? (1.0 - fmod(temp_pos[2], 1)) : fmod(temp_pos[2], 1)) + 0.01); if (xd > yd && xd > zd && !isnan(xd)) { vec3_scale(temp_dir, direction, fabs(1 / xd + 0.01)); } else if (yd > zd && !isnan(yd)) { vec3_scale(temp_dir, direction, fabs(1 / yd + 0.01)); } else if (!isnan(zd)) { vec3_scale(temp_dir, direction, fabs(1 / zd + 0.01)); } vec3_add(temp_pos, temp_pos, temp_dir); if (gen_cube(temp_pos[0], temp_pos[1], temp_pos[2], placeChunk, 0, -1) != 0) { if (mode == 0) vec3_sub(temp_pos, temp_pos, temp_dir); break; } } struct v3f out_pos; vec3_dup(out_pos.pos, temp_pos); return out_pos; } void control_lclick(double cx, double cy, vec3 pos, struct item *inv) { struct v3f highlighted = control_rtrace(cx, cy, pos, 1); struct chunk placeChunk; int cube = gen_cube(highlighted.pos[0], highlighted.pos[1], highlighted.pos[2], placeChunk, 0, -1); if (cube == 0 || (highlighted.pos[0] == (int)pos[0] && highlighted.pos[1] == (int)pos[1] && highlighted.pos[2] == (int)pos[2])) return; gen_cube(highlighted.pos[0], highlighted.pos[1], highlighted.pos[2], placeChunk, 0, 0); for (int i = 0; i < 10; i++) { if (inv[i].id == 0) { inv[i].id = cube; inv[i].count = 0; } if (inv[i].id == cube && inv[i].count < 64) { inv[i].count++; break; } } } void control_rclick(double cx, double cy, vec3 pos, struct item *inv, int slot) { struct v3f highlighted = control_rtrace(cx, cy, pos, 0); struct chunk placeChunk; int cube = gen_cube(highlighted.pos[0], highlighted.pos[1], highlighted.pos[2], placeChunk, 0, -1); if (cube != 0 || (fabs(highlighted.pos[0] - pos[0]) < 1 && fabs(highlighted.pos[1] - pos[1] + 0.5) < 1.5 && fabs(highlighted.pos[2] - pos[2]) < 1)) return; gen_cube(highlighted.pos[0], highlighted.pos[1], highlighted.pos[2], placeChunk, 0, inv[slot].id); for (int i = 0; i < 10; i++) { if (inv[i].id == inv[slot].id) { inv[i].count--; if (inv[i].count < 1) { inv[i].id = 0; inv[i].count = 0; } break; } } }