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
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 */
-/* 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. */
* 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"
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);
}
*/
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));
}
}
}
free((genericptr_t)selected);
} else
ret = (struct obj *) 0;
+ obj->cknown = 1;
return ret;
}
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);
}
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;
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);
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);
pline("Klunk!");
obj->olocked = 1;
obj->obroken = 0;
+ if (Role_if(PM_WIZARD)) obj->lknown = 1;
res = 1;
} /* else already closed and locked */
break;
pline("Klick!");
obj->olocked = 0;
res = 1;
+ if (Role_if(PM_WIZARD)) obj->lknown = 1;
} else /* silently fix if broken */
obj->obroken = 0;
break;
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
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
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)
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...");
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 */
}
return 1;
}
+ obj->lknown = 1;
current_container = obj; /* for use by in/out_container */
if (obj->spe == 1) {
if (!outokay && !inokay) {
pline("%s", emptymsg);
You("don't have anything to put in.");
+ if (used) obj->cknown = 1;
return used;
}
menuprompt[0] = '\0';
break;
case 'q':
default:
+ if (used) obj->cknown = 1;
return used;
}
}
#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) {
break;
case 'q':
default:
+ if (used) obj->cknown = 1;
return used;
}
}
}
if (loot_everything) {
+ container->cknown = 1;
for (otmp = container->cobj; otmp; otmp = otmp2) {
otmp2 = otmp->nobj;
res = out_container(otmp);
} 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,
c = ynq(buf);
if (c == 'q') return 0;
if (c == 'n') continue;
-
+
tipcontainer(cobj);
return 1;
} /* next cobj */
{
boolean empty_it = FALSE;
+ box->lknown = 1;
if (box->olocked) {
pline("It's locked.");
} else if (box->otrapped) {
} 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;
int held = carried(box);
long loss = 0L;
+ box->cknown = 1;
pline("%s out%c",
box->cobj->nobj ? "Objects spill" : "An object spills",
!(highdrop || altarizing) ? ':' : '.');
o->dknown = 1; /* "seen", even if blind */
(void) display_cinventory(obj);
}
+ obj->cknown = 1;
res = 1;
}
if (res) makeknown(WAN_PROBING);