Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-10-19 12:30:38 -04:00
8 changed files with 125 additions and 41 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.141 $ $NHDT-Date: 1571363147 2019/10/18 01:45:47 $
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.143 $ $NHDT-Date: 1571448220 2019/10/19 01:23:40 $
This fixes36.3 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -191,6 +191,17 @@ yellow dragons had green breath
partly eaten food in a bones level shop would show a non-zero sale price
while on the floor but not be placed on shop bill if picked up;
sale price should have been "no charge"
when non-empty container is dropped in shop and hero is asked whether to sell,
counting the subset of contents owned by hero vs those owned by shk
could obtain wrong answer because the container had been placed on
the floor but the 'unpaid' and 'no_charge' flags of its contents
hadn't been updated yet, they were still set for when it was carried
in a shop which doesn't care about tools: You drop a <box> containing 1 item.
<Shk> offers you <gold> for your items in your <box>. Sell them?
[plural 'items' and 'them' were including the box along with the one
item in it even though shk was only offering to buy its contents]
grammar correction for "That walking shoes is really a small mimic" when
applying a stethoscope
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository
@@ -348,6 +359,7 @@ status highlighting using percentage rules now supported for experience level
the start of the current Xp level to the start of the next Xp level;
100% isn't possible so used as special case for next_Xp_lvl - 1 Exp_pt
wizard-mode: display effect to show where an unseen wished-for monster landed
for 'O's symset and roguesymset menus, mark current symbol set as preselected
curses: enable latent mouse support
curses: give menus and text windows a minimum size of 5x25 since tiny ones can
sometimes be overlooked when shown over old messages rather than map

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1567213888 2019/08/31 01:11:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.728 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1571436000 2019/10/18 22:00:00 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.730 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1048,7 +1048,8 @@ E int FDECL(count_unpaid, (struct obj *));
E int FDECL(count_buc, (struct obj *, int, boolean (*)(OBJ_P)));
E void FDECL(tally_BUCX, (struct obj *, BOOLEAN_P,
int *, int *, int *, int *, int *));
E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
E long FDECL(count_contents, (struct obj *,
BOOLEAN_P, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P));
E void FDECL(carry_obj_effects, (struct obj *));
E const char *FDECL(currency, (long));
E void FDECL(silly_thing, (const char *, struct obj *));
@@ -1375,6 +1376,7 @@ E struct obj *FDECL(obj_nexto_xy, (struct obj *, int, int, BOOLEAN_P));
E struct obj *FDECL(obj_absorb, (struct obj **, struct obj **));
E struct obj *FDECL(obj_meld, (struct obj **, struct obj **));
E void FDECL(pudding_merge_message, (struct obj *, struct obj *));
E struct obj *FDECL(init_dummyobj, (struct obj *, SHORT_P, long));
/* ### mkroom.c ### */

View File

