-$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
lineage following the release of 3.6.2 in May 2019. Please note, however,
water failed because dropping stuff left hero overly encumbered and
hero was life saved--or player declined to die--if the hero got
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
-/* 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 */
/* NetHack may be freely redistributed. See license for details. */
STATIC_DCL void FDECL(check_strangling, (BOOLEAN_P));
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 FDECL(drop_weapon, (int));
STATIC_DCL int FDECL(armor_to_dragon, (int));
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
break_armor()
{
if (otmp->oartifact) {
Your("%s falls off!", cloak_simple_name(otmp));
(void) Cloak_off();
- dropx(otmp);
+ dropp(otmp);
} else {
Your("%s tears apart!", cloak_simple_name(otmp));
(void) Cloak_off();
cancel_don();
Your("armor falls around you!");
(void) Armor_gone();
- dropx(otmp);
+ dropp(otmp);
}
if ((otmp = uarmc) != 0) {
if (is_whirly(youmonst.data))
else
You("shrink out of your %s!", cloak_simple_name(otmp));
(void) Cloak_off();
- dropx(otmp);
+ dropp(otmp);
}
if ((otmp = uarmu) != 0) {
if (is_whirly(youmonst.data))
else
You("become much too small for your shirt!");
setworn((struct obj *) 0, otmp->owornmask & W_ARMU);
- dropx(otmp);
+ dropp(otmp);
}
}
if (has_horns(youmonst.data)) {
Your("%s falls to the %s!", helm_simple_name(otmp),
surface(u.ux, u.uy));
(void) Helmet_off();
- dropx(otmp);
+ dropp(otmp);
}
}
}
You("drop your gloves%s!", uwep ? " and weapon" : "");
drop_weapon(0);
(void) Gloves_off();
- dropx(otmp);
+ dropp(otmp);
}
if ((otmp = uarms) != 0) {
You("can no longer hold your shield!");
(void) Shield_off();
- dropx(otmp);
+ dropp(otmp);
}
if ((otmp = uarmh) != 0) {
if (donning(otmp))
Your("%s falls to the %s!", helm_simple_name(otmp),
surface(u.ux, u.uy));
(void) Helmet_off();
- dropx(otmp);
+ dropp(otmp);
}
}
if (nohands(youmonst.data) || verysmall(youmonst.data)
Your("boots %s off your feet!",
verysmall(youmonst.data) ? "slide" : "are pushed");
(void) Boots_off();
- dropx(otmp);
+ dropp(otmp);
}
}
}
updateinv = FALSE;
else if (candropwep)
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)
update_inventory();