From 5a433fe0e0c85e0226a0addbaaae3576c398b451 Mon Sep 17 00:00:00 2001 From: "nethack.allison" Date: Wed, 15 Dec 2004 23:50:18 +0000 Subject: [PATCH] new container flags [Attention: This patch increments EDITLEVEL in patchlevel.h, rendering all previous save and bones files obsolete.] Here's the first cut at the two recommended flags lknown and cknown. I've attempted to stay close to Pat's recommendations: "Containers ought to have two new flags: lknown for lock status known, and cknown for contents known (ie, `secret'). Formatted box and chest descriptions should include locked/unlocked/broken when that is known and empty/nonempty (or something like "holds N items") when contents are known. The contents indicator would also apply to nonlockable containers." I probably overlooked a place where a flag should be adjusted, but this should give us a good starting point. I wasn't sure what to do with the case of the auditory feedback for magical locking "Click" and "Clunk". The question that came to my mind was: Should those reveal the locked or unlocked status of a box? I suppose if you knew the type of wand you were zapping or the spell you were casting, you could argue that they should. In the end, I opted for setting lknown right off the zap/cast effect for anyone playing a Wizard role, and not setting it for anyone else, thus advancing class differentiation a little bit too. I haven't checked the cknown results under all flags.menu_style options at this point, only MENU_FULL. --- doc/fixes35.0 | 2 ++ include/obj.h | 4 +++- include/patchlevel.h | 4 ++-- src/dokick.c | 2 ++ src/invent.c | 21 +++++++++++++++++---- src/lock.c | 7 +++++++ src/mkobj.c | 2 ++ src/objnam.c | 25 +++++++++++++++++++++++++ src/pickup.c | 19 ++++++++++++++++++- src/zap.c | 1 + 10 files changed, 79 insertions(+), 8 deletions(-) diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 097d798ec..ca413c19d 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -115,6 +115,8 @@ vampires can now shapeshift into bats and fog clouds; the latter can be done at will to slip through locked doors shapeshifted vampire will transform back to vampire form after you defeat it and continue to fight in its native form +container lknown flag for locked/unlocked/broken awareness +container cknown flag for container content awareness Platform- and/or Interface-Specific New Features diff --git a/include/obj.h b/include/obj.h index 477fa8b1c..d47a09eb2 100644 --- a/include/obj.h +++ b/include/obj.h @@ -92,7 +92,9 @@ struct obj { Bitfield(in_use,1); /* for magic items before useup items */ Bitfield(bypass,1); /* mark this as an object to be skipped by bhito() */ - /* 6 free bits */ + Bitfield(cknown,1); /* contents of container assumed to be known */ + Bitfield(lknown,1); /* locked/unlocked status is known */ + /* 4 free bits */ int corpsenm; /* type of corpse is mons[corpsenm] */ #define leashmon corpsenm /* gets m_id of attached pet */ diff --git a/include/patchlevel.h b/include/patchlevel.h index fefd12b97..3ab6a90d5 100644 --- a/include/patchlevel.h +++ b/include/patchlevel.h @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)patchlevel.h 3.4 2004/06/12 */ +/* SCCS Id: @(#)patchlevel.h 3.4 2004/12/15 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -13,7 +13,7 @@ * Incrementing EDITLEVEL can be used to force invalidation of old bones * and save files. */ -#define EDITLEVEL 14 +#define EDITLEVEL 15 #define COPYRIGHT_BANNER_A \ "NetHack, Copyright 1985-2004" diff --git a/src/dokick.c b/src/dokick.c index d40df0543..b363cce7a 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -516,12 +516,14 @@ xchar x, y; You("break open the lock!"); kickobj->olocked = 0; kickobj->obroken = 1; + kickobj->lknown = 1; if (otrp) (void) chest_trap(kickobj, LEG, FALSE); return(1); } } else { if (!rn2(3) || (martial() && !rn2(2))) { pline_The("lid slams open, then falls shut."); + kickobj->lknown = 1; if (otrp) (void) chest_trap(kickobj, LEG, FALSE); return(1); } diff --git a/src/invent.c b/src/invent.c index d8b01f111..0b1974d81 100644 --- a/src/invent.c +++ b/src/invent.c @@ -1917,15 +1917,27 @@ dounpaid() */ for (otmp = invent; otmp; otmp = otmp->nobj) { if (Has_contents(otmp)) { + long contcost = 0L; marker = (struct obj *) 0; /* haven't found any */ while (find_unpaid(otmp->cobj, &marker)) { totcost += cost = unpaid_cost(marker); - save_unpaid = marker->unpaid; - marker->unpaid = 0; /* suppress "(unpaid)" suffix */ - putstr(win, 0, + contcost += cost; + if (otmp->cknown) { + save_unpaid = marker->unpaid; + marker->unpaid = 0; /* suppress "(unpaid)" suffix */ + putstr(win, 0, xprname(marker, distant_name(marker, doname), CONTAINED_SYM, TRUE, cost, 0L)); - marker->unpaid = save_unpaid; + marker->unpaid = save_unpaid; + } + } + if (!otmp->cknown) { + char contbuf[BUFSZ]; + /* Shopkeeper knows what to charge for contents */ + Sprintf(contbuf, "%s contents", s_suffix(xname(otmp))); + putstr(win, 0, + xprname((struct obj *)0, contbuf, + CONTAINED_SYM, TRUE, contcost, 0L)); } } } @@ -2937,6 +2949,7 @@ register struct obj *obj; free((genericptr_t)selected); } else ret = (struct obj *) 0; + obj->cknown = 1; return ret; } diff --git a/src/lock.c b/src/lock.c index 4b4542e17..1a0ab0292 100644 --- a/src/lock.c +++ b/src/lock.c @@ -117,6 +117,7 @@ picklock() /* try to open/close a lock */ else xlock.door->doormask = D_LOCKED; } else { xlock.box->olocked = !xlock.box->olocked; + xlock.box->lknown = 1; if(xlock.box->otrapped) (void) chest_trap(xlock.box, FINGER, FALSE); } @@ -163,6 +164,7 @@ forcelock() /* try to force a locked chest */ You("succeed in forcing the lock."); xlock.box->olocked = 0; xlock.box->obroken = 1; + xlock.box->lknown = 1; if(!xlock.picktyp && !rn2(3)) { struct monst *shkp; boolean costly; @@ -301,6 +303,7 @@ pick_lock(pick) /* pick a lock with a given object */ safe_qbuf("", sizeof("There is here, unlock its lock?"), doname(otmp), an(simple_typename(otmp->otyp)), "a box"), verb, it ? "it" : "its lock"); + otmp->lknown = 1; c = ynq(qbuf); if(c == 'q') return(0); @@ -461,12 +464,14 @@ doforce() /* try to force a chest with your weapon */ if (otmp->obroken || !otmp->olocked) { There("is %s here, but its lock is already %s.", doname(otmp), otmp->obroken ? "broken" : "unlocked"); + otmp->lknown = 1; continue; } Sprintf(qbuf,"There is %s here, force its lock?", safe_qbuf("", sizeof("There is here, force its lock?"), doname(otmp), an(simple_typename(otmp->otyp)), "a box")); + otmp->lknown = 1; c = ynq(qbuf); if(c == 'q') return(0); @@ -702,6 +707,7 @@ register struct obj *obj, *otmp; /* obj *is* a box */ pline("Klunk!"); obj->olocked = 1; obj->obroken = 0; + if (Role_if(PM_WIZARD)) obj->lknown = 1; res = 1; } /* else already closed and locked */ break; @@ -711,6 +717,7 @@ register struct obj *obj, *otmp; /* obj *is* a box */ pline("Klick!"); obj->olocked = 0; res = 1; + if (Role_if(PM_WIZARD)) obj->lknown = 1; } else /* silently fix if broken */ obj->obroken = 0; break; diff --git a/src/mkobj.c b/src/mkobj.c index d067deb0a..a8144aac0 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -377,6 +377,8 @@ boolean artif; otmp->dknown = 0; if (!objects[otmp->otyp].oc_uses_known) otmp->known = 1; + otmp->lknown = 0; + otmp->cknown = 0; #ifdef INVISIBLE_OBJECTS otmp->oinvis = !rn2(1250); #endif diff --git a/src/objnam.c b/src/objnam.c index aacd1dd14..ad090c21c 100644 --- a/src/objnam.c +++ b/src/objnam.c @@ -569,6 +569,11 @@ register struct obj *obj; if (obj->oinvis) Strcat(prefix,"invisible "); #endif + /* "empty" goes at the beginning, but item count goes at the end */ + if (obj->cknown && + (Is_container(obj) || obj->otyp == STATUE) && !Has_contents(obj)) + Strcat(prefix, "empty "); + if (obj->bknown && obj->oclass != COIN_CLASS && (obj->otyp != POT_WATER || !objects[POT_WATER].oc_name_known @@ -602,8 +607,28 @@ register struct obj *obj; Strcat(prefix, "uncursed "); } + if (obj->lknown && Is_box(obj)) { + if (obj->obroken) + Strcat(prefix, "unlockable "); + else if (obj->olocked) + Strcat(prefix, "locked "); + else + Strcat(prefix, "unlocked "); + } + if (obj->greased) Strcat(prefix, "greased "); + if (obj->cknown && Has_contents(obj)) { + struct obj *curr; + long itemcount = 0L; + + /* Count the number of contained objects */ + for (curr = obj->cobj; curr; curr = curr->nobj) + itemcount += curr->quan; + Sprintf(eos(bp), " containing %ld item%s", + itemcount, plur(itemcount)); + } + switch(obj->oclass) { case AMULET_CLASS: if(obj->owornmask & W_AMUL) diff --git a/src/pickup.c b/src/pickup.c index 429d2f4da..cda4f94c4 100644 --- a/src/pickup.c +++ b/src/pickup.c @@ -1544,8 +1544,11 @@ lootcont: if (cobj->olocked) { pline("Hmmm, it seems to be locked."); + cobj->lknown = 1; continue; } + cobj->lknown = 1; + if (cobj->otyp == BAG_OF_TRICKS) { int tmp; You("carefully open the bag..."); @@ -2091,9 +2094,11 @@ register int held; if (obj->olocked) { pline("%s to be locked.", Tobjnam(obj, "seem")); if (held) You("must put it down to unlock."); + obj->lknown = 1; return 0; } else if (obj->otrapped) { if (held) You("open %s...", the(xname(obj))); + obj->lknown = 1; (void) chest_trap(obj, HAND, FALSE); /* even if the trap fails, you've used up this turn */ if (multi >= 0) { /* in case we didn't become paralyzed */ @@ -2102,6 +2107,7 @@ register int held; } return 1; } + obj->lknown = 1; current_container = obj; /* for use by in/out_container */ if (obj->spe == 1) { @@ -2147,6 +2153,7 @@ register int held; if (!outokay && !inokay) { pline("%s", emptymsg); You("don't have anything to put in."); + if (used) obj->cknown = 1; return used; } menuprompt[0] = '\0'; @@ -2201,6 +2208,7 @@ ask_again2: break; case 'q': default: + if (used) obj->cknown = 1; return used; } } @@ -2215,6 +2223,7 @@ ask_again2: #endif /* nothing to put in, but some feedback is necessary */ You("don't have anything to put in."); + if (used) obj->cknown = 1; return used; } if (flags.menu_style != MENU_FULL) { @@ -2235,6 +2244,7 @@ ask_again2: break; case 'q': default: + if (used) obj->cknown = 1; return used; } } @@ -2330,6 +2340,7 @@ boolean put_in; } if (loot_everything) { + container->cknown = 1; for (otmp = container->cobj; otmp; otmp = otmp2) { otmp2 = otmp->nobj; res = out_container(otmp); @@ -2338,6 +2349,7 @@ boolean put_in; } else { mflags = INVORDER_SORT; if (put_in && flags.invlet_constant) mflags |= USE_INVLET; + if (takeout) container->cknown = 1; Sprintf(buf,"%s what?", put_in ? putin : takeout); n = query_objlist(buf, put_in ? invent : container->cobj, mflags, &pick_list, PICK_ANY, @@ -2446,7 +2458,7 @@ dotip() c = ynq(buf); if (c == 'q') return 0; if (c == 'n') continue; - + tipcontainer(cobj); return 1; } /* next cobj */ @@ -2511,6 +2523,7 @@ struct obj *box; /* or bag */ { boolean empty_it = FALSE; + box->lknown = 1; if (box->olocked) { pline("It's locked."); } else if (box->otrapped) { @@ -2524,16 +2537,19 @@ struct obj *box; /* or bag */ } else if (box->otyp == BAG_OF_TRICKS && box->spe > 0) { /* apply (not loot) this bag; uses up one charge */ bagotricks(box); + box->cknown = 1; } else if (box->spe) { char yourbuf[BUFSZ]; observe_quantum_cat(box); + box->cknown = 1; if (!Has_contents(box)) /* evidently a live cat came out */ /* container type of "large box" is inferred */ pline("%sbox is now empty.", Shk_Your(yourbuf, box)); else /* holds cat corpse or other random stuff */ empty_it = TRUE; } else if (!Has_contents(box)) { + box->cknown = 1; pline("It's empty."); } else { empty_it = TRUE; @@ -2548,6 +2564,7 @@ struct obj *box; /* or bag */ int held = carried(box); long loss = 0L; + box->cknown = 1; pline("%s out%c", box->cobj->nobj ? "Objects spill" : "An object spills", !(highdrop || altarizing) ? ':' : '.'); diff --git a/src/zap.c b/src/zap.c index c8ce7624f..08599b17e 100644 --- a/src/zap.c +++ b/src/zap.c @@ -1561,6 +1561,7 @@ struct obj *obj, *otmp; o->dknown = 1; /* "seen", even if blind */ (void) display_cinventory(obj); } + obj->cknown = 1; res = 1; } if (res) makeknown(WAN_PROBING); -- 2.40.0