triggering beginnings.
This commit is contained in:
parent
f5400b0205
commit
911208a926
11
src/entity.h
11
src/entity.h
@ -15,7 +15,8 @@ enum entity_prop {
|
|||||||
ENTITY_PROP_EQUIPPER,
|
ENTITY_PROP_EQUIPPER,
|
||||||
ENTITY_PROP_EQUIPABLE,
|
ENTITY_PROP_EQUIPABLE,
|
||||||
|
|
||||||
ENTITY_PROP_FIRING_EQUIPPED,
|
ENTITY_PROP_TRIGGERED,
|
||||||
|
ENTITY_PROP_TRIGGERING_EQUIPPED,
|
||||||
|
|
||||||
/* Test props */
|
/* Test props */
|
||||||
|
|
||||||
@ -62,6 +63,12 @@ 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 */
|
||||||
|
|
||||||
@ -203,8 +210,6 @@ INLINE b32 entity_has_prop(struct entity *entity, enum entity_prop prop)
|
|||||||
* Entity functions
|
* Entity functions
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
INLINE struct entity_array entity_store_as_array(struct entity_store *store) { return (struct entity_array) { .count = store->count, .entities = store->entities }; }
|
|
||||||
|
|
||||||
/* Entity store */
|
/* Entity store */
|
||||||
struct entity_store *entity_store_alloc(void);
|
struct entity_store *entity_store_alloc(void);
|
||||||
void entity_store_release(struct entity_store *store);
|
void entity_store_release(struct entity_store *store);
|
||||||
|
|||||||
293
src/game.c
293
src/game.c
@ -188,8 +188,21 @@ INTERNAL void game_update(void)
|
|||||||
* Begin frame
|
* Begin frame
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
|
++G.world.tick_id;
|
||||||
|
G.world.tick_ts = sys_timestamp();
|
||||||
|
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);
|
||||||
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Spawn test entities
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
/* TODO: remove this (testing) */
|
/* TODO: remove this (testing) */
|
||||||
/* Initialize entities */
|
/* Initialize entities */
|
||||||
static b32 run = 0;
|
static b32 run = 0;
|
||||||
@ -198,20 +211,8 @@ INTERNAL void game_update(void)
|
|||||||
spawn_test_entities();
|
spawn_test_entities();
|
||||||
}
|
}
|
||||||
|
|
||||||
++G.world.tick_id;
|
|
||||||
G.world.tick_ts = sys_timestamp();
|
|
||||||
G.world.dt = max_f64(0.0, (1.0 / GAME_FPS) * G.world.timescale);
|
|
||||||
G.world.time += G.world.dt;
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Pull cmds
|
* Process pre-sim game cmds
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
struct entity_store *store = G.world.entity_store;
|
|
||||||
struct game_cmd_array game_cmds = pop_cmds(scratch.arena);
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Pre-sim 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) {
|
||||||
@ -239,18 +240,143 @@ INTERNAL void game_update(void)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
/* ---------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
struct entity *root = entity_from_handle(store, store->root);
|
|
||||||
struct entity_array entities_array = entity_store_as_array(store);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update sprite
|
* Make valid or release entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
{
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
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];
|
||||||
|
|
||||||
|
u64 valid_tick = ent->valid_tick;
|
||||||
|
u64 release_tick = ent->release_tick;
|
||||||
|
|
||||||
|
b32 valid = ent->valid;
|
||||||
|
if (valid_tick != 0 && valid_tick >= world_tick && !valid) {
|
||||||
|
ent->valid = true;
|
||||||
|
valid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid && release_tick != 0 && release_tick >= world_tick) {
|
||||||
|
*arena_push(scratch.arena, struct entity *) = ent;
|
||||||
|
++ents_to_release_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (u64 i = 0; i < ents_to_release_count; ++i) {
|
||||||
|
struct entity *ent = ents_to_release[i];
|
||||||
|
entity_release(store, ent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update entities from cmds
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
|
struct entity *ent = &store->entities[entity_index];
|
||||||
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Initialize test
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
/* ENTITY_PROP_TEST */
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) {
|
||||||
|
ent->test_initialized = true;
|
||||||
|
ent->test_start_local_xform = entity_get_local_xform(ent);
|
||||||
|
ent->test_start_sprite_xform = ent->sprite_local_xform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update control from player cmds
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
|
/* Process cmds */
|
||||||
|
struct v2 move = ent->control.move;
|
||||||
|
struct v2 focus = ent->control.focus;
|
||||||
|
b32 firing = entity_has_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < game_cmds.count; ++i) {
|
||||||
|
struct game_cmd cmd = game_cmds.cmds[i];
|
||||||
|
b32 start = cmd.state == GAME_CMD_STATE_START;
|
||||||
|
b32 stop = cmd.state == GAME_CMD_STATE_STOP;
|
||||||
|
(UNUSED)start;
|
||||||
|
(UNUSED)stop;
|
||||||
|
|
||||||
|
/* TODO: Combine movement from multiple inputs? E.G. a sudden
|
||||||
|
* start and immediate stop cmd should still move the player a
|
||||||
|
* tad. */
|
||||||
|
switch (cmd.kind) {
|
||||||
|
case GAME_CMD_KIND_PLAYER_MOVE: {
|
||||||
|
move = cmd.move_dir;
|
||||||
|
focus = v2_sub(cmd.aim_pos, entity_get_xform(ent).og);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
case GAME_CMD_KIND_PLAYER_FIRE: {
|
||||||
|
if (start) {
|
||||||
|
firing = true;
|
||||||
|
} else if (stop) {
|
||||||
|
firing = false;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Movement */
|
||||||
|
if (v2_len_squared(move) > 1) {
|
||||||
|
/* Cap movement vector magnitude at 1 */
|
||||||
|
move = v2_norm(move);
|
||||||
|
}
|
||||||
|
ent->control.move = move;
|
||||||
|
ent->control.focus = focus;
|
||||||
|
|
||||||
|
/* Firing */
|
||||||
|
if (firing) {
|
||||||
|
entity_enable_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED);
|
||||||
|
} else {
|
||||||
|
entity_disable_prop(ent, ENTITY_PROP_TRIGGERING_EQUIPPED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Test
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
/* ENTITY_PROP_TEST */
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
||||||
|
f32 t = ((f32)G.world.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 = entity_get_local_xform(ent);
|
||||||
|
xf.og = og;
|
||||||
|
xf= xform_with_rotation(xf, r);
|
||||||
|
xf= xform_with_scale(xf, s);
|
||||||
|
entity_set_local_xform(ent, xf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Update sprites
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
for (u64 entity_index = 0; entity_index < store->count; ++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;
|
if (sprite_tag_is_nil(ent->sprite)) continue;
|
||||||
|
|
||||||
@ -301,66 +427,28 @@ INTERNAL void game_update(void)
|
|||||||
ent->sprite_local_xform = xf;
|
ent->sprite_local_xform = xf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Update entities pre-simulation
|
* Update triggering
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
|
if (entity_has_prop(ent, ENTITY_PROP_TRIGGERED)) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ========================== *
|
||||||
|
* Simulate entities
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Initialize test
|
* Player angle
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
/* ENTITY_PROP_TEST */
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TEST) && !ent->test_initialized) {
|
|
||||||
ent->test_initialized = true;
|
|
||||||
ent->test_start_local_xform = entity_get_local_xform(ent);
|
|
||||||
ent->test_start_sprite_xform = ent->sprite_local_xform;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Update control from player cmds
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
|
||||||
for (u64 i = 0; i < game_cmds.count; ++i) {
|
|
||||||
struct game_cmd cmd = game_cmds.cmds[i];
|
|
||||||
b32 start = cmd.state == 1;
|
|
||||||
b32 stop = cmd.state == -1;
|
|
||||||
|
|
||||||
/* TODO: Combine movement from multiple inputs? E.G. a sudden
|
|
||||||
* start and immediate stop cmd should still move the player a
|
|
||||||
* tad. */
|
|
||||||
|
|
||||||
switch (cmd.kind) {
|
|
||||||
case GAME_CMD_KIND_PLAYER_MOVE: {
|
|
||||||
struct v2 move = cmd.move_dir;
|
|
||||||
if (v2_len_squared(move) > 1) {
|
|
||||||
/* Cap movement vector magnitude at 1 */
|
|
||||||
move = v2_norm(move);
|
|
||||||
}
|
|
||||||
ent->control.move = move;
|
|
||||||
ent->control.focus = v2_sub(cmd.aim_pos, entity_get_xform(ent).og);
|
|
||||||
} break;
|
|
||||||
|
|
||||||
case GAME_CMD_KIND_PLAYER_FIRE: {
|
|
||||||
if (start) {
|
|
||||||
entity_enable_prop(ent, ENTITY_PROP_FIRING_EQUIPPED);
|
|
||||||
} else if (stop) {
|
|
||||||
entity_disable_prop(ent, ENTITY_PROP_FIRING_EQUIPPED);
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
|
|
||||||
default: break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Update player angle
|
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
@ -417,54 +505,7 @@ INTERNAL void game_update(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Test
|
* Player movement
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
/* ENTITY_PROP_TEST */
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_TEST)) {
|
|
||||||
f32 t = ((f32)G.world.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 = entity_get_local_xform(ent);
|
|
||||||
xf.og = og;
|
|
||||||
xf= xform_with_rotation(xf, r);
|
|
||||||
xf= xform_with_scale(xf, s);
|
|
||||||
entity_set_local_xform(ent, xf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ENTITY_PROP_FIRING_EQUIPPED */
|
|
||||||
{
|
|
||||||
struct entity *eq = entity_from_handle(store, ent->equipped);
|
|
||||||
if (eq->valid) {
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_FIRING_EQUIPPED)) {
|
|
||||||
eq->sprite_tint = RGBA_32_F(1, 0, 0, 1);
|
|
||||||
} else {
|
|
||||||
eq->sprite_tint = RGBA_32_F(1, 1, 1, 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Simulate entities
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
|
||||||
if (!ent->valid) continue;
|
|
||||||
|
|
||||||
/* ========================== *
|
|
||||||
* Player control
|
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
if (entity_has_prop(ent, ENTITY_PROP_PLAYER_CONTROLLED)) {
|
||||||
@ -498,8 +539,8 @@ INTERNAL void game_update(void)
|
|||||||
* Update entities post-simulation
|
* Update entities post-simulation
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
|
|||||||
10
src/game.h
10
src/game.h
@ -6,6 +6,12 @@ struct mixer_startup_receipt;
|
|||||||
struct sprite_startup_receipt;
|
struct sprite_startup_receipt;
|
||||||
struct sound_startup_receipt;
|
struct sound_startup_receipt;
|
||||||
|
|
||||||
|
enum game_cmd_state {
|
||||||
|
GAME_CMD_STATE_STOP = -1,
|
||||||
|
GAME_CMD_STATE_NO_CHANGE = 0,
|
||||||
|
GAME_CMD_STATE_START = 1
|
||||||
|
};
|
||||||
|
|
||||||
enum game_cmd_kind {
|
enum game_cmd_kind {
|
||||||
GAME_CMD_KIND_NONE,
|
GAME_CMD_KIND_NONE,
|
||||||
|
|
||||||
@ -21,9 +27,7 @@ enum game_cmd_kind {
|
|||||||
|
|
||||||
struct game_cmd {
|
struct game_cmd {
|
||||||
enum game_cmd_kind kind;
|
enum game_cmd_kind kind;
|
||||||
|
enum game_cmd_state state;
|
||||||
/* 1 = start, -1 = stop */
|
|
||||||
i32 state;
|
|
||||||
|
|
||||||
/* GAME_CMD_KIND_PLAYER_MOVE */
|
/* GAME_CMD_KIND_PLAYER_MOVE */
|
||||||
struct v2 move_dir;
|
struct v2 move_dir;
|
||||||
|
|||||||
48
src/user.c
48
src/user.c
@ -394,23 +394,21 @@ INTERNAL void debug_draw_movement(struct entity *ent)
|
|||||||
INTERNAL void user_update(void)
|
INTERNAL void user_update(void)
|
||||||
{
|
{
|
||||||
struct temp_arena scratch = scratch_begin_no_conflict();
|
struct temp_arena scratch = scratch_begin_no_conflict();
|
||||||
struct game_cmd_list cmd_list = {
|
|
||||||
.arena = scratch.arena
|
|
||||||
};
|
|
||||||
|
|
||||||
struct entity_store *store = G.world.entity_store;
|
/* ========================== *
|
||||||
|
* Begin frame
|
||||||
|
* ========================== */
|
||||||
|
|
||||||
/* Get time */
|
|
||||||
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
|
f64 cur_time = sys_timestamp_seconds(sys_timestamp());
|
||||||
G.dt = max_f64(0.0, cur_time - G.time);
|
G.dt = max_f64(0.0, cur_time - G.time);
|
||||||
G.time += G.dt;
|
G.time += G.dt;
|
||||||
G.screen_size = sys_window_get_size(G.window);
|
G.screen_size = sys_window_get_size(G.window);
|
||||||
|
|
||||||
/* ========================== *
|
struct entity_store *store = G.world.entity_store;
|
||||||
* Begin frame cache scopes
|
|
||||||
* ========================== */
|
|
||||||
|
|
||||||
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
struct sprite_scope *sprite_frame_scope = sprite_scope_begin();
|
||||||
|
struct game_cmd_list cmd_list = {
|
||||||
|
.arena = scratch.arena
|
||||||
|
};
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Produce interpolated tick
|
* Produce interpolated tick
|
||||||
@ -450,17 +448,13 @@ INTERNAL void user_update(void)
|
|||||||
G.world.time = math_lerp64(t0->time, t1->time, (f64)tick_blend);
|
G.world.time = math_lerp64(t0->time, t1->time, (f64)tick_blend);
|
||||||
|
|
||||||
/* Blend entities */
|
/* Blend entities */
|
||||||
struct entity_array t0_entities = entity_store_as_array(t0->entity_store);
|
u64 num_entities = min_u64(t0->entity_store->count, t1->entity_store->count);
|
||||||
struct entity_array t1_entities = entity_store_as_array(t1->entity_store);
|
|
||||||
struct entity_array world_entities = entity_store_as_array(store);
|
|
||||||
|
|
||||||
u64 num_entities = min_u64(t0_entities.count, t1_entities.count);
|
|
||||||
{
|
{
|
||||||
__profscope(tick_blending);
|
__profscope(tick_blending);
|
||||||
for (u64 i = 0; i < num_entities; ++i) {
|
for (u64 i = 0; i < num_entities; ++i) {
|
||||||
struct entity *e0 = &t0_entities.entities[i];
|
struct entity *e0 = &t0->entity_store->entities[i];
|
||||||
struct entity *e1 = &t1_entities.entities[i];
|
struct entity *e1 = &t1->entity_store->entities[i];
|
||||||
struct entity *e = &world_entities.entities[i];
|
struct entity *e = &store->entities[i];
|
||||||
ASSERT(e->cached_global_xform_dirty == false); /* Game thread should have cached all global xforms before publishing */
|
ASSERT(e->cached_global_xform_dirty == false); /* Game thread should have cached all global xforms before publishing */
|
||||||
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
if (e0->handle.gen == e1->handle.gen && e0->continuity_gen == e1->continuity_gen) {
|
||||||
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
e->local_xform = xform_lerp(e0->local_xform, e1->local_xform, tick_blend);
|
||||||
@ -489,8 +483,6 @@ INTERNAL void user_update(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
struct entity_array entities_array = entity_store_as_array(store);
|
|
||||||
|
|
||||||
/* ========================== *
|
/* ========================== *
|
||||||
* Find important entities
|
* Find important entities
|
||||||
* ========================== */
|
* ========================== */
|
||||||
@ -768,10 +760,10 @@ INTERNAL void user_update(void)
|
|||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* Iterate entities */
|
/* Iterate entities */
|
||||||
for (u64 entity_index = 0; entity_index < entities_array.count; ++entity_index) {
|
for (u64 entity_index = 0; entity_index < store->count; ++entity_index) {
|
||||||
__profscope(user_entity_iter);
|
__profscope(user_entity_iter);
|
||||||
|
|
||||||
struct entity *ent = &entities_array.entities[entity_index];
|
struct entity *ent = &store->entities[entity_index];
|
||||||
if (!ent->valid) continue;
|
if (!ent->valid) continue;
|
||||||
if (ent->is_root) continue;
|
if (ent->is_root) continue;
|
||||||
|
|
||||||
@ -954,8 +946,9 @@ INTERNAL void user_update(void)
|
|||||||
* Construct player control cmd
|
* Construct player control cmd
|
||||||
* ========================== */
|
* ========================== */
|
||||||
|
|
||||||
/* Movement */
|
|
||||||
{
|
{
|
||||||
|
|
||||||
|
/* Queue player move cmd */
|
||||||
struct v2 input_move_dir = { 0 };
|
struct v2 input_move_dir = { 0 };
|
||||||
{
|
{
|
||||||
for (enum user_bind_kind bind = 0; bind < (i32)ARRAY_COUNT(G.bind_states); ++bind) {
|
for (enum user_bind_kind bind = 0; bind < (i32)ARRAY_COUNT(G.bind_states); ++bind) {
|
||||||
@ -990,28 +983,21 @@ INTERNAL void user_update(void)
|
|||||||
input_move_dir = xform_basis_invert_mul_v2(G.world_view, input_move_dir); /* Make move dir relative to world view */
|
input_move_dir = xform_basis_invert_mul_v2(G.world_view, input_move_dir); /* Make move dir relative to world view */
|
||||||
input_move_dir = v2_norm(input_move_dir);
|
input_move_dir = v2_norm(input_move_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct v2 input_aim_pos = G.world_cursor;
|
struct v2 input_aim_pos = G.world_cursor;
|
||||||
|
|
||||||
i32 cmd_fire = (G.bind_states[USER_BIND_KIND_FIRE].num_presses > 0 || G.bind_states[USER_BIND_KIND_FIRE].is_held) ? 1 : -1;
|
|
||||||
|
|
||||||
if (!G.debug_camera) {
|
if (!G.debug_camera) {
|
||||||
/* Queue player move cmd */
|
|
||||||
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
||||||
.kind = GAME_CMD_KIND_PLAYER_MOVE,
|
.kind = GAME_CMD_KIND_PLAYER_MOVE,
|
||||||
.move_dir = input_move_dir,
|
.move_dir = input_move_dir,
|
||||||
.aim_pos = input_aim_pos
|
.aim_pos = input_aim_pos
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/* Queue player fire cmd */
|
/* Queue player fire cmd */
|
||||||
if (cmd_fire) {
|
|
||||||
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
queue_game_cmd(&cmd_list, (struct game_cmd) {
|
||||||
.kind = GAME_CMD_KIND_PLAYER_FIRE,
|
.kind = GAME_CMD_KIND_PLAYER_FIRE,
|
||||||
.state = cmd_fire
|
.state = (G.bind_states[USER_BIND_KIND_FIRE].num_presses > 0 || G.bind_states[USER_BIND_KIND_FIRE].is_held) ? GAME_CMD_STATE_START : GAME_CMD_STATE_STOP
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
/* ---------------------------------------------------------------------- */
|
/* ---------------------------------------------------------------------- */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user