-$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.229 $ $NHDT-Date: 1547421445 2019/01/13 23:17:25 $
+$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.230 $ $NHDT-Date: 1547680081 2019/01/16 23:08:01 $
This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however,
one corner spot; that corner is beyond candle radius but other spots
even further away were being shown; force the walls to unlit in order
to prevent those wall spots from showing so soon
+boulder dropped or launched by a monster onto a monster trapped in a pit and
+ killing it credited/blamed the hero and might trigger a deltrap panic
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
-/* NetHack 3.6 do.c $NHDT-Date: 1547512513 2019/01/15 00:35:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.185 $ */
+/* NetHack 3.6 do.c $NHDT-Date: 1547680082 2019/01/16 23:08:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.186 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */
struct trap *t;
struct monst *mtmp;
struct obj *otmp;
+ boolean tseen;
+ int ttyp = NO_TRAP;
if (obj->where != OBJ_FREE)
panic("flooreffects: obj not free");
return TRUE;
} else if (obj->otyp == BOULDER && (t = t_at(x, y)) != 0
&& (is_pit(t->ttyp) || is_hole(t->ttyp))) {
+ ttyp = t->ttyp;
+ tseen = t->tseen ? TRUE : FALSE;
if (((mtmp = m_at(x, y)) && mtmp->mtrapped)
|| (u.utrap && u.ux == x && u.uy == y)) {
- if (*verb)
- pline_The("boulder %s into the pit%s.",
- vtense((const char *) 0, verb),
- (mtmp) ? "" : " with you");
+ if (*verb && (cansee(x, y) || distu(x, y) == 0))
+ pline("%s boulder %s into the pit%s.",
+ Blind ? "A" : "The",
+ vtense((const char *) 0, verb),
+ mtmp ? "" : " with you");
if (mtmp) {
if (!passes_walls(mtmp->data) && !throws_rocks(mtmp->data)) {
- int dieroll = rnd(20);
-
- if (hmon(mtmp, obj, HMON_THROWN, dieroll)
- && !is_whirly(mtmp->data))
+ /* dieroll was rnd(20); 1: maximum chance to hit
+ since trapped target is a sitting duck */
+ int damage, dieroll = 1;
+
+ /* 3.6.2: this was calling hmon() unconditionally
+ so always credited/blamed the hero but the boulder
+ might have been thrown by a giant or launched by
+ a rolling boulder trap triggered by a monster or
+ dropped by a scroll of earth read by a monster */
+ if (context.mon_moving) {
+ /* normally we'd use ohitmon() but it can call
+ drop_throw() which calls flooreffects() */
+ damage = dmgval(obj, mtmp);
+ mtmp->mhp -= damage;
+ if (DEADMONSTER(mtmp)) {
+ if (canspotmon(mtmp))
+ pline("%s is %s!", Monnam(mtmp),
+ (nonliving(mtmp->data)
+ || is_vampshifter(mtmp))
+ ? "destroyed" : "killed");
+ mondied(mtmp);
+ }
+ } else {
+ (void) hmon(mtmp, obj, HMON_THROWN, dieroll);
+ }
+ if (!DEADMONSTER(mtmp) && !is_whirly(mtmp->data))
return FALSE; /* still alive */
}
mtmp->mtrapped = 0;
You_hear("a CRASH! beneath you.");
} else if (!Blind && cansee(x, y)) {
pline_The("boulder %s%s.",
- (t->ttyp == TRAPDOOR && !t->tseen)
- ? "triggers and " : "",
- t->ttyp == TRAPDOOR
+ (ttyp == TRAPDOOR && !tseen)
+ ? "triggers and " : "",
+ (ttyp == TRAPDOOR)
? "plugs a trap door"
- : t->ttyp == HOLE ? "plugs a hole"
- : "fills a pit");
+ : (ttyp == HOLE) ? "plugs a hole"
+ : "fills a pit");
} else {
You_hear("a boulder %s.", verb);
}
}
- deltrap(t);
+ /*
+ * Note: trap might have gone away via ((hmon -> killed -> xkilled)
+ * || mondied) -> mondead -> m_detach -> fill_pit.
+ */
+ if ((t = t_at(x, y)) != 0)
+ deltrap(t);
useupf(obj, 1L);
bury_objs(x, y);
newsym(x, y);
-/* NetHack 3.6 uhitm.c $NHDT-Date: 1547118630 2019/01/10 11:10:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.198 $ */
+/* NetHack 3.6 uhitm.c $NHDT-Date: 1547680084 2019/01/16 23:08:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.199 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
break;
#define useup_eggs(o) \
- { \
+ do { \
if (thrown) \
obfree(o, (struct obj *) 0); \
else \
useupall(o); \
o = (struct obj *) 0; \
- } /* now gone */
+ } while (0) /* now gone */
case EGG: {
long cnt = obj->quan;
break;
return (boolean) (!DEADMONSTER(mon));
} else { /* ordinary egg(s) */
- const char *eggp =
- (obj->corpsenm != NON_PM && obj->known)
- ? the(mons[obj->corpsenm].mname)
- : (cnt > 1L) ? "some" : "an";
+ const char *eggp = (obj->corpsenm != NON_PM
+ && obj->known)
+ ? the(mons[obj->corpsenm].mname)
+ : (cnt > 1L) ? "some" : "an";
+
You("hit %s with %s egg%s.", mon_nam(mon), eggp,
plur(cnt));
if (touch_petrifies(mdat) && !stale_egg(obj)) {
case BLINDING_VENOM:
mon->msleeping = 0;
if (can_blnd(&youmonst, mon,
- (uchar) (obj->otyp == BLINDING_VENOM
+ (uchar) ((obj->otyp == BLINDING_VENOM)
? AT_SPIT
: AT_WEAP),
obj)) {
if (unpoisonmsg)
Strcpy(saved_oname, cxname(obj));
- /* [note: thrown obj might go away during killed/xkilled call] */
+ /* [note: thrown obj might go away during killed()/xkilled() call
+ (via 'thrownobj'; if swallowed, it gets added to engulfer's
+ minvent and might merge with a stack that's already there)] */
if (needpoismsg)
pline_The("poison doesn't seem to affect %s.", mon_nam(mon));