677 lines
23 KiB
C
677 lines
23 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include <unistd.h>
|
|
#include <termios.h>
|
|
#include <limits.h>
|
|
#include <time.h>
|
|
#include <glad/glad.h>
|
|
#include <GLFW/glfw3.h>
|
|
#include <cglm/cglm.h>
|
|
|
|
#include "hash.h"
|
|
#include "base.h"
|
|
#include "entities.h"
|
|
#include "proj.h"
|
|
#include "move.h"
|
|
#include "display.h"
|
|
#include "music.h"
|
|
|
|
// ---------------------------------------------------------------------------------------------------- //
|
|
double sensitivity = 0.06;
|
|
double fov = 90.0;
|
|
double creative_speed = 0.5;
|
|
double speed = 5.0;
|
|
double vtmult = 2.7;
|
|
double min_dist = 0.4;
|
|
double friction = 0.3;
|
|
double gravity_factor = 26.0;
|
|
// ---------------------------------------------------------------------------------------------------- //
|
|
|
|
const double blockRestitution = 0.2;
|
|
|
|
entity* entToVelCheck = NULL;
|
|
bool doUpdateEntVel = false;
|
|
|
|
entity* movingPlatformUpdate = NULL;
|
|
bool doUpdateMoving = false;
|
|
|
|
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;
|
|
|
|
float dmgCD;
|
|
int lastDmg;
|
|
|
|
bool buttonSwitch[16];
|
|
float buttonTimes[16];
|
|
float buttonMaxT[16];
|
|
|
|
bool mathSignal;
|
|
int mathSigCD;
|
|
|
|
void init_csts() {
|
|
camx = 2.0;
|
|
camy = 5.0;
|
|
camz = 2.0;
|
|
player_chx = 0;
|
|
player_chy = 0;
|
|
camvx = 0.0;
|
|
camvy = 0.0;
|
|
camvz = 0.0;
|
|
rot_hz = 0.0;
|
|
rot_vt = 0.0;
|
|
|
|
room_width = 16.0;
|
|
room_depth = 16.0;
|
|
|
|
coins = 0;
|
|
player_hp = 1000;
|
|
njumps = 1;
|
|
|
|
draw_type = 0;
|
|
fade_dmg = 0;
|
|
|
|
mathSignal = false;
|
|
mathSigCD = 4;
|
|
|
|
for(int k = 0; k < 16; k++) {
|
|
buttonTimes[k] = 0.0f;
|
|
buttonSwitch[k] = false;
|
|
buttonMaxT[k] = 0.0f;
|
|
}
|
|
|
|
dmgCD = 0.0f;
|
|
lastDmg = player_hp;
|
|
|
|
stop_evetything = false;
|
|
tan_fov = tan((fov * 3.14159 / 180.0) / 2.0);
|
|
sq2 = sqrt(2);
|
|
}
|
|
|
|
void update_buttons(float dtime) {
|
|
for(int k = 0; k < 16; k++) {
|
|
if(buttonSwitch[k]) {
|
|
if(buttonTimes[k] <= dtime && buttonMaxT[k] > 0.0) {
|
|
buttonTimes[k] = 0.0f;
|
|
buttonSwitch[k] = false;
|
|
} else {
|
|
buttonTimes[k] -= dtime;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
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;
|
|
}
|
|
}
|
|
// no TP has been found, placing to the middle of the room
|
|
camx = 0.0;
|
|
camy = 10.0;
|
|
camz = 0.0;
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
pt_2d cross_product(pt_2d p1, pt_2d p2) {
|
|
return (pt_2d){
|
|
.x = p1.y*p2.z - p1.z*p2.y,
|
|
.y = p1.z*p2.x - p1.x*p2.z,
|
|
.z = p1.x*p2.y - p1.y*p2.x
|
|
};
|
|
}
|
|
|
|
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 debugMove(cube_0* cb) {
|
|
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;
|
|
for(int k = 0; k < 3; k++) {
|
|
cube_0* cb2 = create_cube_0(surface[k].x-0.1, surface[k].y-0.1, surface[k].z-0.1, 0.2, 0.2, 0.2, 0.0, 0.0, 255, 255, 255);
|
|
|
|
gl_renderCube(cb2, 0.0, 0.0, 0.0);
|
|
|
|
free(cb2);
|
|
}
|
|
}
|
|
}
|
|
|
|
void updateF_movableCrate(cube_0* cb, double dtime, entity* ent) {
|
|
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 || d==5 || d==1) {
|
|
normal.x *= -1.0;
|
|
normal.y *= -1.0;
|
|
normal.z *= -1.0;
|
|
}
|
|
//printf("%lf %lf\n", dot3D(normal, directors[0]), dot3D(normal, directors[1]));
|
|
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);
|
|
switch (d) {
|
|
case 0:
|
|
ent->metad1 += camvx; break;
|
|
case 1:
|
|
ent->metad1 += camvx; break;
|
|
case 3:
|
|
break;
|
|
case 2:
|
|
ent->metad2 += camvy; break;
|
|
case 4:
|
|
ent->metad3 += camvz; break;
|
|
case 5:
|
|
ent->metad3 += camvz; break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
pt_2d normal_axis = {.x = 0.0, .y = 1.0, .z = 0.0};
|
|
pt_2d normal_axis2 = {.x = 1.0, .y = 0.0, .z = 0.0};
|
|
// rotation axis
|
|
|
|
void updateF(cube_0* cb, double dtime, entity* ent) {
|
|
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 || d==5 || d==1) {
|
|
normal.x *= -1.0;
|
|
normal.y *= -1.0;
|
|
normal.z *= -1.0;
|
|
}
|
|
//printf("%lf %lf\n", dot3D(normal, directors[0]), dot3D(normal, directors[1]));
|
|
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 = normv*sqrt(1-cos(beta));
|
|
|
|
pt_2d u = (pt_2d){.x = normal.x*nu, .y = normal.y*nu, .z = normal.z*nu};
|
|
|
|
normalize(&u);
|
|
|
|
if(ent != NULL && ent->entity_type == 2) {
|
|
double radspeed = distance_pt_pt_3d(camx, camy, camz, ent->metad4+ent->pos->w/2.0, camy, ent->metad6+ent->pos->d/2.0
|
|
)*(ent->metad1);
|
|
double radspeed2 = distance_pt_pt_3d(camx, camy, camz, camx, ent->metad5+ent->pos->h/2.0, ent->metad6+ent->pos->d/2.0
|
|
)*(ent->metad2);
|
|
|
|
pt_2d camD;
|
|
camD.x = camx - ent->pos->w/2.0 - ent->metad4;
|
|
camD.y = 0.0;
|
|
camD.z = camz - ent->pos->d/2.0 - ent->metad6;
|
|
if(camD.x*camD.x + camD.y*camD.y + camD.z*camD.z >= 0.001) { // avoid division by 0.0
|
|
normalize(&camD);
|
|
}
|
|
pt_2d utheta = cross_product(camD, normal_axis);
|
|
|
|
pt_2d camD2;
|
|
camD2.x = 0.0;
|
|
camD2.y = camy - ent->pos->h/2.0 - ent->metad5;
|
|
camD2.z = camz - ent->pos->d/2.0 - ent->metad6;
|
|
if(camD2.x*camD2.x + camD2.y*camD2.y + camD2.z*camD2.z >= 0.001) { // avoid division by 0.0
|
|
normalize(&camD2);
|
|
}
|
|
pt_2d utheta2 = cross_product(camD2, normal_axis2);
|
|
|
|
//printf("(HZ) %lf %lf %lf\n", utheta.x*radspeed , utheta.y*radspeed , utheta.z*radspeed );
|
|
//printf("(VT) %lf %lf %lf\n\n", utheta2.x*radspeed2, utheta2.y*radspeed2, utheta2.z*radspeed2);
|
|
|
|
camvx = u.x*normv*(blockRestitution) + utheta.x*radspeed + utheta2.x*radspeed2;
|
|
camvy = u.y*normv*(blockRestitution) + utheta.y*radspeed + utheta2.y*radspeed2;
|
|
camvz = u.z*normv*(blockRestitution) + utheta.z*radspeed + utheta2.z*radspeed2;
|
|
} else {
|
|
camvx = u.x*normv*(blockRestitution);
|
|
camvy = u.y*normv*(blockRestitution);
|
|
camvz = u.z*normv*(blockRestitution);
|
|
}
|
|
|
|
is_clipping = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void updateF_specific(cube_0* cb, double dtime, entity* ent) {
|
|
double dilat = distance_pt_cube_0_3d_infinite(camx, camy, camz, cb);
|
|
for(int d = 0; d < 6; d++) {
|
|
|
|
// force a collision
|
|
cb->x -= dilat;
|
|
cb->y -= dilat;
|
|
cb->z -= dilat;
|
|
getSF(cb, d);
|
|
cb->x += dilat;
|
|
cb->y += dilat;
|
|
cb->z += dilat;
|
|
getDirectors();
|
|
getNormal();
|
|
if(d==2 || d==5 || d==1) {
|
|
normal.x *= -1.0;
|
|
normal.y *= -1.0;
|
|
normal.z *= -1.0;
|
|
}
|
|
//printf("%lf %lf\n", dot3D(normal, directors[0]), dot3D(normal, directors[1]));
|
|
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)
|
|
) {
|
|
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 = normv*sqrt(1-cos(beta));
|
|
|
|
pt_2d u = (pt_2d){.x = normal.x*nu, .y = normal.y*nu, .z = normal.z*nu};
|
|
|
|
normalize(&u);
|
|
|
|
camvx = u.x*normv*(blockRestitution);
|
|
camvy = u.y*normv*(blockRestitution);
|
|
camvz = u.z*normv*(blockRestitution);
|
|
|
|
is_clipping = false;
|
|
}
|
|
}
|
|
|
|
|
|
if(ent != NULL && ent->entity_type == 2) {
|
|
double radspeed = distance_pt_pt_3d(camx, camy, camz, ent->metad4+ent->pos->w/2.0, camy, ent->metad6+ent->pos->d/2.0
|
|
)*(ent->metad1);
|
|
double radspeed2 = distance_pt_pt_3d(camx, camy, camz, camx, ent->metad5+ent->pos->h/2.0, ent->metad6+ent->pos->d/2.0
|
|
)*(ent->metad2);
|
|
|
|
pt_2d camD;
|
|
camD.x = camx - ent->pos->w/2.0 - ent->metad4;
|
|
camD.y = 0.0;
|
|
camD.z = camz - ent->pos->d/2.0 - ent->metad6;
|
|
if(camD.x*camD.x + camD.y*camD.y + camD.z*camD.z >= 0.001) { // avoid division by 0.0
|
|
normalize(&camD);
|
|
}
|
|
pt_2d utheta = cross_product(camD, normal_axis);
|
|
|
|
pt_2d camD2;
|
|
camD2.x = 0.0;
|
|
camD2.y = camy - ent->pos->h/2.0 - ent->metad5;
|
|
camD2.z = camz - ent->pos->d/2.0 - ent->metad6;
|
|
if(camD2.x*camD2.x + camD2.y*camD2.y + camD2.z*camD2.z >= 0.001) { // avoid division by 0.0
|
|
normalize(&camD2);
|
|
}
|
|
pt_2d utheta2 = cross_product(camD2, normal_axis2);
|
|
|
|
//printf("(HZ) %lf %lf %lf\n", utheta.x*radspeed , utheta.y*radspeed , utheta.z*radspeed );
|
|
//printf("(VT) %lf %lf %lf\n\n", utheta2.x*radspeed2, utheta2.y*radspeed2, utheta2.z*radspeed2);
|
|
|
|
camvx = utheta.x*radspeed + utheta2.x*radspeed2;
|
|
camvy = utheta.y*radspeed + utheta2.y*radspeed2;
|
|
camvz = utheta.z*radspeed + utheta2.z*radspeed2;
|
|
}
|
|
//printf("\n");
|
|
}
|
|
|
|
bool update_physics = true;
|
|
bool is_colliding(float dtime) {
|
|
bool globalCollision = false;
|
|
if(doUpdateEntVel) {
|
|
updateF_movableCrate(entToVelCheck->pos, (double)dtime, entToVelCheck);
|
|
doUpdateEntVel = false;
|
|
}
|
|
if(doUpdateMoving) {
|
|
updateF_specific(movingPlatformUpdate->pos, (double)dtime, movingPlatformUpdate);
|
|
doUpdateMoving = false;
|
|
}
|
|
for(int w = -1; w <= 1; w++) {
|
|
for(int h = -1; h <= 1; h++) {
|
|
room* vstd = hashtbl_find_opt(visited, player_chx+w, player_chy+h);
|
|
if(vstd != NULL) {
|
|
for(int k = 0; k < vstd->map_size; k++) {
|
|
double dist = distance_pt_cube_0_3d_infinite(camx-2*room_width*w, camy, camz-2*room_depth*h, vstd->map[k]);
|
|
//if(vstd->map[k]->vt_angle != 0.0) {
|
|
// printf("(%lf)\n", dist);
|
|
//}
|
|
if(dist <= min_dist) {
|
|
if(update_physics && updateForces) {
|
|
updateF(vstd->map[k], (double)dtime, NULL);
|
|
}
|
|
globalCollision = true;
|
|
}
|
|
}
|
|
|
|
for(int k = 0; k < vstd->tps_size; k++) {
|
|
double dist = distance_pt_cube_0_3d_infinite(camx-2*room_width*w, camy, camz-2*room_depth*h, vstd->tps[k]->hitbox);
|
|
if(dist <= min_dist) {
|
|
if(update_physics && updateForces) {
|
|
updateF(vstd->tps[k]->hitbox, (double)dtime, NULL);
|
|
}
|
|
int old_chx = player_chx;
|
|
int old_chy = player_chy;
|
|
player_chx = vstd->tps[k]->dest_chx;
|
|
player_chy = vstd->tps[k]->dest_chy;
|
|
vstd = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
set_player_coords(old_chx, old_chy);
|
|
resetProj();
|
|
globalCollision = true;
|
|
}
|
|
}
|
|
|
|
for(int k = 0; k < vstd->ent_len; k++) {
|
|
//printf("%d -> %d\n", k, vstd->ents[k]->entity_type);
|
|
if(
|
|
(vstd->ents[k]->entity_type != 12 || xor(buttonSwitch[vstd->ents[k]->metai1], vstd->ents[k]->metai2)) && // disabled button block
|
|
(vstd->ents[k]->entity_type != 9 || vstd->ents[k]->metai1) && // off-beat block
|
|
(vstd->ents[k]->entity_type != 13 || (vstd->ents[k]->metad1 == 0.0 || vstd->ents[k]->metai1 == 0)) // hollow math block
|
|
) {
|
|
double dist = distance_pt_cube_0_3d_infinite(camx-2*room_width*w, camy, camz-2*room_depth*h, vstd->ents[k]->pos);
|
|
//printf("%lf vs %lf\n", dist, min_dist);
|
|
if(dist <= min_dist) {
|
|
bool exists = true;
|
|
if(vstd->ents[k]->onHit != NULL) {
|
|
(*vstd->ents[k]->onHit)(dtime, vstd->ents[k]->hitpoints, &vstd->ents[k]->damage, vstd->ents[k], &(*(vstd->ents[k]->pos)));
|
|
if(*(vstd->ents[k]->hitpoints) <= 0) {
|
|
if(vstd->ents[k]->onDeath != NULL) {
|
|
(*vstd->ents[k]->onDeath)(dtime);
|
|
}
|
|
if(vstd->ents[k]->entity_type == 0) {
|
|
play_sound("sound/audio/smw_coin.wav");
|
|
}
|
|
remove_entity(vstd->ents, &vstd->ent_memlen, &vstd->ent_len, k);
|
|
is_clipping = false;
|
|
exists = false;
|
|
k =- 1;
|
|
}
|
|
}
|
|
if(update_physics && exists && updateForces && vstd->ents[k]->entity_type != 0) {
|
|
updateF(vstd->ents[k]->pos, (double)dtime, vstd->ents[k]);
|
|
}
|
|
if(exists && (
|
|
vstd->ents[k]->entity_type == 13 ||
|
|
vstd->ents[k]->entity_type == 9 ||
|
|
vstd->ents[k]->entity_type == 4 ||
|
|
vstd->ents[k]->entity_type == 5
|
|
)) {
|
|
is_clipping = false;
|
|
}
|
|
globalCollision = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return globalCollision;
|
|
}
|
|
|
|
double old_camx = 0.0;
|
|
double old_camy = 0.0;
|
|
double old_camz = 0.0;
|
|
|
|
void movePlayerG(float dtime) {
|
|
old_camx = camx;
|
|
old_camy = camy;
|
|
old_camz = camz;
|
|
|
|
updateForces = true;
|
|
fx = 0.0;
|
|
fy = 0.0;
|
|
fz = 0.0;
|
|
|
|
camvy -= gravity_factor*dtime;
|
|
bool isfalling = camvy < 0.0;
|
|
|
|
double oldvy = camvy;
|
|
|
|
double delx = camvx*dtime;
|
|
double dely = camvy*dtime;
|
|
double delz = camvz*dtime;
|
|
camx += delx;
|
|
camy += dely;
|
|
camz += delz;
|
|
is_clipping = true;
|
|
update_physics = 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 = 1;
|
|
//printf("%lf\n", absf(oldvy));
|
|
if(is_HR==1 && absf(oldvy) >= 15.0) {
|
|
player_hp -= (int)(0.75*absf(oldvy));
|
|
}
|
|
}
|
|
camx += camvx*dtime;
|
|
camy += camvy*dtime;
|
|
camz += camvz*dtime;
|
|
|
|
camvx *= (1.0 - friction*((double)(dtime)));
|
|
camvy *= (1.0 - friction*((double)(dtime)));
|
|
camvz *= (1.0 - friction*((double)(dtime)));
|
|
|
|
if(camy <= -48) {
|
|
camx = 0.0;
|
|
camz = 0.0;
|
|
camy = 5.0;
|
|
camvx = 0.0;
|
|
camvy = 0.0;
|
|
camvz = 0.0;
|
|
player_chx = 0;
|
|
player_chy = 0;
|
|
if(is_HR==1) {
|
|
player_hp = 0;
|
|
} else {
|
|
player_hp -= 250;
|
|
}
|
|
current_room = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
resetProj();
|
|
}
|
|
|
|
update_physics = false;
|
|
if(is_colliding(dtime)) {
|
|
camx = old_camx;
|
|
camy = old_camy;
|
|
camz = old_camz;
|
|
}
|
|
}
|
|
|
|
void teleport_on_edge() {
|
|
if(camx >= room_width) {
|
|
if(!is_one_room) {
|
|
camx -= 2.0*room_width;
|
|
player_chx += 1;
|
|
current_room = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
resetProj();
|
|
}
|
|
} else if(camx <= -room_width) {
|
|
if(!is_one_room) {
|
|
camx += 2.0*room_width;
|
|
player_chx -= 1;
|
|
current_room = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
resetProj();
|
|
}
|
|
} else if(camz >= room_depth) {
|
|
if(!is_one_room) {
|
|
camz -= 2.0*room_depth;
|
|
player_chy += 1;
|
|
current_room = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
resetProj();
|
|
}
|
|
} else if(camz <= -room_depth) {
|
|
if(!is_one_room) {
|
|
camz += 2.0*room_depth;
|
|
player_chy -= 1;
|
|
current_room = hashtbl_find_opt(visited, player_chx, player_chy);
|
|
resetProj();
|
|
}
|
|
}
|
|
} |