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.
This commit is contained in:
nethack.allison
2004-12-15 23:50:18 +00:00
parent 10b227e242
commit 5a433fe0e0
10 changed files with 79 additions and 8 deletions

View File

@@ -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

View File

@@ -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 */

View File

@@ -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"

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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

View File

@@ -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)

View File

@@ -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) ? ':' : '.');

View File

@@ -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);