give player an inkling of why corpses didn't stack
When corpses haven't stacked, and there is no player-discernable reason why, provide some additional information in some cases, but only when it is required. Gender variance is the supported case in this commit. Related to GitHub issue #1607. This commit doesn't change the underlying mechanics to allow the corpses to stack, but it does help the player understand why that's the case in this instance.
This commit is contained in:
@@ -803,6 +803,9 @@ struct instance_globals_p {
|
|||||||
int poly_zapped;
|
int poly_zapped;
|
||||||
|
|
||||||
/* new stuff */
|
/* new stuff */
|
||||||
|
int puzzling_critera;
|
||||||
|
char puzzling_ilets[invlet_basic + 1];
|
||||||
|
|
||||||
boolean havestate;
|
boolean havestate;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1404,6 +1404,7 @@ extern void perm_invent_toggled(boolean negated);
|
|||||||
extern void prepare_perminvent(winid window);
|
extern void prepare_perminvent(winid window);
|
||||||
extern struct obj *carrying_stoning_corpse(void);
|
extern struct obj *carrying_stoning_corpse(void);
|
||||||
extern void repopulate_perminvent(void);
|
extern void repopulate_perminvent(void);
|
||||||
|
extern int check_for_puzzling_nonmerge(struct obj *);
|
||||||
|
|
||||||
/* ### ioctl.c ### */
|
/* ### ioctl.c ### */
|
||||||
|
|
||||||
@@ -2236,6 +2237,8 @@ extern boolean the_unique_pm(struct permonst *) NONNULLARG1;
|
|||||||
extern boolean erosion_matters(struct obj *) NONNULLARG1;
|
extern boolean erosion_matters(struct obj *) NONNULLARG1;
|
||||||
extern char *doname(struct obj *) NONNULLARG1;
|
extern char *doname(struct obj *) NONNULLARG1;
|
||||||
extern char *doname_with_price(struct obj *) NONNULLARG1;
|
extern char *doname_with_price(struct obj *) NONNULLARG1;
|
||||||
|
extern char *doname_with_cgender(struct obj *) NONNULLARG1;
|
||||||
|
extern char *doname_with_price_and_cgender(struct obj *) NONNULLARG1;
|
||||||
extern char *doname_vague_quan(struct obj *) NONNULLARG1;
|
extern char *doname_vague_quan(struct obj *) NONNULLARG1;
|
||||||
extern boolean not_fully_identified(struct obj *) NONNULLARG1;
|
extern boolean not_fully_identified(struct obj *) NONNULLARG1;
|
||||||
extern char *corpse_xname(struct obj *, const char *, unsigned) NONNULLARG1;
|
extern char *corpse_xname(struct obj *, const char *, unsigned) NONNULLARG1;
|
||||||
|
|||||||
@@ -63,6 +63,7 @@
|
|||||||
#define CXN_PFX_THE 4 /* prefix with "the " (unless pname) */
|
#define CXN_PFX_THE 4 /* prefix with "the " (unless pname) */
|
||||||
#define CXN_ARTICLE 8 /* include a/an/the prefix */
|
#define CXN_ARTICLE 8 /* include a/an/the prefix */
|
||||||
#define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
|
#define CXN_NOCORPSE 16 /* suppress " corpse" suffix */
|
||||||
|
#define CXN_ADDGNDR 32 /* include a gender */
|
||||||
|
|
||||||
/* number of turns it takes for vault guard to show up */
|
/* number of turns it takes for vault guard to show up */
|
||||||
#define VAULT_GUARD_TIME 30
|
#define VAULT_GUARD_TIME 30
|
||||||
|
|||||||
@@ -648,6 +648,13 @@ static const struct instance_globals_p g_init_p = {
|
|||||||
UNDEFINED_PTR, /* propellor */
|
UNDEFINED_PTR, /* propellor */
|
||||||
/* zap.c */
|
/* zap.c */
|
||||||
UNDEFINED_VALUE, /* poly_zap */
|
UNDEFINED_VALUE, /* poly_zap */
|
||||||
|
0, /* puzzling_criteria */
|
||||||
|
{
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||||
|
}, /* puzzling_ilets[] */
|
||||||
|
|
||||||
TRUE, /* havestate*/
|
TRUE, /* havestate*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+60
-4
@@ -2701,6 +2701,51 @@ count_unidentified(struct obj *objchn)
|
|||||||
return unid_cnt;
|
return unid_cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* mark the puzzling items */
|
||||||
|
int
|
||||||
|
check_for_puzzling_nonmerge(struct obj *objchn)
|
||||||
|
{
|
||||||
|
int i, k, idx, puzzling_cnt = 0, ilet, mnums[invlet_basic + 1],
|
||||||
|
gndr[invlet_basic + 1];
|
||||||
|
struct obj *obj;
|
||||||
|
boolean at_least_one = FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < invlet_basic + 1; ++i)
|
||||||
|
gp.puzzling_ilets[i] = mnums[i] = gndr[i] = 0;
|
||||||
|
|
||||||
|
|
||||||
|
for (obj = objchn; obj; obj = obj->nobj) {
|
||||||
|
if (obj->otyp == CORPSE
|
||||||
|
&& obj->corpsenm >= 0 && obj->corpsenm < NUMMONS) {
|
||||||
|
ilet = obj->invlet;
|
||||||
|
idx = (ilet >= 'A' && ilet <= 'Z') ? ilet - 'A'
|
||||||
|
: (ilet >= 'a' && ilet <= 'z') ? ilet - 'a' + 26
|
||||||
|
: 53;
|
||||||
|
if (idx < 53) {
|
||||||
|
mnums[idx] = obj->corpsenm;
|
||||||
|
gndr[idx] = (obj->spe & CORPSTAT_MALE) ? CORPSTAT_MALE
|
||||||
|
: CORPSTAT_FEMALE;
|
||||||
|
at_least_one = TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (at_least_one) {
|
||||||
|
for (i = 0; i < invlet_basic; ++i) {
|
||||||
|
for (k = i + 1; k < invlet_basic; ++k) {
|
||||||
|
if (k == i)
|
||||||
|
continue;
|
||||||
|
if (mnums[k] == mnums[i] && gndr[k] != gndr[i]) {
|
||||||
|
++puzzling_cnt;
|
||||||
|
gp.puzzling_ilets[i] = gp.puzzling_ilets[k] = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (puzzling_cnt)
|
||||||
|
gp.puzzling_critera = 411;
|
||||||
|
}
|
||||||
|
return puzzling_cnt;
|
||||||
|
}
|
||||||
|
|
||||||
/* dialog with user to identify a given number of items; 0 means all */
|
/* dialog with user to identify a given number of items; 0 means all */
|
||||||
void
|
void
|
||||||
identify_pack(
|
identify_pack(
|
||||||
@@ -3064,7 +3109,7 @@ display_pickinv(
|
|||||||
struct obj *otmp, wizid_fakeobj, inuse_fakeobj;
|
struct obj *otmp, wizid_fakeobj, inuse_fakeobj;
|
||||||
char ilet, ret, *formattedobj;
|
char ilet, ret, *formattedobj;
|
||||||
const char *invlet = flags.inv_order;
|
const char *invlet = flags.inv_order;
|
||||||
int n, classcount, inusecount = 0;
|
int n, classcount, inusecount = 0, puzzling_count = 0;
|
||||||
winid win; /* windows being used */
|
winid win; /* windows being used */
|
||||||
anything any;
|
anything any;
|
||||||
menu_item *selected;
|
menu_item *selected;
|
||||||
@@ -3212,6 +3257,9 @@ display_pickinv(
|
|||||||
sortedinvent[0].obj = (struct obj *) 0;
|
sortedinvent[0].obj = (struct obj *) 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
puzzling_count = check_for_puzzling_nonmerge(gi.invent);
|
||||||
|
|
||||||
start_menu(win, menu_behavior);
|
start_menu(win, menu_behavior);
|
||||||
any = cg.zeroany;
|
any = cg.zeroany;
|
||||||
if (wizid) {
|
if (wizid) {
|
||||||
@@ -3314,7 +3362,9 @@ display_pickinv(
|
|||||||
/* normal inventory item */
|
/* normal inventory item */
|
||||||
tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng);
|
tmpglyph = obj_to_glyph(otmp, rn2_on_display_rng);
|
||||||
map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo);
|
map_glyphinfo(0, 0, tmpglyph, 0U, &tmpglyphinfo);
|
||||||
formattedobj = doname(otmp);
|
formattedobj = !puzzling_count
|
||||||
|
? doname(otmp)
|
||||||
|
: doname_with_cgender(otmp);
|
||||||
add_menu(win, &tmpglyphinfo, &any, ilet,
|
add_menu(win, &tmpglyphinfo, &any, ilet,
|
||||||
wizid ? def_oc_syms[(int) otmp->oclass].sym : 0,
|
wizid ? def_oc_syms[(int) otmp->oclass].sym : 0,
|
||||||
ATR_NONE, clr, formattedobj, MENU_ITEMFLAGS_NONE);
|
ATR_NONE, clr, formattedobj, MENU_ITEMFLAGS_NONE);
|
||||||
@@ -4110,6 +4160,7 @@ look_here(
|
|||||||
picked_some = (lookhere_flags & LOOKHERE_PICKED_SOME) != 0,
|
picked_some = (lookhere_flags & LOOKHERE_PICKED_SOME) != 0,
|
||||||
/* skip 'dfeature' if caller used describe_decor() to show it */
|
/* skip 'dfeature' if caller used describe_decor() to show it */
|
||||||
skip_dfeature = (lookhere_flags & LOOKHERE_SKIP_DFEATURE) != 0;
|
skip_dfeature = (lookhere_flags & LOOKHERE_SKIP_DFEATURE) != 0;
|
||||||
|
int puzzling_count = 0;
|
||||||
|
|
||||||
/* default pile_limit is 5; a value of 0 means "never skip"
|
/* default pile_limit is 5; a value of 0 means "never skip"
|
||||||
(and 1 effectively forces "always skip") */
|
(and 1 effectively forces "always skip") */
|
||||||
@@ -4173,6 +4224,7 @@ look_here(
|
|||||||
}
|
}
|
||||||
|
|
||||||
otmp = svl.level.objects[u.ux][u.uy];
|
otmp = svl.level.objects[u.ux][u.uy];
|
||||||
|
puzzling_count = check_for_puzzling_nonmerge(otmp);
|
||||||
dfeature = dfeature_at(u.ux, u.uy, fbuf2);
|
dfeature = dfeature_at(u.ux, u.uy, fbuf2);
|
||||||
if (dfeature && !strcmp(dfeature, "pool of water") && Underwater)
|
if (dfeature && !strcmp(dfeature, "pool of water") && Underwater)
|
||||||
dfeature = 0;
|
dfeature = 0;
|
||||||
@@ -4294,11 +4346,15 @@ look_here(
|
|||||||
for (; otmp; otmp = otmp->nexthere) {
|
for (; otmp; otmp = otmp->nexthere) {
|
||||||
if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
|
if (otmp->otyp == CORPSE && will_feel_cockatrice(otmp, FALSE)) {
|
||||||
felt_cockatrice = TRUE;
|
felt_cockatrice = TRUE;
|
||||||
Sprintf(buf, "%s...", doname(otmp));
|
Sprintf(buf, "%s...",
|
||||||
|
(puzzling_count) ? doname_with_cgender(otmp)
|
||||||
|
: doname(otmp));
|
||||||
putstr(tmpwin, 0, buf);
|
putstr(tmpwin, 0, buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
putstr(tmpwin, 0, doname_with_price(otmp));
|
putstr(tmpwin, 0,
|
||||||
|
(puzzling_count) ? doname_with_price_and_cgender(otmp)
|
||||||
|
: doname_with_price(otmp));
|
||||||
}
|
}
|
||||||
display_nhwindow(tmpwin, TRUE);
|
display_nhwindow(tmpwin, TRUE);
|
||||||
destroy_nhwindow(tmpwin);
|
destroy_nhwindow(tmpwin);
|
||||||
|
|||||||
+36
-7
@@ -1214,9 +1214,10 @@ erosion_matters(struct obj *obj)
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define DONAME_WITH_PRICE 1
|
#define DONAME_WITH_PRICE 1
|
||||||
#define DONAME_VAGUE_QUAN 2
|
#define DONAME_VAGUE_QUAN 2
|
||||||
#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */
|
#define DONAME_FOR_MENU 4 /* [not used anywhere yet] */
|
||||||
|
#define DONAME_FORCE_GENDER 8 /* always add male or female */
|
||||||
|
|
||||||
/* core of doname() */
|
/* core of doname() */
|
||||||
staticfn char *
|
staticfn char *
|
||||||
@@ -1227,7 +1228,8 @@ doname_base(
|
|||||||
boolean ispoisoned = FALSE,
|
boolean ispoisoned = FALSE,
|
||||||
with_price = (doname_flags & DONAME_WITH_PRICE) != 0,
|
with_price = (doname_flags & DONAME_WITH_PRICE) != 0,
|
||||||
vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0,
|
vague_quan = (doname_flags & DONAME_VAGUE_QUAN) != 0,
|
||||||
for_menu = (doname_flags & DONAME_FOR_MENU) != 0;
|
for_menu = (doname_flags & DONAME_FOR_MENU) != 0,
|
||||||
|
with_corpse_genders = (doname_flags & DONAME_FORCE_GENDER) != 0;
|
||||||
boolean known, dknown, cknown, bknown, lknown,
|
boolean known, dknown, cknown, bknown, lknown,
|
||||||
fake_arti, force_the;
|
fake_arti, force_the;
|
||||||
char prefix[PREFIX];
|
char prefix[PREFIX];
|
||||||
@@ -1511,7 +1513,15 @@ doname_base(
|
|||||||
unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE)
|
unsigned cxarg = (((obj->quan != 1L) ? 0 : CXN_ARTICLE)
|
||||||
| CXN_NOCORPSE);
|
| CXN_NOCORPSE);
|
||||||
char *cxstr, *save_xnamep;
|
char *cxstr, *save_xnamep;
|
||||||
|
int puzzidx = (obj->invlet >= 'A' && obj->invlet <= 'Z')
|
||||||
|
? obj->invlet - 'A'
|
||||||
|
: (obj->invlet >= 'a' && obj->invlet <= 'z')
|
||||||
|
? obj->invlet - 'a' + 26
|
||||||
|
: 53; /* valid index, but always holds zero */
|
||||||
|
|
||||||
|
if (with_corpse_genders && puzzidx < 53
|
||||||
|
&& gp.puzzling_critera == 411 && gp.puzzling_ilets[puzzidx])
|
||||||
|
cxarg |= CXN_ADDGNDR;
|
||||||
/* corpse_xname() sets xnamep; callers other than doname_base()
|
/* corpse_xname() sets xnamep; callers other than doname_base()
|
||||||
itself shouldn't care about xnamep (pointer to start of
|
itself shouldn't care about xnamep (pointer to start of
|
||||||
current obuf[]) but keep it accurate anyway */
|
current obuf[]) but keep it accurate anyway */
|
||||||
@@ -1763,6 +1773,20 @@ doname_with_price(struct obj *obj)
|
|||||||
return doname_base(obj, DONAME_WITH_PRICE);
|
return doname_base(obj, DONAME_WITH_PRICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Name of object including corpse genders. */
|
||||||
|
char *
|
||||||
|
doname_with_cgender(struct obj *obj)
|
||||||
|
{
|
||||||
|
return doname_base(obj, DONAME_FORCE_GENDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* doname with both price and corpse gender */
|
||||||
|
char *
|
||||||
|
doname_with_price_and_cgender(struct obj *obj)
|
||||||
|
{
|
||||||
|
return doname_base(obj, DONAME_WITH_PRICE | DONAME_FORCE_GENDER);
|
||||||
|
}
|
||||||
|
|
||||||
/* "some" instead of precise quantity if obj->dknown not set */
|
/* "some" instead of precise quantity if obj->dknown not set */
|
||||||
char *
|
char *
|
||||||
doname_vague_quan(struct obj *obj)
|
doname_vague_quan(struct obj *obj)
|
||||||
@@ -1837,9 +1861,10 @@ corpse_xname(
|
|||||||
any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
|
any_prefix = (cxn_flags & CXN_ARTICLE) != 0,
|
||||||
/* leave off suffix (do_name() appends "corpse" itself) */
|
/* leave off suffix (do_name() appends "corpse" itself) */
|
||||||
omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
|
omit_corpse = (cxn_flags & CXN_NOCORPSE) != 0,
|
||||||
|
gndr_prefix = (cxn_flags & CXN_ADDGNDR) != 0,
|
||||||
possessive = FALSE,
|
possessive = FALSE,
|
||||||
glob = (otmp->otyp != CORPSE && otmp->globby);
|
glob = (otmp->otyp != CORPSE && otmp->globby);
|
||||||
const char *mnam;
|
const char *mnam, *gndr;
|
||||||
|
|
||||||
/* some callers [aobjnam()] rely on prefix area that xname() sets aside */
|
/* some callers [aobjnam()] rely on prefix area that xname() sets aside */
|
||||||
gx.xnamep = nextobuf();
|
gx.xnamep = nextobuf();
|
||||||
@@ -1879,15 +1904,19 @@ corpse_xname(
|
|||||||
into the code, so the() has been modified to deal with capitalized
|
into the code, so the() has been modified to deal with capitalized
|
||||||
monster names; we could switch to using it below like an() */
|
monster names; we could switch to using it below like an() */
|
||||||
|
|
||||||
|
gndr = (gndr_prefix && otmp->spe & CORPSTAT_MALE) != 0 ? "male "
|
||||||
|
: (gndr_prefix && otmp->spe & CORPSTAT_FEMALE) != 0 ? "female "
|
||||||
|
: "";
|
||||||
if (!adjective || !*adjective) {
|
if (!adjective || !*adjective) {
|
||||||
|
Strcat(nambuf, gndr);
|
||||||
/* normal case: newt corpse */
|
/* normal case: newt corpse */
|
||||||
Strcat(nambuf, mnam);
|
Strcat(nambuf, mnam);
|
||||||
} else {
|
} else {
|
||||||
/* adjective positioning depends upon format of monster name */
|
/* adjective positioning depends upon format of monster name */
|
||||||
if (possessive) /* Medusa's cursed partly eaten corpse */
|
if (possessive) /* Medusa's cursed partly eaten corpse */
|
||||||
Sprintf(eos(nambuf), "%s %s", mnam, adjective);
|
Sprintf(eos(nambuf), "%s %s%s", mnam, gndr, adjective);
|
||||||
else /* cursed partly eaten troll corpse */
|
else /* cursed partly eaten troll corpse */
|
||||||
Sprintf(eos(nambuf), "%s %s", adjective, mnam);
|
Sprintf(eos(nambuf), "%s %s%s", adjective, gndr, mnam);
|
||||||
/* in case adjective has a trailing space, squeeze it out */
|
/* in case adjective has a trailing space, squeeze it out */
|
||||||
mungspaces(nambuf);
|
mungspaces(nambuf);
|
||||||
/* doname() might include a count in the adjective argument;
|
/* doname() might include a count in the adjective argument;
|
||||||
|
|||||||
+6
-2
@@ -1041,7 +1041,7 @@ query_objlist(const char *qstr, /* query string */
|
|||||||
unsigned sortflags;
|
unsigned sortflags;
|
||||||
glyph_info tmpglyphinfo = nul_glyphinfo;
|
glyph_info tmpglyphinfo = nul_glyphinfo;
|
||||||
Loot *sortedolist, *srtoli;
|
Loot *sortedolist, *srtoli;
|
||||||
int clr = NO_COLOR;
|
int clr = NO_COLOR, puzzling_count = 0;
|
||||||
|
|
||||||
*pick_list = (menu_item *) 0;
|
*pick_list = (menu_item *) 0;
|
||||||
if (!olist && !engulfer)
|
if (!olist && !engulfer)
|
||||||
@@ -1076,6 +1076,8 @@ query_objlist(const char *qstr, /* query string */
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
puzzling_count = check_for_puzzling_nonmerge(olist);
|
||||||
|
|
||||||
sortflags = (((flags.sortloot == 'f'
|
sortflags = (((flags.sortloot == 'f'
|
||||||
|| (flags.sortloot == 'l' && !(qflags & USE_INVLET)))
|
|| (flags.sortloot == 'l' && !(qflags & USE_INVLET)))
|
||||||
? SORTLOOT_LOOT
|
? SORTLOOT_LOOT
|
||||||
@@ -1134,7 +1136,9 @@ query_objlist(const char *qstr, /* query string */
|
|||||||
(qflags & USE_INVLET) ? curr->invlet
|
(qflags & USE_INVLET) ? curr->invlet
|
||||||
: (first && curr->oclass == COIN_CLASS) ? '$' : 0,
|
: (first && curr->oclass == COIN_CLASS) ? '$' : 0,
|
||||||
def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
|
def_oc_syms[(int) objects[curr->otyp].oc_class].sym,
|
||||||
ATR_NONE, clr, doname_with_price(curr),
|
ATR_NONE, clr,
|
||||||
|
(puzzling_count) ? doname_with_price_and_cgender(curr)
|
||||||
|
: doname_with_price(curr),
|
||||||
MENU_ITEMFLAGS_NONE);
|
MENU_ITEMFLAGS_NONE);
|
||||||
first = FALSE;
|
first = FALSE;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user