diff --git a/src/pp/pp.c b/src/pp/pp.c index f4e6640d..645972d1 100644 --- a/src/pp/pp.c +++ b/src/pp/pp.c @@ -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"))); } + else if (ent->is_bomb) + { + result.sheet = SPR_SheetKeyFromResource(ResourceKeyFromStore(&P_Resources, Lit("misc/bomb.ase"))); + } if (wep->is_uzi) { @@ -2900,6 +2904,8 @@ void P_StepFrame(P_Frame *frame) Vec2 vel = SubVec2(end, start); bullet->bullet_start = end; 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)) { 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) { // 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 spread = Tau * 0.05; // 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); b32 can_fire = (firer->last_fire_ns + NsFromSeconds(1.0 / fire_rate)) <= frame->time_ns; @@ -3002,40 +3009,85 @@ void P_StepFrame(P_Frame *frame) if (can_fire) { - i64 tick_bullets_count = bullets_per_fire; - if (tick_bullets_count > 0) + if (weapon->is_uzi) { - 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) + i64 tick_bullets_count = bullets_per_fire; + if (tick_bullets_count > 0) { - P_Ent *bullet = P_PushTempEnt(scratch.arena, &bullets_to_spawn); - bullet->is_bullet = 1; - bullet->key = P_RandEntKey(); + P_Shape firer_world_shape = P_WorldShapeFromEnt(firer); - f32 rand_speed = Norm24(P_RandU64FromEnt(firer)) - 0.5; - f32 rand_angle = Norm24(P_RandU64FromEnt(firer)) - 0.5; + // Vec2 fire_pos = P_EdgePointFromShape(firer_world_shape, firer->control.look); + // Vec2 fire_dir = firer->control.look; - f32 speed = tweak_speed * sim_dt; - f32 angle = AngleFromVec2(fire_dir); + for (i64 bullet_idx = 0; bullet_idx < tick_bullets_count; ++bullet_idx) + { + P_Ent *bullet = P_PushTempEnt(scratch.arena, &bullets_to_spawn); + bullet->is_bullet = 1; + bullet->key = P_RandEntKey(); - speed += (speed * 0.5) * rand_speed; - angle += rand_angle * spread; + f32 rand_speed = Norm24(P_RandU64FromEnt(firer)) - 0.5; + f32 rand_angle = Norm24(P_RandU64FromEnt(firer)) - 0.5; - Vec2 dir = Vec2FromAngle(angle); + f32 speed = bullet_speed * sim_dt; + f32 angle = AngleFromVec2(fire_dir); - bullet->bullet_base0 = fire_base0; - bullet->bullet_base1 = fire_base1; - bullet->bullet_start = fire_pos; - bullet->bullet_end = AddVec2(bullet->bullet_start, MulVec2(dir, speed)); - bullet->source = weapon->key; - bullet->damage_attribution = firer->source; + speed += (speed * 0.5) * rand_speed; + angle += rand_angle * spread; + + Vec2 dir = Vec2FromAngle(angle); + + bullet->bullet_base0 = fire_base0; + bullet->bullet_base1 = fire_base1; + bullet->bullet_start = fire_pos; + 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->damage_attribution = firer->source; + } } + 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; } - firer->last_fire_ns = frame->time_ns; } } } diff --git a/src/pp/pp.h b/src/pp/pp.h index 99e8fb6b..0523dc96 100644 --- a/src/pp/pp.h +++ b/src/pp/pp.h @@ -139,6 +139,10 @@ Struct(P_Ent) Vec2 hit_entry_normal; P_MaterialKind hit_material; + //- Bomb + + b32 is_bomb; + //- Player / guy / weapon / bullet P_EntKey source; diff --git a/src/pp/pp_res/misc/bomb.ase b/src/pp/pp_res/misc/bomb.ase new file mode 100644 index 00000000..29700f61 --- /dev/null +++ b/src/pp/pp_res/misc/bomb.ase @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fd5e7ce1be6b930c0c27c6939c8d721cd8e08a1f3faba2e001dc177d17d4348 +size 559 diff --git a/src/pp/pp_transcode.c b/src/pp/pp_transcode.c index 357a5223..2f02cad5 100644 --- a/src/pp/pp_transcode.c +++ b/src/pp/pp_transcode.c @@ -23,7 +23,7 @@ String P_PackWorld(Arena *arena, P_World *src_world) { // TODO: Pack ignored ents b32 ignore = 0; - if (ent->is_bullet || ent->is_weapon) + if (ent->is_weapon || ent->is_bullet || ent->is_bomb) { ignore = 1; } diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index ac271cc5..58097b55 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -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 for (P_Ent *ent = P_FirstEnt(local_frame); !P_IsEntNil(ent); ent = P_NextEnt(ent)) { @@ -2200,7 +2212,10 @@ void V_TickForever(WaveLaneCtx *lane) body_quad.quad_uv_to_world_af = body_uv_to_world_af; body_quad.tex = body.tex; body_quad.tex_slice_uv = DivRng2Vec2(body.tex_rect, body.tex_dims); - body_quad.occluder_id = ent->key.v & 0xFFFFFFFF; + if (ent->is_guy) + { + body_quad.occluder_id = ent->key.v & 0xFFFFFFFF; + } } //- Weapon quad @@ -2266,34 +2281,36 @@ void V_TickForever(WaveLaneCtx *lane) if (!skip) { - f32 trail_len = Vec2Len(SubVec2(end, start)); - f32 particles_count = trail_len * frame->dt * Kibi(8); // Particles per meter per second - particles_count = MaxF32(particles_count, 1); - - f32 angle = AngleFromVec2(PerpVec2(SubVec2(end, start))); - // f32 angle = AngleFromVec2(NegVec2(SubVec2(end, start))); - - V_Emitter emitter = Zi; { - emitter.kind = V_ParticleKind_BulletTrail; - emitter.count = particles_count; + f32 trail_len = Vec2Len(SubVec2(end, start)); + f32 particles_count = trail_len * frame->dt * Kibi(8); // Particles per meter per second + particles_count = MaxF32(particles_count, 1); - f32 angle_spread = Tau / 4.0; + f32 angle = AngleFromVec2(PerpVec2(SubVec2(end, start))); + // f32 angle = AngleFromVec2(NegVec2(SubVec2(end, start))); - emitter.angle.min = angle - angle_spread / 2; - emitter.angle.max = angle + angle_spread / 2; + V_Emitter emitter = Zi; + { + emitter.kind = V_ParticleKind_BulletTrail; + emitter.count = particles_count; - emitter.pos.p0 = start; - emitter.pos.p1 = end; + f32 angle_spread = Tau / 4.0; - // emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1)); + emitter.angle.min = angle - angle_spread / 2; + emitter.angle.max = angle + angle_spread / 2; - // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1)); + emitter.pos.p0 = start; + emitter.pos.p1 = end; - emitter.speed.min = 0; - emitter.speed.max = 1; + // emitter.color_lin = LinearFromSrgb(VEC4(0, 1, 0, 1)); + + // emitter.color_lin = LinearFromSrgb(VEC4(0.8, 0.6, 0.2, 1)); + + emitter.speed.min = -1; + emitter.speed.max = 1; + } + V_PushParticles(emitter); } - V_PushParticles(emitter); } } } @@ -2761,8 +2778,8 @@ void V_TickForever(WaveLaneCtx *lane) ////////////////////////////// //- Push test explosion - if (frame->held_buttons[Button_G]) - // if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G]) + // if (frame->held_buttons[Button_G]) + if (frame->held_buttons[Button_G] && !prev_frame->held_buttons[Button_G]) { // Fire {