weapon triggering testing

This commit is contained in:
jacob 2024-08-09 22:57:38 -05:00
parent 911208a926
commit 1125015ff7
3 changed files with 85 additions and 87 deletions

View File

@ -15,8 +15,9 @@ enum entity_prop {
ENTITY_PROP_EQUIPPER,
ENTITY_PROP_EQUIPABLE,
ENTITY_PROP_TRIGGERED,
ENTITY_PROP_WEAPON,
ENTITY_PROP_TRIGGERING_EQUIPPED,
ENTITY_PROP_TRIGGERED_THIS_TICK,
/* Test props */
@ -63,12 +64,6 @@ struct entity {
struct entity_handle first;
struct entity_handle last;
/* ====================================================================== */
/* Allocation/Release timing */
u64 valid_tick; /* `valid` will be set to true when world tick >= `valid_tick` & `valid_tick` != 0 */
u64 release_tick; /* Entity will be released when world tick >= `release_tick` & `release_tick` != 0 */
/* ====================================================================== */
/* Position */

View File

@ -145,8 +145,9 @@ INTERNAL void spawn_test_entities(void)
e->sprite = sprite_tag_from_path(STR("res/graphics/gun.ase"));
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
entity_enable_prop(e, ENTITY_PROP_EQUIPABLE);
entity_enable_prop(e, ENTITY_PROP_WEAPON);
player_ent->equipped = e->handle;
}
@ -193,7 +194,6 @@ INTERNAL void game_update(void)
G.world.dt = max_f64(0.0, (1.0 / GAME_FPS) * G.world.timescale);
G.world.time += G.world.dt;
u64 world_tick = G.world.tick_id;
struct game_cmd_array game_cmds = pop_cmds(scratch.arena);
struct entity_store *store = G.world.entity_store;
struct entity *root = entity_from_handle(store, store->root);
@ -212,7 +212,7 @@ INTERNAL void game_update(void)
}
/* ========================== *
* Process pre-sim game cmds
* Process global game cmds
* ========================== */
for (u64 cmd_index = 0; cmd_index < game_cmds.count; ++cmd_index) {
@ -241,34 +241,59 @@ INTERNAL void game_update(void)
}
/* ========================== *
* Make valid or release entities
* Update sprite from animation
* ========================== */
{
u64 ents_to_release_count = 0;
struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *);
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue;
if (sprite_tag_is_nil(ent->sprite)) continue;
u64 valid_tick = ent->valid_tick;
u64 release_tick = ent->release_tick;
/* ========================== *
* Update sprite animation
* ========================== */
b32 valid = ent->valid;
if (valid_tick != 0 && valid_tick >= world_tick && !valid) {
ent->valid = true;
valid = true;
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 frame_index = ent->animation_frame;
if (frame_index < span.start || frame_index > span.end) {
frame_index = span.start;
}
if (valid && release_tick != 0 && release_tick >= world_tick) {
*arena_push(scratch.arena, struct entity *) = ent;
++ents_to_release_count;
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, frame_index);
while (time_in_frame > frame.duration) {
time_in_frame -= frame.duration;
++frame_index;
if (frame_index > span.end) {
/* Loop animation */
frame_index = span.start;
}
frame = sprite_sheet_get_frame(sheet, frame_index);
}
ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = frame_index;
}
for (u64 i = 0; i < ents_to_release_count; ++i) {
struct entity *ent = ents_to_release[i];
entity_release(store, ent);
}
/* ========================== *
* Update sprite xform
* ========================== */
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
struct v2 dir = v2_mul_v2(sprite_size, slice.dir);
f32 rot = v2_angle(dir) + PI / 2;
struct xform xf = XFORM_IDENT;
xf = xform_rotate(xf, -rot);
xf = xform_scale(xf, sprite_size);
xf = xform_translate(xf, v2_neg(slice.center));
ent->sprite_local_xform = xf;
}
/* ========================== *
@ -372,80 +397,42 @@ INTERNAL void game_update(void)
}
/* ========================== *
* Update sprites
* Activate triggers
* ========================== */
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue;
if (sprite_tag_is_nil(ent->sprite)) continue;
/* ========================== *
* Update sprite animation
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
f64 time_in_frame = ent->animation_time_in_frame + G.world.dt;
u64 frame_index = ent->animation_frame;
if (frame_index < span.start || frame_index > span.end) {
frame_index = span.start;
/* Trigger equipped */
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) {
struct entity *eq = entity_from_handle(store, ent->equipped);
if (eq->valid) {
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
}
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, frame_index);
while (time_in_frame > frame.duration) {
time_in_frame -= frame.duration;
++frame_index;
if (frame_index > span.end) {
/* Loop animation */
frame_index = span.start;
}
frame = sprite_sheet_get_frame(sheet, frame_index);
}
ent->animation_time_in_frame = time_in_frame;
ent->animation_frame = frame_index;
}
/* ========================== *
* Update sprite xform
* ========================== */
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
struct sprite_sheet_slice slice = sprite_sheet_get_slice(sheet, STR("pivot"), ent->animation_frame);
struct v2 sprite_size = v2_div(sheet->frame_size, (f32)PIXELS_PER_UNIT);
struct v2 dir = v2_mul_v2(sprite_size, slice.dir);
f32 rot = v2_angle(dir) + PI / 2;
struct xform xf = XFORM_IDENT;
xf = xform_rotate(xf, -rot);
xf = xform_scale(xf, sprite_size);
xf = xform_translate(xf, v2_neg(slice.center));
ent->sprite_local_xform = xf;
}
/* ========================== *
* Update triggering
* Simulate entity physics
* ========================== */
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue;
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED)) {
/* ========================== *
* Weapon firing
* ========================== */
if (entity_has_prop(ent, ENTITY_PROP_WEAPON)) {
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) {
ent->sprite_tint = RGBA_32_F(1, 0, 0, 1);
} else {
ent->sprite_tint = RGBA_32_F(1, 1, 1, 1);
}
}
}
/* ========================== *
* Simulate entities
* ========================== */
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue;
/* ========================== *
* Player angle
@ -603,9 +590,6 @@ INTERNAL void game_update(void)
}
}
/* ---------------------------------------------------------------------- */
/* ---------------------------------------------------------------------- */
/* ========================== *
* Publish tick
* ========================== */
@ -656,6 +640,19 @@ INTERNAL void game_update(void)
publish_game_tick();
__profframe("Game");
/* ========================== *
* Reset triggered entities
* ========================== */
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
struct entity *ent = &store->entities[entity_index];
if (!ent->valid) continue;
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK)) {
entity_disable_prop(ent, ENTITY_PROP_TRIGGERED_THIS_TICK);
}
}
/* ========================== *
* End frame cache scopes
* ========================== */

View File

@ -767,6 +767,12 @@ INTERNAL void user_update(void)
if (!ent->valid) continue;
if (ent->is_root) continue;
/* Skip undrawable entities */
if (sprite_tag_is_nil(ent->sprite)
&& entity_has_prop(ent, ENTITY_PROP_CAMERA)) {
continue;
}
struct entity *parent = entity_from_handle(store, ent->parent);
struct xform xf = entity_get_xform(ent);