fix github issue #1257 - nymph theft while blind
Issue reported by Meklon2007: some theft feedback during nymph attacks refers to the attacker as "she" and others as "it" if hero is blind. The "she" references are intentional. However, mixing them with "it" references when a series of messages occurs is jarring. This changes "it" to "someone", which is still different from "she" but hopefully enough less so to be tolerable. That resulted in monkeys also being referred to as "someone" because they're classified as humanoid. Change x_monnam()'s AUGMENT_IT handling, which chooses between "someone" and "something" when the monster is not seen, to override humanoid for animals (affects 'Y' class) and for mindless (affects zombies, mummies, and golems). So an unseen monkey will be "it" again. The final message for current item was relying on a cached monster name value. If an unseen nymph or monkey stole a worn blindfold so that hero's vision was restored: "It <stole> item" before the changes and "Someone|Something <stole> item" after. So update the cached name if sight gets regained, to give "<Mon> stole <item>." (If the item is worn armor and the thief is a nymph, it was and still is "She stole <item>".) The message for having any worn item be stolen, which got split into two parts within the past year, was giving "<Mon> takes off <alt weapon>". When not dual-wielded, the alternate weapon isn't really worn. Rather than suppress it outright, change the message for uwep/uswapwep/uquiver to say "disarms" instead of "takes off". For accessories, change "takes off" to "removes". Those are more or less interchangeable these days but "removes" matches R instead of T. While testing, my pet evidently killed a nymph (I was blinded and couldn't see it happen) while she stole my gloves and the next message I got was "You finish taking off your suit." The gloves weren't worn anymore so equipname() defaulted to suit. Get rid of equipname() altogether and switch to armor_simple_name() which doesn't rely on the worn-armor pointers. Fixes #1257
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1450 $ $NHDT-Date: 1720074479 2024/07/04 06:27:59 $
|
||||
NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.1455 $ $NHDT-Date: 1720895738 2024/07/13 18:35:38 $
|
||||
|
||||
General Fixes and Modified Features
|
||||
-----------------------------------
|
||||
@@ -1439,6 +1439,12 @@ using #loot -> 'i'n to put multiple items into a shop-owned container would
|
||||
don't-sell state was being reset for each item so 'a' and 'q' didn't
|
||||
stick beyond the current one
|
||||
join wall "spines" with walls of water and lava
|
||||
some theft messages by nymphs force "she", others use default monster naming
|
||||
which yields "it" when unseen; change the latter to "someone" which
|
||||
still differs from "she" in a series of messages but isn't as jarring
|
||||
if a nymph stole worn armor and got killed (perhaps by pet) before hero's next
|
||||
turn, feedback would be "You finish taking off your suit." regardless
|
||||
of the type of armor being taken off
|
||||
|
||||
|
||||
Fixes to 3.7.0-x General Problems Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 do_name.c $NHDT-Date: 1720128164 2024/07/04 21:22:44 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.319 $ */
|
||||
/* NetHack 3.7 do_name.c $NHDT-Date: 1720895738 2024/07/13 18:35:38 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.320 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -870,8 +870,11 @@ x_monnam(
|
||||
/* unseen monsters, etc.; usually "it" but sometimes more specific;
|
||||
when hallucinating, the more specific values might be inverted */
|
||||
if (do_it) {
|
||||
/* !is_animal excludes all Y; !mindless excludes Z, M, \' */
|
||||
boolean s_one = humanoid(mdat) && !is_animal(mdat) && !mindless(mdat);
|
||||
|
||||
Strcpy(buf, !augment_it ? "it"
|
||||
: (!do_hallu ? humanoid(mdat) : !rn2(2)) ? "someone"
|
||||
: (!do_hallu ? s_one : !rn2(2)) ? "someone"
|
||||
: "something");
|
||||
return buf;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 do_wear.c $NHDT-Date: 1702017586 2023/12/08 06:39:46 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.175 $ */
|
||||
/* NetHack 3.7 do_wear.c $NHDT-Date: 1720895740 2024/07/13 18:35:40 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1853,7 +1853,8 @@ armoroff(struct obj *otmp)
|
||||
}
|
||||
if (what) {
|
||||
/* sizeof offdelaybuf == 60; increase it if this becomes longer */
|
||||
Sprintf(offdelaybuf, "You finish taking off your %s.", what);
|
||||
Snprintf(offdelaybuf, sizeof offdelaybuf,
|
||||
"You finish taking off your %s.", what);
|
||||
gn.nomovemsg = offdelaybuf;
|
||||
}
|
||||
} else {
|
||||
|
||||
59
src/steal.c
59
src/steal.c
@@ -1,27 +1,14 @@
|
||||
/* NetHack 3.7 steal.c $NHDT-Date: 1707122967 2024/02/05 08:49:27 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.121 $ */
|
||||
/* NetHack 3.7 steal.c $NHDT-Date: 1720895742 2024/07/13 18:35:42 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.132 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
#include "hack.h"
|
||||
|
||||
staticfn const char *equipname(struct obj *);
|
||||
staticfn int unstolenarm(void);
|
||||
staticfn int stealarm(void);
|
||||
staticfn void worn_item_removal(struct monst *, struct obj *);
|
||||
|
||||
staticfn const char *
|
||||
equipname(struct obj *otmp)
|
||||
{
|
||||
return ((otmp == uarmu) ? shirt_simple_name(otmp)
|
||||
: (otmp == uarmf) ? boots_simple_name(otmp)
|
||||
: (otmp == uarms) ? shield_simple_name(otmp)
|
||||
: (otmp == uarmg) ? gloves_simple_name(otmp)
|
||||
: (otmp == uarmc) ? cloak_simple_name(otmp)
|
||||
: (otmp == uarmh) ? helm_simple_name(otmp)
|
||||
: suit_simple_name(otmp));
|
||||
}
|
||||
|
||||
/* proportional subset of gold; return value actually fits in an int */
|
||||
long
|
||||
somegold(long lmoney)
|
||||
@@ -168,7 +155,7 @@ unstolenarm(void)
|
||||
break;
|
||||
gs.stealoid = 0;
|
||||
if (obj) {
|
||||
You("finish taking off your %s.", equipname(obj));
|
||||
You("finish taking off your %s.", armor_simple_name(obj));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -319,6 +306,7 @@ worn_item_removal(
|
||||
struct obj *obj)
|
||||
{
|
||||
char objbuf[BUFSZ], article[20], *p;
|
||||
const char *verb;
|
||||
int strip_art;
|
||||
|
||||
Strcpy(objbuf, doname(obj));
|
||||
@@ -342,7 +330,13 @@ worn_item_removal(
|
||||
&& (!strncmp(p + 5, "left ", 5) || !strncmp(p + 5, "right ", 6)))
|
||||
(void) strsubst(p + 2, "on", "from");
|
||||
|
||||
pline("%s takes off %s.", Monnam(mon), objbuf);
|
||||
/* slightly iffy for alternate weapon that isn't actively dual-wielded,
|
||||
but it's better to alert the player to the change in equipment than
|
||||
to suppress the message for that case */
|
||||
verb = ((obj->owornmask & W_WEAPONS) != 0L) ? "disarms"
|
||||
: ((obj->owornmask & W_ACCESSORY) != 0L) ? "removes"
|
||||
: "takes off";
|
||||
pline("%s %s %s.", Some_Monnam(mon), verb, objbuf);
|
||||
iflags.last_msg = PLNMSG_MON_TAKES_OFF_ITEM;
|
||||
/* removal might trigger more messages (due to loss of Lev|Fly;
|
||||
descending happens before the theft in progress finishes) */
|
||||
@@ -363,6 +357,7 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
int tmp, could_petrify, armordelay, olddelay, icnt,
|
||||
named = 0, retrycnt = 0;
|
||||
boolean monkey_business = is_animal(mtmp->data),
|
||||
seen = canspotmon(mtmp),
|
||||
was_doffing, was_punished = Punished;
|
||||
|
||||
if (objnambuf)
|
||||
@@ -375,10 +370,9 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
teleporting to safety could result in a previously visible thief
|
||||
no longer being visible; it could also be a case of a blinded
|
||||
hero being able to see via wearing the Eyes of the Overworld and
|
||||
having those stolen; remember the name in order to avoid "It"
|
||||
in the eventual "<Monnam> stole <item>" message; (the name might
|
||||
already be "It"; if so, that's ok) */
|
||||
Strcpy(Monnambuf, Monnam(mtmp));
|
||||
having those stolen; remember the name as it is now; if unseen,
|
||||
monkeys will be "It" and nymphs will be "Someone" */
|
||||
Strcpy(Monnambuf, Some_Monnam(mtmp));
|
||||
|
||||
/* food being eaten might already be used up but will not have
|
||||
been removed from inventory yet; we don't want to steal that,
|
||||
@@ -496,7 +490,7 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
pline("%s tries to %s %s%s but gives up.", Monnambuf,
|
||||
ROLL_FROM(how),
|
||||
(otmp->owornmask & W_ARMOR) ? "your " : "",
|
||||
(otmp->owornmask & W_ARMOR) ? equipname(otmp)
|
||||
(otmp->owornmask & W_ARMOR) ? armor_simple_name(otmp)
|
||||
: yname(otmp));
|
||||
/* the fewer items you have, the less likely the thief
|
||||
is going to stick around to try again (0) instead of
|
||||
@@ -541,7 +535,6 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
} else {
|
||||
int curssv = otmp->cursed;
|
||||
int slowly;
|
||||
boolean seen = canspotmon(mtmp);
|
||||
|
||||
otmp->cursed = 0;
|
||||
slowly = (armordelay >= 1 || gm.multi < 0);
|
||||
@@ -552,7 +545,7 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
: !slowly ? "hand over"
|
||||
: was_doffing ? "continue removing"
|
||||
: "start removing",
|
||||
equipname(otmp));
|
||||
armor_simple_name(otmp));
|
||||
else
|
||||
urgent_pline("%s seduces you and %s off your %s.",
|
||||
!seen ? "She" : Adjmonnam(mtmp, "beautiful"),
|
||||
@@ -560,7 +553,7 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
: !slowly ? "you take"
|
||||
: was_doffing ? "you continue taking"
|
||||
: "you start taking",
|
||||
equipname(otmp));
|
||||
armor_simple_name(otmp));
|
||||
named++;
|
||||
/* the following is to set multi for later on */
|
||||
nomul(-armordelay);
|
||||
@@ -580,6 +573,10 @@ steal(struct monst *mtmp, char *objnambuf)
|
||||
impossible("Tried to steal a strange worn thing. [%d]",
|
||||
otmp->oclass);
|
||||
}
|
||||
/* hero's blindfold might have just been stolen; if so, replace
|
||||
cached "It" or "Someone" with Monnam */
|
||||
if (!seen && canspotmon(mtmp))
|
||||
Strcpy(Monnambuf, Monnam(mtmp));
|
||||
} else if (otmp->owornmask) { /* weapon or ball&chain */
|
||||
struct obj *item = otmp;
|
||||
|
||||
@@ -750,29 +747,29 @@ stealamulet(struct monst *mtmp)
|
||||
/* take off outer gear if we're targeting [hypothetical]
|
||||
quest artifact suit, shirt, gloves, or rings */
|
||||
if ((otmp == uarm || otmp == uarmu) && uarmc)
|
||||
remove_worn_item(uarmc, FALSE);
|
||||
worn_item_removal(mtmp, uarmc);
|
||||
if (otmp == uarmu && uarm)
|
||||
remove_worn_item(uarm, FALSE);
|
||||
worn_item_removal(mtmp, uarm);
|
||||
if ((otmp == uarmg || ((otmp == uright || otmp == uleft) && uarmg))
|
||||
&& uwep) {
|
||||
/* gloves are about to be unworn; unwield weapon(s) first */
|
||||
if (u.twoweap) /* remove_worn_item(uswapwep) indirectly */
|
||||
remove_worn_item(uswapwep, FALSE); /* clears u.twoweap */
|
||||
remove_worn_item(uwep, FALSE);
|
||||
worn_item_removal(mtmp, uswapwep); /* clears u.twoweap */
|
||||
worn_item_removal(mtmp, uwep);
|
||||
}
|
||||
if ((otmp == uright || otmp == uleft) && uarmg)
|
||||
/* calls Gloves_off() to handle wielded cockatrice corpse */
|
||||
remove_worn_item(uarmg, FALSE);
|
||||
worn_item_removal(mtmp, uarmg);
|
||||
|
||||
/* finally, steal the target item */
|
||||
if (otmp->owornmask)
|
||||
remove_worn_item(otmp, TRUE);
|
||||
worn_item_removal(mtmp, otmp);
|
||||
if (otmp->unpaid)
|
||||
subfrombill(otmp, shop_keeper(*u.ushops));
|
||||
freeinv(otmp);
|
||||
Strcpy(buf, doname(otmp));
|
||||
(void) mpickobj(mtmp, otmp); /* could merge and free otmp but won't */
|
||||
pline("%s steals %s!", Monnam(mtmp), buf);
|
||||
pline("%s steals %s!", Some_Monnam(mtmp), buf);
|
||||
if (can_teleport(mtmp->data) && !tele_restrict(mtmp))
|
||||
(void) rloc(mtmp, RLOC_MSG);
|
||||
(void) encumber_msg();
|
||||
|
||||
Reference in New Issue
Block a user