diff --git a/include/extern.h b/include/extern.h index 8d6fda3d29..7e5195cc8a 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1446336781 2015/11/01 00:13:01 $ $NHDT-Branch: master $:$NHDT-Revision: 1.511 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1446516834 2015/11/03 02:13:54 $ $NHDT-Branch: master $:$NHDT-Revision: 1.513 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -910,8 +910,8 @@ E boolean NDECL(wearing_armor); E boolean FDECL(is_worn, (struct obj *)); E struct obj *FDECL(g_at, (int, int)); E struct obj *FDECL(getobj, (const char *, const char *)); -E int FDECL(ggetobj, - (const char *, int (*)(OBJ_P), int, BOOLEAN_P, unsigned *)); +E int FDECL(ggetobj, (const char *, int (*)(OBJ_P), int, + BOOLEAN_P, unsigned *)); E int FDECL(askchain, (struct obj **, const char *, int, int (*)(OBJ_P), int (*)(OBJ_P), int, const char *)); E void FDECL(fully_identify_obj, (struct obj *)); @@ -945,6 +945,7 @@ E char *FDECL(let_to_name, (CHAR_P, BOOLEAN_P, BOOLEAN_P)); E void NDECL(free_invbuf); E void NDECL(reassign); E int NDECL(doorganize); +E void NDECL(free_pickinv_cache); E int FDECL(count_unpaid, (struct obj *)); E int FDECL(count_buc, (struct obj *, int)); E long FDECL(count_contents, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); diff --git a/src/end.c b/src/end.c index 0500bc4d87..c8560b2177 100644 --- a/src/end.c +++ b/src/end.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 end.c $NHDT-Date: 1434408399 2015/06/15 22:46:39 $ $NHDT-Branch: master $:$NHDT-Revision: 1.100 $ */ +/* NetHack 3.6 end.c $NHDT-Date: 1446510332 2015/11/03 00:25:32 $ $NHDT-Branch: master $:$NHDT-Revision: 1.102 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -214,7 +214,7 @@ NH_panictrace_libc() for (x = 0; x < count; x++) { raw_printf("[%lu] %s", (unsigned long) x, info[x]); } - /* free(info); Don't risk it. */ + /* free(info); -- Don't risk it. */ return TRUE; #else return FALSE; @@ -273,22 +273,23 @@ NH_panictrace_gdb() /* * The order of these needs to match the macros in hack.h. */ -static NEARDATA const char *deaths[] = - { /* the array of death */ - "died", "choked", "poisoned", "starvation", "drowning", "burning", - "dissolving under the heat and pressure", "crushed", "turned to stone", - "turned into slime", "genocided", "panic", "trickery", "quit", - "escaped", "ascended" - }; - -static NEARDATA const char *ends[] = { /* "when you..." */ - "died", "choked", "were poisoned", - "starved", "drowned", "burned", - "dissolved in the lava", - "were crushed", "turned to stone", - "turned into slime", "were genocided", - "panicked", "were tricked", "quit", - "escaped", "ascended" +static NEARDATA const char *deaths[] = { + /* the array of death */ + "died", "choked", "poisoned", "starvation", "drowning", "burning", + "dissolving under the heat and pressure", "crushed", "turned to stone", + "turned into slime", "genocided", "panic", "trickery", "quit", + "escaped", "ascended" +}; + +static NEARDATA const char *ends[] = { + /* "when you %s" */ + "died", "choked", "were poisoned", + "starved", "drowned", "burned", + "dissolved in the lava", + "were crushed", "turned to stone", + "turned into slime", "were genocided", + "panicked", "were tricked", "quit", + "escaped", "ascended" }; static boolean Schroedingers_cat = FALSE; @@ -366,8 +367,8 @@ done2() #ifndef NO_SIGNAL /*ARGSUSED*/ -STATIC_PTR void done_intr( - sig_unused) /* called as signal() handler, so sent at least one arg */ +STATIC_PTR void +done_intr(sig_unused) /* called as signal() handler, so sent at least 1 arg */ int sig_unused UNUSED; { done_stopprint++; @@ -396,10 +397,11 @@ struct monst *mtmp; int how; { char buf[BUFSZ]; - struct permonst *mptr = mtmp->data, *champtr = (mtmp->cham >= LOW_PM) - ? &mons[mtmp->cham] - : mptr; - boolean distorted = (boolean)(Hallucination && canspotmon(mtmp)), + struct permonst *mptr = mtmp->data, + *champtr = ((mtmp->cham >= LOW_PM) + ? &mons[mtmp->cham] + : mptr); + boolean distorted = (boolean) (Hallucination && canspotmon(mtmp)), mimicker = (mtmp->m_ap_type == M_AP_MONSTER), imitator = (mptr != champtr || mimicker); @@ -452,8 +454,9 @@ int how; Strcpy(shape, an(fakenm)); /* omit "called" to avoid excessive verbosity */ Sprintf(eos(buf), - alt ? "%s in %s form" : mimicker ? "%s disguised as %s" - : "%s imitating %s", + alt ? "%s in %s form" + : mimicker ? "%s disguised as %s" + : "%s imitating %s", realnm, shape); mptr = mtmp->data; /* reset for mimicker case */ } else if (mptr == &mons[PM_GHOST]) { @@ -462,9 +465,8 @@ int how; Sprintf(eos(buf), " of %s", MNAME(mtmp)); } else if (mtmp->isshk) { const char *shknm = shkname(mtmp), - *honorific = shkname_is_pname(mtmp) ? "" : mtmp->female - ? "Ms. " - : "Mr. "; + *honorific = shkname_is_pname(mtmp) ? "" + : mtmp->female ? "Ms. " : "Mr. "; Sprintf(eos(buf), "%s%s, the shopkeeper", honorific, shknm); killer.format = KILLED_BY; @@ -925,7 +927,7 @@ int how; } /* - * The game is now over... + * The game is now over... */ die: @@ -1092,6 +1094,8 @@ int how; /* clean up unneeded windows */ if (have_windows) { wait_synch(); + if (WIN_INVEN != WIN_ERR) + destroy_nhwindow(WIN_INVEN), WIN_INVEN = WIN_ERR; display_nhwindow(WIN_MESSAGE, TRUE); destroy_nhwindow(WIN_MAP), WIN_MAP = WIN_ERR; #ifndef STATUS_VIA_WINDOWPORT @@ -1130,8 +1134,8 @@ int how; } if (how == ESCAPED || how == ASCENDED) { - register struct monst *mtmp; - register struct obj *otmp; + struct monst *mtmp; + struct obj *otmp; register struct val_list *val; register int i; diff --git a/src/invent.c b/src/invent.c index 79f8e921ac..5309d3b8d1 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 invent.c $NHDT-Date: 1445388918 2015/10/21 00:55:18 $ $NHDT-Branch: master $:$NHDT-Revision: 1.175 $ */ +/* NetHack 3.6 invent.c $NHDT-Date: 1446516832 2015/11/03 02:13:52 $ $NHDT-Branch: master $:$NHDT-Revision: 1.178 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -7,7 +7,7 @@ #define NOINVSYM '#' #define CONTAINED_SYM '>' /* designator for inside a container */ -STATIC_DCL int FDECL(sortloot_cmp, (struct obj *, struct obj *)); +STATIC_DCL int FDECL(CFDECLSPEC sortloot_cmp, (struct obj *, struct obj *)); STATIC_DCL void NDECL(reorder_invent); STATIC_DCL boolean FDECL(mergable, (struct obj *, struct obj *)); STATIC_DCL void FDECL(noarmor, (BOOLEAN_P)); @@ -40,11 +40,13 @@ static int lastinvnr = 51; /* 0 ... 51 (never saved&restored) */ * suddenly become a choice for all the inventory-class commands, which * would probably cause mass confusion. the test for inventory venom * is only WIZARD and not wizard because the wizard can leave venom lying - * around on a bones level for normal players to find. + * around on a bones level for normal players to find. [Note to the + * confused: 'WIZARD' used to be a compile-time conditional so this was + * guarded by #ifdef WIZARD/.../#endif.] */ static char venom_inv[] = { VENOM_CLASS, 0 }; /* (constant) */ -int +STATIC_OVL int CFDECLSPEC sortloot_cmp(obj1, obj2) struct obj *obj1; struct obj *obj2; @@ -104,7 +106,9 @@ struct obj *obj2; return val2 - val1; /* Because bigger is better. */ } - return 0; /* They're identical, as far as we're concerned. */ + /* They're identical, as far as we're concerned, + but we want to force a determistic order between them. */ + return (obj1->o_id > obj2->o_id) ? 1 : -1; } struct obj ** @@ -316,18 +320,17 @@ struct obj **potmp, **pobj; setnotworn(otmp); setworn(otmp, wmask); setnotworn(obj); - } #if 0 /* (this should not be necessary, since items already in a monster's inventory don't ever get merged into other objects [only vice versa]) */ - else if (obj->owornmask && mcarried(otmp)) { + } else if (obj->owornmask && mcarried(otmp)) { if (obj == MON_WEP(otmp->ocarry)) { - MON_WEP(otmp->ocarry) = otmp; - otmp->owornmask = W_WEP; + MON_WEP(otmp->ocarry) = otmp; + otmp->owornmask = W_WEP; } - } #endif /*0*/ + } /* handle puddings a bit differently; absorption will * free the other object automatically so we can just @@ -335,11 +338,11 @@ struct obj **potmp, **pobj; if (Is_pudding(obj)) { pudding_merge_message(otmp, obj); obj_absorb(potmp, pobj); - return (1); + return 1; } obfree(obj, otmp); /* free(obj), bill->otmp */ - return (1); + return 1; } return 0; } @@ -477,7 +480,7 @@ struct obj *obj; addinv_core2(obj); carry_obj_effects(obj); /* carrying affects the obj */ update_inventory(); - return (obj); + return obj; } /* @@ -595,8 +598,8 @@ void useup(obj) register struct obj *obj; { - /* Note: This works correctly for containers because they */ - /* (containers) don't merge. */ + /* Note: This works correctly for containers because they (containers) + don't merge. */ if (obj->quan > 1L) { obj->in_use = FALSE; /* no longer in use */ obj->quan--; @@ -763,12 +766,13 @@ register int type; for (otmp = invent; otmp; otmp = otmp->nobj) if (otmp->otyp == type) - return (otmp); - return ((struct obj *) 0); + return otmp; + return (struct obj *) 0; } -/** Fictional and not-so-fictional currencies. - * http://concord.wikia.com/wiki/List_of_Fictional_Currencies */ +/* Fictional and not-so-fictional currencies. + * http://concord.wikia.com/wiki/List_of_Fictional_Currencies + */ static const char *const currencies[] = { "Altarian Dollar", /* The Hitchhiker's Guide to the Galaxy */ "Ankh-Morpork Dollar", /* Discworld */ @@ -812,8 +816,8 @@ have_lizard() for (otmp = invent; otmp; otmp = otmp->nobj) if (otmp->otyp == CORPSE && otmp->corpsenm == PM_LIZARD) - return (TRUE); - return (FALSE); + return TRUE; + return FALSE; } /* 3.6.0 tribute */ @@ -825,7 +829,7 @@ u_have_novel() for (otmp = invent; otmp; otmp = otmp->nobj) if (otmp->otyp == SPE_NOVEL) return otmp; - return (struct obj *)0; + return (struct obj *) 0; } struct obj * @@ -837,12 +841,12 @@ register struct obj *objchn; while (objchn) { if (objchn->o_id == id) - return (objchn); + return objchn; if (Has_contents(objchn) && (temp = o_on(id, objchn->cobj))) return temp; objchn = objchn->nobj; } - return ((struct obj *) 0); + return (struct obj *) 0; } boolean @@ -854,8 +858,8 @@ int x, y; for (otmp = level.objects[x][y]; otmp; otmp = otmp->nexthere) if (obj == otmp) - return (TRUE); - return (FALSE); + return TRUE; + return FALSE; } struct obj * @@ -863,12 +867,13 @@ g_at(x, y) register int x, y; { register struct obj *obj = level.objects[x][y]; + while (obj) { if (obj->oclass == COIN_CLASS) return obj; obj = obj->nexthere; } - return ((struct obj *) 0); + return (struct obj *) 0; } /* compact a string of inventory letters by dashing runs of letters */ @@ -936,9 +941,9 @@ const char *action; /* * getobj returns: - * struct obj *xxx: object to do something with. - * (struct obj *) 0 error return: no object. - * &zeroobj explicitly no object (as in w-). + * struct obj *xxx: object to do something with. + * (struct obj *) 0 error return: no object. + * &zeroobj explicitly no object (as in w-). !!!! test if gold can be used in unusual ways (eaten etc.) !!!! may be able to remove "usegold" */ @@ -1147,7 +1152,7 @@ register const char *let, *word; if (!foo && !allowall && !allownone) { You("don't have anything %sto %s.", foox ? "else " : "", word); - return ((struct obj *) 0); + return (struct obj *) 0; } for (;;) { cnt = 0; @@ -1189,18 +1194,19 @@ register const char *let, *word; if (index(quitchars, ilet)) { if (flags.verbose) pline1(Never_mind); - return ((struct obj *) 0); + return (struct obj *) 0; } if (ilet == '-') { if (!allownone) { - char *suf = NULL; + char *suf = (char *) 0; + strcpy(buf, word); - if ((bp = strstr(buf, " on the ")) - != NULL) { /* rub on the stone[s] */ + if ((bp = strstr(buf, " on the ")) != 0) { + /* rub on the stone[s] */ *bp = '\0'; suf = (bp + 1); } - if ((bp = strstr(buf, " or ")) != NULL) { + if ((bp = strstr(buf, " or ")) != 0) { *bp = '\0'; bp = (rn2(2) ? buf : (bp + 4)); } else @@ -1283,12 +1289,12 @@ register const char *let, *word; if (!otmp) { You("don't have that object."); if (in_doagain) - return ((struct obj *) 0); + return (struct obj *) 0; continue; } else if (cnt < 0 || otmp->quan < cnt) { You("don't have that many! You have only %ld.", otmp->quan); if (in_doagain) - return ((struct obj *) 0); + return (struct obj *) 0; continue; } break; @@ -1296,7 +1302,7 @@ register const char *let, *word; if (!allowall && let && !index(let, otmp->oclass) && !(usegold && otmp->oclass == COIN_CLASS)) { silly_thing(word, otmp); - return ((struct obj *) 0); + return (struct obj *) 0; } if (allowcnt == 2) { /* cnt given */ if (cnt == 0) @@ -1310,7 +1316,7 @@ register const char *let, *word; otmp->corpsenm = (int) cnt; } } - return (otmp); + return otmp; } void @@ -1354,15 +1360,15 @@ struct obj *otmp; STATIC_PTR int ckvalidcat(otmp) -register struct obj *otmp; +struct obj *otmp; { /* use allow_category() from pickup.c */ - return ((int) allow_category(otmp)); + return (int) allow_category(otmp); } STATIC_PTR int ckunpaid(otmp) -register struct obj *otmp; +struct obj *otmp; { return (otmp->unpaid || (Has_contents(otmp) && count_unpaid(otmp->cobj))); } @@ -1435,7 +1441,7 @@ unsigned *resultflags; takeoff = ident = allflag = m_seen = FALSE; if (!invent) { You("have nothing to %s.", word); - return (0); + return 0; } add_valid_menu_class(0); /* reset */ if (taking_off(word)) { @@ -1478,7 +1484,7 @@ unsigned *resultflags; ilets); getlin(qbuf, buf); if (buf[0] == '\033') - return (0); + return 0; if (index(buf, 'i')) { if (display_inventory((char *) 0, TRUE) == '\033') return 0; @@ -1563,14 +1569,16 @@ unsigned *resultflags; } } - if (m_seen) + if (m_seen) { return (allflag || (!oletct && ckfn != ckunpaid)) ? -2 : -3; - else if (flags.menu_style != MENU_TRADITIONAL && combo && !allflag) + } else if (flags.menu_style != MENU_TRADITIONAL && combo && !allflag) { return 0; - else /*!!!! if (allowgold == 2 && !oletct) - !!!! return 1; you dropped gold (or at least tried to) - !!!! test gold dropping - else*/ { +#if 0 + /* !!!! test gold dropping */ + } else if (allowgold == 2 && !oletct) { + return 1; /* you dropped gold (or at least tried to) */ +#endif + } else { int cnt = askchain(&invent, olets, allflag, fn, ckfn, mx, word); /* * askchain() has already finished the job in this case @@ -1625,10 +1633,10 @@ register int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P)); * (dropping a burning potion of oil while levitating creates * an explosion which can destroy inventory items), so simple * list traversal - * for (otmp = *objchn; otmp; otmp = otmp2) { - * otmp2 = otmp->nobj; - * ... - * } + * for (otmp = *objchn; otmp; otmp = otmp2) { + * otmp2 = otmp->nobj; + * ... + * } * is inadequate here. Use each object's bypass bit to keep * track of which list elements have already been processed. */ @@ -1721,11 +1729,11 @@ register int FDECL((*fn), (OBJ_P)), FDECL((*ckfn), (OBJ_P)); pline("No applicable objects."); ret: bypass_objlist(*objchn, FALSE); - return (cnt); + return cnt; } /* - * Object identification routines: + * Object identification routines: */ /* make an object actually be identified; no display updating */ @@ -1860,9 +1868,10 @@ learn_unseen_invent() update_inventory(); } +/* should of course only be called for things in invent */ STATIC_OVL char -obj_to_let(obj) /* should of course only be called for things in invent */ -register struct obj *obj; +obj_to_let(obj) +struct obj *obj; { if (!flags.invlet_constant) { obj->invlet = NOINVSYM; @@ -1878,7 +1887,7 @@ register struct obj *obj; void prinv(prefix, obj, quan) const char *prefix; -register struct obj *obj; +struct obj *obj; long quan; { if (!prefix) @@ -1911,8 +1920,8 @@ long quan; /* if non-0, print this quantity, not obj->quan */ /* * If let is: - * * Then obj == null and we are printing a total amount. - * > Then the object is contained and doesn't have an inventory letter. + * * Then obj == null and we are printing a total amount. + * > Then the object is contained and doesn't have an inventory letter. */ if (cost != 0 || let == '*') { /* if dot is true, we're doing Iu, otherwise Ix */ @@ -1960,7 +1969,7 @@ struct obj *list, **last_found; if (list == *last_found) *last_found = (struct obj *) 0; } else - return (*last_found = list); + return ((*last_found = list)); } if (Has_contents(list)) { if ((obj = find_unpaid(list->cobj, last_found)) != 0) @@ -1971,6 +1980,22 @@ struct obj *list, **last_found; return (struct obj *) 0; } +/* for perm_invent when operating on a partial inventory display, so that + the persistent one doesn't get shrunk during filtering for item selection + then regrown to full inventory, possibly being resized in the process */ +static winid cached_pickinv_win = WIN_ERR; + +/* #ifdef FREE_ALL_MEMORY */ +void +free_pickinv_cache() +{ + if (cached_pickinv_win != WIN_ERR) { + destroy_nhwindow(cached_pickinv_win); + cached_pickinv_win = WIN_ERR; + } +} +/* #endif */ + /* * Internal function used by display_inventory and getobj that can display * inventory and return a count as well as a letter. If out_cnt is not null, @@ -1987,31 +2012,31 @@ long *out_cnt; char *invlet = flags.inv_order; int i, n, classcount; winid win; /* windows being used */ - static winid local_win = WIN_ERR; /* window for partial menus */ anything any; menu_item *selected; struct obj **oarray; - /* overridden by global flag */ - if (flags.perm_invent) { - win = (lets && *lets) ? local_win : WIN_INVEN; - /* create the first time used */ - if (win == WIN_ERR) - win = local_win = create_nhwindow(NHW_MENU); + if (flags.perm_invent && lets && *lets) { + /* 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 */ + if (cached_pickinv_win == WIN_ERR) + cached_pickinv_win = create_nhwindow(NHW_MENU); + win = cached_pickinv_win; } else win = WIN_INVEN; /* - Exit early if no inventory -- but keep going if we are doing - a permanent inventory update. We need to keep going so the - permanent inventory window updates itself to remove the last - item(s) dropped. One down side: the addition of the exception - for permanent inventory window updates _can_ pop the window - up when it's not displayed -- even if it's empty -- because we - don't know at this level if its up or not. This may not be - an issue if empty checks are done before hand and the call - to here is short circuited away. - */ + * Exit early if no inventory -- but keep going if we are doing + * a permanent inventory update. We need to keep going so the + * permanent inventory window updates itself to remove the last + * item(s) dropped. One down side: the addition of the exception + * for permanent inventory window updates _can_ pop the window + * up when it's not displayed -- even if it's empty -- because we + * don't know at this level if its up or not. This may not be + * an issue if empty checks are done before hand and the call + * to here is short circuited away. + */ if (!invent && !(flags.perm_invent && !lets && !want_reply)) { pline("Not carrying anything."); return 0; @@ -2117,7 +2142,7 @@ long *out_cnt; */ char display_inventory(lets, want_reply) -register const char *lets; +const char *lets; boolean want_reply; { return display_pickinv(lets, want_reply, (long *) 0); @@ -2535,8 +2560,7 @@ dotypeinv() if (oclass == COIN_CLASS) return doprgold(); if (index(types, c) > index(types, '\033')) { - /* '> ESC' => "hidden choice", something known not to be carried - */ + /* '> ESC' => hidden choice, something known not to be carried */ const char *which = 0; switch (c) { @@ -2690,7 +2714,7 @@ boolean picked_some; } else { You("%s no objects here.", verb); } - return (!!Blind); + return !!Blind; } if (!skip_objects && (trap = t_at(u.ux, u.uy)) && trap->tseen) There("is %s here.", @@ -2722,7 +2746,7 @@ boolean picked_some; dfeature = 0; /* ice already identified */ if (!can_reach_floor(TRUE)) { pline("But you can't reach it!"); - return (0); + return 0; } } @@ -2736,7 +2760,7 @@ boolean picked_some; read_engr_at(u.ux, u.uy); /* Eric Backus */ if (!skip_objects && (Blind || !dfeature)) You("%s no objects here.", verb); - return (!!Blind); + return !!Blind; } /* we know there is something here */ @@ -2806,10 +2830,10 @@ boolean picked_some; feel_cockatrice(otmp, FALSE); read_engr_at(u.ux, u.uy); /* Eric Backus */ } - return (!!Blind); + return !!Blind; } -/* explicitly look at what is here, including all objects */ +/* the ':' command - explicitly look at what is here, including all objects */ int dolook() { @@ -2862,8 +2886,9 @@ struct obj *obj; return; } +/* returns TRUE if obj & otmp can be merged */ STATIC_OVL boolean -mergable(otmp, obj) /* returns TRUE if obj & otmp can be merged */ +mergable(otmp, obj) register struct obj *otmp, *obj; { int objnamelth = 0, otmpnamelth = 0; @@ -2882,7 +2907,7 @@ register struct obj *otmp, *obj; || obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit || obj->greased != otmp->greased || obj->oeroded != otmp->oeroded || obj->oeroded2 != otmp->oeroded2 || obj->bypass != otmp->bypass) - return (FALSE); + return FALSE; if (obj->nomerge) /* explicitly marked to prevent merge */ return FALSE; @@ -2894,7 +2919,7 @@ register struct obj *otmp, *obj; if (obj->oclass == FOOD_CLASS && (obj->oeaten != otmp->oeaten || obj->orotten != otmp->orotten)) - return (FALSE); + return FALSE; if (obj->otyp == CORPSE || obj->otyp == EGG || obj->otyp == TIN) { if (obj->corpsenm != otmp->corpsenm) @@ -2910,7 +2935,7 @@ register struct obj *otmp, *obj; /* allow candle merging only if their ages are close */ /* see begin_burn() for a reference for the magic "25" */ if (Is_candle(obj) && obj->age / 25 != otmp->age / 25) - return (FALSE); + return FALSE; /* burning potions of oil never merge */ if (obj->otyp == POT_OIL && obj->lamplit) @@ -2943,6 +2968,7 @@ register struct obj *otmp, *obj; return FALSE; } +/* the '$' command */ int doprgold() { @@ -2957,6 +2983,7 @@ doprgold() return 0; } +/* the ')' command */ int doprwep() { @@ -2994,15 +3021,21 @@ boolean report_uskin; } } +/* the '[' command */ int doprarm() { + char lets[8]; + register int ct = 0; + /* + * Note: players sometimes get here by pressing a function key which + * transmits ''ESC [ '' rather than by pressing '['; + * there's nothing we can--or should-do about that here. + */ + if (!wearing_armor()) { noarmor(TRUE); } else { - char lets[8]; - register int ct = 0; - if (uarmu) lets[ct++] = obj_to_let(uarmu); if (uarm) @@ -3023,6 +3056,7 @@ doprarm() return 0; } +/* the '=' command */ int doprring() { @@ -3042,6 +3076,7 @@ doprring() return 0; } +/* the '"' command */ int dopramulet() { @@ -3064,6 +3099,7 @@ struct obj *obj; || (obj->otyp == LEASH && obj->leashmon)); } +/* the '(' command */ int doprtool() { @@ -3236,27 +3272,27 @@ reassign() /* #adjust command * - * User specifies a 'from' slot for inventory stack to move, - * then a 'to' slot for its destination. Open slots and those - * filled by compatible stacks are listed as likely candidates - * but user can pick any inventory letter (including 'from'). - * All compatible items found are gathered into the 'from' - * stack as it is moved. If the 'to' slot isn't empty and - * doesn't merge, then its stack is swapped to the 'from' slot. + * User specifies a 'from' slot for inventory stack to move, + * then a 'to' slot for its destination. Open slots and those + * filled by compatible stacks are listed as likely candidates + * but user can pick any inventory letter (including 'from'). + * All compatible items found are gathered into the 'from' + * stack as it is moved. If the 'to' slot isn't empty and + * doesn't merge, then its stack is swapped to the 'from' slot. * - * If the user specifies a count when choosing the 'from' slot, - * and that count is less than the full size of the stack, - * then the stack will be split. The 'count' portion is moved - * to the destination, and the only candidate for merging with - * it is the stack already at the 'to' slot, if any. When the - * destination is non-empty but won't merge, whatever is there - * will be moved to an open slot; if there isn't any open slot - * available, the adjustment attempt fails. + * If the user specifies a count when choosing the 'from' slot, + * and that count is less than the full size of the stack, + * then the stack will be split. The 'count' portion is moved + * to the destination, and the only candidate for merging with + * it is the stack already at the 'to' slot, if any. When the + * destination is non-empty but won't merge, whatever is there + * will be moved to an open slot; if there isn't any open slot + * available, the adjustment attempt fails. * - * Splitting has one special case: if 'to' slot is non-empty - * and is compatible with 'from' in all respects except for - * user-assigned names, the 'count' portion being moved is - * effectively renamed so that it will merge with 'to' stack. + * Splitting has one special case: if 'to' slot is non-empty + * and is compatible with 'from' in all respects except for + * user-assigned names, the 'count' portion being moved is + * effectively renamed so that it will merge with 'to' stack. */ int doorganize() /* inventory organizer by Del Lamb */ @@ -3281,7 +3317,7 @@ doorganize() /* inventory organizer by Del Lamb */ allowall[1] = ALL_CLASSES; allowall[2] = '\0'; if (!(obj = getobj(allowall, "adjust"))) - return (0); + return 0; /* figure out whether user gave a split count to getobj() */ splitting = bumped = 0; @@ -3440,7 +3476,7 @@ doorganize() /* inventory organizer by Del Lamb */ if (splitting) clear_splitobjs(); /* reset splitobj context */ update_inventory(); - return (0); + return 0; } /* common to display_minventory and display_cinventory */ @@ -3466,15 +3502,25 @@ const char *hdr, *txt; return; } -/* query_objlist callback: return things that could possibly be worn/wielded - */ +/* query_objlist callback: return things that are worn or wielded */ STATIC_OVL boolean worn_wield_only(obj) struct obj *obj; { - return (obj->oclass == WEAPON_CLASS || obj->oclass == ARMOR_CLASS - || obj->oclass == AMULET_CLASS || obj->oclass == RING_CLASS - || obj->oclass == TOOL_CLASS); +#if 1 + /* check for things that *are* worn or wielded (only used for monsters, + so we don't worry about excluding W_CHAIN, W_ARTI and the like) */ + return (boolean) (obj->owornmask != 0L); +#else + /* this used to check for things that *might* be worn or wielded, + but that's not particularly interesting */ + if (is_weptool(obj) || is_wet_towel(obj) || obj->otyp == MEAT_RING) + return TRUE; + return (boolean) (obj->oclass == WEAPON_CLASS + || obj->oclass == ARMOR_CLASS + || obj->oclass == AMULET_CLASS + || obj->oclass == RING_CLASS); +#endif } /* @@ -3485,8 +3531,8 @@ struct obj *obj; * By default, only worn and wielded items are displayed. The caller * can pick one. Modifier flags are: * - * MINV_NOLET - nothing selectable - * MINV_ALL - display all inventory + * MINV_NOLET - nothing selectable + * MINV_ALL - display all inventory */ struct obj * display_minventory(mon, dflags, title) diff --git a/src/save.c b/src/save.c index e1c737dec6..cb080ef788 100644 --- a/src/save.c +++ b/src/save.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 save.c $NHDT-Date: 1432536532 2015/05/25 06:48:52 $ $NHDT-Branch: master $:$NHDT-Revision: 1.88 $ */ +/* NetHack 3.6 save.c $NHDT-Date: 1446516854 2015/11/03 02:14:14 $ $NHDT-Branch: master $:$NHDT-Revision: 1.91 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -1387,10 +1387,14 @@ freedynamicdata() if (iflags.wc_tile_file) free(iflags.wc_tile_file); free_autopickup_exceptions(); + + /* miscellaneous */ + free_pickinv_cache(); #endif /* FREE_ALL_MEMORY */ #ifdef STATUS_VIA_WINDOWPORT status_finish(); #endif + sysopt_release(); /* SYSCF strings */ return; }