stethoscope use on corpses & statues (trunk only)

Prompted by the report that it was possible to check a corpse at an
adjacent spot while levitating:  substantially revamp the handling of
applying a stethoscope to corpses and/or statues.  Aside from the missing
reachability check, the old code suffered from grammar problems when
multiple corpses were present and it didn't try to figure out the gender
of the monster who left the corpse.

     This now lets non-healers check corpses and statues at any time
(previously that only worked for them while hallucinating).  For healers
it gives some new feedback:  when listening to a corpse, they'll be given
a hint if it (actually any corpse in the pile at that location) is going
to revive, and when listening to a statue they'll be given a hint if it
contains any items.  The existing hint when a statue is actually a trap
is still only given to healers.
This commit is contained in:
nethack.rankin
2003-11-20 04:54:39 +00:00
parent cf1b96c0e7
commit 29f21b488c
3 changed files with 103 additions and 25 deletions

View File

@@ -92,6 +92,7 @@ silver items such as wands avoided all the silver checks in hmon_hitmon()
resuming an interrupted 'A' command could cause crash if pending worn item(s) resuming an interrupted 'A' command could cause crash if pending worn item(s)
were stolen or destroyed were stolen or destroyed
when you're asleep you shouldn't "notice" monsters that have become undetected when you're asleep you shouldn't "notice" monsters that have become undetected
must be able to reach floor in order to use stethoscope on corpse or statue
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -50,6 +50,7 @@ healers notice when a wand of undead turning revives a monster so the
update display if bestowed a spellbook while unable to see invisible self update display if bestowed a spellbook while unable to see invisible self
use small pool of static buffers for mon_nam() and Monnam() use small pool of static buffers for mon_nam() and Monnam()
Acknowledge Schroedinger's cat at end of game Acknowledge Schroedinger's cat at end of game
grammar fixes for applying stethoscope to corpses and statues
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes

View File

@@ -1,4 +1,4 @@
/* SCCS Id: @(#)apply.c 3.4 2003/10/21 */ /* SCCS Id: @(#)apply.c 3.4 2003/11/18 */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -163,34 +163,110 @@ STATIC_OVL boolean
its_dead(rx, ry, resp) its_dead(rx, ry, resp)
int rx, ry, *resp; int rx, ry, *resp;
{ {
struct obj *otmp; char buf[BUFSZ];
struct trap *ttmp; boolean more_corpses;
struct permonst *mptr;
struct obj *corpse = sobj_at(CORPSE, rx, ry),
*statue = sobj_at(STATUE, rx, ry);
/* additional stethoscope messages from jyoung@apanix.apana.org.au */ if (!can_reach_floor()) { /* levitation or unskilled riding */
if (Hallucination && sobj_at(CORPSE, rx, ry)) { corpse = 0; /* can't reach corpse on floor */
/* (a corpse doesn't retain the monster's sex, /* you can't reach tiny statues (even though you can fight
so we're forced to use generic pronoun here) */ tiny monsters while levitating--consistency, what's that?) */
You_hear("a voice say, \"It's dead, Jim.\""); while (statue && mons[statue->corpsenm].msize == MZ_TINY)
*resp = 1; statue = nxtobj(statue, STATUE, TRUE);
return TRUE; }
} else if (Role_if(PM_HEALER) && ((otmp = sobj_at(CORPSE, rx, ry)) != 0 || /* when both corpse and statue are present, pick the uppermost one */
(otmp = sobj_at(STATUE, rx, ry)) != 0)) { if (corpse && statue) {
/* possibly should check uppermost {corpse,statue} in the pile if (nxtobj(statue, CORPSE, TRUE) == corpse)
if both types are present, but it's not worth the effort */ corpse = 0; /* corpse follows statue; ignore it */
if (vobj_at(rx, ry)->otyp == STATUE) otmp = vobj_at(rx, ry); else
if (otmp->otyp == CORPSE) { statue = 0; /* corpse precedes statue; ignore statue */
You("determine that %s unfortunate being is dead.", }
(rx == u.ux && ry == u.uy) ? "this" : "that"); more_corpses = (corpse && nxtobj(corpse, CORPSE, TRUE));
/* additional stethoscope messages from jyoung@apanix.apana.org.au */
if (!corpse && !statue) {
; /* nothing to do */
} else if (Hallucination) {
if (!corpse) {
/* it's a statue */
Strcpy(buf, "You're both stoned");
} else if (corpse->quan == 1L && !more_corpses) {
int gndr = 2; /* neuter: "it" */
struct monst *mtmp = get_mtraits(corpse, FALSE);
/* (most corpses don't retain the monster's sex, so
we're usually forced to use generic pronoun here) */
if (mtmp) {
mptr = &mons[mtmp->mnum];
/* can't use mhe() here; it calls pronoun_gender() which
expects monster to be on the map (visibility check) */
if ((humanoid(mptr) || (mptr->geno & G_UNIQ) ||
type_is_pname(mptr)) && !is_neuter(mptr))
gndr = (int)mtmp->female;
} else { } else {
ttmp = t_at(rx, ry); mptr = &mons[corpse->corpsenm];
pline("%s appears to be in %s health for a statue.", if (is_female(mptr)) gndr = 1;
The(mons[otmp->corpsenm].mname), else if (is_male(mptr)) gndr = 0;
(ttmp && ttmp->ttyp == STATUE_TRAP) ?
"extraordinary" : "excellent");
} }
return TRUE; Sprintf(buf, "%s's dead", genders[gndr].he); /* "he"/"she"/"it" */
buf[0] = highc(buf[0]);
} else { /* plural */
Strcpy(buf, "They're dead");
} }
return FALSE; /* variations on "He's dead, Jim." (Star Trek's Dr McCoy) */
You_hear("a voice say, \"%s, Jim.\"", buf);
*resp = 1;
return TRUE;
} else if (corpse) {
boolean here = (rx == u.ux && ry == u.uy),
one = (corpse->quan == 1L && !more_corpses),
reviver = FALSE;
if (Role_if(PM_HEALER)) {
/* ok to reset `corpse' here; we're done with it */
do {
if (obj_has_timer(corpse, REVIVE_MON))
reviver = TRUE;
else
corpse = nxtobj(corpse, CORPSE, TRUE);
} while (corpse && !reviver);
}
You("determine that %s unfortunate being%s %s%s dead.",
one ? (here ? "this" : "that") : (here ? "these" : "those"),
one ? "" : "s", one ? "is" : "are",
reviver ? " mostly" : "");
return TRUE;
} else { /* statue */
const char *what, *how;
mptr = &mons[statue->corpsenm];
if (Blind) { /* ignore statue->dknown; it'll always be set */
Sprintf(buf, "%s %s",
(rx == u.ux && ry == u.uy) ? "This" : "That",
humanoid(mptr) ? "person" : "creature");
what = buf;
} else {
what = mptr->mname;
if (!type_is_pname(mptr)) what = The(what);
}
how = "fine";
if (Role_if(PM_HEALER)) {
struct trap *ttmp = t_at(rx, ry);
if (ttmp && ttmp->ttyp == STATUE_TRAP) how = "extraordinary";
else if (Has_contents(statue)) how = "remarkable";
}
pline("%s is in %s health for a statue.", what, how);
return TRUE;
}
return FALSE; /* no corpse or statue */
} }
static const char hollow_str[] = "a hollow sound. This must be a secret %s!"; static const char hollow_str[] = "a hollow sound. This must be a secret %s!";