This commit is contained in:
jacob 2026-02-19 18:17:30 -06:00
parent 65ae383d75
commit 2d18116470
5 changed files with 127 additions and 51 deletions

View File

@ -281,6 +281,10 @@ P_Anim P_AnimFromEnt(P_Frame *frame, P_Ent *ent)
{ {
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/GuySpawn.ase"))); result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("prefab/GuySpawn.ase")));
} }
else if (ent->is_bomb)
{
result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/bomb.ase")));
}
if (wep->is_uzi) if (wep->is_uzi)
{ {
@ -2900,6 +2904,8 @@ void P_StepFrame(P_Frame *frame)
Vec2 vel = SubVec2(end, start); Vec2 vel = SubVec2(end, start);
bullet->bullet_start = end; bullet->bullet_start = end;
bullet->bullet_end = AddVec2(end, vel); bullet->bullet_end = AddVec2(end, vel);
bullet->xf.t = bullet->bullet_start;
bullet->xf.r = NormRot(vel);
} }
} }
@ -2913,7 +2919,7 @@ void P_StepFrame(P_Frame *frame)
for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer)) for (P_Ent *firer = P_FirstEnt(frame); !P_IsEntNil(firer); firer = P_NextEnt(firer))
{ {
P_Ent *weapon = P_EntFromKey(frame, firer->weapon); P_Ent *weapon = P_EntFromKey(frame, firer->weapon);
if (weapon->is_weapon && firer->control.fire_held) if (weapon->is_weapon && firer->control.fire_held || firer->control.fire_presses)
// if (weapon->is_weapon && firer->control.fire_presses) // if (weapon->is_weapon && firer->control.fire_presses)
{ {
// i64 fire_delta_ns = frame->time_ns - firer->last_fire_ns; // i64 fire_delta_ns = frame->time_ns - firer->last_fire_ns;
@ -2926,7 +2932,8 @@ void P_StepFrame(P_Frame *frame)
f32 bullets_per_fire = 1; f32 bullets_per_fire = 1;
f32 spread = Tau * 0.05; f32 spread = Tau * 0.05;
// f32 spread = Tau * 0.01; // f32 spread = Tau * 0.01;
f32 tweak_speed = TweakFloat("Bullet speed", 100, 1, 100); f32 bullet_speed = TweakFloat("Bullet speed", 100, 1, 100);
f32 bomb_speed = TweakFloat("Bomb speed", 2, 1, 100);
// f32 tweak_speed = TweakFloat("Bullet speed", 1, 1, 100); // f32 tweak_speed = TweakFloat("Bullet speed", 1, 1, 100);
b32 can_fire = (firer->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns; b32 can_fire = (firer->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns;
@ -3001,6 +3008,8 @@ void P_StepFrame(P_Frame *frame)
// FIXME: Prevent obstructed weapons from firing through walls // FIXME: Prevent obstructed weapons from firing through walls
if (can_fire) if (can_fire)
{
if (weapon->is_uzi)
{ {
i64 tick_bullets_count = bullets_per_fire; i64 tick_bullets_count = bullets_per_fire;
if (tick_bullets_count > 0) if (tick_bullets_count > 0)
@ -3019,7 +3028,7 @@ void P_StepFrame(P_Frame *frame)
f32 rand_speed = Norm24(P_RandU64FromEnt(firer)) - 0.5; f32 rand_speed = Norm24(P_RandU64FromEnt(firer)) - 0.5;
f32 rand_angle = Norm24(P_RandU64FromEnt(firer)) - 0.5; f32 rand_angle = Norm24(P_RandU64FromEnt(firer)) - 0.5;
f32 speed = tweak_speed * sim_dt; f32 speed = bullet_speed * sim_dt;
f32 angle = AngleFromVec2(fire_dir); f32 angle = AngleFromVec2(fire_dir);
speed += (speed * 0.5) * rand_speed; speed += (speed * 0.5) * rand_speed;
@ -3031,12 +3040,55 @@ void P_StepFrame(P_Frame *frame)
bullet->bullet_base1 = fire_base1; bullet->bullet_base1 = fire_base1;
bullet->bullet_start = fire_pos; bullet->bullet_start = fire_pos;
bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed)); bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed));
bullet->xf.t = bullet->bullet_start;
bullet->xf.r = NormRot(dir);
bullet->source = weapon->key; bullet->source = weapon->key;
bullet->damage_attribution = firer->source; bullet->damage_attribution = firer->source;
} }
} }
firer->last_fire_ns = frame->time_ns; firer->last_fire_ns = frame->time_ns;
} }
else if (weapon->is_launcher)
{
i64 tick_bullets_count = bullets_per_fire;
if (tick_bullets_count > 0)
{
P_Shape firer_world_shape = P_WorldShapeFromEnt(firer);
// Vec2 fire_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look);
// Vec2 fire_dir = firer->control.look;
for (i64 bullet_idx = 0; bullet_idx < tick_bullets_count; ++bullet_idx)
{
P_Ent *bomb = P_PushTempEnt(scratch.arena, &bullets_to_spawn);
bomb->is_bomb = 1;
bomb->is_bullet = 1;
bomb->key = P_RandEntKey();
f32 rand_speed = Norm24(P_RandU64FromEnt(firer)) - 0.5;
f32 rand_angle = Norm24(P_RandU64FromEnt(firer)) - 0.5;
f32 speed = bomb_speed * sim_dt;
f32 angle = AngleFromVec2(fire_dir);
speed += (speed * 0.5) * rand_speed;
angle += rand_angle * spread;
Vec2 dir = Vec2FromAngle(angle);
bomb->bullet_base0 = fire_base0;
bomb->bullet_base1 = fire_base1;
bomb->bullet_start = fire_pos;
bomb->xf.t = bomb->bullet_start;
bomb->xf.r = NormRot(dir);
bomb->bullet_end = AddVec2(bomb->bullet_start, MulVec2(dir, speed));
bomb->source = weapon->key;
bomb->damage_attribution = firer->source;
}
}
firer->last_fire_ns = frame->time_ns;
}
}
} }
} }
P_SpawnEntsFromList(frame, bullets_to_spawn); P_SpawnEntsFromList(frame, bullets_to_spawn);

