-/* NetHack 3.6 invent.c $NHDT-Date: 1555196229 2019/04/13 22:57:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.253 $ */
+/* NetHack 3.6 invent.c $NHDT-Date: 1575245062 2019/12/02 00:04:22 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.267 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
/* JNetHack Copyright */
/* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
-/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */
+/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2021 */
/* JNetHack may be freely redistributed. See license for details. */
#include "hack.h"
case DRUM_OF_EARTHQUAKE:
case HORN_OF_PLENTY: /* not a musical instrument */
k = 3; /* instrument or unknown horn of plenty */
+ break;
default:
k = 4; /* 'other' tool */
+ break;
}
break;
case FOOD_CLASS:
* (fragile) or by avoiding sortloot() during inventory display
* (more robust).
*
- * 3.6.2 reverts to the temporary array of ordered obj pointers
- * but has sortloot() do the counting and allocation. Callers
+ * As of 3.6.2: revert to the temporary array of ordered obj pointers
+ * but have sortloot() do the counting and allocation. Callers
* need to use array traversal instead of linked list traversal
* and need to free the temporary array when done. And the
* array contains 'struct sortloot_item' (aka 'Loot') entries
otmp->age = ((otmp->age * otmp->quan) + (obj->age * obj->quan))
/ (otmp->quan + obj->quan);
- otmp->quan += obj->quan;
+ if (!otmp->globby)
+ otmp->quan += obj->quan;
/* temporary special case for gold objects!!!! */
if (otmp->oclass == COIN_CLASS)
otmp->owt = weight(otmp), otmp->bknown = 0;
menuquery[0] = qbuf[0] = '\0';
if (iflags.force_invmenu)
+/*JP
Sprintf(menuquery, "What do you want to %s?", word);
+*/
+ Sprintf(menuquery, "%s%s%s\82©\81H", what, joshi, jpolite(jword));
if (!strcmp(word, "grease"))
- Sprintf(qbuf, "your %s", makeplural(body_part(FINGER)));
+/*JP
+ Sprintf(qbuf, "your %s", fingers_or_gloves(FALSE));
+*/
+ Sprintf(qbuf, "\82 \82È\82½\82Ì%s", fingers_or_gloves(FALSE));
else if (!strcmp(word, "write with"))
+/*JP
Sprintf(qbuf, "your %s", body_part(FINGERTIP));
+*/
+ Sprintf(qbuf, "\82 \82È\82½\82Ì%s", body_part(FINGERTIP));
else if (!strcmp(word, "wield"))
+#if 0 /*JP:T*/
Sprintf(qbuf, "your %s %s%s", uarmg ? "gloved" : "bare",
makeplural(body_part(HAND)),
!uwep ? " (wielded)" : "");
+#else
+ Sprintf(qbuf, "\89½\82à\8eè\82É\82µ\82È\82¢%s",
+ !uwep ? "(\8c»\8dÝ)" : "");
+#endif
else if (!strcmp(word, "ready"))
+#if 0 /*JP*/
Sprintf(qbuf, "empty quiver%s",
!uquiver ? " (nothing readied)" : "");
+#else
+ Sprintf(qbuf, "\8bó\82Ì\96î\93\9b%s",
+ !uquiver ? " (\89½\82à\8f\80\94õ\82µ\82Ä\82¢\82È\82¢)" : "");
+#endif
if (ilet == '?' && !*lets && *altlets)
allowed_choices = altlets;
/*JP
You("don't have that many! You have only %ld.", otmp->quan);
*/
- pline("\82»\82ñ\82È\82É\82½\82\82³\82ñ\82Í\8e\9d\82Á\82Ä\82¢\82È\82¢\81I\82¹\82¢\82º\82¢%ld\8cÂ\82Á\82Ä\82Æ\82±\82¾\81D", otmp->quan);
+ pline("\82»\82ñ\82È\82É\82½\82\82³\82ñ\82Í\8e\9d\82Á\82Ä\82¢\82È\82¢\81I\82¹\82¢\82º\82¢%ld%s\82Á\82Ä\82Æ\82±\82¾\81D", otmp->quan, numeral(otmp));
if (in_doagain)
return (struct obj *) 0;
continue;
is_worn(otmp)
struct obj *otmp;
{
- return (otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE | W_WEAPON))
+ return (otmp->owornmask & (W_ARMOR | W_ACCESSORY | W_SADDLE | W_WEAPONS))
? TRUE
: FALSE;
}
update_inventory();
}
+/* persistent inventory window is maintained by interface code;
+ 'update_inventory' used to be a macro for
+ (*windowprocs.win_update_inventory) but the restore hackery
+ was getting out of hand; this is now a central call point */
+void
+update_inventory()
+{
+ if (restoring)
+ return;
+
+ /*
+ * Ought to check (windowprocs.wincap2 & WC2_PERM_INVENT) here....
+ *
+ * We currently don't skip this call when iflags.perm_invent is False
+ * because curses uses that to disable a previous perm_invent window
+ * (after toggle via 'O'; perhaps the options code should handle that).
+ */
+ (*windowprocs.win_update_inventory)();
+}
+
/* should of course only be called for things in invent */
STATIC_OVL char
obj_to_let(obj)
menu_item *selected;
unsigned sortflags;
Loot *sortedinvent, *srtinv;
- boolean wizid = FALSE;
+ boolean wizid = (wizard && iflags.override_ID), gotsomething = FALSE;
if (lets && !*lets)
lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */
- if (iflags.perm_invent && (lets || xtra_choice)) {
+ if (iflags.perm_invent && (lets || xtra_choice || wizid)) {
/* partial inventory in perm_invent setting; don't operate on
full inventory window, use an alternate one instead; create
the first time needed and keep it for re-use as needed later */
add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
"(all items are permanently identified already)",
MENU_UNSELECTED);
+ gotsomething = TRUE;
} else {
any.a_obj = &wizid_fakeobj;
Sprintf(prompt, "select %s to permanently identify",
/* wiz_identify stuffed the wiz_identify command character (^I)
into iflags.override_ID for our use as an accelerator;
it could be ambiguous if player has assigned a letter to
- the #wizidentify command */
+ the #wizidentify command, so include it as a group accelator
+ but use '_' as the primary selector */
if (unid_cnt > 1)
Sprintf(eos(prompt), " (%s for all)",
visctrl(iflags.override_ID));
add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE,
prompt, MENU_UNSELECTED);
- wizid = TRUE;
+ gotsomething = TRUE;
}
} else if (xtra_choice) {
/* wizard override ID and xtra_choice are mutually exclusive */
any.a_char = HANDS_SYM; /* '-' */
add_menu(win, NO_GLYPH, &any, HANDS_SYM, 0, ATR_NONE,
xtra_choice, MENU_UNSELECTED);
+ gotsomething = TRUE;
}
nextclass:
classcount = 0;
add_menu(win, obj_to_glyph(otmp, rn2_on_display_rng), &any, ilet,
wizid ? def_oc_syms[(int) otmp->oclass].sym : 0,
ATR_NONE, doname(otmp), MENU_UNSELECTED);
+ gotsomething = TRUE;
}
}
if (flags.sortpack) {
add_menu(win, NO_GLYPH, &any, '*', 0, ATR_NONE,
"(\91S\82Ä\82Ì\88ê\97\97)", MENU_UNSELECTED);
#endif
+ gotsomething = TRUE;
}
unsortloot(&sortedinvent);
/* for permanent inventory where we intend to show everything but
nothing has been listed (because there isn't anyhing to list;
- recognized via any.a_char still being zero; the n==0 case above
- gets skipped for perm_invent), put something into the menu */
- if (iflags.perm_invent && !lets && !any.a_char) {
+ the n==0 case above gets skipped for perm_invent), put something
+ into the menu */
+ if (iflags.perm_invent && !lets && !gotsomething) {
any = zeroany;
add_menu(win, NO_GLYPH, &any, 0, 0, 0,
not_carrying_anything, MENU_UNSELECTED);
if (wizid) {
int i;
+ /* identifying items will update perm_invent, calling this
+ routine recursively, and we don't want the nested call
+ to filter on unID'd items */
+ iflags.override_ID = 0;
ret = '\0';
for (i = 0; i < n; ++i) {
otmp = selected[i].item.a_obj;
/* 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;
}
if (u.uswallow && u.ustuck) {
struct monst *mtmp = u.ustuck;
+ /*
+ * FIXME?
+ * Engulfer's inventory can include worn items (specific case is
+ * Juiblex being created with an amulet as random defensive item)
+ * which will be flagged as "(being worn)". This code includes
+ * such a worn item under the header "Contents of <mon>'s stomach",
+ * a nifty trick for how/where to wear stuff. The situation is
+ * rare enough to turn a blind eye.
+ *
+ * 3.6.3: Pickup has been changed to decline to pick up a worn
+ * item from inside an engulfer, but if player tries, it just
+ * says "you can't" without giving a reason why (which would be
+ * something along the lines of "because it's worn on the outside
+ * so is unreachable from in here...").
+ */
#if 0 /*JP:T*/
Sprintf(fbuf, "Contents of %s %s", s_suffix(mon_nam(mtmp)),
mbodypart(mtmp, STOMACH));
if (obj->oclass == COIN_CLASS)
return TRUE;
- if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe
- || obj->cursed != otmp->cursed || obj->blessed != otmp->blessed
- || obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken
- || obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit
- || obj->bypass != otmp->bypass)
+ if (obj->bypass != otmp->bypass
+ || obj->cursed != otmp->cursed || obj->blessed != otmp->blessed)
return FALSE;
if (obj->globby)
* or don't inhibit their merger.
*/
+ if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe
+ || obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken
+ || obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit)
+ return FALSE;
+
if (obj->oclass == FOOD_CLASS
&& (obj->oeaten != otmp->oeaten || obj->orotten != otmp->orotten))
return FALSE;
const char *adj_type;
boolean ever_mind = FALSE, collect;
- if (!invent) {
-/*JP
- You("aren't carrying anything to adjust.");
-*/
+ /* when no invent, or just gold in '$' slot, there's nothing to adjust */
+ if (!invent || (invent->oclass == COIN_CLASS
+ && invent->invlet == GOLD_SYM && !invent->nobj)) {
+#if 0 /*JP:T*/
+ You("aren't carrying anything %s.",
+ !invent ? "to adjust" : "adjustable");
+#else
You("\8f\87\8f\98\82ð\95Ï\82¦\82é\82à\82Ì\82ð\89½\82à\8e\9d\82Á\82Ä\82¢\82È\82¢\81D");
+#endif
return 0;
}