diff --git a/doc/fixes36.2 b/doc/fixes36.2 index b63630534..d796f3260 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$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, @@ -335,6 +335,8 @@ entering Ft.Ludios with a lit candle lit up the entire entry room except for 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 diff --git a/src/do.c b/src/do.c index 610983622..d97b3dac1 100644 --- a/src/do.c +++ b/src/do.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -137,6 +137,8 @@ const char *verb; 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"); @@ -148,18 +150,43 @@ const char *verb; 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); + /* dieroll was rnd(20); 1: maximum chance to hit + since trapped target is a sitting duck */ + int damage, dieroll = 1; - if (hmon(mtmp, obj, HMON_THROWN, dieroll) - && !is_whirly(mtmp->data)) + /* 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; @@ -177,17 +204,22 @@ const char *verb; 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); diff --git a/src/uhitm.c b/src/uhitm.c index 21f30e547..1b14b271f 100644 --- a/src/uhitm.c +++ b/src/uhitm.c @@ -1,4 +1,4 @@ -/* 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. */ @@ -918,13 +918,13 @@ int dieroll; 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; @@ -958,10 +958,11 @@ int dieroll; 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)) { @@ -996,7 +997,7 @@ int dieroll; case BLINDING_VENOM: mon->msleeping = 0; if (can_blnd(&g.youmonst, mon, - (uchar) (obj->otyp == BLINDING_VENOM + (uchar) ((obj->otyp == BLINDING_VENOM) ? AT_SPIT : AT_WEAP), obj)) { @@ -1304,7 +1305,9 @@ int dieroll; 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));