More missile safety

main
Cameron Murphy Reikes 2 years ago
parent 082d3a8e42
commit 847e4b835d

@ -1156,7 +1156,9 @@ SerMaybeFailure ser_entity(SerState *ser, GameState *gs, Entity *e)
{ {
SER_MAYBE_RETURN(ser_V2(ser, &e->explosion_pos)); SER_MAYBE_RETURN(ser_V2(ser, &e->explosion_pos));
SER_MAYBE_RETURN(ser_V2(ser, &e->explosion_vel)); SER_MAYBE_RETURN(ser_V2(ser, &e->explosion_vel));
SER_VAR(&e->explosion_progresss); SER_VAR(&e->explosion_progress);
SER_VAR(&e->explosion_push_strength);
SER_VAR(&e->explosion_radius);
} }
SER_VAR(&e->is_sun); SER_VAR(&e->is_sun);
@ -1690,25 +1692,27 @@ static bool scanner_filter(Entity *e)
static float cur_explosion_damage = 0.0f; static float cur_explosion_damage = 0.0f;
static V2 explosion_origin = {0}; static V2 explosion_origin = {0};
static float explosion_push_strength = 0.0f;
static void explosion_callback_func(cpShape *shape, cpContactPointSet *points, void *data) static void explosion_callback_func(cpShape *shape, cpContactPointSet *points, void *data)
{ {
GameState *gs = (GameState *)data; GameState *gs = (GameState *)data;
cp_shape_entity(shape)->damage += cur_explosion_damage; cp_shape_entity(shape)->damage += cur_explosion_damage;
Entity *parent = get_entity(gs, cp_shape_entity(shape)->shape_parent_entity); Entity *parent = get_entity(gs, cp_shape_entity(shape)->shape_parent_entity);
V2 from_pos = entity_pos(cp_shape_entity(shape)); V2 from_pos = entity_pos(cp_shape_entity(shape));
V2 impulse = V2scale(V2normalize(V2sub(from_pos, explosion_origin)), EXPLOSION_PUSH_STRENGTH); V2 impulse = V2scale(V2normalize(V2sub(from_pos, explosion_origin)), explosion_push_strength);
assert(parent->body != NULL); assert(parent->body != NULL);
cpBodyApplyImpulseAtWorldPoint(parent->body, v2_to_cp(impulse), v2_to_cp(from_pos)); cpBodyApplyImpulseAtWorldPoint(parent->body, v2_to_cp(impulse), v2_to_cp(from_pos));
} }
static void do_explosion(GameState *gs, Entity *explosion, float dt) static void do_explosion(GameState *gs, Entity *explosion, float dt)
{ {
cur_explosion_damage = dt * EXPLOSION_DAMAGE_PER_SEC;
explosion_origin = explosion->explosion_pos;
cpBody *tmpbody = cpBodyNew(0.0f, 0.0f); cpBody *tmpbody = cpBodyNew(0.0f, 0.0f);
cpShape *circle = cpCircleShapeNew(tmpbody, EXPLOSION_RADIUS, v2_to_cp(explosion_origin)); cpShape *circle = cpCircleShapeNew(tmpbody, explosion->explosion_radius, v2_to_cp(explosion_origin));
cur_explosion_damage = dt * EXPLOSION_DAMAGE_PER_SEC;
explosion_origin = explosion->explosion_pos;
explosion_push_strength = explosion->explosion_push_strength;
cpSpaceShapeQuery(gs->space, circle, explosion_callback_func, (void *)gs); cpSpaceShapeQuery(gs->space, circle, explosion_callback_func, (void *)gs);
cpShapeFree(circle); cpShapeFree(circle);
@ -2450,10 +2454,10 @@ void process(GameState *gs, float dt)
if (e->is_explosion) if (e->is_explosion)
{ {
e->explosion_progresss += dt; e->explosion_progress += dt;
e->explosion_pos = V2add(e->explosion_pos, V2scale(e->explosion_vel, dt)); e->explosion_pos = V2add(e->explosion_pos, V2scale(e->explosion_vel, dt));
do_explosion(gs, e, dt); do_explosion(gs, e, dt);
if (e->explosion_progresss >= EXPLOSION_TIME) if (e->explosion_progress >= EXPLOSION_TIME)
{ {
entity_destroy(gs, e); entity_destroy(gs, e);
} }
@ -2466,13 +2470,14 @@ void process(GameState *gs, float dt)
e->time_burned_for += dt; e->time_burned_for += dt;
cpBodyApplyForceAtWorldPoint(e->body, v2_to_cp(V2rotate((V2){.x = MISSILE_BURN_FORCE, .y = 0.0f}, entity_rotation(e))), v2_to_cp(entity_pos(e))); cpBodyApplyForceAtWorldPoint(e->body, v2_to_cp(V2rotate((V2){.x = MISSILE_BURN_FORCE, .y = 0.0f}, entity_rotation(e))), v2_to_cp(entity_pos(e)));
} }
if (e->damage >= MISSILE_DAMAGE_THRESHOLD) if (e->damage >= MISSILE_DAMAGE_THRESHOLD && e->time_burned_for >= MISSILE_ARM_TIME)
{ {
Entity *explosion = new_entity(gs); Entity *explosion = new_entity(gs);
explosion->is_explosion = true; explosion->is_explosion = true;
explosion->explosion_pos = entity_pos(e); explosion->explosion_pos = entity_pos(e);
explosion->explosion_vel = cp_to_v2(cpBodyGetVelocity(e->body)); explosion->explosion_vel = cp_to_v2(cpBodyGetVelocity(e->body));
explosion->explosion_push_strength = MISSILE_EXPLOSION_PUSH;
explosion->explosion_radius = MISSILE_EXPLOSION_RADIUS;
entity_destroy(gs, e); entity_destroy(gs, e);
} }
} }
@ -2490,6 +2495,8 @@ void process(GameState *gs, float dt)
explosion->is_explosion = true; explosion->is_explosion = true;
explosion->explosion_pos = entity_pos(e); explosion->explosion_pos = entity_pos(e);
explosion->explosion_vel = grid_vel(box_grid(e)); explosion->explosion_vel = grid_vel(box_grid(e));
explosion->explosion_push_strength = BOMB_EXPLOSION_PUSH;
explosion->explosion_radius = BOMB_EXPLOSION_RADIUS;
if (!e->is_platonic) if (!e->is_platonic)
grid_remove_box(gs, get_entity(gs, e->shape_parent_entity), e); grid_remove_box(gs, get_entity(gs, e->shape_parent_entity), e);
} }

