ball&chain sanity checking

Add a bc sanity check.  It seems to work ok--in other words, not
trigger--under normal punishment.  I don't have any test cases to
exercise its warnings.

This dragged in a couple of minor bc changes that were pending.  I
should have cleared those out before tackling the sanity checking.
This commit is contained in:
PatR
2019-05-05 13:33:30 -07:00
parent bed2c2307e
commit a8550fc0e7
3 changed files with 83 additions and 13 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1555201698 2019/04/14 00:28:18 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.702 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1557088399 2019/05/05 20:33:19 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.703 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -135,6 +135,7 @@ E boolean FDECL(drag_ball, (XCHAR_P, XCHAR_P, int *, xchar *, xchar *,
xchar *, xchar *, boolean *, BOOLEAN_P));
E void FDECL(drop_ball, (XCHAR_P, XCHAR_P));
E void NDECL(drag_down);
E void NDECL(bc_sanity_check);
/* ### bones.c ### */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 ball.c $NHDT-Date: 1450402033 2015/12/18 01:27:13 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.29 $ */
/* NetHack 3.6 ball.c $NHDT-Date: 1557088406 2019/05/05 20:33:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.36 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) David Cohrs, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -24,12 +24,14 @@ boolean showmsg;
setuswapwep((struct obj *) 0);
if (uquiver == uball)
setuqwep((struct obj *) 0);
;
if (uwep != uball)
freeinv(uball);
/* [this used to test 'if (uwep != uball)' but that always passes
after the setuwep() above] */
freeinv(uball); /* remove from inventory but don't place on floor */
encumber_msg();
}
}
/* ball&chain might hit hero when falling through a trap door */
void
ballfall()
{
@@ -40,6 +42,7 @@ ballfall()
ballrelease(TRUE);
if (gets_hit) {
int dmg = rn1(7, 25);
pline_The("iron ball falls on your %s.", body_part(HEAD));
if (uarmh) {
if (is_metallic(uarmh)) {
@@ -113,9 +116,9 @@ placebc()
(void) flooreffects(uchain, u.ux, u.uy, ""); /* chain might rust */
if (carried(uball)) /* the ball is carried */
if (carried(uball)) { /* the ball is carried */
u.bc_order = BCPOS_DIFFER;
else {
} else {
/* ball might rust -- already checked when carried */
(void) flooreffects(uball, u.ux, u.uy, "");
place_object(uball, u.ux, u.uy);
@@ -411,6 +414,7 @@ boolean allow_drag;
/* only need to move the chain? */
if (carried(uball) || distmin(x, y, uball->ox, uball->oy) <= 2) {
xchar oldchainx = uchain->ox, oldchainy = uchain->oy;
*bc_control = BC_CHAIN;
move_bc(1, *bc_control, *ballx, *bally, *chainx, *chainy);
if (carried(uball)) {
@@ -584,7 +588,7 @@ boolean allow_drag;
return TRUE;
}
drag:
drag:
if (near_capacity() > SLT_ENCUMBER && dist2(x, y, u.ux, u.uy) <= 2) {
You("cannot %sdrag the heavy iron ball.",
@@ -774,21 +778,24 @@ xchar x, y;
}
}
/* ball&chain cause hero to randomly lose stuff from inventory */
STATIC_OVL void
litter()
{
struct obj *otmp = invent, *nextobj;
struct obj *otmp, *nextobj = 0;
int capacity = weight_cap();
while (otmp) {
for (otmp = invent; otmp; otmp = nextobj) {
nextobj = otmp->nobj;
if ((otmp != uball) && (rnd(capacity) <= (int) otmp->owt)) {
if (canletgo(otmp, "")) {
pline("%s you down the stairs.", Yobjnam2(otmp, "follow"));
You("drop %s and %s %s down the stairs with you.",
yname(otmp), (otmp->quan == 1L) ? "it" : "they",
otense(otmp, "fall"));
dropx(otmp);
encumber_msg(); /* drop[xyz]() probably ought to to this... */
}
}
otmp = nextobj;
}
}
@@ -839,4 +846,65 @@ drag_down()
}
}
void
bc_sanity_check()
{
int otyp;
unsigned save_nameknown;
const char *onam;
if (Punished && (!uball || !uchain)) {
impossible("Punished without %s%s%s?",
!uball ? "iron ball" : "",
(!uball && !uchain) ? " and " : "",
!uchain ? "attached chain" : "");
} else if (!Punished && (uball || uchain)) {
impossible("Attached %s%s%s without being Punished?",
uchain ? "chain" : "",
(uchain && uball) ? " and " : "",
uball ? "iron ball" : "");
}
/* ball is free when swallowed, changing levels, other times? */
if (uball && (uball->otyp != HEAVY_IRON_BALL
|| (uball->where != OBJ_FLOOR
&& uball->where != OBJ_INVENT
&& uball->where != OBJ_FREE)
|| (uball->owornmask & W_BALL) == 0L
|| (uball->owornmask & ~(W_BALL | W_WEAPON)) != 0L)) {
otyp = uball->otyp;
if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
|| !OBJ_NAME(objects[otyp])) {
onam = "glorkum";
} else {
save_nameknown = objects[otyp].oc_name_known;
objects[otyp].oc_name_known = 1;
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uball: type %d (%s), where %d, wornmask=0x%08lx",
otyp, onam, uball->where, uball->owornmask);
}
/* similar check to ball except can't be in inventory */
if (uchain && (uchain->otyp != IRON_CHAIN
|| (uchain->where != OBJ_FLOOR
&& uchain->where != OBJ_FREE)
/* [could simplify this to owornmask != W_CHAIN] */
|| (uchain->owornmask & W_CHAIN) == 0L
|| (uchain->owornmask & ~W_CHAIN) != 0L)) {
otyp = uchain->otyp;
if (otyp < STRANGE_OBJECT || otyp >= NUM_OBJECTS
|| !OBJ_NAME(objects[otyp])) {
onam = "glorkum";
} else {
save_nameknown = objects[otyp].oc_name_known;
objects[otyp].oc_name_known = 1;
onam = simple_typename(otyp);
objects[otyp].oc_name_known = save_nameknown;
}
impossible("uchain: type %d (%s), where %d, wornmask=0x%08lx",
otyp, onam, uchain->where, uchain->owornmask);
}
/* [check bc_order too?] */
}
/*ball.c*/

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 cmd.c $NHDT-Date: 1549327488 2019/02/05 00:44:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.331 $ */
/* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -4102,6 +4102,7 @@ sanity_check()
timer_sanity_check();
mon_sanity_check();
light_sources_sanity_check();
bc_sanity_check();
}
#ifdef DEBUG_MIGRATING_MONS