Merge branch 'NetHack-3.6.2'
This commit is contained in:
@@ -205,6 +205,8 @@ successfully paying for shop damage with shop credit would be followed by
|
||||
if a migrating monster was killed off because there was no room on the
|
||||
destination level, it would leave a corpse even if it was a type
|
||||
which should never leave one (demon, golem, blob, &c)
|
||||
end of game while carrying Schroedinger's Box would reveal cat-or-corpse
|
||||
for inventory disclosure or put that info into dumplog, but not both
|
||||
|
||||
|
||||
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1541719965 2018/11/08 23:32:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.647 $ */
|
||||
/* NetHack 3.6 extern.h $NHDT-Date: 1542798602 2018/11/21 11:10:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.650 $ */
|
||||
/* Copyright (c) Steve Creps, 1988. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
|
||||
@@ -1851,6 +1851,7 @@ E struct obj *FDECL(pick_obj, (struct obj *));
|
||||
E int NDECL(encumber_msg);
|
||||
E int FDECL(container_at, (int, int, BOOLEAN_P));
|
||||
E int NDECL(doloot);
|
||||
E void FDECL(observe_quantum_cat, (struct obj *, BOOLEAN_P, BOOLEAN_P));
|
||||
E boolean FDECL(container_gone, (int (*)(OBJ_P)));
|
||||
E boolean NDECL(u_handsy);
|
||||
E int FDECL(use_container, (struct obj **, int, BOOLEAN_P));
|
||||
|
||||
@@ -484,7 +484,7 @@ fail_mon_placement:
|
||||
&& !LEVEL_SPECIFIC_NOCORPSE(mtmp->data))
|
||||
(void) mkcorpstat(CORPSE, mtmp, mtmp->data,
|
||||
xlocale, ylocale, CORPSTAT_NONE);
|
||||
mtmp->mx = mtmp->my = -1; /* for mongone, mon is not anywhere */
|
||||
mtmp->mx = mtmp->my = 0; /* for mongone, mon is not anywhere */
|
||||
mongone(mtmp);
|
||||
}
|
||||
}
|
||||
|
||||
122
src/end.c
122
src/end.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 end.c $NHDT-Date: 1541902951 2018/11/11 02:22:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.150 $ */
|
||||
/* NetHack 3.6 end.c $NHDT-Date: 1542798619 2018/11/21 11:10:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.152 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -49,7 +49,6 @@ STATIC_DCL void FDECL(get_valuables, (struct obj *));
|
||||
STATIC_DCL void FDECL(sort_valuables, (struct valuable_data *, int));
|
||||
STATIC_DCL void FDECL(artifact_score, (struct obj *, BOOLEAN_P, winid));
|
||||
STATIC_DCL void FDECL(really_done, (int)) NORETURN;
|
||||
STATIC_DCL boolean FDECL(odds_and_ends, (struct obj *, int));
|
||||
STATIC_DCL void FDECL(savelife, (int));
|
||||
STATIC_PTR int FDECL(CFDECLSPEC vanqsort_cmp, (const genericptr,
|
||||
const genericptr));
|
||||
@@ -954,6 +953,13 @@ int size; /* max value is less than 20 */
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* odds_and_ends() was used for 3.6.0 and 3.6.1.
|
||||
* Schroedinger's Cat is handled differently starting with 3.6.2.
|
||||
*/
|
||||
STATIC_DCL boolean FDECL(odds_and_ends, (struct obj *, int));
|
||||
|
||||
#define CAT_CHECK 2
|
||||
|
||||
STATIC_OVL boolean
|
||||
@@ -962,6 +968,7 @@ struct obj *list;
|
||||
int what;
|
||||
{
|
||||
struct obj *otmp;
|
||||
|
||||
for (otmp = list; otmp; otmp = otmp->nobj) {
|
||||
switch (what) {
|
||||
case CAT_CHECK: /* Schroedinger's Cat */
|
||||
@@ -975,6 +982,7 @@ int what;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* called twice; first to calculate total, then to list relevant items */
|
||||
STATIC_OVL void
|
||||
@@ -1218,6 +1226,20 @@ int how;
|
||||
obj->known = obj->bknown = obj->dknown = obj->rknown = 1;
|
||||
if (Is_container(obj) || obj->otyp == STATUE)
|
||||
obj->cknown = obj->lknown = 1;
|
||||
/* we resolve Schroedinger's cat now in case of both
|
||||
disclosure and dumplog, where the 50:50 chance for
|
||||
live cat has to be the same both times */
|
||||
if (SchroedingersBox(obj)) {
|
||||
if (!Schroedingers_cat) {
|
||||
/* tell observe_quantum_cat() not to create a cat; if it
|
||||
chooses live cat in this situation, it will leave the
|
||||
SchroedingersBox flag set (for container_contents()) */
|
||||
observe_quantum_cat(obj, FALSE, FALSE);
|
||||
if (SchroedingersBox(obj))
|
||||
Schroedingers_cat = TRUE;
|
||||
} else
|
||||
obj->spe = 0; /* ordinary box with cat corpse in it */
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(flags.end_disclose, "none"))
|
||||
@@ -1228,7 +1250,7 @@ int how;
|
||||
|
||||
/* if pets will contribute to score, populate mydogs list now
|
||||
(bones creation isn't a factor, but pline() messaging is; used to
|
||||
be done ever sooner, but we need it to come after dump_everything()
|
||||
be done even sooner, but we need it to come after dump_everything()
|
||||
so that any accompanying pets are still on the map during dump) */
|
||||
if (how == ESCAPED || how == ASCENDED)
|
||||
keepdogs(TRUE);
|
||||
@@ -1389,22 +1411,22 @@ int how;
|
||||
viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */
|
||||
mtmp = mydogs;
|
||||
Strcpy(pbuf, "You");
|
||||
if (!Schroedingers_cat) /* check here in case disclosure was off */
|
||||
Schroedingers_cat = odds_and_ends(invent, CAT_CHECK);
|
||||
if (Schroedingers_cat) {
|
||||
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
|
||||
|
||||
mhp = d(m_lev, 8);
|
||||
nowrap_add(u.urexp, mhp);
|
||||
Strcat(eos(pbuf), " and Schroedinger's cat");
|
||||
}
|
||||
if (mtmp) {
|
||||
if (mtmp || Schroedingers_cat) {
|
||||
while (mtmp) {
|
||||
Sprintf(eos(pbuf), " and %s", mon_nam(mtmp));
|
||||
if (mtmp->mtame)
|
||||
nowrap_add(u.urexp, mtmp->mhp);
|
||||
mtmp = mtmp->nmon;
|
||||
}
|
||||
/* [it might be more robust to create a housecat and add it to
|
||||
mydogs; it doesn't have to be placed on the map for that] */
|
||||
if (Schroedingers_cat) {
|
||||
int mhp, m_lev = adj_lev(&mons[PM_HOUSECAT]);
|
||||
|
||||
mhp = d(m_lev, 8);
|
||||
nowrap_add(u.urexp, mhp);
|
||||
Strcat(eos(pbuf), " and Schroedinger's cat");
|
||||
}
|
||||
dump_forward_putstr(endwin, 0, pbuf, done_stopprint);
|
||||
pbuf[0] = '\0';
|
||||
} else {
|
||||
@@ -1513,23 +1535,18 @@ boolean identified, all_containers, reportempty;
|
||||
{
|
||||
register struct obj *box, *obj;
|
||||
char buf[BUFSZ];
|
||||
boolean cat, deadcat;
|
||||
boolean cat,
|
||||
dumping =
|
||||
#ifdef DUMPLOG
|
||||
iflags.in_dumplog ? TRUE :
|
||||
#endif
|
||||
FALSE;
|
||||
|
||||
for (box = list; box; box = box->nobj) {
|
||||
if (Is_container(box) || box->otyp == STATUE) {
|
||||
box->cknown = 1; /* we're looking at the contents now */
|
||||
if (identified)
|
||||
box->lknown = 1;
|
||||
cat = deadcat = FALSE;
|
||||
if (SchroedingersBox(box) && !Schroedingers_cat) {
|
||||
/* Schroedinger's Cat? */
|
||||
cat = odds_and_ends(box, CAT_CHECK);
|
||||
if (cat)
|
||||
Schroedingers_cat = TRUE;
|
||||
else
|
||||
deadcat = TRUE;
|
||||
box->spe = 0;
|
||||
}
|
||||
if (box->otyp == BAG_OF_TRICKS) {
|
||||
continue; /* wrong type of container */
|
||||
} else if (box->cobj) {
|
||||
@@ -1537,38 +1554,49 @@ boolean identified, all_containers, reportempty;
|
||||
Loot *sortedcobj, *srtc;
|
||||
unsigned sortflags;
|
||||
|
||||
/* at this stage, the SchroedingerBox() flag is only set
|
||||
if the cat inside the box is alive; the box actually
|
||||
contains a cat corpse that we'll pretend is not there;
|
||||
for dead cat, the flag will be clear and there'll be
|
||||
a cat corpse inside the box; either way, inventory
|
||||
reports the box as containing "1 item" */
|
||||
cat = SchroedingersBox(box);
|
||||
|
||||
Sprintf(buf, "Contents of %s:", the(xname(box)));
|
||||
putstr(tmpwin, 0, buf);
|
||||
putstr(tmpwin, 0, "");
|
||||
sortflags = (((flags.sortloot == 'l' || flags.sortloot == 'f')
|
||||
? SORTLOOT_LOOT : 0)
|
||||
| (flags.sortpack ? SORTLOOT_PACK : 0));
|
||||
sortedcobj = sortloot(&box->cobj, sortflags, FALSE,
|
||||
(boolean FDECL((*), (OBJ_P))) 0);
|
||||
for (srtc = sortedcobj; ((obj = srtc->obj) != 0); ++srtc) {
|
||||
if (identified) {
|
||||
discover_object(obj->otyp, TRUE, FALSE);
|
||||
obj->known = obj->bknown = obj->dknown
|
||||
= obj->rknown = 1;
|
||||
if (Is_container(obj) || obj->otyp == STATUE)
|
||||
obj->cknown = obj->lknown = 1;
|
||||
if (!dumping)
|
||||
putstr(tmpwin, 0, "");
|
||||
buf[0] = buf[1] = ' '; /* two leading spaces */
|
||||
if (box->cobj && !cat) {
|
||||
sortflags = (((flags.sortloot == 'l'
|
||||
|| flags.sortloot == 'f')
|
||||
? SORTLOOT_LOOT : 0)
|
||||
| (flags.sortpack ? SORTLOOT_PACK : 0));
|
||||
sortedcobj = sortloot(&box->cobj, sortflags, FALSE,
|
||||
(boolean FDECL((*), (OBJ_P))) 0);
|
||||
for (srtc = sortedcobj; ((obj = srtc->obj) != 0); ++srtc) {
|
||||
if (identified) {
|
||||
discover_object(obj->otyp, TRUE, FALSE);
|
||||
obj->known = obj->bknown = obj->dknown
|
||||
= obj->rknown = 1;
|
||||
if (Is_container(obj) || obj->otyp == STATUE)
|
||||
obj->cknown = obj->lknown = 1;
|
||||
}
|
||||
Strcpy(&buf[2], doname(obj));
|
||||
putstr(tmpwin, 0, buf);
|
||||
}
|
||||
putstr(tmpwin, 0, doname(obj));
|
||||
unsortloot(&sortedcobj);
|
||||
} else if (cat) {
|
||||
Strcpy(&buf[2], "Schroedinger's cat!");
|
||||
putstr(tmpwin, 0, buf);
|
||||
}
|
||||
unsortloot(&sortedcobj);
|
||||
if (cat)
|
||||
putstr(tmpwin, 0, "Schroedinger's cat");
|
||||
else if (deadcat)
|
||||
putstr(tmpwin, 0, "Schroedinger's dead cat");
|
||||
if (dumping)
|
||||
putstr(0, 0, "");
|
||||
display_nhwindow(tmpwin, TRUE);
|
||||
destroy_nhwindow(tmpwin);
|
||||
if (all_containers)
|
||||
container_contents(box->cobj, identified, TRUE,
|
||||
reportempty);
|
||||
} else if (cat || deadcat) {
|
||||
pline("%s Schroedinger's %scat!", Tobjnam(box, "contain"),
|
||||
deadcat ? "dead " : "");
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
} else if (reportempty) {
|
||||
pline("%s is empty.", upstart(thesimpleoname(box)));
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
|
||||
@@ -423,7 +423,7 @@ struct mail_info *info;
|
||||
/* zip back to starting location */
|
||||
go_back:
|
||||
if (!md_rush(md, start.x, start.y))
|
||||
md->mx = md->my = -1; /* for mongone, md is not on map */
|
||||
md->mx = md->my = 0; /* for mongone, md is not on map */
|
||||
mongone(md);
|
||||
/* deliver some classes of messages even if no daemon ever shows up */
|
||||
give_up:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1539804904 2018/10/17 19:35:04 $ $NHDT-Branch: keni-makedefsm $:$NHDT-Revision: 1.127 $ */
|
||||
/* NetHack 3.6 makemon.c $NHDT-Date: 1542798623 2018/11/21 11:10:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -280,7 +280,8 @@ register struct monst *mtmp;
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, rn2(3) ? DAGGER : KNIFE);
|
||||
if (rn2(5))
|
||||
(void) mongets(mtmp, rn2(3) ? LEATHER_JACKET : LEATHER_CLOAK);
|
||||
(void) mongets(mtmp, rn2(3) ? LEATHER_JACKET
|
||||
: LEATHER_CLOAK);
|
||||
if (rn2(3))
|
||||
(void) mongets(mtmp, rn2(3) ? LOW_BOOTS : HIGH_BOOTS);
|
||||
if (rn2(3))
|
||||
@@ -304,7 +305,8 @@ register struct monst *mtmp;
|
||||
case PM_HUNTER:
|
||||
(void) mongets(mtmp, rn2(3) ? SHORT_SWORD : DAGGER);
|
||||
if (rn2(2))
|
||||
(void) mongets(mtmp, rn2(2) ? LEATHER_JACKET : LEATHER_ARMOR);
|
||||
(void) mongets(mtmp, rn2(2) ? LEATHER_JACKET
|
||||
: LEATHER_ARMOR);
|
||||
(void) mongets(mtmp, BOW);
|
||||
m_initthrow(mtmp, ARROW, 12);
|
||||
break;
|
||||
@@ -744,9 +746,21 @@ register struct monst *mtmp;
|
||||
break;
|
||||
case S_QUANTMECH:
|
||||
if (!rn2(20)) {
|
||||
struct obj *catcorpse;
|
||||
|
||||
otmp = mksobj(LARGE_BOX, FALSE, FALSE);
|
||||
otmp->spe = 1; /* flag for special box */
|
||||
otmp->owt = weight(otmp);
|
||||
/* we used to just set the flag, which resulted in weight()
|
||||
treating the box as being heavier by the weight of a cat;
|
||||
now we include a cat corpse that won't rot; when opening or
|
||||
disclosing the box's contents, the corpse might be revived,
|
||||
otherwise it's given a rot timer; weight is now ordinary */
|
||||
if ((catcorpse = mksobj(CORPSE, TRUE, FALSE)) != 0) {
|
||||
otmp->spe = 1; /* flag for special SchroedingersBox */
|
||||
set_corpsenm(catcorpse, PM_HOUSECAT);
|
||||
(void) stop_timer(ROT_CORPSE, obj_to_any(catcorpse));
|
||||
add_to_container(otmp, catcorpse);
|
||||
otmp->owt = weight(otmp);
|
||||
}
|
||||
(void) mpickobj(mtmp, otmp);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1518053380 2018/02/08 01:29:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.130 $ */
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1542798624 2018/11/21 11:10:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.136 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1388,8 +1388,6 @@ register struct obj *obj;
|
||||
when we assume this is a brand new glob so use objects[].oc_weight */
|
||||
if (obj->globby && obj->owt > 0)
|
||||
wt = obj->owt;
|
||||
if (SchroedingersBox(obj))
|
||||
wt += mons[PM_HOUSECAT].cwt;
|
||||
if (Is_container(obj) || obj->otyp == STATUE) {
|
||||
struct obj *contents;
|
||||
register int cwt = 0;
|
||||
|
||||
@@ -105,7 +105,7 @@ mon_sanity_check()
|
||||
}
|
||||
}
|
||||
|
||||
for (x = 0; x < COLNO; x++)
|
||||
for (x = 1; x < COLNO; x++)
|
||||
for (y = 0; y < ROWNO; y++)
|
||||
if ((mtmp = level.monsters[x][y]) != 0) {
|
||||
for (m = fmon; m; m = m->nmon)
|
||||
@@ -1747,7 +1747,7 @@ m_detach(mtmp, mptr)
|
||||
struct monst *mtmp;
|
||||
struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */
|
||||
{
|
||||
boolean onmap = (mtmp->mx > -1);
|
||||
boolean onmap = (mtmp->mx > 0);
|
||||
|
||||
if (mtmp == context.polearm.hitmon)
|
||||
context.polearm.hitmon = 0;
|
||||
|
||||
80
src/pickup.c
80
src/pickup.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pickup.c $NHDT-Date: 1541312259 2018/11/04 06:17:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.201 $ */
|
||||
/* NetHack 3.6 pickup.c $NHDT-Date: 1542798625 2018/11/21 11:10:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.202 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -34,7 +34,6 @@ STATIC_PTR int FDECL(in_container, (struct obj *));
|
||||
STATIC_PTR int FDECL(out_container, (struct obj *));
|
||||
STATIC_DCL void FDECL(removed_from_icebox, (struct obj *));
|
||||
STATIC_DCL long FDECL(mbag_item_gone, (int, struct obj *));
|
||||
STATIC_DCL void FDECL(observe_quantum_cat, (struct obj *));
|
||||
STATIC_DCL void FDECL(explain_container_prompt, (BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(traditional_loot, (BOOLEAN_P));
|
||||
STATIC_DCL int FDECL(menu_loot, (int, BOOLEAN_P));
|
||||
@@ -2321,45 +2320,66 @@ struct obj *item;
|
||||
return loss;
|
||||
}
|
||||
|
||||
STATIC_OVL void
|
||||
observe_quantum_cat(box)
|
||||
/* used for #loot/apply, #tip, and final disclosure */
|
||||
void
|
||||
observe_quantum_cat(box, makecat, givemsg)
|
||||
struct obj *box;
|
||||
boolean makecat, givemsg;
|
||||
{
|
||||
static NEARDATA const char sc[] = "Schroedinger's Cat";
|
||||
struct obj *deadcat;
|
||||
struct monst *livecat;
|
||||
struct monst *livecat = 0;
|
||||
xchar ox, oy;
|
||||
boolean itsalive = !rn2(2);
|
||||
|
||||
box->spe = 0; /* box->owt will be updated below */
|
||||
if (get_obj_location(box, &ox, &oy, 0))
|
||||
box->ox = ox, box->oy = oy; /* in case it's being carried */
|
||||
|
||||
/* this isn't really right, since any form of observation
|
||||
(telepathic or monster/object/food detection) ought to
|
||||
force the determination of alive vs dead state; but basing
|
||||
it just on opening the box is much simpler to cope with */
|
||||
livecat = rn2(2)
|
||||
? makemon(&mons[PM_HOUSECAT], box->ox, box->oy, NO_MINVENT)
|
||||
: 0;
|
||||
if (livecat) {
|
||||
livecat->mpeaceful = 1;
|
||||
set_malign(livecat);
|
||||
if (!canspotmon(livecat))
|
||||
You("think %s brushed your %s.", something, body_part(FOOT));
|
||||
else
|
||||
pline("%s inside the box is still alive!", Monnam(livecat));
|
||||
(void) christen_monst(livecat, sc);
|
||||
} else {
|
||||
deadcat = mk_named_object(CORPSE, &mons[PM_HOUSECAT],
|
||||
box->ox, box->oy, sc);
|
||||
if (deadcat) {
|
||||
obj_extract_self(deadcat);
|
||||
(void) add_to_container(box, deadcat);
|
||||
force the determination of alive vs dead state; but basing it
|
||||
just on opening or disclosing the box is much simpler to cope with */
|
||||
|
||||
/* SchroedingersBox already has a cat corpse in it */
|
||||
deadcat = box->cobj;
|
||||
if (itsalive) {
|
||||
if (makecat)
|
||||
livecat = makemon(&mons[PM_HOUSECAT], box->ox, box->oy,
|
||||
NO_MINVENT | MM_ADJACENTOK);
|
||||
if (livecat) {
|
||||
livecat->mpeaceful = 1;
|
||||
set_malign(livecat);
|
||||
if (givemsg) {
|
||||
if (!canspotmon(livecat))
|
||||
You("think %s brushed your %s.", something,
|
||||
body_part(FOOT));
|
||||
else
|
||||
pline("%s inside the box is still alive!",
|
||||
Monnam(livecat));
|
||||
}
|
||||
(void) christen_monst(livecat, sc);
|
||||
if (deadcat) {
|
||||
obj_extract_self(deadcat);
|
||||
obfree(deadcat, (struct obj *) 0), deadcat = 0;
|
||||
}
|
||||
box->owt = weight(box);
|
||||
box->spe = 0;
|
||||
}
|
||||
pline_The("%s inside the box is dead!",
|
||||
Hallucination ? rndmonnam((char *) 0) : "housecat");
|
||||
} else {
|
||||
box->spe = 0; /* now an ordinary box (with a cat corpse inside) */
|
||||
if (deadcat) {
|
||||
/* set_corpsenm() will start the rot timer that was removed
|
||||
when makemon() created SchroedingersBox; start it from
|
||||
now rather than from when this special corpse got created */
|
||||
deadcat->age = monstermoves;
|
||||
set_corpsenm(deadcat, PM_HOUSECAT);
|
||||
deadcat = oname(deadcat, sc);
|
||||
}
|
||||
if (givemsg)
|
||||
pline_The("%s inside the box is dead!",
|
||||
Hallucination ? rndmonnam((char *) 0) : "housecat");
|
||||
}
|
||||
box->owt = weight(box);
|
||||
nhUse(deadcat);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2472,7 +2492,7 @@ boolean more_containers; /* True iff #loot multiple and this isn't last one */
|
||||
/* check for Schroedinger's Cat */
|
||||
quantum_cat = SchroedingersBox(current_container);
|
||||
if (quantum_cat) {
|
||||
observe_quantum_cat(current_container);
|
||||
observe_quantum_cat(current_container, TRUE, TRUE);
|
||||
used = 1;
|
||||
}
|
||||
|
||||
@@ -3096,7 +3116,7 @@ struct obj *box; /* or bag */
|
||||
} else if (SchroedingersBox(box)) {
|
||||
char yourbuf[BUFSZ];
|
||||
|
||||
observe_quantum_cat(box);
|
||||
observe_quantum_cat(box, TRUE, TRUE);
|
||||
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));
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 restore.c $NHDT-Date: 1451082255 2015/12/25 22:24:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.103 $ */
|
||||
/* NetHack 3.6 restore.c $NHDT-Date: 1542798626 2018/11/21 11:10:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.109 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Michael Allison, 2009. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -298,10 +298,32 @@ boolean ghostly, frozen;
|
||||
/* get contents of a container or statue */
|
||||
if (Has_contents(otmp)) {
|
||||
struct obj *otmp3;
|
||||
|
||||
otmp->cobj = restobjchn(fd, ghostly, Is_IceBox(otmp));
|
||||
/* restore container back pointers */
|
||||
for (otmp3 = otmp->cobj; otmp3; otmp3 = otmp3->nobj)
|
||||
otmp3->ocontainer = otmp;
|
||||
} else if (SchroedingersBox(otmp)) {
|
||||
struct obj *catcorpse;
|
||||
|
||||
/*
|
||||
* TODO: Remove this after 3.6.x save compatibility is dropped.
|
||||
*
|
||||
* For 3.6.2, SchroedingersBox() always has a cat corpse in it.
|
||||
* For 3.6.[01], it was empty and its weight was falsified
|
||||
* to have the value it would have had if there was one inside.
|
||||
* Put a non-rotting cat corpse in this box to convert to 3.6.2.
|
||||
*
|
||||
* [Note: after this fix up, future save/restore of this object
|
||||
* will take the Has_contents() code path above.]
|
||||
*/
|
||||
if ((catcorpse = mksobj(CORPSE, TRUE, FALSE)) != 0) {
|
||||
otmp->spe = 1; /* flag for special SchroedingersBox */
|
||||
set_corpsenm(catcorpse, PM_HOUSECAT);
|
||||
(void) stop_timer(ROT_CORPSE, obj_to_any(catcorpse));
|
||||
add_to_container(otmp, catcorpse);
|
||||
otmp->owt = weight(otmp);
|
||||
}
|
||||
}
|
||||
if (otmp->bypass)
|
||||
otmp->bypass = 0;
|
||||
|
||||
15
src/zap.c
15
src/zap.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1537234123 2018/09/18 01:28:43 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.287 $ */
|
||||
/* NetHack 3.6 zap.c $NHDT-Date: 1542798627 2018/11/21 11:10:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.289 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1916,14 +1916,17 @@ struct obj *obj, *otmp;
|
||||
if (Is_container(obj) || obj->otyp == STATUE) {
|
||||
obj->cknown = obj->lknown = 1;
|
||||
if (!obj->cobj) {
|
||||
boolean catbox = SchroedingersBox(obj);
|
||||
|
||||
pline("%s empty.", Tobjnam(obj, "are"));
|
||||
} else if (SchroedingersBox(obj)) {
|
||||
/* we don't want to force alive vs dead
|
||||
determination for Schroedinger's Cat here,
|
||||
so just make probing be inconclusive for it */
|
||||
if (catbox)
|
||||
obj->cknown = 0;
|
||||
pline("%s empty.", Tobjnam(obj, catbox ? "seem" : "are"));
|
||||
You("aren't sure whether %s has %s or its corpse inside.",
|
||||
the(xname(obj)),
|
||||
/* unfortunately, we can't tell whether rndmonnam()
|
||||
picks a form which can't leave a corpse */
|
||||
an(Hallucination ? rndmonnam((char *) 0) : "cat"));
|
||||
obj->cknown = 0;
|
||||
} else {
|
||||
struct obj *o;
|
||||
/* view contents (not recursively) */
|
||||
|
||||
@@ -688,11 +688,11 @@ tty_delay_output()
|
||||
clock_t goal;
|
||||
int k;
|
||||
|
||||
goal = 50 + clock();
|
||||
back_buffer_flip();
|
||||
if (iflags.debug_fuzzer)
|
||||
return;
|
||||
|
||||
goal = 50 + clock();
|
||||
back_buffer_flip();
|
||||
while (goal > clock()) {
|
||||
k = junk; /* Do nothing */
|
||||
}
|
||||
|
||||
@@ -185,6 +185,8 @@ static const char scanmap[] = {
|
||||
'b', 'n', 'm', ',', '.', '?' /* ... */
|
||||
};
|
||||
|
||||
#define IDT_FUZZ_TIMER 100
|
||||
|
||||
/*
|
||||
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
|
||||
//
|
||||
@@ -727,6 +729,62 @@ mswin_layout_main_window(HWND changed_child)
|
||||
SetForegroundWindow(changed_child);
|
||||
}
|
||||
|
||||
VOID CALLBACK FuzzTimerProc(
|
||||
_In_ HWND hwnd,
|
||||
_In_ UINT uMsg,
|
||||
_In_ UINT_PTR idEvent,
|
||||
_In_ DWORD dwTime
|
||||
)
|
||||
{
|
||||
INPUT input[16];
|
||||
int i_pos = 0;
|
||||
int c = randomkey();
|
||||
SHORT k = VkKeyScanA(c);
|
||||
BOOL gen_alt = (rn2(50) == 0) && isalpha(c);
|
||||
|
||||
if (!iflags.debug_fuzzer) {
|
||||
KillTimer(hwnd, IDT_FUZZ_TIMER);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!GetFocus())
|
||||
return;
|
||||
|
||||
ZeroMemory(input, sizeof(input));
|
||||
if (gen_alt) {
|
||||
input[i_pos].type = INPUT_KEYBOARD;
|
||||
input[i_pos].ki.dwFlags = KEYEVENTF_SCANCODE;
|
||||
input[i_pos].ki.wScan = MapVirtualKey(VK_MENU, 0);
|
||||
i_pos++;
|
||||
}
|
||||
|
||||
if (HIBYTE(k) & 1) {
|
||||
input[i_pos].type = INPUT_KEYBOARD;
|
||||
input[i_pos].ki.dwFlags = KEYEVENTF_SCANCODE;
|
||||
input[i_pos].ki.wScan = MapVirtualKey(VK_LSHIFT, 0);
|
||||
i_pos++;
|
||||
}
|
||||
|
||||
input[i_pos].type = INPUT_KEYBOARD;
|
||||
input[i_pos].ki.dwFlags = KEYEVENTF_SCANCODE;
|
||||
input[i_pos].ki.wScan = MapVirtualKey(LOBYTE(k), 0);
|
||||
i_pos++;
|
||||
|
||||
if (HIBYTE(k) & 1) {
|
||||
input[i_pos].type = INPUT_KEYBOARD;
|
||||
input[i_pos].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
|
||||
input[i_pos].ki.wScan = MapVirtualKey(VK_LSHIFT, 0);
|
||||
i_pos++;
|
||||
}
|
||||
if (gen_alt) {
|
||||
input[i_pos].type = INPUT_KEYBOARD;
|
||||
input[i_pos].ki.dwFlags = KEYEVENTF_SCANCODE | KEYEVENTF_KEYUP;
|
||||
input[i_pos].ki.wScan = MapVirtualKey(VK_MENU, 0);
|
||||
i_pos++;
|
||||
}
|
||||
SendInput(i_pos, input, sizeof(input[0]));
|
||||
}
|
||||
|
||||
LRESULT
|
||||
onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@@ -745,11 +803,22 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
mswin_display_splash_window(TRUE);
|
||||
break;
|
||||
|
||||
case IDM_FUZZ:
|
||||
if (iflags.debug_fuzzer)
|
||||
KillTimer(hWnd, IDT_FUZZ_TIMER);
|
||||
else
|
||||
SetTimer(hWnd, IDT_FUZZ_TIMER, 10, FuzzTimerProc);
|
||||
iflags.debug_fuzzer = !iflags.debug_fuzzer;
|
||||
break;
|
||||
case IDM_EXIT:
|
||||
if (iflags.debug_fuzzer)
|
||||
break;
|
||||
done2();
|
||||
break;
|
||||
|
||||
case IDM_SAVE:
|
||||
if (iflags.debug_fuzzer)
|
||||
break;
|
||||
if (!program_state.gameover && !program_state.done_hup)
|
||||
dosave();
|
||||
else
|
||||
@@ -829,6 +898,9 @@ onWMCommand(HWND hWnd, WPARAM wParam, LPARAM lParam)
|
||||
wchar_t *wtext;
|
||||
int tlen = 0;
|
||||
|
||||
if (iflags.debug_fuzzer)
|
||||
break;
|
||||
|
||||
ZeroMemory(filename, sizeof(filename));
|
||||
ZeroMemory(&ofn, sizeof(ofn));
|
||||
ofn.lStructSize = sizeof(OPENFILENAME);
|
||||
|
||||
@@ -142,6 +142,7 @@
|
||||
#define IDM_SETTING_LOCKWINDOWS 32797
|
||||
#define IDM_SETTING_SCREEN_TO_CLIPBOARD 32798
|
||||
#define IDM_SETTING_SCREEN_TO_FILE 32799
|
||||
#define IDM_FUZZ 32800
|
||||
#define IDC_STATIC -1
|
||||
|
||||
// Next default values for new objects
|
||||
@@ -149,7 +150,7 @@
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 146
|
||||
#define _APS_NEXT_COMMAND_VALUE 32800
|
||||
#define _APS_NEXT_COMMAND_VALUE 32801
|
||||
#define _APS_NEXT_CONTROL_VALUE 1341
|
||||
#define _APS_NEXT_SYMED_VALUE 110
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user