github issue #1312 - prot from shape changers

Issue reported by youkan700:  shape change anomalies.  Shapechangers
could change shape despite active protection-from-shape-changers if
hero wore two rings of protection from shape changers and took one
off.  Shapechangers who migrated to a not-yet-visited level that
eventually got visited with protection from shape changers in effect
would be stuck in their current shape, even if the PfSC attribute
got toggled off and back on.

The issue included suggested fixes and those are what I've used.  I
noticed a third case that only applies to wizard mode:  if player
used #wizintrinsic to set a timed value for PfSC, monsters wouldn't
resume changing shape after it timed out, unless/until it got toggled
on and back off via a PfSC ring or hero left the level and returned.

Fixes #1312
This commit is contained in:
PatR
2024-11-28 11:33:26 -08:00
parent 755b70de69
commit cbc93a0555
4 changed files with 18 additions and 5 deletions

View File

@@ -1410,10 +1410,11 @@ Ring_off_or_gone(struct obj *obj, boolean gone)
find_ac(); /* updates botl */
break;
case RIN_PROTECTION_FROM_SHAPE_CHAN:
/* If you're no longer protected, let the chameleons
* change shape again -dgk
*/
restartcham();
/* if you're no longer protected, let the chameleons change
shape again; however, might still be protected if wearing
2nd ring of this type (or via #wizintrinsic) */
if (!Protection_from_shape_changers)
restartcham();
break;
}
}

View File

@@ -417,6 +417,12 @@ mon_arrive(struct monst *mtmp, int when)
fromdlev.dnum = mtmp->mtrack[2].x;
fromdlev.dlevel = mtmp->mtrack[2].y;
mon_track_clear(mtmp);
/* in case Protection_from_shape_changers is different now from when
'mtmp' went onto the migrating monsters list; that's handled in
getlev() when returning to a previously visited level and by the
special level code for monsters specified in the level, but needed
here for monsters migrating to a newly created level */
restore_cham(mtmp);
if (mtmp == u.usteed)
return; /* don't place steed on the map */

View File

@@ -4465,7 +4465,7 @@ get_iter_mons_xy(
/* force all chameleons and mimics to become themselves and werecreatures
to revert to human form; called when Protection_from_shape_changers gets
activated via wearing or eating ring or wizintrinsics */
activated via wearing or eating ring or via #wizintrinsic */
void
rescham(void)
{

View File

@@ -930,6 +930,12 @@ nh_timeout(void)
case GLIB:
make_glib(0); /* might update persistent inventory */
break;
case PROT_FROM_SHAPE_CHANGERS:
/* timed Protection_from_shape_changers is via
#wizintrinsic only */
if (!Protection_from_shape_changers)
restartcham();
break;
}
}