Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-09-23 20:46:38 -04:00
5 changed files with 63 additions and 53 deletions

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.115 $ $NHDT-Date: 1569189769 2019/09/22 22:02:49 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ $NHDT-Date: 1569276988 2019/09/23 22:16:28 $
This fixes36.3 file is here to capture information about updates in the 3.6.x This fixes36.3 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.2 in May 2019. Please note, however, lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -149,6 +149,9 @@ zapping self with wand of opening or spell of knock to escape from a trap
reported "you're released from <trap>" rather than "from the <trap>" reported "you're released from <trap>" rather than "from the <trap>"
zapping self with wand of opening or spell of knock to escape from a pit trap zapping self with wand of opening or spell of knock to escape from a pit trap
didn't reset vision limits--only spots adjacent to pit were visible didn't reset vision limits--only spots adjacent to pit were visible
wielded aklys that returned to hero when thrown while inside an engulfer left
a stale 'thrownobj' pointer that triggered "add_to_minv: obj not free"
panic if same weapon killed any engulfer via melee from inside
Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository Fixes to Post-3.6.2 Problems that Were Exposed Via git Repository

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 flag.h $NHDT-Date: 1562532730 2019/07/07 20:52:10 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.152 $ */ /* NetHack 3.6 flag.h $NHDT-Date: 1569276988 2019/09/23 22:16:28 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.155 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */ /*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -432,6 +432,7 @@ struct instance_flags {
boolean windowtype_deferred; /* pick a windowport and store it in boolean windowtype_deferred; /* pick a windowport and store it in
chosen_windowport[], but do not switch to chosen_windowport[], but do not switch to
it in the midst of options processing */ it in the midst of options processing */
genericptr_t returning_missile; /* 'struct obj *'; Mjollnir or aklys */
boolean obsolete; /* obsolete options can point at this, it isn't used */ boolean obsolete; /* obsolete options can point at this, it isn't used */
}; };

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1556201496 2019/04/25 14:11:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.160 $ */ /* NetHack 3.6 dothrow.c $NHDT-Date: 1569276989 2019/09/23 22:16:29 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.161 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1096,10 +1096,11 @@ long wep_mask; /* used to re-equip returning boomerang */
boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
{ {
register struct monst *mon; register struct monst *mon;
register int range, urange; int range, urange;
boolean crossbowing, impaired = (Confusion || Stunned || Blind boolean crossbowing, clear_thrownobj = FALSE,
|| Hallucination || Fumbling); impaired = (Confusion || Stunned || Blind
boolean tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0); || Hallucination || Fumbling),
tethered_weapon = (obj->otyp == AKLYS && (wep_mask & W_WEP) != 0);
g.notonhead = FALSE; /* reset potentially stale value */ g.notonhead = FALSE; /* reset potentially stale value */
if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) { if ((obj->cursed || obj->greased) && (u.dx || u.dy) && !rn2(7)) {
@@ -1140,6 +1141,12 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
g.thrownobj = obj; g.thrownobj = obj;
g.thrownobj->was_thrown = 1; g.thrownobj->was_thrown = 1;
iflags.returning_missile = ((obj->oartifact == ART_MJOLLNIR
&& Role_if(PM_VALKYRIE))
|| tethered_weapon) ? (genericptr_t) obj
: (genericptr_t) 0;
/* NOTE: No early returns after this point or returning_missile
will be left with a stale pointer. */
if (u.uswallow) { if (u.uswallow) {
mon = u.ustuck; mon = u.ustuck;
@@ -1151,8 +1158,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
if (u.dz < 0 if (u.dz < 0
/* Mjollnir must we wielded to be thrown--caller verifies this; /* Mjollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */ aklys must we wielded as primary to return when thrown */
&& ((Role_if(PM_VALKYRIE) && obj->oartifact == ART_MJOLLNIR) && iflags.returning_missile
|| tethered_weapon)
&& !impaired) { && !impaired) {
pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"), pline("%s the %s and returns to your hand!", Tobjnam(obj, "hit"),
ceiling(u.ux, u.uy)); ceiling(u.ux, u.uy));
@@ -1172,8 +1178,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
} else { } else {
hitfloor(obj, TRUE); hitfloor(obj, TRUE);
} }
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} else if (obj->otyp == BOOMERANG && !Underwater) { } else if (obj->otyp == BOOMERANG && !Underwater) {
if (Is_airlevel(&u.uz) || Levitation) if (Is_airlevel(&u.uz) || Levitation)
@@ -1187,8 +1193,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
setworn(obj, wep_mask); setworn(obj, wep_mask);
u.twoweap = twoweap; u.twoweap = twoweap;
} }
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} }
} else { } else {
/* crossbow range is independent of strength */ /* crossbow range is independent of strength */
@@ -1263,7 +1269,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
we're about to return */ we're about to return */
if (tethered_weapon) if (tethered_weapon)
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
return; goto throwit_return;
} }
} }
@@ -1271,8 +1277,8 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
boolean obj_gone; boolean obj_gone;
if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) { if (mon->isshk && obj->where == OBJ_MINVENT && obj->ocarry == mon) {
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; /* alert shk caught it */ goto throwit_return; /* alert shk caught it */
} }
(void) snuff_candle(obj); (void) snuff_candle(obj);
g.notonhead = (g.bhitpos.x != mon->mx || g.bhitpos.y != mon->my); g.notonhead = (g.bhitpos.x != mon->mx || g.bhitpos.y != mon->my);
@@ -1287,33 +1293,22 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
hot_pursuit(mon); hot_pursuit(mon);
if (obj_gone) if (obj_gone)
g.thrownobj = 0; g.thrownobj = (struct obj *) 0;
} }
if (!g.thrownobj) { if (!g.thrownobj) {
/* missile has already been handled */ /* missile has already been handled */
if (tethered_weapon) tmp_at(DISP_END, 0); if (tethered_weapon)
} else if (u.uswallow) {
if (tethered_weapon) {
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
pline("%s returns to your hand!", The(xname(g.thrownobj))); } else if (u.uswallow && !iflags.returning_missile) {
g.thrownobj = addinv(g.thrownobj); swallowit:
(void) encumber_msg(); if (obj != uball)
/* in case addinv() autoquivered */ (void) mpickobj(u.ustuck, obj); /* clears 'g.thrownobj' */
if (g.thrownobj->owornmask & W_QUIVER) goto throwit_return;
setuqwep((struct obj *) 0);
setuwep(g.thrownobj);
} else {
/* ball is not picked up by monster */
if (obj != uball)
(void) mpickobj(u.ustuck, obj);
g.thrownobj = (struct obj *) 0;
}
} else { } else {
/* Mjollnir must we wielded to be thrown--caller verifies this; /* Mjollnir must we wielded to be thrown--caller verifies this;
aklys must we wielded as primary to return when thrown */ aklys must we wielded as primary to return when thrown */
if ((obj->oartifact == ART_MJOLLNIR && Role_if(PM_VALKYRIE)) if (iflags.returning_missile) { /* Mjollnir or aklys */
|| tethered_weapon) {
if (rn2(100)) { if (rn2(100)) {
if (tethered_weapon) if (tethered_weapon)
tmp_at(DISP_END, BACKTRACK); tmp_at(DISP_END, BACKTRACK);
@@ -1353,14 +1348,14 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
losehp(Maybe_Half_Phys(dmg), killer_xname(obj), losehp(Maybe_Half_Phys(dmg), killer_xname(obj),
KILLED_BY); KILLED_BY);
} }
if (ship_object(obj, u.ux, u.uy, FALSE)) {
g.thrownobj = (struct obj *) 0; if (u.uswallow)
return; goto swallowit;
} if (!ship_object(obj, u.ux, u.uy, FALSE))
dropy(obj); dropy(obj);
} }
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} else { } else {
if (tethered_weapon) if (tethered_weapon)
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
@@ -1372,6 +1367,9 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
explicitly rewield the weapon to get throw-and-return explicitly rewield the weapon to get throw-and-return
capability back anyway, quivered or not shouldn't matter */ capability back anyway, quivered or not shouldn't matter */
pline("%s to return!", Tobjnam(obj, "fail")); pline("%s to return!", Tobjnam(obj, "fail"));
if (u.uswallow)
goto swallowit;
/* continue below with placing 'obj' at target location */ /* continue below with placing 'obj' at target location */
} }
} }
@@ -1386,12 +1384,12 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
tmp_at(DISP_END, 0); tmp_at(DISP_END, 0);
breakmsg(obj, cansee(g.bhitpos.x, g.bhitpos.y)); breakmsg(obj, cansee(g.bhitpos.x, g.bhitpos.y));
breakobj(obj, g.bhitpos.x, g.bhitpos.y, TRUE, TRUE); breakobj(obj, g.bhitpos.x, g.bhitpos.y, TRUE, TRUE);
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} }
if (flooreffects(obj, g.bhitpos.x, g.bhitpos.y, "fall")) { if (flooreffects(obj, g.bhitpos.x, g.bhitpos.y, "fall")) {
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} }
obj_no_longer_held(obj); obj_no_longer_held(obj);
if (mon && mon->isshk && is_pick(obj)) { if (mon && mon->isshk && is_pick(obj)) {
@@ -1400,13 +1398,13 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
if (*u.ushops || obj->unpaid) if (*u.ushops || obj->unpaid)
check_shop_obj(obj, g.bhitpos.x, g.bhitpos.y, FALSE); check_shop_obj(obj, g.bhitpos.x, g.bhitpos.y, FALSE);
(void) mpickobj(mon, obj); /* may merge and free obj */ (void) mpickobj(mon, obj); /* may merge and free obj */
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} }
(void) snuff_candle(obj); (void) snuff_candle(obj);
if (!mon && ship_object(obj, g.bhitpos.x, g.bhitpos.y, FALSE)) { if (!mon && ship_object(obj, g.bhitpos.x, g.bhitpos.y, FALSE)) {
g.thrownobj = (struct obj *) 0; clear_thrownobj = TRUE;
return; goto throwit_return;
} }
g.thrownobj = (struct obj *) 0; g.thrownobj = (struct obj *) 0;
place_object(obj, g.bhitpos.x, g.bhitpos.y); place_object(obj, g.bhitpos.x, g.bhitpos.y);
@@ -1429,6 +1427,12 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
if (obj_sheds_light(obj)) if (obj_sheds_light(obj))
g.vision_full_recalc = 1; g.vision_full_recalc = 1;
} }
throwit_return:
iflags.returning_missile = (genericptr_t) 0;
if (clear_thrownobj)
g.thrownobj = (struct obj *) 0;
return;
} }
/* an object may hit a monster; various factors adjust chance of hitting */ /* an object may hit a monster; various factors adjust chance of hitting */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 mon.c $NHDT-Date: 1565833749 2019/08/15 01:49:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.296 $ */ /* NetHack 3.6 mon.c $NHDT-Date: 1569276991 2019/09/23 22:16:31 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.297 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -2368,7 +2368,9 @@ int xkill_flags; /* 1: suppress message, 2: suppress corpse, 4: pacifist */
if (mtmp->mtame && !mtmp->isminion) if (mtmp->mtame && !mtmp->isminion)
EDOG(mtmp)->killed_by_u = 1; EDOG(mtmp)->killed_by_u = 1;
if (wasinside && g.thrownobj && g.thrownobj != uball) { if (wasinside && g.thrownobj && g.thrownobj != uball
/* don't give to mon if missile is going to return to hero */
&& g.thrownobj != (struct obj *) iflags.returning_missile) {
/* thrown object has killed hero's engulfer; add it to mon's /* thrown object has killed hero's engulfer; add it to mon's
inventory now so that it will be placed with mon's other inventory now so that it will be placed with mon's other
stuff prior to lookhere/autopickup when hero is expelled stuff prior to lookhere/autopickup when hero is expelled

View File

@@ -2855,7 +2855,7 @@ boolean wep_was_destroyed;
reaction rather than the hero's escape] */ reaction rather than the hero's escape] */
pline("%s looks %s%s.", Monnam(mon), pline("%s looks %s%s.", Monnam(mon),
!rn2(2) ? "" : "rather ", !rn2(2) ? "" : "rather ",
!rn2(2) ? "numb" : "stupified"); !rn2(2) ? "numb" : "stupefied");
} else if (Free_action) { } else if (Free_action) {
You("momentarily stiffen under %s gaze!", You("momentarily stiffen under %s gaze!",
s_suffix(mon_nam(mon))); s_suffix(mon_nam(mon)));