fix theft of uball

Yesterday's commit to add a "<Mon> takes off <item>" during theft
of a worn item used uchain instead of uball when the item was uball.
That works as intended when uball is just carried, but if it is also
wielded, alt-wielded, or quivered then the pointers for those weapon
slots weren't updated (because uchain doesn't have the corresponding
owornmask bits set when removal performs unpunish()).  Check for that
and call remove_worn_item() again if necessary.

Also, the subsequent "<Mon|She> stole <item>" message was inserting
"removed the chain and" before "stole" when item is uball, but that
isn't needed anymore since the preface message "<Mon> takes off the
iron chain (attached to you)" will have just been given.
This commit is contained in:
PatR
2024-02-05 12:57:13 -08:00
parent 32e5c1df5c
commit 163fb7613f

View File

@@ -329,7 +329,10 @@ worn_item_removal(
: 0;
if (strip_art) { /* convert "a/an/the <object>" to "your object" */
copynchars(article, objbuf, strip_art);
(void) strsubst(objbuf, article, "your ");
/* when removing attached iron ball, caller passes 'uchain';
when formatted, it will be "an iron chain (attached to you)";
change "an" to "the" rather than to "your" in that situation */
(void) strsubst(objbuf, article, (obj == uchain) ? "the " : "your ");
}
/* these ought to be guarded against matching user-supplied name */
(void) strsubst(objbuf, " (being worn)", "");
@@ -579,6 +582,14 @@ steal(struct monst* mtmp, char* objnambuf)
if (otmp == uball && uchain != NULL)
item = uchain; /* yields a more accurate 'takes off' message */
worn_item_removal(mtmp, item);
/* if we switched from uball to uchain for the preface message,
then unpunish() took place and both those pointers are now Null,
with 'item' a stale pointer to freed chain; the ball is still
present though and 'otmp' is still valid; if uball was also
wielded or quivered, the corresponding weapon pointer hasn't
been cleared yet; do that, with no preface message this time */
if ((otmp->owornmask & W_WEAPONS) != 0L)
remove_worn_item(otmp, FALSE);
}
/* do this before removing it from inventory */
@@ -599,9 +610,7 @@ steal(struct monst* mtmp, char* objnambuf)
if (iflags.last_msg == PLNMSG_MON_TAKES_OFF_ITEM
&& mtmp->data->mlet == S_NYMPH)
++named;
urgent_pline("%s%s stole %s.", named ? "She" : Monnambuf,
(was_punished && !Punished) ? " removed your chain and" : "",
doname(otmp));
urgent_pline("%s stole %s.", named ? "She" : Monnambuf, doname(otmp));
(void) encumber_msg();
could_petrify = (otmp->otyp == CORPSE
&& touch_petrifies(&mons[otmp->corpsenm]));