From 5d205a850b85a5ad003d8a6fd9671d6aa4196b82 Mon Sep 17 00:00:00 2001 From: Vito Caputo Date: Tue, 29 Nov 2022 23:48:55 -0800 Subject: game: fix flashers list corruption (entity_t.flashes_remaining == 0) was being misused to indicate an entity wasn't on any of the flashers lists. At some point during the feature's development that was actually true, but as the code evolved that was no longer the case and entities would sit in the flashers_off list with flashes_remaining at 0 before flipping back on for a cycle at which point they'd be found with 0 flashes_remaining and dropped from any flashers lists. This is a problem because flash_entity() would come along and use the flashes_remaining == 0 state to see if the entity needed to get on a flashers list before resetting the flashes_remaining count. Furthermore, when adult->holding gets cleared (baby drop off) the flashes_remaining gets zeroed to ensure the reset baby doesn't start out with residual flashing at its new location. This just created more opportunities where the flashes_remaining is zero while still on a list, since the holding reset was just expediting the list removal - not actually doing it. This commit simply introduces a discrete flag for flashing vs. not flashing to indicate flashers_{on,off} list membership, independent of the flashes_remaining count. Fixes infinite loop / apparent freeze bug reported by Tara and Phil during some play testing. Thanks guys! --- src/game.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/game.c b/src/game.c index f845327..19ec9d4 100644 --- a/src/game.c +++ b/src/game.c @@ -118,6 +118,7 @@ struct entity_any_t { v3f_t scale; m4f_t model_x; bb2f_t aabb_x; + unsigned flashing:1; entity_any_t *flashers_next; unsigned flashes_remaining; }; @@ -385,7 +386,8 @@ static void mask_adult(game_t *game, adult_t *adult, mask_t *mask) static void flash_entity(game_t *game, entity_any_t *any, unsigned count) { - if (!any->flashes_remaining) { + if (!any->flashing) { + any->flashing = 1; any->flashers_next = game->flashers_on_head; game->flashers_on_head = any; } @@ -1068,6 +1070,7 @@ static void game_update(play_t *play, void *context) e_next = e->flashers_next; if (!e->flashes_remaining) { + e->flashing = 0; e->flashers_next = NULL; continue; } -- cgit v1.2.3