@ -1930,8 +1930,8 @@ static void frame(void)
{ {
sgp_set_image(0, image_explosion); sgp_set_image(0, image_explosion);
sgp_set_color(1.0f, 1.0f, 1.0f, sgp_set_color(1.0f, 1.0f, 1.0f,
1.0f - (e->explosion_progresss / EXPLOSION_TIME)); 1.0f - (e->explosion_progress / EXPLOSION_TIME));
draw_texture_centered(e->explosion_pos, EXPLOSION_RADIUS * 2.0f); draw_texture_centered(e->explosion_pos, e->explosion_radius * 2.0f);
sgp_reset_image(0); sgp_reset_image(0);
} }
} }

@ -10,11 +10,12 @@
#define MERGE_MAX_DIST (BOX_SIZE / 2.0f + 0.01f) #define MERGE_MAX_DIST (BOX_SIZE / 2.0f + 0.01f)
#define PLAYER_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE}) #define PLAYER_SIZE ((V2){.x = BOX_SIZE, .y = BOX_SIZE})
#define PLAYER_MASS 0.5f #define PLAYER_MASS 0.5f
#define PLAYER_JETPACK_FORCE 4.0f #define PLAYER_JETPACK_FORCE 2.0f
#define PLAYER_JETPACK_TORQUE 0.05f #define PLAYER_JETPACK_TORQUE 0.05f
#define MISSILE_RANGE 4.0f #define MISSILE_RANGE 4.0f
#define MISSILE_BURN_TIME 1.5f #define MISSILE_BURN_TIME 1.5f
#define MISSILE_BURN_FORCE 2.0f #define MISSILE_ARM_TIME 0.5f
#define MISSILE_BURN_FORCE 4.0f
#define MISSILE_MASS 1.0f #define MISSILE_MASS 1.0f
// how many missiles grown per second // how many missiles grown per second
#define MISSILE_DAMAGE_THRESHOLD 0.2f #define MISSILE_DAMAGE_THRESHOLD 0.2f
@ -51,13 +52,17 @@
#define BATTERY_CAPACITY 1.5f #define BATTERY_CAPACITY 1.5f
#define PLAYER_ENERGY_RECHARGE_PER_SECOND 0.2f #define PLAYER_ENERGY_RECHARGE_PER_SECOND 0.2f
#define EXPLOSION_TIME 0.5f #define EXPLOSION_TIME 0.5f
#define EXPLOSION_PUSH_STRENGTH 5.0f
#define EXPLOSION_DAMAGE_PER_SEC 10.0f #define EXPLOSION_DAMAGE_PER_SEC 10.0f
#define EXPLOSION_RADIUS 1.0f
#define EXPLOSION_DAMAGE_THRESHOLD 0.2f // how much damage until it explodes #define EXPLOSION_DAMAGE_THRESHOLD 0.2f // how much damage until it explodes
#define GOLD_UNLOCK_RADIUS 1.0f #define GOLD_UNLOCK_RADIUS 1.0f
#define TIME_BETWEEN_WORLD_SAVE 30.0f #define TIME_BETWEEN_WORLD_SAVE 30.0f
#define MISSILE_EXPLOSION_PUSH 2.5f
#define MISSILE_EXPLOSION_RADIUS 0.4f
#define BOMB_EXPLOSION_PUSH 5.0f
#define BOMB_EXPLOSION_RADIUS 1.0f
// VOIP // VOIP
#define VOIP_PACKET_BUFFER_SIZE 15 // audio. Must be bigger than 2 #define VOIP_PACKET_BUFFER_SIZE 15 // audio. Must be bigger than 2
#define VOIP_EXPECTED_FRAME_COUNT 240 #define VOIP_EXPECTED_FRAME_COUNT 240
@ -255,7 +260,9 @@ typedef struct Entity
bool is_explosion; bool is_explosion;
V2 explosion_pos; V2 explosion_pos;
V2 explosion_vel; V2 explosion_vel;
float explosion_progresss; // in seconds float explosion_progress; // in seconds
float explosion_push_strength;
float explosion_radius;
// sun // sun
bool is_sun; bool is_sun;
@ -266,7 +273,7 @@ typedef struct Entity
// missile // missile
bool is_missile; bool is_missile;
float time_burned_for; // until MISSILE_BURN_TIME float time_burned_for; // until MISSILE_BURN_TIME. Before MISSILE_ARM_TIME cannot explode
// grids // grids
bool is_grid; bool is_grid;

Loading…
Cancel
Save