#include #include #include #include #include #include #include #include #include #include "hash.h" #include "structure.h" #include "base.h" #include "entities.h" #include "proj.h" #include "move.h" // ---------------------------------------------------------------------------------------------------- // double sensitivity = 0.06; double fov = 90.0; double creative_speed = 0.3; double speed = 8.0; double vtmult = 1.5; double min_dist = 0.4; double friction = 0.3; double gravity_factor = 9.8; // ---------------------------------------------------------------------------------------------------- // bool is_clipping = false; int clip_dps = 500; int njumps; double fx; double fy; double fz; bool updateForces = false; int player_hp; bool stop_evetything; double camx; double camy; double camz; double camvx; double camvy; double camvz; double rot_hz; double rot_vt; double tan_fov; int draw_type; int fade_dmg; bool has_changed; int collisionVal = 0; double room_width; double room_depth; double sq2; void init_csts() { camx = 2.0; camy = 5.0; camz = 2.0; camvx = 0.0; camvy = 0.0; camvz = 0.0; rot_hz = 0.0; rot_vt = 0.0; draw_type = 0; player_hp = 1000; fade_dmg = 0; room_width = 16.0; room_depth = 16.0; sq2 = sqrt(2); njumps = 3; stop_evetything = false; tan_fov = tan((fov * 3.14159 / 180.0) / 2.0); } void set_player_coords(int old_chx, int old_chy) { for(int k = 0; k < current_room->tps_size; k++) { if(current_room->tps[k]->dest_chx == old_chx && current_room->tps[k]->dest_chy == old_chy) { if(true) { camx = current_room->tps[k]->hitbox->x + current_room->tps[k]->hitbox->w/2.0; camy = current_room->tps[k]->hitbox->y + current_room->tps[k]->hitbox->h +1.5; camz = current_room->tps[k]->hitbox->z + current_room->tps[k]->hitbox->d/2.0; } return; } } } pt_2d surface[3]; pt_2d directors[2]; pt_2d normal; double p1, p2, p3; void getSF(cube_0* cb, int sf) { if(sf == 0 || sf == 1) { project_to_cube(cb->x + (sf==0)*(cb->w), cb->y , cb->z , &p1, &p2, &p3, cb); surface[0] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x + (sf==0)*(cb->w), cb->y + cb->h, cb->z , &p1, &p2, &p3, cb); surface[1] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x + (sf==0)*(cb->w), cb->y , cb->z + cb->d, &p1, &p2, &p3, cb); surface[2] = (pt_2d){.x = p1, .y = p2, .z = p3}; } else if(sf == 2 || sf == 3) { project_to_cube(cb->x , cb->y + (sf==2)*(cb->h), cb->z , &p1, &p2, &p3, cb); surface[0] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x + cb->w, cb->y + (sf==2)*(cb->h), cb->z , &p1, &p2, &p3, cb); surface[1] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x , cb->y + (sf==2)*(cb->h), cb->z + cb->d, &p1, &p2, &p3, cb); surface[2] = (pt_2d){.x = p1, .y = p2, .z = p3}; } else { project_to_cube(cb->x , cb->y , cb->z + (sf==4)*(cb->d), &p1, &p2, &p3, cb); surface[0] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x + cb->w, cb->y , cb->z + (sf==4)*(cb->d), &p1, &p2, &p3, cb); surface[1] = (pt_2d){.x = p1, .y = p2, .z = p3}; project_to_cube(cb->x , cb->y + cb->h, cb->z + (sf==4)*(cb->d), &p1, &p2, &p3, cb); surface[2] = (pt_2d){.x = p1, .y = p2, .z = p3}; } } void getDirectors() { directors[0] = (pt_2d){.x = surface[1].x - surface[0].x, .y = surface[1].y - surface[0].y, .z = surface[1].z - surface[0].z}; directors[1] = (pt_2d){.x = surface[2].x - surface[0].x, .y = surface[2].y - surface[0].y, .z = surface[2].z - surface[0].z}; } void getNormal() { normal.x = directors[0].y*directors[1].z - directors[1].y*directors[0].z; normal.y = -directors[0].z*directors[1].x + directors[1].z*directors[0].x; normal.z = directors[0].x*directors[1].y - directors[1].x*directors[0].y; double norm = sqrt(normal.x*normal.x + normal.y*normal.y + normal.z*normal.z); normal.x /= norm; normal.y /= norm; normal.z /= norm; } void normalize(pt_2d* p) { double norm = sqrt(p->x*p->x + p->y*p->y + p->z*p->z); p->x /= norm; p->y /= norm; p->z /= norm; } void updateF(cube_0* cb, double dtime) { for(int d = 0; d < 6; d++) { cb->x -= min_dist; cb->y -= min_dist; cb->z -= min_dist; cb->w += 2*min_dist; cb->h += 2*min_dist; cb->d += 2*min_dist; getSF(cb, d); cb->x += min_dist; cb->y += min_dist; cb->z += min_dist; cb->w -= 2*min_dist; cb->h -= 2*min_dist; cb->d -= 2*min_dist; getDirectors(); getNormal(); if(d%2==1) { normal.x *= -1.0; normal.y *= -1.0; normal.z *= -1.0; } pt_2d vt = (pt_2d){.x = camx-camvx*dtime - surface[0].x, .y = camy-camvy*dtime - surface[0].y, .z = camz-camvz*dtime - surface[0].z}; pt_2d vtdt = (pt_2d){.x = camx - surface[0].x, .y = camy - surface[0].y, .z = camz - surface[0].z}; normalize(&vtdt); normalize(&vt); if( (dot3D(vt, normal) <= 0.0 && dot3D(vtdt, normal) >= 0.0) || (dot3D(vt, normal) >= 0.0 && dot3D(vtdt, normal) <= 0.0) ) { printf("%d\n", d); double normv = sqrt(camvx*camvx + camvy*camvy + camvz*camvz); double alpha = acos(dot3D(normal, (pt_2d){.x = camvx, .y = camvy, .z = camvz})/normv); double beta = 3.1415926535 - 2*alpha; double nu = sqrt(2)*normv*sqrt(1-cos(beta)); pt_2d u = (pt_2d){.x = normal.x*nu, .y = normal.y*nu, .z = normal.z*nu}; camvx += u.x; camvy += u.y; camvz += u.z; camvx /= 1.41; camvy /= 1.41; camvz /= 1.41; is_clipping = false; } } } bool is_colliding(float dtime) { for(int k = 0; k < current_room->map_size; k++) { double dist = distance_pt_cube_0_3d_infinite(camx, camy, camz, current_room->map[k]); if(dist <= min_dist) { if(updateForces) { updateF(current_room->map[k], (double)dtime); } return true; } } for(int k = 0; k < current_room->tps_size; k++) { double dist = distance_pt_cube_0_3d_infinite(camx, camy, camz, current_room->tps[k]->hitbox); if(dist <= min_dist) { if(updateForces) { updateF(current_room->tps[k]->hitbox, (double)dtime); } int old_chx = player_chx; int old_chy = player_chy; player_chx = current_room->tps[k]->dest_chx; player_chy = current_room->tps[k]->dest_chy; current_room = hashtbl_find_opt(visited, player_chx, player_chy); set_player_coords(old_chx, old_chy); resetProj(); return true; } } for(int k = 0; k < current_room->ent_len; k++) { double dist = distance_pt_cube_0_3d_infinite(camx, camy, camz, current_room->ents[k]->pos); if(dist <= min_dist) { if(current_room->ents[k]->onHit != NULL) { (*current_room->ents[k]->onHit)(dtime, current_room->ents[k]->hitpoints, ¤t_room->ents[k]->damage, current_room->ents[k], &(*(current_room->ents[k]->pos))); if(*(current_room->ents[k]->hitpoints) <= 0) { if(current_room->ents[k]->onDeath != NULL) { (*current_room->ents[k]->onDeath)(dtime); } remove_entity(current_room->ents, ¤t_room->ent_memlen, ¤t_room->ent_len, k); } else { if(updateForces) { updateF(current_room->ents[k]->pos, (double)dtime); } } } return true; } } return false; } void movePlayerG(float dtime) { updateForces = true; fx = 0.0; fy = 0.0; fz = 0.0; camvy -= gravity_factor*dtime; bool isfalling = camvy < 0.0; double delx = camvx*dtime; double dely = camvy*dtime; double delz = camvz*dtime; camx += delx; camy += dely; camz += delz; is_clipping = true; if(is_colliding(dtime)) { if(is_clipping) { player_hp -= (dtime)*clip_dps; } //printf("HIT\n"); //printf("[%lf, %lf, %lf]\n{%lf, %lf, %lf}\n\n", fx, fy, fz, camvx, camvy, camvz); } camx -= delx; camy -= dely; camz -= delz; //printf("%lf | %lf | %lf\n", fx, fy, fz); updateForces = false; camvx += fx*dtime; camvy += fy*dtime; camvz += fz*dtime; //printf("%lf | %lf | %lf\n\n", camvx, camvy, camvz); if(isfalling && camvy > 0.0) { njumps = 3; } camx += camvx*dtime; camy += camvy*dtime; camz += camvz*dtime; camvx *= (1.0 - friction*((double)(dtime))); camvz *= (1.0 - friction*((double)(dtime))); } void teleport_on_edge() { if(camx >= room_width) { camx -= 2.0*room_width; player_chx += 1; current_room = hashtbl_find_opt(visited, player_chx, player_chy); resetProj(); } else if(camx <= -room_width) { camx += 2.0*room_width; player_chx -= 1; current_room = hashtbl_find_opt(visited, player_chx, player_chy); resetProj(); } else if(camz >= room_depth) { camz -= 2.0*room_depth; player_chy += 1; current_room = hashtbl_find_opt(visited, player_chx, player_chy); resetProj(); } else if(camz <= -room_depth) { camz += 2.0*room_depth; player_chy -= 1; current_room = hashtbl_find_opt(visited, player_chx, player_chy); resetProj(); } }