chucker start

This commit is contained in:
jacob 2025-05-16 19:59:20 -05:00
parent 1943b2d81b
commit c432ca5b77
5 changed files with 181 additions and 205 deletions

View File

@ -135,15 +135,16 @@ enum sim_sync_flag {
enum sim_control_flag { enum sim_control_flag {
SIM_CONTROL_FLAG_FIRE = 1 << 0, SIM_CONTROL_FLAG_FIRE = 1 << 0,
SIM_CONTROL_FLAG_FIRE_ALT = 1 << 1,
/* Testing */ /* Testing */
SIM_CONTROL_FLAG_DRAG = 1 << 1, SIM_CONTROL_FLAG_DRAG = 1 << 2,
SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 2, SIM_CONTROL_FLAG_CLEAR_ALL = 1 << 3,
SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 3, SIM_CONTROL_FLAG_SPAWN1_TEST = 1 << 4,
SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 4, SIM_CONTROL_FLAG_SPAWN2_TEST = 1 << 5,
SIM_CONTROL_FLAG_TILE_TEST = 1 << 5, SIM_CONTROL_FLAG_TILE_TEST = 1 << 6,
SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 6, SIM_CONTROL_FLAG_EXPLODE_TEST = 1 << 7,
SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 7, SIM_CONTROL_FLAG_TELEPORT_TEST = 1 << 8,
}; };
struct sim_control { struct sim_control {

View File

@ -48,10 +48,7 @@ enum sim_ent_prop {
SEPROP_BULLET, SEPROP_BULLET,
SEPROP_WEAPON_SMG, SEPROP_WEAPON_SMG,
SEPROP_WEAPON_LAUNCHER, SEPROP_WEAPON_LAUNCHER,
SEPROP_WEAPON_CHUCKER,
SEPROP_TRIGGERING_EQUIPPED,
SEPROP_TRIGGERED_THIS_TICK,
SEPROP_TRIGGER_NEXT_TICK,
SEPROP_EXPLOSION, SEPROP_EXPLOSION,
@ -285,11 +282,26 @@ struct sim_ent {
struct sim_ent_id equipped; struct sim_ent_id equipped;
/* ====================================================================== */ /* ====================================================================== */
/* Triggers */ /* Triggerable */
/* SEPROP_TRIGGERED_THIS_TICK */ i32 num_primary_triggers;
f32 trigger_delay; /* Minimum time between triggers */ i32 num_secondary_triggers;
i64 last_triggered_ns;
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 */ /* Bullet */

View File

@ -121,9 +121,9 @@ INTERNAL struct sim_ent *spawn_test_employee(struct sim_step_ctx *ctx)
e->attach_slice = LIT("attach.wep"); e->attach_slice = LIT("attach.wep");
e->layer = SIM_LAYER_RELATIVE_WEAPON; e->layer = SIM_LAYER_RELATIVE_WEAPON;
sim_ent_enable_prop(e, SEPROP_WEAPON_LAUNCHER); sim_ent_enable_prop(e, SEPROP_WEAPON_CHUCKER);
e->trigger_delay = 1.0f / 10.0f; e->primary_fire_delay = 1.0f / 10.0f;
//e->trigger_delay = 1.0f / 100.0f; e->secondary_fire_delay = 1.0f / 10.0f;
employee->equipped = e->id; employee->equipped = e->id;
} }
@ -515,23 +515,7 @@ void sim_step(struct sim_step_ctx *ctx)
} }
/* ========================== * /* ========================== *
* Reset triggered entities * Process player cmds
* ========================== */
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
* ========================== */ * ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { 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 */ /* Player's will send control cmds a lot, so keep it around to prevent re-creating it each time */
persist_cmd = true; persist_cmd = true;
/* Process control cmd for client */ /* Process control cmd for player */
struct sim_control old_control = player->player_control; struct sim_control old_control = player->player_control;
struct sim_control *control = &player->player_control; struct sim_control *control = &player->player_control;
*control = cmd_ent->cmd_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_start = false;
player->player_dbg_drag_stop = false; player->player_dbg_drag_stop = false;
/* Cap movement vector magnitude at 1 */ /* Cap movement vector magnitude */
if (v2_len_sq(control->move) > 1) { if (v2_len_sq(control->move) > 1) {
control->move = v2_norm(control->move); control->move = v2_norm(control->move);
} }
if (flags & SIM_CONTROL_FLAG_TELEPORT_TEST) { /* Debug cmds */
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 */
if (ctx->is_master) { if (ctx->is_master) {
if (flags & SIM_CONTROL_FLAG_DRAG) { if (flags & SIM_CONTROL_FLAG_DRAG) {
if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) { if (!(old_control.flags & SIM_CONTROL_FLAG_DRAG)) {
@ -596,7 +572,6 @@ void sim_step(struct sim_step_ctx *ctx)
} }
} }
if (flags & SIM_CONTROL_FLAG_SPAWN1_TEST) { if (flags & SIM_CONTROL_FLAG_SPAWN1_TEST) {
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN1_TEST)) {
logf_info("Spawn1 (test)"); logf_info("Spawn1 (test)");
u32 count = 1; u32 count = 1;
f32 spread = 0; f32 spread = 0;
@ -606,7 +581,6 @@ void sim_step(struct sim_step_ctx *ctx)
spawn_test_entities1(ctx, pos); spawn_test_entities1(ctx, pos);
} }
} }
}
if (flags & SIM_CONTROL_FLAG_SPAWN2_TEST) { if (flags & SIM_CONTROL_FLAG_SPAWN2_TEST) {
if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN2_TEST)) { if (!(old_control.flags & SIM_CONTROL_FLAG_SPAWN2_TEST)) {
logf_info("Spawn1 (test)"); logf_info("Spawn1 (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) { 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 * Update entities from sprite
* ========================== */ * ========================== */
@ -866,68 +834,30 @@ void sim_step(struct sim_step_ctx *ctx)
} }
/* ========================== * /* ========================== *
* Test * Process ent control
* ========================== */
#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
* ========================== */ * ========================== */
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &world->ents[ent_index]; struct sim_ent *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue; if (!sim_ent_should_simulate(ent)) continue;
if (sim_ent_has_prop(ent, SEPROP_TRIGGERING_EQUIPPED)) { if (sim_ent_has_prop(ent, SEPROP_CONTROLLED)) {
struct sim_ent *eq = sim_ent_from_id(world, ent->equipped); struct sim_control *control = &ent->control;
if (sim_ent_should_simulate(eq)) { u32 flags = control->flags;
sim_ent_enable_prop(eq, SEPROP_TRIGGERED_THIS_TICK); 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,13 +869,32 @@ void sim_step(struct sim_step_ctx *ctx)
for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) { for (u64 ent_index = 0; ent_index < world->num_ents_reserved; ++ent_index) {
struct sim_ent *ent = &world->ents[ent_index]; struct sim_ent *ent = &world->ents[ent_index];
if (!sim_ent_should_simulate(ent)) continue; 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 */ /* Fire smg */
if (sim_ent_has_prop(ent, SEPROP_WEAPON_SMG)) { if (sim_ent_has_prop(ent, SEPROP_WEAPON_SMG)) {
if (primary_triggered) {
struct sprite_tag sprite = ent->sprite; struct sprite_tag sprite = ent->sprite;
u32 animation_frame = ent->animation_frame; u32 animation_frame = ent->animation_frame;
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
@ -968,14 +917,14 @@ void sim_step(struct sim_step_ctx *ctx)
bullet->bullet_knockback = 10; bullet->bullet_knockback = 10;
bullet->layer = SIM_LAYER_BULLETS; bullet->layer = SIM_LAYER_BULLETS;
#if 1 #if 1
/* Point collider */ /* Point collider */
bullet->local_collider.points[0] = V2(0, 0); bullet->local_collider.points[0] = V2(0, 0);
bullet->local_collider.count = 1; bullet->local_collider.count = 1;
#else #else
bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase")); bullet->sprite = sprite_tag_from_path(LIT("res/graphics/bullet.ase"));
bullet->sprite_collider_slice = LIT("shape"); bullet->sprite_collider_slice = LIT("shape");
#endif #endif
} }
/* Spawn tracer */ /* Spawn tracer */
@ -988,9 +937,11 @@ void sim_step(struct sim_step_ctx *ctx)
bullet->bullet_tracer = tracer->id; bullet->bullet_tracer = tracer->id;
} }
} }
}
/* Fire launcher */ /* Fire launcher */
if (sim_ent_has_prop(ent, SEPROP_WEAPON_LAUNCHER)) { if (sim_ent_has_prop(ent, SEPROP_WEAPON_LAUNCHER)) {
if (primary_triggered) {
struct sprite_tag sprite = ent->sprite; struct sprite_tag sprite = ent->sprite;
u32 animation_frame = ent->animation_frame; u32 animation_frame = ent->animation_frame;
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite); struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, sprite);
@ -1034,6 +985,13 @@ void sim_step(struct sim_step_ctx *ctx)
} }
} }
/* Fire chucker */
if (sim_ent_has_prop(ent, SEPROP_WEAPON_CHUCKER)) {
if (primary_triggered) {
}
}
}
/* ========================== * /* ========================== *
* Create & update motor joints from control move * Create & update motor joints from control move
* ========================== */ * ========================== */

View File

@ -1591,6 +1591,7 @@ INTERNAL void user_update(void)
control.dbg_cursor = G.world_cursor; control.dbg_cursor = G.world_cursor;
struct bind_state fire_state = G.bind_states[USER_BIND_KIND_FIRE]; 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 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 clear_state = G.bind_states[USER_BIND_KIND_DEBUG_CLEAR];
struct bind_state spawn1_state = G.bind_states[USER_BIND_KIND_DEBUG_SPAWN1]; 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) { if (fire_state.num_presses || fire_state.is_held) {
control.flags |= SIM_CONTROL_FLAG_FIRE; 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) { if (drag_state.num_presses || drag_state.is_held) {
control.flags |= SIM_CONTROL_FLAG_DRAG; control.flags |= SIM_CONTROL_FLAG_DRAG;
} }

View File

@ -23,6 +23,7 @@ enum user_bind_kind {
USER_BIND_KIND_MOVE_RIGHT, USER_BIND_KIND_MOVE_RIGHT,
USER_BIND_KIND_WALK, USER_BIND_KIND_WALK,
USER_BIND_KIND_FIRE, USER_BIND_KIND_FIRE,
USER_BIND_KIND_FIRE_ALT,
/* Testing */ /* Testing */