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:
23
src/mkobj.c
23
src/mkobj.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1542798624 2018/11/21 11:10:24 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.136 $ */
|
||||
/* NetHack 3.6 mkobj.c $NHDT-Date: 1545597425 2018/12/23 20:37:05 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2168,18 +2168,21 @@ boolean tipping; /* caller emptying entire contents; affects shop handling */
|
||||
being included in its formatted name during next message */
|
||||
iflags.suppress_price++;
|
||||
if (!tipping) {
|
||||
obj = hold_another_object(
|
||||
obj, u.uswallow ? "Oops! %s out of your reach!"
|
||||
: (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
|
||||
|| levl[u.ux][u.uy].typ < IRONBARS
|
||||
|| levl[u.ux][u.uy].typ >= ICE)
|
||||
? "Oops! %s away from you!"
|
||||
: "Oops! %s to the floor!",
|
||||
The(aobjnam(obj, "slip")), (const char *) 0);
|
||||
obj = hold_another_object(obj,
|
||||
u.uswallow
|
||||
? "Oops! %s out of your reach!"
|
||||
: (Is_airlevel(&u.uz)
|
||||
|| Is_waterlevel(&u.uz)
|
||||
|| levl[u.ux][u.uy].typ < IRONBARS
|
||||
|| levl[u.ux][u.uy].typ >= ICE)
|
||||
? "Oops! %s away from you!"
|
||||
: "Oops! %s to the floor!",
|
||||
The(aobjnam(obj, "slip")), (char *) 0);
|
||||
nhUse(obj);
|
||||
} else {
|
||||
/* assumes this is taking place at hero's location */
|
||||
if (!can_reach_floor(TRUE)) {
|
||||
hitfloor(obj); /* does altar check, message, drop */
|
||||
hitfloor(obj, TRUE); /* does altar check, message, drop */
|
||||
} else {
|
||||
if (IS_ALTAR(levl[u.ux][u.uy].typ))
|
||||
doaltarobj(obj); /* does its own drop message */
|
||||
|
||||
Reference in New Issue
Block a user