corpse_xname overhaul (trunk only)
Extend the capabilities of corpse_xname() so that various callers can
be simplified. It can how handle an article prefix, effectively turning it
into corpse_doname() (not quite; still need doname() to see a count when
quantity is more than one, or to see bless/curse state). It can also handle
inclusion of adjectives like "partly eaten" or "bite-covered". For unique
monsters those come out in the form
the Chromatic Dragon's partly eaten corpse
instead of the old
partly eaten Chromatic Dragon corpse
[so wishing probably needs to be taught about potentially finding a monster
name before assorted adjectives such as blessed; also, name_to_mon() needs
to learn how to cope with the possessive suffix].
A sizeable chunk of this patch deals with consolidating some of the
redundant "petrified by a cockatrice corpse" handling. It may be possible
to consolidate all remaining instances together since they're quite similar,
but I didn't think about that until just now and I want to get this patch
over with.
This commit is contained in:
@@ -1428,7 +1428,7 @@ E boolean FDECL(the_unique_obj, (struct obj *));
|
||||
E boolean FDECL(the_unique_pm, (struct permonst *));
|
||||
E char *FDECL(doname, (struct obj *));
|
||||
E boolean FDECL(not_fully_identified, (struct obj *));
|
||||
E char *FDECL(corpse_xname, (struct obj *,BOOLEAN_P));
|
||||
E char *FDECL(corpse_xname, (struct obj *,const char *,unsigned));
|
||||
E char *FDECL(cxname, (struct obj *));
|
||||
E char *FDECL(killer_xname, (struct obj *));
|
||||
E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P)));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)hack.h 3.5 2005/03/28 */
|
||||
/* SCCS Id: @(#)hack.h 3.5 2005/12/10 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -76,6 +76,15 @@
|
||||
#define COST_BITE 13 /* start eating food */
|
||||
#define COST_OPEN 14 /* open tin */
|
||||
|
||||
/* bitmask flags for corpse_xname();
|
||||
PFX_THE takes precedence over ARTICLE, NO_PFX takes precedence over both */
|
||||
#define CXN_NORMAL 0 /* no special handling */
|
||||
#define CXN_SINGULAR 1 /* override quantity if greather than 1 */
|
||||
#define CXN_NO_PFX 2 /* suppress "the" from "the Unique Monst */
|
||||
#define CXN_PFX_THE 4 /* prefix with "the " (unless pname) */
|
||||
#define CXN_ARTICLE 8 /* include a/an/the prefix */
|
||||
#define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
|
||||
|
||||
/*
|
||||
* This is the way the game ends. If these are rearranged, the arrays
|
||||
* in end.c and topten.c will need to be changed. Some parts of the
|
||||
|
||||
@@ -1538,7 +1538,8 @@ long timeout; /* unused */
|
||||
y = obj->oy;
|
||||
} else if (in_invent) {
|
||||
if (flags.verbose) {
|
||||
char *cname = corpse_xname(obj, FALSE);
|
||||
char *cname = corpse_xname(obj, (const char *)0, CXN_NO_PFX);
|
||||
|
||||
Your("%s%s %s away%c",
|
||||
obj == uwep ? "wielded " : nul, cname,
|
||||
otense(obj, "rot"), obj == uwep ? '!' : '.');
|
||||
|
||||
17
src/do.c
17
src/do.c
@@ -1486,28 +1486,29 @@ struct obj *corpse;
|
||||
struct monst *mtmp, *mcarry;
|
||||
boolean is_uwep, chewed;
|
||||
xchar where;
|
||||
char *cname, cname_buf[BUFSZ];
|
||||
char cname[BUFSZ];
|
||||
struct obj *container = (struct obj *)0;
|
||||
int container_where = 0;
|
||||
|
||||
where = corpse->where;
|
||||
is_uwep = corpse == uwep;
|
||||
cname = eos(strcpy(cname_buf, "bite-covered "));
|
||||
Strcpy(cname, corpse_xname(corpse, TRUE));
|
||||
is_uwep = (corpse == uwep);
|
||||
chewed = (corpse->oeaten != 0);
|
||||
Strcpy(cname, corpse_xname(corpse,
|
||||
chewed ? "bite-covered" : (const char *)0,
|
||||
CXN_SINGULAR));
|
||||
mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0;
|
||||
|
||||
if (where == OBJ_CONTAINED) {
|
||||
struct monst *mtmp2 = (struct monst *)0;
|
||||
struct monst *mtmp2;
|
||||
|
||||
container = corpse->ocontainer;
|
||||
mtmp2 = get_container_location(container, &container_where, (int *)0);
|
||||
mtmp2 = get_container_location(container, &container_where, (int *)0);
|
||||
/* container_where is the outermost container's location even if nested */
|
||||
if (container_where == OBJ_MINVENT && mtmp2) mcarry = mtmp2;
|
||||
}
|
||||
mtmp = revive(corpse, FALSE); /* corpse is gone if successful */
|
||||
|
||||
if (mtmp) {
|
||||
chewed = (mtmp->mhp < mtmp->mhpmax);
|
||||
if (chewed) cname = cname_buf; /* include "bite-covered" prefix */
|
||||
switch (where) {
|
||||
case OBJ_INVENT:
|
||||
if (is_uwep)
|
||||
|
||||
@@ -422,7 +422,7 @@ boolean voluntary; /* taking gloves off on purpose? */
|
||||
|
||||
if (touch_petrifies(&mons[obj->corpsenm]) && !Stone_resistance) {
|
||||
You("now wield %s in your bare %s.",
|
||||
the(corpse_xname(obj, TRUE)),
|
||||
corpse_xname(obj, (const char *)0, CXN_ARTICLE),
|
||||
makeplural(body_part(HAND)));
|
||||
Sprintf(kbuf, "%s gloves while wielding %s",
|
||||
voluntary ? "removing" : "losing",
|
||||
|
||||
20
src/dokick.c
20
src/dokick.c
@@ -432,16 +432,20 @@ xchar x, y;
|
||||
return(1);
|
||||
}
|
||||
|
||||
if(kickobj->otyp == CORPSE && touch_petrifies(&mons[kickobj->corpsenm])
|
||||
&& !Stone_resistance && !uarmf) {
|
||||
You("kick the %s with your bare %s.",
|
||||
corpse_xname(kickobj, TRUE), makeplural(body_part(FOOT)));
|
||||
if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
|
||||
if (!uarmf && kickobj->otyp == CORPSE &&
|
||||
touch_petrifies(&mons[kickobj->corpsenm]) &&
|
||||
!Stone_resistance) {
|
||||
You("kick %s with your bare %s.",
|
||||
corpse_xname(kickobj, (const char *)0, CXN_PFX_THE),
|
||||
makeplural(body_part(FOOT)));
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
|
||||
; /* hero has been transformed but kick continues */
|
||||
} else {
|
||||
You("turn to stone...");
|
||||
killer.format = KILLED_BY;
|
||||
/* KMH -- otmp should be kickobj */
|
||||
Sprintf(killer.name, "kicking %s without boots",
|
||||
an(corpse_xname(kickobj, TRUE)));
|
||||
/* normalize body shape here; foot, not body_part(FOOT) */
|
||||
Sprintf(killer.name, "kicking %s barefoot",
|
||||
killer_xname(kickobj));
|
||||
done(STONING);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,11 +91,16 @@ int shotlimit;
|
||||
return(0);
|
||||
}
|
||||
u_wipe_engr(2);
|
||||
if (!uarmg && !Stone_resistance && (obj->otyp == CORPSE &&
|
||||
touch_petrifies(&mons[obj->corpsenm]))) {
|
||||
You("throw the %s corpse with your bare %s.",
|
||||
mons[obj->corpsenm].mname, body_part(HAND));
|
||||
Sprintf(killer.name, "%s corpse", an(mons[obj->corpsenm].mname));
|
||||
if (!uarmg && obj->otyp == CORPSE &&
|
||||
touch_petrifies(&mons[obj->corpsenm]) &&
|
||||
!Stone_resistance) {
|
||||
You("throw %s with your bare %s.",
|
||||
corpse_xname(obj, (const char *)0, CXN_PFX_THE),
|
||||
/* throwing with one hand, but pluralize since the
|
||||
expression "with your bare hands" sounds better */
|
||||
makeplural(body_part(HAND)));
|
||||
Sprintf(killer.name, "throwing %s bare-handed",
|
||||
killer_xname(obj));
|
||||
instapetrify(killer.name);
|
||||
}
|
||||
if (welded(obj)) {
|
||||
|
||||
51
src/eat.c
51
src/eat.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)eat.c 3.5 2005/09/27 */
|
||||
/* SCCS Id: @(#)eat.c 3.5 2005/12/09 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -163,7 +163,7 @@ eatmdone() /* called after mimicing is over */
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ``[the(] singular(food, xname) [)]'' with awareness of unique monsters */
|
||||
/* ``[the(] singular(food, xname) [)]'' */
|
||||
STATIC_OVL const char *
|
||||
food_xname(food, the_pfx)
|
||||
struct obj *food;
|
||||
@@ -172,18 +172,17 @@ boolean the_pfx;
|
||||
const char *result;
|
||||
int mnum = food->corpsenm;
|
||||
|
||||
if (food->otyp == CORPSE && (mons[mnum].geno & G_UNIQ)) {
|
||||
/* grab xname()'s modifiable return buffer for our own use */
|
||||
char *bufp = xname(food);
|
||||
Sprintf(bufp, "%s%s corpse",
|
||||
(the_pfx && !type_is_pname(&mons[mnum])) ? "the " : "",
|
||||
s_suffix(mons[mnum].mname));
|
||||
result = bufp;
|
||||
if (food->otyp == CORPSE) {
|
||||
result = corpse_xname(food, (const char *)0,
|
||||
CXN_SINGULAR | (the_pfx ? CXN_PFX_THE : 0));
|
||||
/* not strictly needed since pname values are capitalized
|
||||
and the() is a no-op for them */
|
||||
if (type_is_pname(&mons[food->corpsenm])) the_pfx = FALSE;
|
||||
} else {
|
||||
/* the ordinary case */
|
||||
result = singular(food, xname);
|
||||
if (the_pfx) result = the(result);
|
||||
}
|
||||
if (the_pfx) result = the(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -227,17 +226,8 @@ choke(food) /* To a full belly all food is bad. (It.) */
|
||||
if (food->oclass == COIN_CLASS) {
|
||||
Strcpy(killer.name, "very rich meal");
|
||||
} else {
|
||||
Strcpy(killer.name, food_xname(food, FALSE));
|
||||
if (food->otyp == CORPSE &&
|
||||
(mons[food->corpsenm].geno & G_UNIQ)) {
|
||||
if (!type_is_pname(&mons[food->corpsenm]))
|
||||
Strcpy(killer.name, the(killer.name));
|
||||
killer.format = KILLED_BY;
|
||||
} else if (obj_is_pname(food)) {
|
||||
killer.format = KILLED_BY;
|
||||
if (food->oartifact >= ART_ORB_OF_DETECTION)
|
||||
Strcpy(killer.name, the(killer.name));
|
||||
}
|
||||
killer.format = KILLED_BY;
|
||||
Strcpy(killer.name, killer_xname(food));
|
||||
}
|
||||
} else {
|
||||
You("choke over it.");
|
||||
@@ -1269,8 +1259,8 @@ opentin() /* called during each move whilst opening a tin */
|
||||
what = rndmonnam();
|
||||
} else {
|
||||
what = mons[mnum].mname;
|
||||
if (mons[mnum].geno & G_UNIQ)
|
||||
which = type_is_pname(&mons[mnum]) ? 1 : 2;
|
||||
if (the_unique_pm(&mons[mnum])) which = 2;
|
||||
else if (type_is_pname(&mons[mnum])) which = 1;
|
||||
}
|
||||
if (which == 0) what = makeplural(what);
|
||||
|
||||
@@ -1463,7 +1453,6 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
|
||||
{
|
||||
int tp = 0, mnum = otmp->corpsenm;
|
||||
long rotted = 0L;
|
||||
boolean uniq = !!(mons[mnum].geno & G_UNIQ);
|
||||
int retcode = 0;
|
||||
boolean stoneable = (flesh_petrifies(&mons[mnum]) &&
|
||||
!Stone_resistance &&
|
||||
@@ -1490,20 +1479,15 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
|
||||
if (Sick_resistance) {
|
||||
pline("It doesn't seem at all sickening, though...");
|
||||
} else {
|
||||
char buf[BUFSZ];
|
||||
long sick_time;
|
||||
|
||||
sick_time = (long) rn1(10, 10);
|
||||
/* make sure new ill doesn't result in improvement */
|
||||
if (Sick && (sick_time > Sick))
|
||||
sick_time = (Sick > 1L) ? Sick - 1L : 1L;
|
||||
if (!uniq)
|
||||
Sprintf(buf, "rotted %s", corpse_xname(otmp,TRUE));
|
||||
else
|
||||
Sprintf(buf, "%s%s rotted corpse",
|
||||
!type_is_pname(&mons[mnum]) ? "the " : "",
|
||||
s_suffix(mons[mnum].mname));
|
||||
make_sick(sick_time, buf, TRUE, SICK_VOMITABLE);
|
||||
make_sick(sick_time,
|
||||
corpse_xname(otmp, "rotted", CXN_NORMAL),
|
||||
TRUE, SICK_VOMITABLE);
|
||||
}
|
||||
if (carried(otmp)) useup(otmp);
|
||||
else useupf(otmp, 1L);
|
||||
@@ -1552,7 +1536,8 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
|
||||
pline("This tastes just like chicken!");
|
||||
} else {
|
||||
pline("%s%s %s!",
|
||||
!uniq ? "This " : !type_is_pname(&mons[mnum]) ? "The " : "",
|
||||
type_is_pname(&mons[mnum]) ? "" :
|
||||
the_unique_pm(&mons[mnum]) ? "The " : "This ",
|
||||
food_xname(otmp, FALSE),
|
||||
(vegan(&mons[mnum]) ?
|
||||
(!carnivorous(youmonst.data) && herbivorous(youmonst.data)) :
|
||||
|
||||
99
src/objnam.c
99
src/objnam.c
@@ -592,6 +592,10 @@ register struct obj *obj;
|
||||
|
||||
if(obj->quan != 1L)
|
||||
Sprintf(prefix, "%ld ", obj->quan);
|
||||
else if (obj->otyp == CORPSE)
|
||||
/* skip article prefix for corpses [else corpse_xname()
|
||||
would have to be taught how to strip it off again] */
|
||||
*prefix = '\0';
|
||||
else if (obj_is_pname(obj) || the_unique_obj(obj)) {
|
||||
if (!strncmpi(bp, "the ", 4))
|
||||
bp += 4;
|
||||
@@ -750,16 +754,9 @@ ring:
|
||||
if (obj->oeaten)
|
||||
Strcat(prefix, "partly eaten ");
|
||||
if (obj->otyp == CORPSE) {
|
||||
if (the_unique_pm(&mons[omndx]) ||
|
||||
type_is_pname(&mons[omndx])) {
|
||||
Sprintf(prefix, "%s%s ",
|
||||
the_unique_pm(&mons[omndx]) ? "the " : "",
|
||||
s_suffix(mons[omndx].mname));
|
||||
if (obj->oeaten) Strcat(prefix, "partly eaten ");
|
||||
} else {
|
||||
Strcat(prefix, mons[omndx].mname);
|
||||
Strcat(prefix, " ");
|
||||
}
|
||||
Sprintf(prefix, "%s ",
|
||||
corpse_xname(obj, prefix,
|
||||
CXN_ARTICLE|CXN_NOCORPSE));
|
||||
} else if (obj->otyp == EGG) {
|
||||
#if 0 /* corpses don't tell if they're stale either */
|
||||
if (obj->known && stale_egg(obj))
|
||||
@@ -868,41 +865,92 @@ register struct obj *otmp;
|
||||
}
|
||||
|
||||
char *
|
||||
corpse_xname(otmp, ignore_oquan)
|
||||
corpse_xname(otmp, adjective, cxn_flags)
|
||||
struct obj *otmp;
|
||||
boolean ignore_oquan; /* to force singular */
|
||||
const char *adjective;
|
||||
unsigned cxn_flags; /* bitmask of CXN_xxx values */
|
||||
{
|
||||
char *nambuf = nextobuf();
|
||||
int omndx = otmp->corpsenm;
|
||||
boolean ignore_quan = (cxn_flags & CXN_SINGULAR) != 0,
|
||||
/* suppress "the" from "the unique monster corpse" */
|
||||
no_prefix = (cxn_flags & CXN_NO_PFX) != 0,
|
||||
/* include "the" for "the woodchuck corpse */
|
||||
the_prefix = (cxn_flags & CXN_PFX_THE) != 0,
|
||||
/* include "an" for "an ogre corpse */
|
||||
any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
|
||||
/* leave off suffix (do_name() appends "corpse" itself) */
|
||||
omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
|
||||
possessive = FALSE;
|
||||
const char *mname;
|
||||
|
||||
if (omndx == NON_PM) return strcpy(nambuf, "thing"); /* paranoia */
|
||||
|
||||
if (omndx == NON_PM) { /* paranoia */
|
||||
mname = "thing";
|
||||
/* [Possible enhancement: check whether corpse has monster traits
|
||||
attached in order to use priestname() for priests and minions.] */
|
||||
if (omndx == PM_ALIGNED_PRIEST) {
|
||||
} else if (omndx == PM_ALIGNED_PRIEST) {
|
||||
/* avoid "aligned priest"; it just exposes internal details */
|
||||
mname = "priest";
|
||||
} else {
|
||||
mname = mons[omndx].mname;
|
||||
if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx]))
|
||||
if (the_unique_pm(&mons[omndx]) || type_is_pname(&mons[omndx])) {
|
||||
mname = s_suffix(mname);
|
||||
possessive = TRUE;
|
||||
/* don't precede personal name like "Medusa" with an article */
|
||||
if (type_is_pname(&mons[omndx]))
|
||||
no_prefix = TRUE;
|
||||
/* always precede non-personal unique monster name like
|
||||
"Oracle" with "the" unless explicitly overridden */
|
||||
else if (the_unique_pm(&mons[omndx]) && !no_prefix)
|
||||
the_prefix = TRUE;
|
||||
}
|
||||
}
|
||||
Sprintf(nambuf, "%s corpse", mname);
|
||||
if (no_prefix) the_prefix = any_prefix = FALSE;
|
||||
else if (the_prefix) any_prefix = FALSE; /* mutually exclusive */
|
||||
|
||||
if (ignore_oquan || otmp->quan < 2)
|
||||
return nambuf;
|
||||
else
|
||||
return makeplural(nambuf);
|
||||
*nambuf = '\0';
|
||||
/* can't use the() the way we use an() below because any capitalized
|
||||
Name causes it to assume a personal name and return Name as-is;
|
||||
that's usually the behavior wanted, but here we need to force "the"
|
||||
to precede capitalized unique monsters (pnames are handled above) */
|
||||
if (the_prefix) Strcat(nambuf, "the ");
|
||||
|
||||
if (!adjective || !*adjective) {
|
||||
/* normal case: newt corpse */
|
||||
Strcat(nambuf, mname);
|
||||
} else {
|
||||
/* adjective positioning depends upon format of monster name */
|
||||
if (possessive) /* Medusa's cursed partly eaten corpse */
|
||||
Sprintf(eos(nambuf), "%s %s", mname, adjective);
|
||||
else /* cursed partly eaten troll corpse */
|
||||
Sprintf(eos(nambuf), "%s %s", adjective, mname);
|
||||
/* in case adjective has a trailing space, squeeze it out */
|
||||
mungspaces(nambuf);
|
||||
/* doname() might include a count in the adjective argument;
|
||||
if so, don't prepend an article */
|
||||
if (digit(*adjective)) any_prefix = FALSE;
|
||||
}
|
||||
|
||||
if (!omit_corpse) {
|
||||
Strcat(nambuf, " corpse");
|
||||
/* makeplural(nambuf) => append "s" to "corpse" */
|
||||
if (otmp->quan > 1L && !ignore_quan) Strcat(nambuf, "s");
|
||||
}
|
||||
|
||||
/* it's safe to overwrite our nambuf after an() has copied
|
||||
its old value into another buffer */
|
||||
if (any_prefix) Strcpy(nambuf, an(nambuf));
|
||||
|
||||
return nambuf;
|
||||
}
|
||||
|
||||
/* xname, unless it's a corpse, then corpse_xname(obj, FALSE) */
|
||||
/* xname doesn't include monster type for "corpse"; cxname does */
|
||||
char *
|
||||
cxname(obj)
|
||||
struct obj *obj;
|
||||
{
|
||||
if (obj->otyp == CORPSE)
|
||||
return corpse_xname(obj, FALSE);
|
||||
return corpse_xname(obj, (const char *)0, CXN_NORMAL);
|
||||
return xname(obj);
|
||||
}
|
||||
|
||||
@@ -941,10 +989,7 @@ struct obj *obj;
|
||||
/* format the object */
|
||||
if (obj->otyp == CORPSE) {
|
||||
buf = nextobuf();
|
||||
Sprintf(buf, "%s%s",
|
||||
/* can't use the(); capitalized name blocks its article */
|
||||
the_unique_pm(&mons[obj->corpsenm]) ? "the " : "",
|
||||
corpse_xname(obj, FALSE));
|
||||
Strcpy(buf, corpse_xname(obj, (const char *)0, CXN_NORMAL));
|
||||
} else if (obj->otyp == SLIME_MOLD) {
|
||||
/* concession to "most unique deaths competition" in the annual
|
||||
devnull tournament, suppress player supplied fruit names because
|
||||
|
||||
70
src/pickup.c
70
src/pickup.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)pickup.c 3.5 2005/11/02 */
|
||||
/* SCCS Id: @(#)pickup.c 3.5 2005/12/07 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -16,6 +16,7 @@ STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *,
|
||||
STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *,
|
||||
const char *,struct obj *,BOOLEAN_P,int *));
|
||||
#endif
|
||||
STATIC_DCL boolean FDECL(fatal_corpse_mistake, (struct obj *,BOOLEAN_P));
|
||||
STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
|
||||
STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
|
||||
STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *));
|
||||
@@ -262,6 +263,27 @@ ask_again:
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* check whether hero is bare-handedly touching a cockatrice corpse */
|
||||
STATIC_OVL boolean
|
||||
fatal_corpse_mistake(obj, remotely)
|
||||
struct obj *obj;
|
||||
boolean remotely;
|
||||
{
|
||||
if (uarmg || remotely || obj->otyp != CORPSE ||
|
||||
!touch_petrifies(&mons[obj->corpsenm]) || Stone_resistance)
|
||||
return FALSE;
|
||||
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
|
||||
display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
pline("Touching %s is a fatal mistake.",
|
||||
corpse_xname(obj, (const char *)0, CXN_SINGULAR|CXN_ARTICLE));
|
||||
instapetrify(killer_xname(obj));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* look at the objects at our location, unless there are too many of them */
|
||||
STATIC_OVL void
|
||||
check_here(picked_some)
|
||||
@@ -1307,18 +1329,8 @@ boolean telekinesis; /* not picking it up directly by hand */
|
||||
return 1;
|
||||
#endif
|
||||
} else if (obj->otyp == CORPSE) {
|
||||
if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg
|
||||
&& !Stone_resistance && !telekinesis) {
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
else {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
Strcpy(kbuf, an(corpse_xname(obj, TRUE)));
|
||||
pline("Touching %s is a fatal mistake.", kbuf);
|
||||
instapetrify(kbuf);
|
||||
return -1;
|
||||
}
|
||||
if (fatal_corpse_mistake(obj, telekinesis)) {
|
||||
return -1;
|
||||
} else if (is_rider(&mons[obj->corpsenm])) {
|
||||
pline("At your %s, the corpse suddenly moves...",
|
||||
telekinesis ? "attempted acquisition" : "touch");
|
||||
@@ -1823,21 +1835,7 @@ register struct obj *obj;
|
||||
if (uquiver) return 0; /* unwielded, died, rewielded */
|
||||
}
|
||||
|
||||
if (obj->otyp == CORPSE) {
|
||||
if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg
|
||||
&& !Stone_resistance) {
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
else {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
Strcpy(kbuf, an(corpse_xname(obj, TRUE)));
|
||||
pline("Touching %s is a fatal mistake.", kbuf);
|
||||
instapetrify(kbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fatal_corpse_mistake(obj, FALSE)) return -1;
|
||||
|
||||
/* boxes, boulders, and big statues can't fit into any container */
|
||||
if (obj->otyp == ICE_BOX || Is_box(obj) || obj->otyp == BOULDER ||
|
||||
@@ -1946,21 +1944,7 @@ register struct obj *obj;
|
||||
|
||||
if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0;
|
||||
|
||||
if (obj->otyp == CORPSE) {
|
||||
if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg
|
||||
&& !Stone_resistance) {
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
else {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
Strcpy(kbuf, an(corpse_xname(obj, TRUE)));
|
||||
pline("Touching %s is a fatal mistake.", kbuf);
|
||||
instapetrify(kbuf);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (fatal_corpse_mistake(obj, FALSE)) return -1;
|
||||
|
||||
count = obj->quan;
|
||||
if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0)
|
||||
|
||||
47
src/uhitm.c
47
src/uhitm.c
@@ -753,13 +753,12 @@ int thrown;
|
||||
#endif
|
||||
case CORPSE: /* fixed by polder@cs.vu.nl */
|
||||
if (touch_petrifies(&mons[obj->corpsenm])) {
|
||||
static const char withwhat[] = "corpse";
|
||||
tmp = 1;
|
||||
hittxt = TRUE;
|
||||
You("hit %s with %s %s.", mon_nam(mon),
|
||||
obj->dknown ? the(mons[obj->corpsenm].mname) :
|
||||
an(mons[obj->corpsenm].mname),
|
||||
(obj->quan > 1L) ? makeplural(withwhat) : withwhat);
|
||||
You("hit %s with %s.", mon_nam(mon),
|
||||
corpse_xname(obj, (const char *)0,
|
||||
obj->dknown ? CXN_PFX_THE : CXN_ARTICLE));
|
||||
obj->dknown = 1;
|
||||
if (!munstone(mon, TRUE))
|
||||
minstapetrify(mon, TRUE);
|
||||
if (resists_ston(mon)) break;
|
||||
@@ -1215,28 +1214,20 @@ STATIC_OVL boolean
|
||||
theft_petrifies(otmp)
|
||||
struct obj *otmp;
|
||||
{
|
||||
const char *fmt;
|
||||
char *p, cbuf[BUFSZ], kbuf[BUFSZ];
|
||||
|
||||
if (uarmg || otmp->otyp != CORPSE ||
|
||||
!touch_petrifies(&mons[otmp->corpsenm])) return FALSE;
|
||||
!touch_petrifies(&mons[otmp->corpsenm]) || Stone_resistance)
|
||||
return FALSE;
|
||||
|
||||
/* no poly_when_stoned() critter has theft capability */
|
||||
#if 0
|
||||
if (poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM)) {
|
||||
display_nhwindow(WIN_MESSAGE, FALSE); /* --More-- */
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* stealing this corpse is fatal... */
|
||||
Strcpy(cbuf, cxname(otmp)); /* "cockatrice corpse" */
|
||||
fmt = "a stolen %s";
|
||||
if (otmp->quan > 1L) {
|
||||
/* stack of multiple cockatrice corpses; no article for plural */
|
||||
fmt += 2; /* skip "a ", leaving "stolen %s" */
|
||||
} else if ((p = strstri(cbuf, "'s corpse")) != 0 ||
|
||||
(p = strstri(cbuf, "s' corpse")) != 0) {
|
||||
/* in case a unique monster with petrifying touch and
|
||||
a personal name ever gets introduced: we want to use
|
||||
"Foo's stolen corpse" instead of "a stolen Foo's corpse" */
|
||||
*(p + 2) = '\0'; /* chop " corpse" off of cbuf */
|
||||
fmt = "%s stolen corpse";
|
||||
}
|
||||
Sprintf(kbuf, fmt, cbuf);
|
||||
instapetrify(kbuf);
|
||||
instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
|
||||
/* apparently wasn't fatal after all... */
|
||||
return TRUE;
|
||||
}
|
||||
@@ -1246,12 +1237,6 @@ struct obj *otmp;
|
||||
*
|
||||
* If the target is wearing body armor, take all of its possesions;
|
||||
* otherwise, take one object. [Is this really the behavior we want?]
|
||||
*
|
||||
* This routine implicitly assumes that there is no way to be able to
|
||||
* resist petfication (ie, be polymorphed into a xorn or golem) at the
|
||||
* same time as being able to steal (poly'd into nymph or succubus).
|
||||
* If that ever changes, the check for touching a cockatrice corpse
|
||||
* will need to be smarter about whether to break out of the theft loop.
|
||||
*/
|
||||
STATIC_OVL void
|
||||
steal_it(mdef, mattk)
|
||||
@@ -1801,7 +1786,7 @@ register struct attack *mattk;
|
||||
/* engulfing a cockatrice or digesting a Rider or Medusa */
|
||||
fatal_gulp = (touch_petrifies(pd) && !Stone_resistance) ||
|
||||
(mattk->adtyp == AD_DGST && (is_rider(pd) ||
|
||||
((pd == &mons[PM_MEDUSA]) && !Stone_resistance)));
|
||||
(pd == &mons[PM_MEDUSA] && !Stone_resistance)));
|
||||
|
||||
if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp) {
|
||||
/* KMH, conduct */
|
||||
|
||||
45
src/wield.c
45
src/wield.c
@@ -1,4 +1,4 @@
|
||||
/* SCCS Id: @(#)wield.c 3.5 2005/04/15 */
|
||||
/* SCCS Id: @(#)wield.c 3.5 2005/12/26 */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -50,6 +50,7 @@
|
||||
*/
|
||||
|
||||
|
||||
STATIC_DCL boolean FDECL(cant_wield_corpse, (struct obj *));
|
||||
STATIC_DCL int FDECL(ready_weapon, (struct obj *));
|
||||
|
||||
/* used by will_weld() */
|
||||
@@ -112,6 +113,25 @@ register struct obj *obj;
|
||||
update_inventory();
|
||||
}
|
||||
|
||||
STATIC_OVL boolean
|
||||
cant_wield_corpse(obj)
|
||||
struct obj *obj;
|
||||
{
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
if (uarmg || obj->otyp != CORPSE ||
|
||||
!touch_petrifies(&mons[obj->corpsenm]) || Stone_resistance)
|
||||
return FALSE;
|
||||
|
||||
/* Prevent wielding cockatrice when not wearing gloves --KAA */
|
||||
You("wield %s in your bare %s.",
|
||||
corpse_xname(obj, (const char *)0, CXN_PFX_THE),
|
||||
makeplural(body_part(HAND)));
|
||||
Sprintf(kbuf, "wielding %s bare-handed", killer_xname(obj));
|
||||
instapetrify(kbuf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
STATIC_OVL int
|
||||
ready_weapon(wep)
|
||||
struct obj *wep;
|
||||
@@ -127,15 +147,9 @@ struct obj *wep;
|
||||
res++;
|
||||
} else
|
||||
You("are already empty %s.", body_part(HANDED));
|
||||
} else if (!uarmg && !Stone_resistance && wep->otyp == CORPSE
|
||||
&& touch_petrifies(&mons[wep->corpsenm])) {
|
||||
/* Prevent wielding cockatrice when not wearing gloves --KAA */
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
You("wield the %s corpse in your bare %s.",
|
||||
mons[wep->corpsenm].mname, makeplural(body_part(HAND)));
|
||||
Sprintf(kbuf, "%s corpse", an(mons[wep->corpsenm].mname));
|
||||
instapetrify(kbuf);
|
||||
} else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
|
||||
/* hero must have been life-saved to get here; use a turn */
|
||||
res++; /* corpse won't be wielded */
|
||||
} else if (uarms && bimanual(wep))
|
||||
You("cannot wield a two-handed %s while wearing a shield.",
|
||||
is_sword(wep) ? "sword" :
|
||||
@@ -497,14 +511,9 @@ can_twoweapon()
|
||||
else if (uswapwep->oartifact)
|
||||
pline("%s being held second to another weapon!",
|
||||
Yobjnam2(uswapwep, "resist"));
|
||||
else if (!uarmg && !Stone_resistance && (uswapwep->otyp == CORPSE &&
|
||||
touch_petrifies(&mons[uswapwep->corpsenm]))) {
|
||||
char kbuf[BUFSZ];
|
||||
|
||||
You("wield the %s corpse with your bare %s.",
|
||||
mons[uswapwep->corpsenm].mname, body_part(HAND));
|
||||
Sprintf(kbuf, "%s corpse", an(mons[uswapwep->corpsenm].mname));
|
||||
instapetrify(kbuf);
|
||||
else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) {
|
||||
/* [Note: NOT_WEAPON() check prevents ever getting here...] */
|
||||
; /* must be life-saved to reach here; return FALSE */
|
||||
} else if (Glib || uswapwep->cursed) {
|
||||
if (!Glib)
|
||||
uswapwep->bknown = TRUE;
|
||||
|
||||
@@ -786,7 +786,9 @@ struct monst *mon;
|
||||
revive_egg(otmp);
|
||||
if (otmp->otyp != CORPSE) continue;
|
||||
/* save the name; the object is liable to go away */
|
||||
if (youseeit) Strcpy(corpse, corpse_xname(otmp, TRUE));
|
||||
if (youseeit)
|
||||
Strcpy(corpse,
|
||||
corpse_xname(otmp, (const char *)0, CXN_SINGULAR));
|
||||
|
||||
/* for a merged group, only one is revived; should this be fixed? */
|
||||
if ((mtmp2 = revive(otmp, !context.mon_moving)) != 0) {
|
||||
|
||||
Reference in New Issue
Block a user