fix #H9272 - "object lost" panic
when polymorph causes loss of levitation boots or water walking boots while over water. If discarding stuff while trying to crawl out got rid of the taken-off boots, they wouldn't be in inventory any more when break_armor() tried to drop them after taking them off.
This commit is contained in:
+4
-1
@@ -1,4 +1,4 @@
|
|||||||
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.122 $ $NHDT-Date: 1570227405 2019/10/04 22:16:45 $
|
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.123 $ $NHDT-Date: 1570230710 2019/10/04 23:11:50 $
|
||||||
|
|
||||||
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,
|
||||||
@@ -168,6 +168,9 @@ ball and chain could end up too far from punished hero (triggering b&c warning
|
|||||||
water failed because dropping stuff left hero overly encumbered and
|
water failed because dropping stuff left hero overly encumbered and
|
||||||
hero was life saved--or player declined to die--if the hero got
|
hero was life saved--or player declined to die--if the hero got
|
||||||
teleported one step further from ball and chain's current location
|
teleported one step further from ball and chain's current location
|
||||||
|
avoid 'object lost' panic when polymorph causes loss of levitation boots or
|
||||||
|
water walking boots which dumps hero into water where emergency
|
||||||
|
disrobing/dropping in order to crawl out chooses to drop those boots
|
||||||
|
|
||||||
|
|
||||||
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
|
||||||
|
|||||||
+42
-10
@@ -1,4 +1,4 @@
|
|||||||
/* NetHack 3.6 polyself.c $NHDT-Date: 1559664952 2019/06/04 16:15:52 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.133 $ */
|
/* NetHack 3.6 polyself.c $NHDT-Date: 1570230710 2019/10/04 23:11:50 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.134 $ */
|
||||||
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
|
/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
STATIC_DCL void FDECL(check_strangling, (BOOLEAN_P));
|
STATIC_DCL void FDECL(check_strangling, (BOOLEAN_P));
|
||||||
STATIC_DCL void FDECL(polyman, (const char *, const char *));
|
STATIC_DCL void FDECL(polyman, (const char *, const char *));
|
||||||
|
STATIC_DCL void FDECL(dropp, (struct obj *));
|
||||||
STATIC_DCL void NDECL(break_armor);
|
STATIC_DCL void NDECL(break_armor);
|
||||||
STATIC_DCL void FDECL(drop_weapon, (int));
|
STATIC_DCL void FDECL(drop_weapon, (int));
|
||||||
STATIC_DCL int FDECL(armor_to_dragon, (int));
|
STATIC_DCL int FDECL(armor_to_dragon, (int));
|
||||||
@@ -858,6 +859,33 @@ int mntmp;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* dropx() jacket for break_armor() */
|
||||||
|
STATIC_OVL void
|
||||||
|
dropp(obj)
|
||||||
|
struct obj *obj;
|
||||||
|
{
|
||||||
|
struct obj *otmp;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Dropping worn armor while polymorphing might put hero into water
|
||||||
|
* (loss of levitation boots or water walking boots that the new
|
||||||
|
* form can't wear), where emergency_disrobe() could remove it from
|
||||||
|
* inventory. Without this, dropx() could trigger an 'object lost'
|
||||||
|
* panic. Right now, boots are the only armor which might encounter
|
||||||
|
* this situation, but handle it for all armor.
|
||||||
|
*
|
||||||
|
* Hypothetically, 'obj' could have merged with something (not
|
||||||
|
* applicable for armor) and no longer be a valid pointer, so scan
|
||||||
|
* inventory for it instead of trusting obj->where.
|
||||||
|
*/
|
||||||
|
for (otmp = invent; otmp; otmp = otmp->nobj) {
|
||||||
|
if (otmp == obj) {
|
||||||
|
dropx(obj);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
STATIC_OVL void
|
STATIC_OVL void
|
||||||
break_armor()
|
break_armor()
|
||||||
{
|
{
|
||||||
@@ -876,7 +904,7 @@ break_armor()
|
|||||||
if (otmp->oartifact) {
|
if (otmp->oartifact) {
|
||||||
Your("%s falls off!", cloak_simple_name(otmp));
|
Your("%s falls off!", cloak_simple_name(otmp));
|
||||||
(void) Cloak_off();
|
(void) Cloak_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
} else {
|
} else {
|
||||||
Your("%s tears apart!", cloak_simple_name(otmp));
|
Your("%s tears apart!", cloak_simple_name(otmp));
|
||||||
(void) Cloak_off();
|
(void) Cloak_off();
|
||||||
@@ -893,7 +921,7 @@ break_armor()
|
|||||||
cancel_don();
|
cancel_don();
|
||||||
Your("armor falls around you!");
|
Your("armor falls around you!");
|
||||||
(void) Armor_gone();
|
(void) Armor_gone();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
if ((otmp = uarmc) != 0) {
|
if ((otmp = uarmc) != 0) {
|
||||||
if (is_whirly(youmonst.data))
|
if (is_whirly(youmonst.data))
|
||||||
@@ -901,7 +929,7 @@ break_armor()
|
|||||||
else
|
else
|
||||||
You("shrink out of your %s!", cloak_simple_name(otmp));
|
You("shrink out of your %s!", cloak_simple_name(otmp));
|
||||||
(void) Cloak_off();
|
(void) Cloak_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
if ((otmp = uarmu) != 0) {
|
if ((otmp = uarmu) != 0) {
|
||||||
if (is_whirly(youmonst.data))
|
if (is_whirly(youmonst.data))
|
||||||
@@ -909,7 +937,7 @@ break_armor()
|
|||||||
else
|
else
|
||||||
You("become much too small for your shirt!");
|
You("become much too small for your shirt!");
|
||||||
setworn((struct obj *) 0, otmp->owornmask & W_ARMU);
|
setworn((struct obj *) 0, otmp->owornmask & W_ARMU);
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (has_horns(youmonst.data)) {
|
if (has_horns(youmonst.data)) {
|
||||||
@@ -927,7 +955,7 @@ break_armor()
|
|||||||
Your("%s falls to the %s!", helm_simple_name(otmp),
|
Your("%s falls to the %s!", helm_simple_name(otmp),
|
||||||
surface(u.ux, u.uy));
|
surface(u.ux, u.uy));
|
||||||
(void) Helmet_off();
|
(void) Helmet_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -939,12 +967,12 @@ break_armor()
|
|||||||
You("drop your gloves%s!", uwep ? " and weapon" : "");
|
You("drop your gloves%s!", uwep ? " and weapon" : "");
|
||||||
drop_weapon(0);
|
drop_weapon(0);
|
||||||
(void) Gloves_off();
|
(void) Gloves_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
if ((otmp = uarms) != 0) {
|
if ((otmp = uarms) != 0) {
|
||||||
You("can no longer hold your shield!");
|
You("can no longer hold your shield!");
|
||||||
(void) Shield_off();
|
(void) Shield_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
if ((otmp = uarmh) != 0) {
|
if ((otmp = uarmh) != 0) {
|
||||||
if (donning(otmp))
|
if (donning(otmp))
|
||||||
@@ -952,7 +980,7 @@ break_armor()
|
|||||||
Your("%s falls to the %s!", helm_simple_name(otmp),
|
Your("%s falls to the %s!", helm_simple_name(otmp),
|
||||||
surface(u.ux, u.uy));
|
surface(u.ux, u.uy));
|
||||||
(void) Helmet_off();
|
(void) Helmet_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nohands(youmonst.data) || verysmall(youmonst.data)
|
if (nohands(youmonst.data) || verysmall(youmonst.data)
|
||||||
@@ -966,7 +994,7 @@ break_armor()
|
|||||||
Your("boots %s off your feet!",
|
Your("boots %s off your feet!",
|
||||||
verysmall(youmonst.data) ? "slide" : "are pushed");
|
verysmall(youmonst.data) ? "slide" : "are pushed");
|
||||||
(void) Boots_off();
|
(void) Boots_off();
|
||||||
dropx(otmp);
|
dropp(otmp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1019,6 +1047,10 @@ int alone;
|
|||||||
updateinv = FALSE;
|
updateinv = FALSE;
|
||||||
else if (candropwep)
|
else if (candropwep)
|
||||||
dropx(otmp);
|
dropx(otmp);
|
||||||
|
/* [note: dropp vs dropx -- if heart of ahriman is wielded, we
|
||||||
|
might be losing levitation by dropping it; but that won't
|
||||||
|
happen until the drop, unlike Boots_off() dumping hero into
|
||||||
|
water and triggering emergency_disrobe() before dropx()] */
|
||||||
|
|
||||||
if (updateinv)
|
if (updateinv)
|
||||||
update_inventory();
|
update_inventory();
|
||||||
|
|||||||
Reference in New Issue
Block a user