From c432ca5b77228efc2b46de1c9e87bb3e696be1ef Mon Sep 17 00:00:00 2001 From: jacob Date: Fri, 16 May 2025 19:59:20 -0500 Subject: [PATCH] chucker start --- src/sim.h | 15 ++- src/sim_ent.h | 28 ++-- src/sim_step.c | 338 ++++++++++++++++++++++--------------------------- src/user.c | 4 + src/user.h | 1 + 5 files changed, 181 insertions(+), 205 deletions(-) diff --git a/src/sim.h b/src/sim.h index 72bb684c..6ae44213 100644 --- a/src/sim.h +++ b/src/sim.h @@ -135,15 +135,16 @@ enum sim_sync_flag { enum sim_control_flag { SIM_CONTROL_FLAG_FIRE = 1 << 0, + SIM_CONTROL_FLAG_FIRE_ALT = 1 << 1, /* Testing */ - SIM_CONTROL_FLAG_DRAG = 1 << 1, - SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2, - SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 3, - SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 4, - SIM_CONTROL_FLAG_TILE_TEST = 1 << 5, - SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 6, - SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 7, + SIM_CONTROL_FLAG_DRAG = 1 << 2, + SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 3, + SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 4, + SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 5, + SIM_CONTROL_FLAG_TILE_TEST = 1 << 6, + SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 7, + SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 8, }; struct sim_control { diff --git a/src/sim_ent.h b/src/sim_ent.h index 4116308d..0b6bd1b3 100644 --- a/src/sim_ent.h +++ b/src/sim_ent.h @@ -48,10 +48,7 @@ enum sim_ent_prop { SEPROP_BULLET, SEPROP_WEAPON_SMG, SEPROP_WEAPON_LAUNCHER, - - SEPROP_TRIGGERING_EQUIPPED, - SEPROP_TRIGGERED_THIS_TICK, - SEPROP_TRIGGER_NEXT_TICK, + SEPROP_WEAPON_CHUCKER, SEPROP_EXPLOSION, @@ -285,11 +282,26 @@ struct sim_ent { struct sim_ent_id equipped; /* ====================================================================== */ - /* Triggers */ + /* Triggerable */ - /* SEPROP_TRIGGERED_THIS_TICK */ - f32 trigger_delay; /* Minimum time between triggers */ - i64 last_triggered_ns; + i32 num_primary_triggers; + i32 num_secondary_triggers; + + f32 primary_fire_delay; + f32 secondary_fire_delay; + + i64 last_primary_fire_ns; + i64 last_secondary_fire_ns; + + /* ====================================================================== */ + /* Trigger */ + + /* How many times has this trigger been triggered this tick */ + i64 triggered_count; + + /* Other triggers to activate when this entity has been triggered */ + //struct sim_ent_id trigger_out_left; + //struct sim_ent_id trigger_out_right; /* ====================================================================== */ /* Bullet */ diff --git a/src/sim_step.c b/src/sim_step.c index 5609d5ba..39fcf080 100644 --- a/src/sim_step.c +++ b/src/sim_step.c @@ -121,9 +121,9 @@ INTERNAL struct sim_ent *spawn_test_employee(struct sim_step_ctx *ctx) e->attach_slice = LIT("attach.wep"); e->layer = SIM_LAYER_RELATIVE_WEAPON; - sim_ent_enable_prop(e, SEPROP_WEAPON_LAUNCHER); - e->trigger_delay = 1.0f / 10.0f; - //e->trigger_delay = 1.0f / 100.0f; + sim_ent_enable_prop(e, SEPROP_WEAPON_CHUCKER); + e->primary_fire_delay = 1.0f / 10.0f; + e->secondary_fire_delay = 1.0f / 10.0f; employee->equipped = e->id; } @@ -515,23 +515,7 @@ void sim_step(struct sim_step_ctx *ctx) } /* ========================== * - * Reset triggered entities - * ========================== */ - - for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_should_simulate(ent)) continue; - - if (sim_ent_has_prop(ent, SEPROP_TRIGGER_NEXT_TICK)) { - sim_ent_disable_prop(ent, SEPROP_TRIGGER_NEXT_TICK); - sim_ent_enable_prop(ent, SEPROP_TRIGGERED_THIS_TICK); - } else if (sim_ent_has_prop(ent, SEPROP_TRIGGERED_THIS_TICK)) { - sim_ent_disable_prop(ent, SEPROP_TRIGGERED_THIS_TICK); - } - } - - /* ========================== * - * Process client cmds + * Process player cmds * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { @@ -554,7 +538,7 @@ void sim_step(struct sim_step_ctx *ctx) /* Player's will send control cmds a lot, so keep it around to prevent re-creating it each time */ persist_cmd = true; - /* Process control cmd for client */ + /* Process control cmd for player */ struct sim_control old_control = player->player_control; struct sim_control *control = &player->player_control; *control = cmd_ent->cmd_control; @@ -566,20 +550,12 @@ void sim_step(struct sim_step_ctx *ctx) player->player_dbg_drag_start = false; player->player_dbg_drag_stop = false; - /* Cap movement vector magnitude at 1 */ + /* Cap movement vector magnitude */ if (v2_len_sq(control->move) > 1) { control->move = v2_norm(control->move); } - if (flags & SIM_CONTROL_FLAG_TELEPORT_TEST) { - logf_info("Teleport (test)"); - struct sim_ent *ent = sim_ent_from_id(world, player->player_control_ent); - if (ent->valid) { - test_teleport(ent, player->player_cursor_pos); - } - } - - /* Non-predicted cmds */ + /* Debug cmds */ if (ctx->is_master) { if (flags & SIM_CONTROL_FLAG_DRAG) { if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) { @@ -596,15 +572,13 @@ void sim_step(struct sim_step_ctx *ctx) } } if (flags & SIM_CONTROL_FLAG_SPAWN1_TEST) { - if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN1_TEST)) { - logf_info("Spawn1 (test)"); - u32 count = 1; - f32 spread = 0; - for (u32 j = 0; j < count; ++j) { - struct v2 pos = player->player_cursor_pos; - pos.y += (((f32)j / (f32)count) - 0.5) * spread; - spawn_test_entities1(ctx, pos); - } + logf_info("Spawn1 (test)"); + u32 count = 1; + f32 spread = 0; + for (u32 j = 0; j < count; ++j) { + struct v2 pos = player->player_cursor_pos; + pos.y += (((f32)j / (f32)count) - 0.5) * spread; + spawn_test_entities1(ctx, pos); } } if (flags & SIM_CONTROL_FLAG_SPAWN2_TEST) { @@ -691,7 +665,23 @@ void sim_step(struct sim_step_ctx *ctx) } /* ========================== * - * Create client player ents + * Update entity control from player control + * ========================== */ + + for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { + struct sim_ent *ent = &world->ents[ent_index]; + if (!sim_ent_should_simulate(ent)) continue; + + if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { + struct sim_ent *player = sim_ent_from_id(world, ent->controlling_player); + if (player->valid) { + ent->control = player->player_control; + } + } + } + + /* ========================== * + * Create employees * ========================== */ if (is_master) { @@ -718,28 +708,6 @@ void sim_step(struct sim_step_ctx *ctx) } } - /* ========================== * - * Update entity control from client control - * ========================== */ - - for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &world->ents[ent_index]; - if (!sim_ent_should_simulate(ent)) continue; - - if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { - struct sim_ent *player = sim_ent_from_id(world, ent->controlling_player); - if (player->valid) { - ent->control = player->player_control; - /* TODO: Move this */ - if (ent->control.flags & SIM_CONTROL_FLAG_FIRE) { - sim_ent_enable_prop(ent, SEPROP_TRIGGERING_EQUIPPED); - } else { - sim_ent_disable_prop(ent, SEPROP_TRIGGERING_EQUIPPED); - } - } - } - } - /* ========================== * * Update entities from sprite * ========================== */ @@ -866,68 +834,30 @@ void sim_step(struct sim_step_ctx *ctx) } /* ========================== * - * Test - * ========================== */ - -#if 0 - for (u64 ent_index = 0; ent_index < ss_blended->num_ents_reserved; ++ent_index) { - struct sim_ent *ent = &ss_blended->ents[ent_index]; - if (!sim_ent_is_valid_and_active(ent)) continue; - if (!sim_ent_has_prop(ent, SEPROP_TEST)) continue; - -#if 0 - if (!ent->test_initialized) { - ent->test_initialized = true; - ent->test_start_local_xform = sim_ent_get_local_xform(ent); - ent->test_start_sprite_xform = ent->sprite_local_xform; - } - - f32 t = (f32)time; - struct v2 og = v2_mul(V2(math_cos(t), math_sin(t)), 3); - f32 r = t * 3; - struct v2 s = V2(1 + (math_fabs(math_sin(t * 5)) * 3), 1); - (UNUSED)og; - (UNUSED)r; - (UNUSED)s; - - og = v2_add(og, ent->test_start_local_xform.og); - r += xform_get_rotation(ent->test_start_local_xform); - s = v2_add(s, xform_get_scale(ent->test_start_local_xform)); - - struct xform xf = sim_ent_get_local_xform(ent); - xf.og = og; - xf = xform_rotated_to(xf, r); - xf = xform_scaled_to(xf, s); - sim_ent_set_local_xform(ent, xf); -#else - f32 t = (f32)time; - struct v2 og = v2_mul(V2(math_cos(t), math_sin(t)), 3); - f32 rot = t * PI / 3; - struct v2 scale = V2(1 + (math_fabs(math_sin(t * 5)) * 3), 1); - (UNUSED)og; - (UNUSED)rot; - (UNUSED)scale; - - struct xform xf = sim_ent_get_local_xform(ent); - xf = xform_rotated_to(xf, rot); - xf = xform_scaled_to(xf, scale); - sim_ent_set_local_xform(ent, xf); -#endif - } -#endif - - /* ========================== * - * Trigger equipped + * Process ent control * ========================== */ for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; - if (sim_ent_has_prop(ent, SEPROP_TRIGGERING_EQUIPPED)) { - struct sim_ent *eq = sim_ent_from_id(world, ent->equipped); - if (sim_ent_should_simulate(eq)) { - sim_ent_enable_prop(eq, SEPROP_TRIGGERED_THIS_TICK); + if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) { + struct sim_control *control = &ent->control; + u32 flags = control->flags; + if (flags & SIM_CONTROL_FLAG_FIRE) { + struct sim_ent *equipped = sim_ent_from_id(world, ent->equipped); + if (equipped->valid) { + ++equipped->num_primary_triggers; + } + } + if (flags & SIM_CONTROL_FLAG_FIRE_ALT) { + struct sim_ent *equipped = sim_ent_from_id(world, ent->equipped); + if (equipped->valid) { + ++equipped->num_secondary_triggers; + } + } + if (flags & SIM_CONTROL_FLAG_TELEPORT_TEST) { + test_teleport(ent, control->dbg_cursor); } } } @@ -939,97 +869,125 @@ void sim_step(struct sim_step_ctx *ctx) for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { struct sim_ent *ent = &world->ents[ent_index]; if (!sim_ent_should_simulate(ent)) continue; - if (!sim_ent_has_prop(ent, SEPROP_TRIGGERED_THIS_TICK)) continue; - if ((world->sim_time_ns - ent->last_triggered_ns < NS_FROM_SECONDS(ent->trigger_delay)) && ent->last_triggered_ns != 0) continue; - ent->last_triggered_ns = world->sim_time_ns; + b32 primary_triggered = ent->num_primary_triggers > 0; + b32 secondary_triggered = ent->num_secondary_triggers > 0; + ent->num_primary_triggers = 0; + ent->num_secondary_triggers = 0; + + if (primary_triggered) { + i64 world_time_ns = world->sim_time_ns; + if ((world_time_ns - ent->last_primary_fire_ns >= NS_FROM_SECONDS(ent->primary_fire_delay)) || ent->last_primary_fire_ns == 0) { + ent->last_primary_fire_ns = world_time_ns; + } else { + primary_triggered = false; + } + } + if (secondary_triggered) { + i64 world_time_ns = world->sim_time_ns; + if ((world_time_ns - ent->last_secondary_fire_ns >= NS_FROM_SECONDS(ent->secondary_fire_delay)) || ent->last_secondary_fire_ns == 0) { + ent->last_secondary_fire_ns = world_time_ns; + } else { + secondary_triggered = false; + } + } /* Fire smg */ if (sim_ent_has_prop(ent, SEPROP_WEAPON_SMG)) { - struct sprite_tag sprite = ent->sprite; - u32 animation_frame = ent->animation_frame; - struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); - struct xform sprite_local_xform = ent->sprite_local_xform; - struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); - struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center); - struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); + if (primary_triggered) { + struct sprite_tag sprite = ent->sprite; + u32 animation_frame = ent->animation_frame; + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); + struct xform sprite_local_xform = ent->sprite_local_xform; + struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); + struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center); + struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); - /* Spawn bullet */ - struct sim_ent *bullet; - { - bullet = sim_ent_alloc_sync_src(root); + /* Spawn bullet */ + struct sim_ent *bullet; + { + bullet = sim_ent_alloc_sync_src(root); - sim_ent_enable_prop(bullet, SEPROP_BULLET); - bullet->bullet_src = ent->id; - bullet->bullet_src_pos = rel_pos; - bullet->bullet_src_dir = rel_dir; - //bullet->bullet_launch_velocity = 0.75f; - bullet->bullet_launch_velocity = 50.0f; - bullet->bullet_knockback = 10; - bullet->layer = SIM_LAYER_BULLETS; + sim_ent_enable_prop(bullet, SEPROP_BULLET); + bullet->bullet_src = ent->id; + bullet->bullet_src_pos = rel_pos; + bullet->bullet_src_dir = rel_dir; + //bullet->bullet_launch_velocity = 0.75f; + bullet->bullet_launch_velocity = 50.0f; + bullet->bullet_knockback = 10; + bullet->layer = SIM_LAYER_BULLETS; -#if 1 - /* Point collider */ - bullet->local_collider.points[0] = V2(0, 0); - bullet->local_collider.count = 1; -#else - bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase")); - bullet->sprite_collider_slice = LIT("shape"); -#endif - } + #if 1 + /* Point collider */ + bullet->local_collider.points[0] = V2(0, 0); + bullet->local_collider.count = 1; + #else + bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase")); + bullet->sprite_collider_slice = LIT("shape"); + #endif + } - /* Spawn tracer */ - { - struct sim_ent *tracer = sim_ent_alloc_sync_src(root); - tracer->tracer_fade_duration = 0.025f; - tracer->layer = SIM_LAYER_TRACERS; - sim_ent_enable_prop(tracer, SEPROP_TRACER); + /* Spawn tracer */ + { + struct sim_ent *tracer = sim_ent_alloc_sync_src(root); + tracer->tracer_fade_duration = 0.025f; + tracer->layer = SIM_LAYER_TRACERS; + sim_ent_enable_prop(tracer, SEPROP_TRACER); - bullet->bullet_tracer = tracer->id; + bullet->bullet_tracer = tracer->id; + } } } /* Fire launcher */ if (sim_ent_has_prop(ent, SEPROP_WEAPON_LAUNCHER)) { - struct sprite_tag sprite = ent->sprite; - u32 animation_frame = ent->animation_frame; - struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); - struct xform sprite_local_xform = ent->sprite_local_xform; - struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); - struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center); - struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); + if (primary_triggered) { + struct sprite_tag sprite = ent->sprite; + u32 animation_frame = ent->animation_frame; + struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); + struct xform sprite_local_xform = ent->sprite_local_xform; + struct sprite_sheet_slice out_slice = sprite_sheet_get_slice(sheet, LIT("out"), animation_frame); + struct v2 rel_pos = xform_mul_v2(sprite_local_xform, out_slice.center); + struct v2 rel_dir = xform_basis_mul_v2(sprite_local_xform, out_slice.dir); - /* Spawn bullet */ - struct sim_ent *bullet; - { - bullet = sim_ent_alloc_sync_src(root); + /* Spawn bullet */ + struct sim_ent *bullet; + { + bullet = sim_ent_alloc_sync_src(root); - sim_ent_enable_prop(bullet, SEPROP_BULLET); - bullet->bullet_src = ent->id; - bullet->bullet_src_pos = rel_pos; - bullet->bullet_src_dir = rel_dir; - //bullet->bullet_launch_velocity = 0.75f; - bullet->bullet_launch_velocity = 15; - bullet->bullet_knockback = 50; - bullet->bullet_explosion_strength = 100; - bullet->bullet_explosion_radius = 4; - bullet->layer = SIM_LAYER_BULLETS; + sim_ent_enable_prop(bullet, SEPROP_BULLET); + bullet->bullet_src = ent->id; + bullet->bullet_src_pos = rel_pos; + bullet->bullet_src_dir = rel_dir; + //bullet->bullet_launch_velocity = 0.75f; + bullet->bullet_launch_velocity = 15; + bullet->bullet_knockback = 50; + bullet->bullet_explosion_strength = 100; + bullet->bullet_explosion_radius = 4; + bullet->layer = SIM_LAYER_BULLETS; - /* Point collider */ - bullet->local_collider.points[0] = V2(0, 0); - bullet->local_collider.count = 1; - bullet->local_collider.radius = 0.05; + /* Point collider */ + bullet->local_collider.points[0] = V2(0, 0); + bullet->local_collider.count = 1; + bullet->local_collider.radius = 0.05; + } + + /* Spawn tracer */ + { + struct sim_ent *tracer = sim_ent_alloc_sync_src(root); + tracer->tracer_fade_duration = 0.025f; + tracer->layer = SIM_LAYER_TRACERS; + sim_ent_enable_prop(tracer, SEPROP_TRACER); + + bullet->bullet_tracer = tracer->id; + } } + } - /* Spawn tracer */ - { - struct sim_ent *tracer = sim_ent_alloc_sync_src(root); - tracer->tracer_fade_duration = 0.025f; - tracer->layer = SIM_LAYER_TRACERS; - sim_ent_enable_prop(tracer, SEPROP_TRACER); - - bullet->bullet_tracer = tracer->id; + /* Fire chucker */ + if (sim_ent_has_prop(ent, SEPROP_WEAPON_CHUCKER)) { + if (primary_triggered) { } } } diff --git a/src/user.c b/src/user.c index 1435cc45..3d80b7ff 100644 --- a/src/user.c +++ b/src/user.c @@ -1591,6 +1591,7 @@ INTERNAL void user_update(void) control.dbg_cursor = G.world_cursor; struct bind_state fire_state = G.bind_states[USER_BIND_KIND_FIRE]; + struct bind_state fire_alt_state = G.bind_states[USER_BIND_KIND_FIRE_ALT]; struct bind_state drag_state = G.bind_states[USER_BIND_KIND_DEBUG_DRAG]; struct bind_state clear_state = G.bind_states[USER_BIND_KIND_DEBUG_CLEAR]; struct bind_state spawn1_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN1]; @@ -1604,6 +1605,9 @@ INTERNAL void user_update(void) if (fire_state.num_presses || fire_state.is_held) { control.flags |= SIM_CONTROL_FLAG_FIRE; } + if (fire_alt_state.num_presses || fire_alt_state.is_held) { + control.flags |= SIM_CONTROL_FLAG_FIRE_ALT; + } if (drag_state.num_presses || drag_state.is_held) { control.flags |= SIM_CONTROL_FLAG_DRAG; } diff --git a/src/user.h b/src/user.h index 51aefede..a5fedafa 100644 --- a/src/user.h +++ b/src/user.h @@ -23,6 +23,7 @@ enum user_bind_kind { USER_BIND_KIND_MOVE_RIGHT, USER_BIND_KIND_WALK, USER_BIND_KIND_FIRE, + USER_BIND_KIND_FIRE_ALT, /* Testing */