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:
+1
-1
@@ -1428,7 +1428,7 @@ E boolean FDECL(the_unique_obj, (struct obj *));
|
|||||||
E boolean FDECL(the_unique_pm, (struct permonst *));
|
E boolean FDECL(the_unique_pm, (struct permonst *));
|
||||||
E char *FDECL(doname, (struct obj *));
|
E char *FDECL(doname, (struct obj *));
|
||||||
E boolean FDECL(not_fully_identified, (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(cxname, (struct obj *));
|
||||||
E char *FDECL(killer_xname, (struct obj *));
|
E char *FDECL(killer_xname, (struct obj *));
|
||||||
E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P)));
|
E const char *FDECL(singular, (struct obj *,char *(*)(OBJ_P)));
|
||||||
|
|||||||
+10
-1
@@ -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. */
|
/* 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. */
|
||||||
|
|
||||||
@@ -76,6 +76,15 @@
|
|||||||
#define COST_BITE 13 /* start eating food */
|
#define COST_BITE 13 /* start eating food */
|
||||||
#define COST_OPEN 14 /* open tin */
|
#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
|
* 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
|
* 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;
|
y = obj->oy;
|
||||||
} else if (in_invent) {
|
} else if (in_invent) {
|
||||||
if (flags.verbose) {
|
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",
|
Your("%s%s %s away%c",
|
||||||
obj == uwep ? "wielded " : nul, cname,
|
obj == uwep ? "wielded " : nul, cname,
|
||||||
otense(obj, "rot"), obj == uwep ? '!' : '.');
|
otense(obj, "rot"), obj == uwep ? '!' : '.');
|
||||||
|
|||||||
@@ -1486,28 +1486,29 @@ struct obj *corpse;
|
|||||||
struct monst *mtmp, *mcarry;
|
struct monst *mtmp, *mcarry;
|
||||||
boolean is_uwep, chewed;
|
boolean is_uwep, chewed;
|
||||||
xchar where;
|
xchar where;
|
||||||
char *cname, cname_buf[BUFSZ];
|
char cname[BUFSZ];
|
||||||
struct obj *container = (struct obj *)0;
|
struct obj *container = (struct obj *)0;
|
||||||
int container_where = 0;
|
int container_where = 0;
|
||||||
|
|
||||||
where = corpse->where;
|
where = corpse->where;
|
||||||
is_uwep = corpse == uwep;
|
is_uwep = (corpse == uwep);
|
||||||
cname = eos(strcpy(cname_buf, "bite-covered "));
|
chewed = (corpse->oeaten != 0);
|
||||||
Strcpy(cname, corpse_xname(corpse, TRUE));
|
Strcpy(cname, corpse_xname(corpse,
|
||||||
|
chewed ? "bite-covered" : (const char *)0,
|
||||||
|
CXN_SINGULAR));
|
||||||
mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0;
|
mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0;
|
||||||
|
|
||||||
if (where == OBJ_CONTAINED) {
|
if (where == OBJ_CONTAINED) {
|
||||||
struct monst *mtmp2 = (struct monst *)0;
|
struct monst *mtmp2;
|
||||||
|
|
||||||
container = corpse->ocontainer;
|
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 */
|
/* container_where is the outermost container's location even if nested */
|
||||||
if (container_where == OBJ_MINVENT && mtmp2) mcarry = mtmp2;
|
if (container_where == OBJ_MINVENT && mtmp2) mcarry = mtmp2;
|
||||||
}
|
}
|
||||||
mtmp = revive(corpse, FALSE); /* corpse is gone if successful */
|
mtmp = revive(corpse, FALSE); /* corpse is gone if successful */
|
||||||
|
|
||||||
if (mtmp) {
|
if (mtmp) {
|
||||||
chewed = (mtmp->mhp < mtmp->mhpmax);
|
|
||||||
if (chewed) cname = cname_buf; /* include "bite-covered" prefix */
|
|
||||||
switch (where) {
|
switch (where) {
|
||||||
case OBJ_INVENT:
|
case OBJ_INVENT:
|
||||||
if (is_uwep)
|
if (is_uwep)
|
||||||
|
|||||||
+1
-1
@@ -422,7 +422,7 @@ boolean voluntary; /* taking gloves off on purpose? */
|
|||||||
|
|
||||||
if (touch_petrifies(&mons[obj->corpsenm]) && !Stone_resistance) {
|
if (touch_petrifies(&mons[obj->corpsenm]) && !Stone_resistance) {
|
||||||
You("now wield %s in your bare %s.",
|
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)));
|
makeplural(body_part(HAND)));
|
||||||
Sprintf(kbuf, "%s gloves while wielding %s",
|
Sprintf(kbuf, "%s gloves while wielding %s",
|
||||||
voluntary ? "removing" : "losing",
|
voluntary ? "removing" : "losing",
|
||||||
|
|||||||
+12
-8
@@ -432,16 +432,20 @@ xchar x, y;
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(kickobj->otyp == CORPSE && touch_petrifies(&mons[kickobj->corpsenm])
|
if (!uarmf && kickobj->otyp == CORPSE &&
|
||||||
&& !Stone_resistance && !uarmf) {
|
touch_petrifies(&mons[kickobj->corpsenm]) &&
|
||||||
You("kick the %s with your bare %s.",
|
!Stone_resistance) {
|
||||||
corpse_xname(kickobj, TRUE), makeplural(body_part(FOOT)));
|
You("kick %s with your bare %s.",
|
||||||
if (!(poly_when_stoned(youmonst.data) && polymon(PM_STONE_GOLEM))) {
|
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...");
|
You("turn to stone...");
|
||||||
killer.format = KILLED_BY;
|
killer.format = KILLED_BY;
|
||||||
/* KMH -- otmp should be kickobj */
|
/* normalize body shape here; foot, not body_part(FOOT) */
|
||||||
Sprintf(killer.name, "kicking %s without boots",
|
Sprintf(killer.name, "kicking %s barefoot",
|
||||||
an(corpse_xname(kickobj, TRUE)));
|
killer_xname(kickobj));
|
||||||
done(STONING);
|
done(STONING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-5
@@ -91,11 +91,16 @@ int shotlimit;
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
u_wipe_engr(2);
|
u_wipe_engr(2);
|
||||||
if (!uarmg && !Stone_resistance && (obj->otyp == CORPSE &&
|
if (!uarmg && obj->otyp == CORPSE &&
|
||||||
touch_petrifies(&mons[obj->corpsenm]))) {
|
touch_petrifies(&mons[obj->corpsenm]) &&
|
||||||
You("throw the %s corpse with your bare %s.",
|
!Stone_resistance) {
|
||||||
mons[obj->corpsenm].mname, body_part(HAND));
|
You("throw %s with your bare %s.",
|
||||||
Sprintf(killer.name, "%s corpse", an(mons[obj->corpsenm].mname));
|
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);
|
instapetrify(killer.name);
|
||||||
}
|
}
|
||||||
if (welded(obj)) {
|
if (welded(obj)) {
|
||||||
|
|||||||
@@ -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. */
|
/* 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,7 +163,7 @@ eatmdone() /* called after mimicing is over */
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ``[the(] singular(food, xname) [)]'' with awareness of unique monsters */
|
/* ``[the(] singular(food, xname) [)]'' */
|
||||||
STATIC_OVL const char *
|
STATIC_OVL const char *
|
||||||
food_xname(food, the_pfx)
|
food_xname(food, the_pfx)
|
||||||
struct obj *food;
|
struct obj *food;
|
||||||
@@ -172,18 +172,17 @@ boolean the_pfx;
|
|||||||
const char *result;
|
const char *result;
|
||||||
int mnum = food->corpsenm;
|
int mnum = food->corpsenm;
|
||||||
|
|
||||||
if (food->otyp == CORPSE && (mons[mnum].geno & G_UNIQ)) {
|
if (food->otyp == CORPSE) {
|
||||||
/* grab xname()'s modifiable return buffer for our own use */
|
result = corpse_xname(food, (const char *)0,
|
||||||
char *bufp = xname(food);
|
CXN_SINGULAR | (the_pfx ? CXN_PFX_THE : 0));
|
||||||
Sprintf(bufp, "%s%s corpse",
|
/* not strictly needed since pname values are capitalized
|
||||||
(the_pfx && !type_is_pname(&mons[mnum])) ? "the " : "",
|
and the() is a no-op for them */
|
||||||
s_suffix(mons[mnum].mname));
|
if (type_is_pname(&mons[food->corpsenm])) the_pfx = FALSE;
|
||||||
result = bufp;
|
|
||||||
} else {
|
} else {
|
||||||
/* the ordinary case */
|
/* the ordinary case */
|
||||||
result = singular(food, xname);
|
result = singular(food, xname);
|
||||||
if (the_pfx) result = the(result);
|
|
||||||
}
|
}
|
||||||
|
if (the_pfx) result = the(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -227,17 +226,8 @@ choke(food) /* To a full belly all food is bad. (It.) */
|
|||||||
if (food->oclass == COIN_CLASS) {
|
if (food->oclass == COIN_CLASS) {
|
||||||
Strcpy(killer.name, "very rich meal");
|
Strcpy(killer.name, "very rich meal");
|
||||||
} else {
|
} else {
|
||||||
Strcpy(killer.name, food_xname(food, FALSE));
|
killer.format = KILLED_BY;
|
||||||
if (food->otyp == CORPSE &&
|
Strcpy(killer.name, killer_xname(food));
|
||||||
(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));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
You("choke over it.");
|
You("choke over it.");
|
||||||
@@ -1269,8 +1259,8 @@ opentin() /* called during each move whilst opening a tin */
|
|||||||
what = rndmonnam();
|
what = rndmonnam();
|
||||||
} else {
|
} else {
|
||||||
what = mons[mnum].mname;
|
what = mons[mnum].mname;
|
||||||
if (mons[mnum].geno & G_UNIQ)
|
if (the_unique_pm(&mons[mnum])) which = 2;
|
||||||
which = type_is_pname(&mons[mnum]) ? 1 : 2;
|
else if (type_is_pname(&mons[mnum])) which = 1;
|
||||||
}
|
}
|
||||||
if (which == 0) what = makeplural(what);
|
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;
|
int tp = 0, mnum = otmp->corpsenm;
|
||||||
long rotted = 0L;
|
long rotted = 0L;
|
||||||
boolean uniq = !!(mons[mnum].geno & G_UNIQ);
|
|
||||||
int retcode = 0;
|
int retcode = 0;
|
||||||
boolean stoneable = (flesh_petrifies(&mons[mnum]) &&
|
boolean stoneable = (flesh_petrifies(&mons[mnum]) &&
|
||||||
!Stone_resistance &&
|
!Stone_resistance &&
|
||||||
@@ -1490,20 +1479,15 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
|
|||||||
if (Sick_resistance) {
|
if (Sick_resistance) {
|
||||||
pline("It doesn't seem at all sickening, though...");
|
pline("It doesn't seem at all sickening, though...");
|
||||||
} else {
|
} else {
|
||||||
char buf[BUFSZ];
|
|
||||||
long sick_time;
|
long sick_time;
|
||||||
|
|
||||||
sick_time = (long) rn1(10, 10);
|
sick_time = (long) rn1(10, 10);
|
||||||
/* make sure new ill doesn't result in improvement */
|
/* make sure new ill doesn't result in improvement */
|
||||||
if (Sick && (sick_time > Sick))
|
if (Sick && (sick_time > Sick))
|
||||||
sick_time = (Sick > 1L) ? Sick - 1L : 1L;
|
sick_time = (Sick > 1L) ? Sick - 1L : 1L;
|
||||||
if (!uniq)
|
make_sick(sick_time,
|
||||||
Sprintf(buf, "rotted %s", corpse_xname(otmp,TRUE));
|
corpse_xname(otmp, "rotted", CXN_NORMAL),
|
||||||
else
|
TRUE, SICK_VOMITABLE);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
if (carried(otmp)) useup(otmp);
|
if (carried(otmp)) useup(otmp);
|
||||||
else useupf(otmp, 1L);
|
else useupf(otmp, 1L);
|
||||||
@@ -1552,7 +1536,8 @@ eatcorpse(otmp) /* called when a corpse is selected as food */
|
|||||||
pline("This tastes just like chicken!");
|
pline("This tastes just like chicken!");
|
||||||
} else {
|
} else {
|
||||||
pline("%s%s %s!",
|
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),
|
food_xname(otmp, FALSE),
|
||||||
(vegan(&mons[mnum]) ?
|
(vegan(&mons[mnum]) ?
|
||||||
(!carnivorous(youmonst.data) && herbivorous(youmonst.data)) :
|
(!carnivorous(youmonst.data) && herbivorous(youmonst.data)) :
|
||||||
|
|||||||
+72
-27
@@ -592,6 +592,10 @@ register struct obj *obj;
|
|||||||
|
|
||||||
if(obj->quan != 1L)
|
if(obj->quan != 1L)
|
||||||
Sprintf(prefix, "%ld ", obj->quan);
|
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)) {
|
else if (obj_is_pname(obj) || the_unique_obj(obj)) {
|
||||||
if (!strncmpi(bp, "the ", 4))
|
if (!strncmpi(bp, "the ", 4))
|
||||||
bp += 4;
|
bp += 4;
|
||||||
@@ -750,16 +754,9 @@ ring:
|
|||||||
if (obj->oeaten)
|
if (obj->oeaten)
|
||||||
Strcat(prefix, "partly eaten ");
|
Strcat(prefix, "partly eaten ");
|
||||||
if (obj->otyp == CORPSE) {
|
if (obj->otyp == CORPSE) {
|
||||||
if (the_unique_pm(&mons[omndx]) ||
|
Sprintf(prefix, "%s ",
|
||||||
type_is_pname(&mons[omndx])) {
|
corpse_xname(obj, prefix,
|
||||||
Sprintf(prefix, "%s%s ",
|
CXN_ARTICLE|CXN_NOCORPSE));
|
||||||
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, " ");
|
|
||||||
}
|
|
||||||
} else if (obj->otyp == EGG) {
|
} else if (obj->otyp == EGG) {
|
||||||
#if 0 /* corpses don't tell if they're stale either */
|
#if 0 /* corpses don't tell if they're stale either */
|
||||||
if (obj->known && stale_egg(obj))
|
if (obj->known && stale_egg(obj))
|
||||||
@@ -868,41 +865,92 @@ register struct obj *otmp;
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *
|
char *
|
||||||
corpse_xname(otmp, ignore_oquan)
|
corpse_xname(otmp, adjective, cxn_flags)
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
boolean ignore_oquan; /* to force singular */
|
const char *adjective;
|
||||||
|
unsigned cxn_flags; /* bitmask of CXN_xxx values */
|
||||||
{
|
{
|
||||||
char *nambuf = nextobuf();
|
char *nambuf = nextobuf();
|
||||||
int omndx = otmp->corpsenm;
|
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;
|
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
|
/* [Possible enhancement: check whether corpse has monster traits
|
||||||
attached in order to use priestname() for priests and minions.] */
|
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 */
|
/* avoid "aligned priest"; it just exposes internal details */
|
||||||
mname = "priest";
|
mname = "priest";
|
||||||
} else {
|
} else {
|
||||||
mname = mons[omndx].mname;
|
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);
|
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)
|
*nambuf = '\0';
|
||||||
return nambuf;
|
/* can't use the() the way we use an() below because any capitalized
|
||||||
else
|
Name causes it to assume a personal name and return Name as-is;
|
||||||
return makeplural(nambuf);
|
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 *
|
char *
|
||||||
cxname(obj)
|
cxname(obj)
|
||||||
struct obj *obj;
|
struct obj *obj;
|
||||||
{
|
{
|
||||||
if (obj->otyp == CORPSE)
|
if (obj->otyp == CORPSE)
|
||||||
return corpse_xname(obj, FALSE);
|
return corpse_xname(obj, (const char *)0, CXN_NORMAL);
|
||||||
return xname(obj);
|
return xname(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -941,10 +989,7 @@ struct obj *obj;
|
|||||||
/* format the object */
|
/* format the object */
|
||||||
if (obj->otyp == CORPSE) {
|
if (obj->otyp == CORPSE) {
|
||||||
buf = nextobuf();
|
buf = nextobuf();
|
||||||
Sprintf(buf, "%s%s",
|
Strcpy(buf, corpse_xname(obj, (const char *)0, CXN_NORMAL));
|
||||||
/* can't use the(); capitalized name blocks its article */
|
|
||||||
the_unique_pm(&mons[obj->corpsenm]) ? "the " : "",
|
|
||||||
corpse_xname(obj, FALSE));
|
|
||||||
} else if (obj->otyp == SLIME_MOLD) {
|
} else if (obj->otyp == SLIME_MOLD) {
|
||||||
/* concession to "most unique deaths competition" in the annual
|
/* concession to "most unique deaths competition" in the annual
|
||||||
devnull tournament, suppress player supplied fruit names because
|
devnull tournament, suppress player supplied fruit names because
|
||||||
|
|||||||
+27
-43
@@ -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. */
|
/* 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. */
|
||||||
|
|
||||||
@@ -16,6 +16,7 @@ STATIC_DCL boolean FDECL(query_classes, (char *,boolean *,boolean *,
|
|||||||
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 *));
|
const char *,struct obj *,BOOLEAN_P,int *));
|
||||||
#endif
|
#endif
|
||||||
|
STATIC_DCL boolean FDECL(fatal_corpse_mistake, (struct obj *,BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
|
STATIC_DCL void FDECL(check_here, (BOOLEAN_P));
|
||||||
STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
|
STATIC_DCL boolean FDECL(n_or_more, (struct obj *));
|
||||||
STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *));
|
STATIC_DCL boolean FDECL(all_but_uchain, (struct obj *));
|
||||||
@@ -262,6 +263,27 @@ ask_again:
|
|||||||
return TRUE;
|
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 */
|
/* look at the objects at our location, unless there are too many of them */
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
check_here(picked_some)
|
check_here(picked_some)
|
||||||
@@ -1307,18 +1329,8 @@ boolean telekinesis; /* not picking it up directly by hand */
|
|||||||
return 1;
|
return 1;
|
||||||
#endif
|
#endif
|
||||||
} else if (obj->otyp == CORPSE) {
|
} else if (obj->otyp == CORPSE) {
|
||||||
if ( (touch_petrifies(&mons[obj->corpsenm])) && !uarmg
|
if (fatal_corpse_mistake(obj, telekinesis)) {
|
||||||
&& !Stone_resistance && !telekinesis) {
|
return -1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
} else if (is_rider(&mons[obj->corpsenm])) {
|
} else if (is_rider(&mons[obj->corpsenm])) {
|
||||||
pline("At your %s, the corpse suddenly moves...",
|
pline("At your %s, the corpse suddenly moves...",
|
||||||
telekinesis ? "attempted acquisition" : "touch");
|
telekinesis ? "attempted acquisition" : "touch");
|
||||||
@@ -1823,21 +1835,7 @@ register struct obj *obj;
|
|||||||
if (uquiver) return 0; /* unwielded, died, rewielded */
|
if (uquiver) return 0; /* unwielded, died, rewielded */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (obj->otyp == CORPSE) {
|
if (fatal_corpse_mistake(obj, FALSE)) return -1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* boxes, boulders, and big statues can't fit into any container */
|
/* boxes, boulders, and big statues can't fit into any container */
|
||||||
if (obj->otyp == ICE_BOX || Is_box(obj) || obj->otyp == BOULDER ||
|
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->oartifact && !touch_artifact(obj,&youmonst)) return 0;
|
||||||
|
|
||||||
if (obj->otyp == CORPSE) {
|
if (fatal_corpse_mistake(obj, FALSE)) return -1;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
count = obj->quan;
|
count = obj->quan;
|
||||||
if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0)
|
if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0)
|
||||||
|
|||||||
+16
-31
@@ -753,13 +753,12 @@ int thrown;
|
|||||||
#endif
|
#endif
|
||||||
case CORPSE: /* fixed by polder@cs.vu.nl */
|
case CORPSE: /* fixed by polder@cs.vu.nl */
|
||||||
if (touch_petrifies(&mons[obj->corpsenm])) {
|
if (touch_petrifies(&mons[obj->corpsenm])) {
|
||||||
static const char withwhat[] = "corpse";
|
|
||||||
tmp = 1;
|
tmp = 1;
|
||||||
hittxt = TRUE;
|
hittxt = TRUE;
|
||||||
You("hit %s with %s %s.", mon_nam(mon),
|
You("hit %s with %s.", mon_nam(mon),
|
||||||
obj->dknown ? the(mons[obj->corpsenm].mname) :
|
corpse_xname(obj, (const char *)0,
|
||||||
an(mons[obj->corpsenm].mname),
|
obj->dknown ? CXN_PFX_THE : CXN_ARTICLE));
|
||||||
(obj->quan > 1L) ? makeplural(withwhat) : withwhat);
|
obj->dknown = 1;
|
||||||
if (!munstone(mon, TRUE))
|
if (!munstone(mon, TRUE))
|
||||||
minstapetrify(mon, TRUE);
|
minstapetrify(mon, TRUE);
|
||||||
if (resists_ston(mon)) break;
|
if (resists_ston(mon)) break;
|
||||||
@@ -1215,28 +1214,20 @@ STATIC_OVL boolean
|
|||||||
theft_petrifies(otmp)
|
theft_petrifies(otmp)
|
||||||
struct obj *otmp;
|
struct obj *otmp;
|
||||||
{
|
{
|
||||||
const char *fmt;
|
|
||||||
char *p, cbuf[BUFSZ], kbuf[BUFSZ];
|
|
||||||
|
|
||||||
if (uarmg || otmp->otyp != CORPSE ||
|
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... */
|
/* stealing this corpse is fatal... */
|
||||||
Strcpy(cbuf, cxname(otmp)); /* "cockatrice corpse" */
|
instapetrify(corpse_xname(otmp, "stolen", CXN_ARTICLE));
|
||||||
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);
|
|
||||||
/* apparently wasn't fatal after all... */
|
/* apparently wasn't fatal after all... */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@@ -1246,12 +1237,6 @@ struct obj *otmp;
|
|||||||
*
|
*
|
||||||
* If the target is wearing body armor, take all of its possesions;
|
* If the target is wearing body armor, take all of its possesions;
|
||||||
* otherwise, take one object. [Is this really the behavior we want?]
|
* 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
|
STATIC_OVL void
|
||||||
steal_it(mdef, mattk)
|
steal_it(mdef, mattk)
|
||||||
@@ -1801,7 +1786,7 @@ register struct attack *mattk;
|
|||||||
/* engulfing a cockatrice or digesting a Rider or Medusa */
|
/* engulfing a cockatrice or digesting a Rider or Medusa */
|
||||||
fatal_gulp = (touch_petrifies(pd) && !Stone_resistance) ||
|
fatal_gulp = (touch_petrifies(pd) && !Stone_resistance) ||
|
||||||
(mattk->adtyp == AD_DGST && (is_rider(pd) ||
|
(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) {
|
if ((mattk->adtyp == AD_DGST && !Slow_digestion) || fatal_gulp) {
|
||||||
/* KMH, conduct */
|
/* KMH, conduct */
|
||||||
|
|||||||
+27
-18
@@ -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. */
|
/* 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. */
|
||||||
|
|
||||||
@@ -50,6 +50,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
STATIC_DCL boolean FDECL(cant_wield_corpse, (struct obj *));
|
||||||
STATIC_DCL int FDECL(ready_weapon, (struct obj *));
|
STATIC_DCL int FDECL(ready_weapon, (struct obj *));
|
||||||
|
|
||||||
/* used by will_weld() */
|
/* used by will_weld() */
|
||||||
@@ -112,6 +113,25 @@ register struct obj *obj;
|
|||||||
update_inventory();
|
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
|
STATIC_OVL int
|
||||||
ready_weapon(wep)
|
ready_weapon(wep)
|
||||||
struct obj *wep;
|
struct obj *wep;
|
||||||
@@ -127,15 +147,9 @@ struct obj *wep;
|
|||||||
res++;
|
res++;
|
||||||
} else
|
} else
|
||||||
You("are already empty %s.", body_part(HANDED));
|
You("are already empty %s.", body_part(HANDED));
|
||||||
} else if (!uarmg && !Stone_resistance && wep->otyp == CORPSE
|
} else if (wep->otyp == CORPSE && cant_wield_corpse(wep)) {
|
||||||
&& touch_petrifies(&mons[wep->corpsenm])) {
|
/* hero must have been life-saved to get here; use a turn */
|
||||||
/* Prevent wielding cockatrice when not wearing gloves --KAA */
|
res++; /* corpse won't be wielded */
|
||||||
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 (uarms && bimanual(wep))
|
} else if (uarms && bimanual(wep))
|
||||||
You("cannot wield a two-handed %s while wearing a shield.",
|
You("cannot wield a two-handed %s while wearing a shield.",
|
||||||
is_sword(wep) ? "sword" :
|
is_sword(wep) ? "sword" :
|
||||||
@@ -497,14 +511,9 @@ can_twoweapon()
|
|||||||
else if (uswapwep->oartifact)
|
else if (uswapwep->oartifact)
|
||||||
pline("%s being held second to another weapon!",
|
pline("%s being held second to another weapon!",
|
||||||
Yobjnam2(uswapwep, "resist"));
|
Yobjnam2(uswapwep, "resist"));
|
||||||
else if (!uarmg && !Stone_resistance && (uswapwep->otyp == CORPSE &&
|
else if (uswapwep->otyp == CORPSE && cant_wield_corpse(uswapwep)) {
|
||||||
touch_petrifies(&mons[uswapwep->corpsenm]))) {
|
/* [Note: NOT_WEAPON() check prevents ever getting here...] */
|
||||||
char kbuf[BUFSZ];
|
; /* must be life-saved to reach here; return FALSE */
|
||||||
|
|
||||||
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 (Glib || uswapwep->cursed) {
|
} else if (Glib || uswapwep->cursed) {
|
||||||
if (!Glib)
|
if (!Glib)
|
||||||
uswapwep->bknown = TRUE;
|
uswapwep->bknown = TRUE;
|
||||||
|
|||||||
@@ -786,7 +786,9 @@ struct monst *mon;
|
|||||||
revive_egg(otmp);
|
revive_egg(otmp);
|
||||||
if (otmp->otyp != CORPSE) continue;
|
if (otmp->otyp != CORPSE) continue;
|
||||||
/* save the name; the object is liable to go away */
|
/* 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? */
|
/* for a merged group, only one is revived; should this be fixed? */
|
||||||
if ((mtmp2 = revive(otmp, !context.mon_moving)) != 0) {
|
if ((mtmp2 = revive(otmp, !context.mon_moving)) != 0) {
|
||||||
|
|||||||
Reference in New Issue
Block a user