View File

@ -139,6 +139,10 @@ Struct(P_Ent)
Vec2 hit_entry_normal; Vec2 hit_entry_normal;
P_MaterialKind hit_material; P_MaterialKind hit_material;
//- Bomb
b32 is_bomb;
//- Player / guy / weapon / bullet //- Player / guy / weapon / bullet
P_EntKey source; P_EntKey source;

BIN
src/pp/pp_res/misc/bomb.ase (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -23,7 +23,7 @@ String P_PackWorld(Arena *arena, P_World *src_world)
{ {
// TODO: Pack ignored ents // TODO: Pack ignored ents
b32 ignore = 0; b32 ignore = 0;
if (ent->is_bullet || ent->is_weapon) if (ent->is_weapon || ent->is_bullet || ent->is_bomb)
{ {
ignore = 1; ignore = 1;
} }

View File

@ -2122,6 +2122,18 @@ void V_TickForever(WaveLaneCtx *lane)
} }
} }
//- Push bombs
for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{
if (ent->is_bomb)
{
DrawNode *draw_node = PushStruct(frame->arena, DrawNode);
SllQueuePush(first_draw_node, last_draw_node, draw_node);
++draw_nodes_count;
draw_node->ent = ent;
}
}
//- Push guys //- Push guys
for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent))
{ {
@ -2200,8 +2212,11 @@ void V_TickForever(WaveLaneCtx *lane)
body_quad.quad_uv_to_world_af = body_uv_to_world_af; body_quad.quad_uv_to_world_af = body_uv_to_world_af;
body_quad.tex = body.tex; body_quad.tex = body.tex;
body_quad.tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims); body_quad.tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims);
if (ent->is_guy)
{
body_quad.occluder_id = ent->key.v & 0xFFFFFFFF; body_quad.occluder_id = ent->key.v & 0xFFFFFFFF;
} }
}
//- Weapon quad //- Weapon quad
V_Quad wep_quad = Zi; V_Quad wep_quad = Zi;
@ -2265,6 +2280,7 @@ void V_TickForever(WaveLaneCtx *lane)
} }
if (!skip) if (!skip)
{
{ {
f32 trail_len = Vec2Len(SubVec2(end, start)); f32 trail_len = Vec2Len(SubVec2(end, start));
f32 particles_count = trail_len * frame->dt * Kibi(8); // Particles per meter per second f32 particles_count = trail_len * frame->dt * Kibi(8); // Particles per meter per second
@ -2290,13 +2306,14 @@ void V_TickForever(WaveLaneCtx *lane)
// emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1)); // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1));
emitter.speed.min = 0; emitter.speed.min = -1;
emitter.speed.max = 1; emitter.speed.max = 1;
} }
V_PushParticles(emitter); V_PushParticles(emitter);
} }
} }
} }
}
@ -2761,8 +2778,8 @@ void V_TickForever(WaveLaneCtx *lane)
////////////////////////////// //////////////////////////////
//- Push test explosion //- Push test explosion
if (frame->held_buttons[Button_G]) // if (frame->held_buttons[Button_G])
// if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G]) if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G])
{ {
// Fire // Fire
{ {