fix #K4210 - vampshifter fog clouds
Messaging for vampires changing into fog clouds was inconsistent in 3.6.x but already fixed in to-be-3.7. However, maintaining an extra set of shape change messages (one in newcham(), the other in vamp_shift() which turns out to only be used when a vampshifter turns into a fog cloud in order to pass under a closed door) was a nuisance. Redo vamp_shift() to use newcham() feedback. Update that feedback to be accessibility-aware and also to use "Your <mon>" instead of "The <mon>" when appropriate. While in there, remove a couple of trailing spaces and eliminate use of one dynamically constructed format string that necessitated warning manipulation.
This commit is contained in:
105
src/mon.c
105
src/mon.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.7 mon.c $NHDT-Date: 1718303201 2024/06/13 18:26:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.576 $ */
|
||||
/* NetHack 3.7 mon.c $NHDT-Date: 1722116051 2024/07/27 21:34:11 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.583 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -712,7 +712,7 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags)
|
||||
case PM_FIRE_ANT: case PM_GIANT_BEETLE: case PM_QUEEN_BEE:
|
||||
|
||||
case PM_QUIVERING_BLOB: case PM_ACID_BLOB: case PM_GELATINOUS_CUBE:
|
||||
case PM_CHICKATRICE: case PM_COCKATRICE: case PM_PYROLISK:
|
||||
case PM_CHICKATRICE: case PM_COCKATRICE: case PM_PYROLISK:
|
||||
|
||||
case PM_JACKAL: case PM_FOX: case PM_COYOTE: case PM_WEREJACKAL:
|
||||
case PM_LITTLE_DOG: case PM_DINGO: case PM_DOG: case PM_LARGE_DOG:
|
||||
@@ -780,7 +780,7 @@ make_corpse(struct monst *mtmp, unsigned int corpseflags)
|
||||
|
||||
case PM_GNOME: case PM_GNOME_LEADER: case PM_GNOMISH_WIZARD:
|
||||
case PM_GNOME_RULER:
|
||||
case PM_GIANT: case PM_STONE_GIANT: case PM_HILL_GIANT:
|
||||
case PM_GIANT: case PM_STONE_GIANT: case PM_HILL_GIANT:
|
||||
case PM_FIRE_GIANT: case PM_FROST_GIANT: case PM_ETTIN:
|
||||
case PM_STORM_GIANT: case PM_TITAN:
|
||||
|
||||
@@ -1151,9 +1151,7 @@ m_calcdistress(struct monst *mtmp)
|
||||
|
||||
/* possibly polymorph shapechangers and lycanthropes */
|
||||
if (ismnum(mtmp->cham))
|
||||
decide_to_shapeshift(mtmp, (canspotmon(mtmp)
|
||||
|| engulfing_u(mtmp))
|
||||
? SHIFT_MSG : 0);
|
||||
decide_to_shapeshift(mtmp);
|
||||
were_change(mtmp);
|
||||
|
||||
/* gradually time out temporary problems */
|
||||
@@ -2808,8 +2806,6 @@ lifesaved_monster(struct monst *mtmp)
|
||||
}
|
||||
}
|
||||
|
||||
DISABLE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/* when a shape-shifted vampire is killed, it reverts to base form instead
|
||||
of dying; moved into separate routine to unclutter mondead() */
|
||||
staticfn boolean
|
||||
@@ -2820,7 +2816,7 @@ vamprises(struct monst *mtmp)
|
||||
if (ismnum(mndx) && mndx != monsndx(mtmp->data)
|
||||
&& !(svm.mvitals[mndx].mvflags & G_GENOD)) {
|
||||
coord new_xy;
|
||||
char buf[BUFSZ];
|
||||
char action[BUFSZ];
|
||||
/* alternate message phrasing for some monster types */
|
||||
boolean spec_mon = (nonliving(mtmp->data)
|
||||
|| noncorporeal(mtmp->data)
|
||||
@@ -2830,13 +2826,12 @@ vamprises(struct monst *mtmp)
|
||||
|| amorphous(mtmp->data));
|
||||
coordxy x = mtmp->mx, y = mtmp->my;
|
||||
|
||||
/* construct a format string before transformation;
|
||||
will be capitalized when used, expects one %s arg */
|
||||
Snprintf(buf, sizeof buf,
|
||||
"%s suddenly %s and rises as %%s!",
|
||||
/* construct a 'before' argument to pass to pline(); this used
|
||||
to construct a dynamic format string but that's overkill */
|
||||
Snprintf(action, sizeof action, "%s suddenly %s and rises as",
|
||||
x_monnam(mtmp, ARTICLE_THE,
|
||||
spec_mon ? (char *) 0 : "seemingly dead",
|
||||
(SUPPRESS_INVISIBLE | SUPPRESS_IT), FALSE),
|
||||
(SUPPRESS_INVISIBLE | AUGMENT_IT), FALSE),
|
||||
spec_death ? "reconstitutes" : "transforms");
|
||||
mtmp->mcanmove = 1;
|
||||
mtmp->mfrozen = 0;
|
||||
@@ -2857,19 +2852,16 @@ vamprises(struct monst *mtmp)
|
||||
rloc_to(mtmp, new_xy.x, new_xy.y);
|
||||
}
|
||||
(void) newcham(mtmp, &mons[mndx], NO_NC_FLAGS);
|
||||
if (mtmp->data == &mons[mndx])
|
||||
mtmp->cham = NON_PM;
|
||||
else
|
||||
mtmp->cham = mndx;
|
||||
mtmp->cham = (mtmp->data == &mons[mndx]) ? NON_PM : mndx;
|
||||
|
||||
if (canspotmon(mtmp)) {
|
||||
/* 3.6.0 used a_monnam(mtmp); that was weird if mtmp was
|
||||
named: "Dracula suddenly transforms and rises as Dracula";
|
||||
3.6.1 used mtmp->data->mname; that ignored hallucination */
|
||||
pline_mon(mtmp, upstart(buf),
|
||||
x_monnam(mtmp, ARTICLE_A, (char *) 0,
|
||||
pline_mon(mtmp, "%s %s!", upstart(action),
|
||||
x_monnam(mtmp, ARTICLE_A, (char *) 0,
|
||||
(SUPPRESS_NAME | SUPPRESS_IT | SUPPRESS_INVISIBLE),
|
||||
FALSE));
|
||||
FALSE));
|
||||
gv.vamp_rise_msg = TRUE;
|
||||
}
|
||||
newsym(x, y);
|
||||
@@ -2878,8 +2870,6 @@ vamprises(struct monst *mtmp)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
RESTORE_WARNING_FORMAT_NONLITERAL
|
||||
|
||||
/* specific combination of x_monnam flags for livelogging; show what was
|
||||
actually killed even when unseen or hallucinated to be something else */
|
||||
#define livelog_mon_nam(mtmp) \
|
||||
@@ -4671,16 +4661,12 @@ pick_animal(void)
|
||||
}
|
||||
|
||||
void
|
||||
decide_to_shapeshift(struct monst *mon, int shiftflags)
|
||||
decide_to_shapeshift(struct monst *mon)
|
||||
{
|
||||
struct permonst *ptr = 0;
|
||||
int mndx;
|
||||
unsigned was_female = mon->female;
|
||||
boolean msg = FALSE, dochng = FALSE;
|
||||
|
||||
if ((shiftflags & SHIFT_MSG)
|
||||
|| ((shiftflags & SHIFT_SEENMSG) && sensemon(mon)))
|
||||
msg = TRUE;
|
||||
boolean dochng = FALSE;
|
||||
|
||||
if (!is_vampshifter(mon)) {
|
||||
/* regular shapeshifter */
|
||||
@@ -4729,11 +4715,27 @@ decide_to_shapeshift(struct monst *mon, int shiftflags)
|
||||
}
|
||||
}
|
||||
if (dochng) {
|
||||
if (newcham(mon, ptr, msg ? NC_SHOW_MSG : 0) && is_vampshifter(mon)) {
|
||||
/* for vampshift, override the 10% chance for sex change */
|
||||
ptr = mon->data;
|
||||
if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
|
||||
mon->female = was_female;
|
||||
unsigned ncflags = (is_vampshifter(mon) || canspotmon(mon))
|
||||
? NC_SHOW_MSG : 0U;
|
||||
|
||||
if (!ncflags) {
|
||||
/* cheat */
|
||||
struct permonst *oldptr = mon->data;
|
||||
|
||||
mon->data = ptr;
|
||||
if (canspotmon(mon))
|
||||
ncflags = NC_SHOW_MSG;
|
||||
mon->data = oldptr;
|
||||
}
|
||||
|
||||
if (newcham(mon, ptr, ncflags)) {
|
||||
/* for vampshift, override the 10% chance for sex change
|
||||
(by forcing original gender in case that occurred) */
|
||||
if (is_vampshifter(mon)) {
|
||||
ptr = mon->data;
|
||||
if (!is_male(ptr) && !is_female(ptr) && !is_neuter(ptr))
|
||||
mon->female = was_female;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5077,10 +5079,11 @@ newcham(
|
||||
{
|
||||
boolean polyspot = ((ncflags & NC_VIA_WAND_OR_SPELL) !=0),
|
||||
/* "The oldmon turns into a newmon!" */
|
||||
msg = ((ncflags & NC_SHOW_MSG) != 0);
|
||||
msg = ((ncflags & NC_SHOW_MSG) != 0),
|
||||
seenorsensed = canspotmon(mtmp);
|
||||
int hpn, hpd, mndx, tryct;
|
||||
struct permonst *olddata = mtmp->data;
|
||||
char *p, oldname[BUFSZ], l_oldname[BUFSZ], newname[BUFSZ];
|
||||
char *p, oldname[BUFSZ], l_oldname[BUFSZ];
|
||||
|
||||
/* Riders are immune to polymorph and green slime
|
||||
(but apparent Rider might actually be a doppelganger) */
|
||||
@@ -5101,9 +5104,10 @@ newcham(
|
||||
}
|
||||
|
||||
if (msg) {
|
||||
/* like Monnam() but never mention saddle */
|
||||
Strcpy(oldname, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
|
||||
SUPPRESS_SADDLE, FALSE));
|
||||
Strcpy(oldname,
|
||||
/* like YMonnam() but never mention saddle */
|
||||
x_monnam(mtmp, mtmp->mtame ? ARTICLE_YOUR : ARTICLE_THE,
|
||||
(char *) 0, SUPPRESS_SADDLE, FALSE));
|
||||
oldname[0] = highc(oldname[0]);
|
||||
}
|
||||
/* we need this one whether msg is true or not */
|
||||
@@ -5251,17 +5255,20 @@ newcham(
|
||||
newsym(mtmp->mx, mtmp->my);
|
||||
|
||||
if (msg) {
|
||||
Strcpy(newname, noname_monnam(mtmp, ARTICLE_A));
|
||||
/* oldname was capitalized above; newname will be lower case */
|
||||
if (!strcmpi(newname, "it")) { /* can't see or sense it now */
|
||||
if (!!strcmpi(oldname, "it")) /* could see or sense it before */
|
||||
pline("%s disappears!", oldname);
|
||||
/* oldname is capitalized and might be an assigned name */
|
||||
if (!canspotmon(mtmp)) { /* can't see or sense it now */
|
||||
if (seenorsensed) /* could see or sense it before */
|
||||
pline_mon(mtmp, "%s disappears!", oldname);
|
||||
(void) usmellmon(mdat);
|
||||
} else { /* can see or sense it now */
|
||||
if (!strcmpi(oldname, "it")) /* couldn't see or sense it before */
|
||||
pline("%s appears!", upstart(newname));
|
||||
else
|
||||
pline("%s turns into %s!", oldname, newname);
|
||||
} else if (!seenorsensed) { /* couldn't see/sense before, can now */
|
||||
char *mnm = x_monnam(mtmp, mtmp->mtame ? ARTICLE_YOUR : ARTICLE_A,
|
||||
(char *) 0, 0, FALSE);
|
||||
|
||||
pline_mon(mtmp, "%s appears!", upstart(mnm));
|
||||
} else { /* saw/sensed it before, still see/sense it now */
|
||||
pline_mon(mtmp, "%s turns into %s!", oldname,
|
||||
/* "a <monster type>" even if it has a name assigned */
|
||||
noname_monnam(mtmp, ARTICLE_A));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user