weapon triggering testing
This commit is contained in:
parent
911208a926
commit
1125015ff7
@ -15,8 +15,9 @@ enum entity_prop {
|
|||||||
ENTITY_PROP_EQUIPPER,
|
ENTITY_PROP_EQUIPPER,
|
||||||
ENTITY_PROP_EQUIPABLE,
|
ENTITY_PROP_EQUIPABLE,
|
||||||
|
|
||||||
ENTITY_PROP_TRIGGERED,
|
ENTITY_PROP_WEAPON,
|
||||||
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
||||||
|
ENTITY_PROP_TRIGGERED_THIS_TICK,
|
||||||
|
|
||||||
/* Test props */
|
/* Test props */
|
||||||
|
|
||||||
@ -63,12 +64,6 @@ struct entity {
|
|||||||
struct entity_handle first;
|
struct entity_handle first;
|
||||||
struct entity_handle last;
|
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 */
|
/* Position */
|
||||||
|
|
||||||
|
|||||||
157
src/game.c
157
src/game.c
@ -145,8 +145,9 @@ INTERNAL void spawn_test_entities(void)
|
|||||||
e->sprite = sprite_tag_from_path(STR("res/graphics/gun.ase"));
|
e->sprite = sprite_tag_from_path(STR("res/graphics/gun.ase"));
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
entity_enable_prop(e, ENTITY_PROP_ANIMATING);
|
||||||
|
|
||||||
entity_enable_prop(e, ENTITY_PROP_EQUIPABLE);
|
entity_enable_prop(e, ENTITY_PROP_EQUIPABLE);
|
||||||
|
entity_enable_prop(e, ENTITY_PROP_WEAPON);
|
||||||
|
|
||||||
player_ent->equipped = e->handle;
|
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.dt = max_f64(0.0, (1.0 / GAME_FPS) * G.world.timescale);
|
||||||
G.world.time += G.world.dt;
|
G.world.time += G.world.dt;
|
||||||
|
|
||||||
u64 world_tick = G.world.tick_id;
|
|
||||||
struct game_cmd_array game_cmds = pop_cmds(scratch.arena);
|
struct game_cmd_array game_cmds = pop_cmds(scratch.arena);
|
||||||
struct entity_store *store = G.world.entity_store;
|
struct entity_store *store = G.world.entity_store;
|
||||||
struct entity *root = entity_from_handle(store, store->root);
|
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) {
|
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
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
{
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
u64 ents_to_release_count = 0;
|
struct entity *ent = &store->entities[entity_index];
|
||||||
struct entity **ents_to_release = arena_dry_push(scratch.arena, struct entity *);
|
if (!ent->valid) continue;
|
||||||
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
struct entity *ent = &store->entities[entity_index];
|
|
||||||
|
|
||||||
u64 valid_tick = ent->valid_tick;
|
/* ========================== *
|
||||||
u64 release_tick = ent->release_tick;
|
* Update sprite animation
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
b32 valid = ent->valid;
|
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
||||||
if (valid_tick != 0 && valid_tick >= world_tick && !valid) {
|
struct sprite_sheet *sheet = sprite_sheet_from_tag_await(sprite_frame_scope, ent->sprite);
|
||||||
ent->valid = true;
|
struct sprite_sheet_span span = sprite_sheet_get_span(sheet, ent->sprite_span_name);
|
||||||
valid = true;
|
|
||||||
|
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) {
|
struct sprite_sheet_frame frame = sprite_sheet_get_frame(sheet, frame_index);
|
||||||
*arena_push(scratch.arena, struct entity *) = ent;
|
while (time_in_frame > frame.duration) {
|
||||||
++ents_to_release_count;
|
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];
|
* Update sprite xform
|
||||||
entity_release(store, ent);
|
* ========================== */
|
||||||
}
|
|
||||||
|
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
if (sprite_tag_is_nil(ent->sprite)) continue;
|
|
||||||
|
|
||||||
/* ========================== *
|
/* Trigger equipped */
|
||||||
* Update sprite animation
|
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED)) {
|
||||||
* ========================== */
|
struct entity *eq = entity_from_handle(store, ent->equipped);
|
||||||
|
if (eq->valid) {
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_ANIMATING)) {
|
entity_enable_prop(eq, ENTITY_PROP_TRIGGERED_THIS_TICK);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &store->entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
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
|
* Player angle
|
||||||
@ -603,9 +590,6 @@ INTERNAL void game_update(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Publish tick
|
* Publish tick
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -656,6 +640,19 @@ INTERNAL void game_update(void)
|
|||||||
publish_game_tick();
|
publish_game_tick();
|
||||||
__profframe("Game");
|
__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
|
* End frame cache scopes
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|||||||
@ -767,6 +767,12 @@ INTERNAL void user_update(void)
|
|||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
if (ent->is_root) 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 entity *parent = entity_from_handle(store, ent->parent);
|
||||||
|
|
||||||
struct xform xf = entity_get_xform(ent);
|
struct xform xf = entity_get_xform(ent);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user