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:
@@ -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
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
21
src/invent.c
21
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
25
src/objnam.c
25
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)
|
||||
|
||||
19
src/pickup.c
19
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) ? ':' : '.');
|
||||
|
||||
Reference in New Issue
Block a user