180 lines
6.4 KiB
C
180 lines
6.4 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <math.h>
|
|
#include <stdbool.h>
|
|
#include <ncurses.h>
|
|
#include <unistd.h>
|
|
#include <termios.h>
|
|
#include <limits.h>
|
|
#include <time.h>
|
|
#include <SDL2/SDL.h>
|
|
#include <SDL2/SDL_image.h>
|
|
|
|
#include "structure.h"
|
|
#include "hash.h"
|
|
#include "base.h"
|
|
#include "move.h"
|
|
#include "entities.h"
|
|
#include "proj.h"
|
|
|
|
projectile** bullets ;
|
|
int bullets_id ;
|
|
|
|
double psize = 1.5;
|
|
|
|
pt_2d build_pt(double x, double y, double z) {
|
|
pt_2d res;
|
|
res.x = x ;
|
|
res.y = y ;
|
|
res.z = z ;
|
|
return res;
|
|
}
|
|
|
|
void init_proj() {
|
|
bullets = malloc(sizeof(projectile*)*MAX_SIZE);
|
|
for(int k = 0; k < MAX_SIZE; k++) {
|
|
bullets[k] = malloc(sizeof(projectile));
|
|
bullets[k]->pos = build_pt(0.0, 0.0, 0.0);
|
|
bullets[k]->vel = build_pt(0.0, 0.0, 0.0);
|
|
bullets[k]->acc = build_pt(0.0, 0.0, 0.0);
|
|
bullets[k]->size = 1.0;
|
|
bullets[k]->ttl = 1.0;
|
|
bullets[k]->red = 0;
|
|
bullets[k]->green = 0;
|
|
bullets[k]->blue = 0;
|
|
bullets[k]->damage = 0;
|
|
}
|
|
bullets_id = 0;
|
|
}
|
|
|
|
bool is_proj_colliding_with_map(double x, double y, double z, double size) {
|
|
for(int k = 0; k < current_room->map_size; k++) {
|
|
if(distance_pt_cube_0_3d(x+size/2, y+size/2, z+size/2, current_room->map[k]) <= size/2) {
|
|
return true ;
|
|
}
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
bool is_proj_colliding_with_tp(double x, double y, double z, double size) {
|
|
for(int k = 0; k < current_room->tps_size; k++) {
|
|
for(int d = 0; d < 8; d++) {
|
|
if(distance_pt_cube_0_3d(x+size/2, y+size/2, z+size/2, current_room->tps[k].hitbox) <= size/2) {
|
|
return true ;
|
|
}
|
|
}
|
|
}
|
|
return false ;
|
|
}
|
|
|
|
bool is_proj_colliding_w_player(double x, double y, double z, double size) {
|
|
return (distance_pt_pt_3d(x, y, z, camx, camy, camz) <= size);
|
|
}
|
|
|
|
double ppx, ppy, ppz;
|
|
double projx, projy;
|
|
void addProjectileToDraw(projectile* proj) {
|
|
if(triangles_i < MAX_SIZE-1) {
|
|
project_to_camera(proj->pos.x, proj->pos.y, proj->pos.z, &ppx, &ppy, &ppz);
|
|
if(ppz >= draw_constant) {
|
|
projx = 1500.0 * (1.0 + (ppx / (1.5 * ppz * tan_fov))) / 2.0;
|
|
projy = 1000.0 * (1.0 + (ppy / (ppz * tan_fov))) / 2.0;
|
|
double rpsize = (40.0*psize/maxd(0.07, ppz));
|
|
//printf("%lf\n", rpsize);
|
|
triangles_to_render[triangles_i][0] = build_pt(projx-rpsize/2, projy-rpsize/2, 0.0);
|
|
triangles_to_render[triangles_i][1] = build_pt(projx-rpsize/2, projy+rpsize/2, 0.0);
|
|
triangles_to_render[triangles_i][2] = build_pt(projx+rpsize/2, projy+rpsize/2, 0.0);
|
|
triangles_og_coords[triangles_i][0] = build_pt(ppx, ppy, ppz);
|
|
triangles_og_coords[triangles_i][1] = build_pt(ppx, ppy, ppz);
|
|
triangles_og_coords[triangles_i][2] = build_pt(ppx, ppy, ppz);
|
|
reds[triangles_i] = proj->red;
|
|
greens[triangles_i] = proj->green;
|
|
blues[triangles_i] = proj->blue;
|
|
triangles_i += 1;
|
|
|
|
triangles_to_render[triangles_i][0] = build_pt(projx-rpsize/2, projy-rpsize/2, 0.0);
|
|
triangles_to_render[triangles_i][1] = build_pt(projx+rpsize/2, projy-rpsize/2, 0.0);
|
|
triangles_to_render[triangles_i][2] = build_pt(projx+rpsize/2, projy+rpsize/2, 0.0);
|
|
triangles_og_coords[triangles_i][0] = build_pt(ppx, ppy, ppz);
|
|
triangles_og_coords[triangles_i][1] = build_pt(ppx, ppy, ppz);
|
|
triangles_og_coords[triangles_i][2] = build_pt(ppx, ppy, ppz);
|
|
reds[triangles_i] = proj->red;
|
|
greens[triangles_i] = proj->green;
|
|
blues[triangles_i] = proj->blue;
|
|
triangles_i += 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawProj() {
|
|
for(int k = 0; k < bullets_id; k++) {
|
|
addProjectileToDraw(bullets[k]);
|
|
}
|
|
}
|
|
|
|
void appendProj(double x, double y, double z, double vx, double vy, double vz, double ax, double ay, double az, int r, int g, int b, int dmg, double ttl) {
|
|
if(bullets_id < MAX_SIZE) {
|
|
bullets[bullets_id]->red = r ;
|
|
bullets[bullets_id]->green = g ;
|
|
bullets[bullets_id]->blue = b ;
|
|
bullets[bullets_id]->size = 1.0 ;
|
|
bullets[bullets_id]->damage = dmg ;
|
|
bullets[bullets_id]->ttl = ttl ;
|
|
bullets[bullets_id]->pos = build_pt(x, y, z) ;
|
|
bullets[bullets_id]->vel = build_pt(vx, vy, vz) ;
|
|
bullets[bullets_id]->acc = build_pt(ax, ay, az) ;
|
|
bullets_id += 1;
|
|
}
|
|
}
|
|
|
|
void removeProj(int k) {
|
|
bullets[k]->red = bullets[bullets_id]->red;
|
|
bullets[k]->green = bullets[bullets_id]->green;
|
|
bullets[k]->blue = bullets[bullets_id]->blue;
|
|
bullets[k]->size = bullets[bullets_id]->size;
|
|
bullets[k]->pos = bullets[bullets_id]->pos;
|
|
bullets[k]->vel = bullets[bullets_id]->vel;
|
|
bullets[k]->acc = bullets[bullets_id]->acc;
|
|
bullets[k]->ttl = bullets[bullets_id]->ttl;
|
|
bullets[k]->damage = bullets[bullets_id]->damage;
|
|
bullets_id -= 1;
|
|
}
|
|
|
|
void updateAllProj(float dtime) {
|
|
for(int k = 0; k < bullets_id; k++) {
|
|
bullets[k]->vel.x += ((double)dtime)*(bullets[k]->acc.x);
|
|
bullets[k]->vel.y += ((double)dtime)*(bullets[k]->acc.y);
|
|
bullets[k]->vel.z += ((double)dtime)*(bullets[k]->acc.z);
|
|
bullets[k]->pos.x += ((double)dtime)*(bullets[k]->vel.x);
|
|
bullets[k]->pos.y += ((double)dtime)*(bullets[k]->vel.y);
|
|
bullets[k]->pos.z += ((double)dtime)*(bullets[k]->vel.z);
|
|
bullets[k]->ttl -= 20.0*(double)dtime;
|
|
//if(k==0) printf("[%d] %lf\n", k, bullets[k]->ttl);
|
|
if(is_proj_colliding_w_player(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size)) {
|
|
if(bullets[k]->damage != 0) {
|
|
player_hp -= bullets[k]->damage ;
|
|
fade_dmg = 255 ;
|
|
}
|
|
removeProj(k);
|
|
k -= 1;
|
|
} else if(bullets[k]->ttl <= 0.0 || (
|
|
is_proj_colliding_with_map(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size) ||
|
|
is_proj_colliding_with_tp(bullets[k]->pos.x - bullets[k]->size/2.0, bullets[k]->pos.y - bullets[k]->size/2.0, bullets[k]->pos.z - bullets[k]->size/2.0, bullets[k]->size)
|
|
)) {
|
|
removeProj(k);
|
|
k -= 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
void resetProj() {
|
|
bullets_id = 0;
|
|
}
|
|
|
|
void free_proj() {
|
|
for(int k = 0; k < MAX_SIZE; k++) {
|
|
free(bullets[k]);
|
|
}
|
|
free(bullets);
|
|
} |