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:
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 artifact.c $NHDT-Date: 1543745353 2018/12/02 10:09:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.127 $ */
|
||||
/* NetHack 3.6 artifact.c $NHDT-Date: 1545597414 2018/12/23 20:36:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.128 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1479,6 +1479,7 @@ struct obj *obj;
|
||||
}
|
||||
case ENERGY_BOOST: {
|
||||
int epboost = (u.uenmax + 1 - u.uen) / 2;
|
||||
|
||||
if (epboost > 120)
|
||||
epboost = 120; /* arbitrary */
|
||||
else if (epboost < 12)
|
||||
@@ -1598,6 +1599,7 @@ struct obj *obj;
|
||||
otmp->owt = weight(otmp);
|
||||
otmp = hold_another_object(otmp, "Suddenly %s out.",
|
||||
aobjnam(otmp, "fall"), (char *) 0);
|
||||
nhUse(otmp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1621,7 +1623,7 @@ struct obj *obj;
|
||||
}
|
||||
|
||||
if ((eprop & ~W_ARTI) || iprop) {
|
||||
nothing_special:
|
||||
nothing_special:
|
||||
/* you had the property from some other source too */
|
||||
if (carried(obj))
|
||||
You_feel("a surge of power, but nothing seems to happen.");
|
||||
@@ -1975,7 +1977,7 @@ boolean loseit; /* whether to drop it if hero can longer touch it */
|
||||
if (loseit && obj) {
|
||||
if (Levitation) {
|
||||
freeinv(obj);
|
||||
hitfloor(obj);
|
||||
hitfloor(obj, TRUE);
|
||||
} else {
|
||||
/* dropx gives a message iff item lands on an altar */
|
||||
if (!IS_ALTAR(levl[u.ux][u.uy].typ))
|
||||
|
||||
4
src/do.c
4
src/do.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 do.c $NHDT-Date: 1545043771 2018/12/17 10:49:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.181 $ */
|
||||
/* NetHack 3.6 do.c $NHDT-Date: 1545597418 2018/12/23 20:36:58 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.182 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -612,7 +612,7 @@ register struct obj *obj;
|
||||
if (obj->oclass == COIN_CLASS)
|
||||
context.botl = 1;
|
||||
freeinv(obj);
|
||||
hitfloor(obj);
|
||||
hitfloor(obj, TRUE);
|
||||
if (levhack)
|
||||
float_down(I_SPECIAL | TIMEOUT, W_ARTI | W_ART);
|
||||
return 1;
|
||||
|
||||
@@ -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;
|
||||
|
||||
24
src/invent.c
24
src/invent.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 invent.c $NHDT-Date: 1545043772 2018/12/17 10:49:32 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.244 $ */
|
||||
/* NetHack 3.6 invent.c $NHDT-Date: 1545597422 2018/12/23 20:37:02 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.245 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Derek S. Ray, 2015. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -975,9 +975,9 @@ const char *drop_fmt, *drop_arg, *hold_msg;
|
||||
}
|
||||
}
|
||||
if (Fumbling) {
|
||||
if (drop_fmt)
|
||||
pline(drop_fmt, drop_arg);
|
||||
dropy(obj);
|
||||
obj->nomerge = 1;
|
||||
obj = addinv(obj); /* dropping expects obj to be in invent */
|
||||
goto drop_it;
|
||||
} else {
|
||||
long oquan = obj->quan;
|
||||
int prev_encumbr = near_capacity(); /* before addinv() */
|
||||
@@ -994,12 +994,10 @@ const char *drop_fmt, *drop_arg, *hold_msg;
|
||||
obj = addinv(obj);
|
||||
if (inv_cnt(FALSE) > 52 || ((obj->otyp != LOADSTONE || !obj->cursed)
|
||||
&& near_capacity() > prev_encumbr)) {
|
||||
if (drop_fmt)
|
||||
pline(drop_fmt, drop_arg);
|
||||
/* undo any merge which took place */
|
||||
if (obj->quan > oquan)
|
||||
obj = splitobj(obj, oquan);
|
||||
dropx(obj);
|
||||
goto drop_it;
|
||||
} else {
|
||||
if (flags.autoquiver && !uquiver && !obj->owornmask
|
||||
&& (is_missile(obj) || ammo_and_launcher(obj, uwep)
|
||||
@@ -1010,6 +1008,18 @@ const char *drop_fmt, *drop_arg, *hold_msg;
|
||||
}
|
||||
}
|
||||
return obj;
|
||||
|
||||
drop_it:
|
||||
if (drop_fmt)
|
||||
pline(drop_fmt, drop_arg);
|
||||
obj->nomerge = 0;
|
||||
if (can_reach_floor(TRUE)) {
|
||||
dropx(obj);
|
||||
} else {
|
||||
freeinv(obj);
|
||||
hitfloor(obj, FALSE);
|
||||
}
|
||||
return (struct obj *) 0; /* might be gone */
|
||||
}
|
||||
|
||||
/* useup() all of an item regardless of its quantity */
|
||||
|
||||
16
src/mail.c
16
src/mail.c
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 mail.c $NHDT-Date: 1542765359 2018/11/21 01:55:59 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.37 $ */
|
||||
/* NetHack 3.6 mail.c $NHDT-Date: 1545597424 2018/12/23 20:37:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.39 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Pasi Kallinen, 2018. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -186,7 +186,7 @@ coord *startp;
|
||||
*/
|
||||
lax = 0; /* be picky */
|
||||
max_distance = -1;
|
||||
retry:
|
||||
retry:
|
||||
for (row = 0; row < ROWNO; row++) {
|
||||
if (viz_rmin[row] < viz_rmax[row]) {
|
||||
/* There are valid positions on this row. */
|
||||
@@ -418,15 +418,17 @@ struct mail_info *info;
|
||||
display_nhwindow(WIN_MESSAGE, FALSE);
|
||||
obj = hold_another_object(obj, "Oops!", (const char *) 0,
|
||||
(const char *) 0);
|
||||
nhUse(obj);
|
||||
}
|
||||
|
||||
/* zip back to starting location */
|
||||
go_back:
|
||||
go_back:
|
||||
/* zip back to starting location */
|
||||
if (!md_rush(md, start.x, start.y))
|
||||
md->mx = md->my = 0; /* for mongone, md is not on map */
|
||||
mongone(md);
|
||||
/* deliver some classes of messages even if no daemon ever shows up */
|
||||
give_up:
|
||||
|
||||
give_up:
|
||||
/* deliver some classes of messages even if no daemon ever shows up */
|
||||
if (!message_seen && info->message_typ == MSG_OTHER)
|
||||
pline("Hark! \"%s.\"", info->display_txt);
|
||||
}
|
||||
@@ -609,7 +611,7 @@ boolean adminmsg;
|
||||
else
|
||||
unlink(mailbox);
|
||||
return;
|
||||
bail:
|
||||
bail:
|
||||
/* bail out _professionally_ */
|
||||
if (!adminmsg)
|
||||
pline("It appears to be all gibberish.");
|
||||
|
||||
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 */
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 pickup.c $NHDT-Date: 1543188989 2018/11/25 23:36:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.220 $ */
|
||||
/* NetHack 3.6 pickup.c $NHDT-Date: 1545597427 2018/12/23 20:37:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.221 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2023,6 +2023,7 @@ boolean *prev_loot;
|
||||
}
|
||||
otmp = hold_another_object(otmp, "You drop %s!", doname(otmp),
|
||||
(const char *) 0);
|
||||
nhUse(otmp);
|
||||
timepassed = rnd(3);
|
||||
if (prev_loot)
|
||||
*prev_loot = TRUE;
|
||||
@@ -3188,7 +3189,7 @@ struct obj *box; /* or bag */
|
||||
|
||||
if (highdrop) {
|
||||
/* might break or fall down stairs; handles altars itself */
|
||||
hitfloor(otmp);
|
||||
hitfloor(otmp, TRUE);
|
||||
} else {
|
||||
if (altarizing) {
|
||||
doaltarobj(otmp);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1545182147 2018/12/19 01:15:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.156 $ */
|
||||
/* NetHack 3.6 potion.c $NHDT-Date: 1545597429 2018/12/23 20:37:09 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.157 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2013. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -2237,6 +2237,7 @@ more_dips:
|
||||
singlepotion =
|
||||
hold_another_object(singlepotion, "You juggle and drop %s!",
|
||||
doname(singlepotion), (const char *) 0);
|
||||
nhUse(singlepotion);
|
||||
update_inventory();
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* NetHack 3.6 uhitm.c $NHDT-Date: 1544840256 2018/12/15 02:17:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.196 $ */
|
||||
/* NetHack 3.6 uhitm.c $NHDT-Date: 1545597432 2018/12/23 20:37:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.197 $ */
|
||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||
/*-Copyright (c) Robert Patrick Rankin, 2012. */
|
||||
/* NetHack may be freely redistributed. See license for details. */
|
||||
@@ -1546,7 +1546,8 @@ struct attack *mattk;
|
||||
/* give the object to the character */
|
||||
otmp = hold_another_object(otmp, "You snatched but dropped %s.",
|
||||
doname(otmp), "You steal: ");
|
||||
if (otmp->where != OBJ_INVENT)
|
||||
/* might have dropped otmp, and it might have broken or left level */
|
||||
if (!otmp || otmp->where != OBJ_INVENT)
|
||||
continue;
|
||||
if (theft_petrifies(otmp))
|
||||
break; /* stop thieving even though hero survived */
|
||||
|
||||
Reference in New Issue
Block a user