@@ -377,10 +377,15 @@ register struct obj *obj;
newsym(mtmp->mx, mtmp->my);
} else if (mtmp->mappearance) {
const char *what = "thing";
boolean use_plural = FALSE;
struct obj dummyobj, *odummy;
switch (M_AP_TYPE(mtmp)) {
case M_AP_OBJECT:
what = simple_typename(mtmp->mappearance);
odummy = init_dummyobj(&dummyobj, mtmp->mappearance, 1L);
what = simple_typename(odummy->otyp);
use_plural = (is_boots(odummy) || is_gloves(odummy)
|| odummy->otyp == LENSES);
break;
case M_AP_MONSTER: /* ignore Hallucination here */
what = mons[mtmp->mappearance].mname;
@@ -390,7 +395,9 @@ register struct obj *obj;
break;
}
seemimic(mtmp);
pline("That %s is really %s.", what, mnm);
pline("%s %s %s really %s.",
use_plural ? "Those" : "That", what,
use_plural ? "are" : "is", mnm);
} else if (flags.verbose && !canspotmon(mtmp)) {
There("is %s there.", mnm);
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 invent.c $NHDT-Date: 1570566378 2019/10/08 20:26:18 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.264 $ */
/* NetHack 3.6 invent.c $NHDT-Date: 1571436003 2019/10/18 22:00:03 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.265 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2951,30 +2951,32 @@ int *bcp, *ucp, *ccp, *xcp, *ocp;
/* count everything inside a container, or just shop-owned items inside */
long
count_contents(container, nested, quantity, everything)
count_contents(container, nested, quantity, everything, newdrop)
struct obj *container;
boolean nested, /* include contents of any nested containers */
quantity, /* count all vs count separate stacks */
everything; /* all objects vs only unpaid objects */
everything, /* all objects vs only unpaid objects */
newdrop; /* on floor, but hero-owned items haven't been marked
* no_charge yet and shop-owned items are still marked
* unpaid -- used when asking the player whether to sell */
{
struct obj *otmp, *topc;
boolean shoppy = FALSE;
long count = 0L;
if (!everything) {
if (!everything && !newdrop) {
xchar x, y;
for (topc = container; topc->where == OBJ_CONTAINED;
topc = topc->ocontainer)
continue;
if (topc->where == OBJ_FLOOR) {
xchar x, y;
(void) get_obj_location(topc, &x, &y, CONTAINED_TOO);
if (topc->where == OBJ_FLOOR && get_obj_location(topc, &x, &y, 0))
shoppy = costly_spot(x, y);
}
}
for (otmp = container->cobj; otmp; otmp = otmp->nobj) {
if (nested && Has_contents(otmp))
count += count_contents(otmp, nested, quantity, everything);
count += count_contents(otmp, nested, quantity, everything,
newdrop);
if (everything || otmp->unpaid || (shoppy && !otmp->no_charge))
count += quantity ? otmp->quan : 1L;
}

View File

@@ -2470,6 +2470,38 @@ struct monst *mon;
}
}
/*
* Initialize a dummy obj with just enough info
* to allow some of the tests in obj.h that
* take an obj pointer to work.
*
*/
struct obj *
init_dummyobj(obj, otyp, oquan)
struct obj *obj;
short otyp;
long oquan;
{
if (obj) {
*obj = cg.zeroobj;
obj->otyp = otyp;
obj->oclass = objects[otyp].oc_class;
/* obj->dknown = 0; */
/* suppress known except for amulets (needed for fakes and real A-of-Y) */
obj->known = (obj->oclass == AMULET_CLASS)
? obj->known
/* default is "on" for types which don't use it */
: !objects[otyp].oc_uses_known;
obj->quan = oquan ? oquan : 1L;
obj->corpsenm = NON_PM; /* suppress statue and figurine details */
/* but suppressing fruit details leads to "bad fruit #0"
[perhaps we should force "slime mold" rather than use xname?] */
if (obj->otyp == SLIME_MOLD)
obj->spe = 1;
}
return obj;
}
/* obj sanity check: check objects inside container */
static void
check_contained(container, mesg)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 objnam.c $NHDT-Date: 1562186589 2019/07/03 20:43:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.245 $ */
/* NetHack 3.6 objnam.c $NHDT-Date: 1571436005 2019/10/18 22:00:05 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.247 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1041,7 +1041,7 @@ unsigned doname_flags;
/* we count the number of separate stacks, which corresponds
to the number of inventory slots needed to be able to take
everything out if no merges occur */
long itemcount = count_contents(obj, FALSE, FALSE, TRUE);
long itemcount = count_contents(obj, FALSE, FALSE, TRUE, FALSE);
Sprintf(eos(bp), " containing %ld item%s", itemcount,
plur(itemcount));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1571347977 2019/10/17 21:32:57 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.379 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1571448220 2019/10/19 01:23:40 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.380 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -761,9 +761,9 @@ initoptions_init()
*/
/* this detects the IBM-compatible console on most 386 boxes */
if ((opts = nh_getenv("TERM")) && !strncmp(opts, "AT", 2)) {
if (!g.symset[PRIMARY].name)
if (!g.symset[PRIMARY].explicitly)
load_symset("IBMGraphics", PRIMARY);
if (!g.symset[ROGUESET].name)
if (!g.symset[ROGUESET].explicitly)
load_symset("RogueIBM", ROGUESET);
switch_symbols(TRUE);
#ifdef TEXTCOLOR
@@ -778,7 +778,7 @@ initoptions_init()
/* [could also check "xterm" which emulates vtXXX by default] */
&& !strncmpi(opts, "vt", 2)
&& AS && AE && index(AS, '\016') && index(AE, '\017')) {
if (!g.symset[PRIMARY].name)
if (!g.symset[PRIMARY].explicitly)
load_symset("DECGraphics", PRIMARY);
switch_symbols(TRUE);
}
@@ -787,15 +787,13 @@ initoptions_init()
#if defined(MSDOS) || defined(WIN32)
/* Use IBM defaults. Can be overridden via config file */
if (!g.symset[PRIMARY].name) {
if (!g.symset[PRIMARY].explicitly)
load_symset("IBMGraphics_2", PRIMARY);
}
if (!g.symset[ROGUESET].name) {
if (!g.symset[ROGUESET].explicitly)
load_symset("RogueEpyx", ROGUESET);
}
#endif
#ifdef MAC_GRAPHICS_ENV
if (!symset[PRIMARY].name)
if (!g.symset[PRIMARY].explicitly)
load_symset("MACGraphics", PRIMARY);
switch_symbols(TRUE);
#endif /* MAC_GRAPHICS_ENV */
@@ -5303,7 +5301,7 @@ boolean setinitial, setfromfile;
nothing_to_do = FALSE;
char *symset_name, fmtstr[20];
struct symsetentry *sl;
int res, which_set, setcount = 0, chosen = -2;
int res, which_set, setcount = 0, chosen = -2, defindx = 0;
which_set = rogueflag ? ROGUESET : PRIMARY;
g.symset_list = (struct symsetentry *) 0;
@@ -5386,9 +5384,13 @@ boolean setinitial, setfromfile;
#else
nhUse(big_desc);
#endif
any.a_int = 1;
any.a_int = 1; /* -1 + 2 [see 'if (sl->name) {' below]*/
if (!symset_name)
defindx = any.a_int;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
"Default Symbols", MENU_UNSELECTED);
"Default Symbols",
(any.a_int == defindx) ? MENU_SELECTED
: MENU_UNSELECTED);
for (sl = g.symset_list; sl; sl = sl->next) {
/* check restrictions */
@@ -5398,20 +5400,34 @@ boolean setinitial, setfromfile;
if (sl->handling == H_MAC)
continue;
#endif
if (sl->name) {
/* +2: sl->idx runs from 0 to N-1 for N symsets;
+1 because Defaults are implicitly in slot [0];
+1 again so that valid data is never 0 */
any.a_int = sl->idx + 2;
if (symset_name && !strcmpi(sl->name, symset_name))
defindx = any.a_int;
Sprintf(buf, fmtstr, sl->name, sl->desc ? sl->desc : "");
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
buf, MENU_UNSELECTED);
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf,
(any.a_int == defindx) ? MENU_SELECTED
: MENU_UNSELECTED);
}
}
Sprintf(buf, "Select %ssymbol set:",
rogueflag ? "rogue level " : "");
end_menu(tmpwin, buf);
if (select_menu(tmpwin, PICK_ONE, &symset_pick) > 0) {
chosen = symset_pick->item.a_int - 2;
n = select_menu(tmpwin, PICK_ONE, &symset_pick);
if (n > 0) {
chosen = symset_pick[0].item.a_int;
/* if picking non-preselected entry yields 2, make sure
that we're going with the non-preselected one */
if (n == 2 && chosen == defindx)
chosen = symset_pick[1].item.a_int;
chosen -= 2; /* convert menu index to symset index;
* "Default symbols" have index -1 */
free((genericptr_t) symset_pick);
} else if (n == 0 && defindx > 0) {
chosen = defindx - 2;
}
destroy_nhwindow(tmpwin);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 shk.c $NHDT-Date: 1571363715 2019/10/18 01:55:15 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.170 $ */
/* NetHack 3.6 shk.c $NHDT-Date: 1571436007 2019/10/18 22:00:07 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.171 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -2898,8 +2898,8 @@ boolean peaceful, silent;
/* gather information for message(s) prior to manipulating bill */
was_unpaid = obj->unpaid ? TRUE : FALSE;
if (Has_contents(obj)) {
c_count = count_contents(obj, TRUE, FALSE, TRUE);
u_count = count_contents(obj, TRUE, FALSE, FALSE);
c_count = count_contents(obj, TRUE, FALSE, TRUE, FALSE);
u_count = count_contents(obj, TRUE, FALSE, FALSE, FALSE);
}
if (!billable(&shkp, obj, roomno, FALSE)) {
@@ -3196,9 +3196,9 @@ xchar x, y;
if (container) {
/* number of items owned by shk */
shksc = count_contents(obj, TRUE, TRUE, FALSE);
shksc = count_contents(obj, TRUE, TRUE, FALSE, TRUE);
/* number of items owned by you (total - shksc) */
yourc = count_contents(obj, TRUE, TRUE, TRUE) - shksc;
yourc = count_contents(obj, TRUE, TRUE, TRUE, TRUE) - shksc;
only_partially_your_contents = shksc && yourc;
}
/*
@@ -3214,14 +3214,27 @@ xchar x, y;
(The case where it has contents already entirely owned
by the shk is treated the same was if it were empty
since the hero isn't selling any of those contents.)
Your container:
Your container and shk is willing to buy it:
"... your <empty bag>. Sell it?"
"... your <bag> and its contents. Sell them?"
"... your <bag> and item inside. Sell them?"
"... your <bag> and items inside. Sell them?"
Your container but shk only cares about the contents:
"... your item in your <bag>. Sell it?"
"... your items in your <bag>. Sell them?"
Shk's container:
"... your item in the <bag>. Sell it?"
"... your items in the <bag>. Sell them?"
FIXME:
"your items" should sometimes be "some of your items"
(when container has some stuff the shk is willing to buy
and other stuff he or she doesn't care about); likewise,
"your item" should sometimes be "one of your items".
That would make the prompting even more verbose so
living without it might be a good thing.
FIXME too:
when container's contents are unknown, plural "items"
should be used to not give away information.
*/
Sprintf(qbuf, "%s offers%s %ld gold piece%s for %s%s ",
Shknam(shkp), short_funds ? " only" : "", offer,
@@ -3230,7 +3243,7 @@ xchar x, y;
? ((yourc == 1L) ? "your item in " : "your items in ")
: "",
obj->unpaid ? "the" : "your");
one = obj->unpaid ? (yourc == 1L) : (obj->quan == 1L && !cltmp);
one = !ltmp ? (yourc == 1L) : (obj->quan == 1L && !cltmp);
Sprintf(qsfx, "%s. Sell %s?",
(cltmp && ltmp)
? (only_partially_your_contents