fix #H6942 - dropx vs hold_another_object

Dropping an existing fragile item while levitating will usually
break it.  Getting a new wished-for fragile item and dropping it
because of fumbling or overfull inventory never would.

Some callers of hold_another_object() held on to its return value,
others discarded that.  That return value was unsafe if the item
was dropped and fell down a hole (or broke [after this change]).
Return Null if we can't be sure of the value, and make sure all
callers are prepared to deal with Null.
This commit is contained in:
PatR
2018-12-23 12:37:26 -08:00
parent df5dc6050d
commit 7bc36ddef4
11 changed files with 68 additions and 47 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dothrow.c $NHDT-Date: 1545044705 2018/12/17 11:05:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.154 $ */
/* NetHack 3.6 dothrow.c $NHDT-Date: 1545597420 2018/12/23 20:37:00 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.155 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2013. */
/* NetHack may be freely redistributed. See license for details. */
@@ -415,21 +415,21 @@ boolean verbose;
}
}
/*
* Object hits floor at hero's feet. Called from drop() and throwit().
*/
/* Object hits floor at hero's feet.
Called from drop(), throwit(), hold_another_object(). */
void
hitfloor(obj)
register struct obj *obj;
hitfloor(obj, verbosely)
struct obj *obj;
boolean verbosely; /* usually True; False if caller has given drop message */
{
if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater) {
if (IS_SOFT(levl[u.ux][u.uy].typ) || u.uinwater || u.uswallow) {
dropy(obj);
return;
}
if (IS_ALTAR(levl[u.ux][u.uy].typ))
doaltarobj(obj);
else
pline("%s hit%s the %s.", Doname2(obj), (obj->quan == 1L) ? "s" : "",
else if (verbosely)
pline("%s %s the %s.", Doname2(obj), otense(obj, "hit"),
surface(u.ux, u.uy));
if (hero_breaks(obj, u.ux, u.uy, TRUE))
@@ -1047,7 +1047,7 @@ boolean hitsroof;
done(STONING);
return obj ? TRUE : FALSE;
}
hitfloor(obj);
hitfloor(obj, TRUE);
thrownobj = 0;
losehp(Maybe_Half_Phys(dmg), "falling object", KILLED_BY_AN);
}
@@ -1168,7 +1168,7 @@ boolean twoweap; /* used to restore twoweapon mode if wielded weapon returns */
for dealing with cursed saddle: throw holy water > */
potionhit(u.usteed, obj, POTHIT_HERO_THROW);
} else {
hitfloor(obj);
hitfloor(obj, TRUE);
}
thrownobj = (struct obj *) 0;
return;