diff options
author | Vito Caputo <vcaputo@pengaru.com> | 2022-11-29 23:48:55 -0800 |
---|---|---|
committer | Vito Caputo <vcaputo@pengaru.com> | 2022-11-29 23:48:55 -0800 |
commit | 5d205a850b85a5ad003d8a6fd9671d6aa4196b82 (patch) | |
tree | dac26addd88febef7c2264db3e456aed187791e1 /src/game.c | |
parent | c216dfb5b737e4b923f521eb3ac2d1309aa2a594 (diff) |
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!
Diffstat (limited to 'src/game.c')
-rw-r--r-- | src/game.c | 5 |
1 files changed, 4 insertions, 1 deletions
@@ -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; } |