From fe8710532e5b5f85e87465fbebf408887c4eba91 Mon Sep 17 00:00:00 2001 From: Michael Meyer Date: Mon, 20 Nov 2023 15:51:01 -0500 Subject: [PATCH] Fix: latent bug with finish_meating on catchup Some players of 3.6 recently noticed that sometimes, mimics in shops seemed to have moved around even before the player had entered the shop or done anything to uncloak them. I found that this was because finish_meating was being called for all non-eating monsters when restoring a level (monsters that weren't eating anything would have meating == 0 so always pass the 'imv > meating' check). This would uncloak mimics -- but not all the time, because the 'mappearance != 0' test meant mimics disguised as strange objects weren't uncloaked. I think that was meant to be an additional check to confirm the monster really did have a disguise, but in reality it meant that M_AP_OBJECT "strange object", M_AP_MONSTER "giant ant", etc disguises wouldn't be removed by finish_meating. As it turns out, this was mostly fixed by coincidence in 221e4a7, which fixed the "exclude actual mimics" check in finish_meating. So at this point in 3.7 it's largely a latent bug, but it still had the potential to improperly uncloak non-mimics who can disguise themselves (like the Wizard of Yendor, maybe?), and could cause other problems if finish_meating were updated to have additional effects, or if some monster types were made to disguise themselves as a strange object when eating a mimic. --- src/dog.c | 10 ++++++---- src/dogmove.c | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/dog.c b/src/dog.c index 09cdb0053..6a664bd9c 100644 --- a/src/dog.c +++ b/src/dog.c @@ -604,10 +604,12 @@ mon_catchup_elapsed_time( mtmp->mstun = 0; /* might finish eating or be able to use special ability again */ - if (imv > mtmp->meating) - finish_meating(mtmp); - else - mtmp->meating -= imv; + if (mtmp->meating) { + if (imv > mtmp->meating) + finish_meating(mtmp); + else + mtmp->meating -= imv; + } if (imv > mtmp->mspec_used) mtmp->mspec_used = 0; else diff --git a/src/dogmove.c b/src/dogmove.c index 5beaea770..90df3790f 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -1401,7 +1401,7 @@ void finish_meating(struct monst *mtmp) { mtmp->meating = 0; - if (M_AP_TYPE(mtmp) && mtmp->mappearance && mtmp->data->mlet != S_MIMIC) { + if (M_AP_TYPE(mtmp) != M_AP_NOTHING && mtmp->data->mlet != S_MIMIC) { /* was eating a mimic and now appearance needs resetting */ mtmp->m_ap_type = M_AP_NOTHING; mtmp->mappearance = 0;