fix #H8330 - kicking obj stack uses wrong weight

Kicking a stack splits off one item (except for gold coins) and
propels it, but the range for how far it would move was calculated
before the split using the entire stack's weight.  So a large stack of
small items might fail with "thump" (which the report suggested hurt
the hero, but it doesn't) and none of the stack would move.  Splitting
sooner looked complicated because of several potential early returns
between the range calculation and the eventual kick, so this hacks the
stack's quantity to get the intended weight instead.
This commit is contained in:
PatR
2019-03-06 16:59:39 -08:00
parent 62507fa40f
commit 8728de2a0a
2 changed files with 24 additions and 6 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 dokick.c $NHDT-Date: 1548209738 2019/01/23 02:15:38 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.130 $ */
/* NetHack 3.6 dokick.c $NHDT-Date: 1551920353 2019/03/07 00:59:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.131 $ */
/* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */
/* NetHack may be freely redistributed. See license for details. */
@@ -529,9 +529,25 @@ xchar x, y;
}
}
/* range < 2 means the object will not move. */
/* maybe dexterity should also figure here. */
range = (int) ((ACURRSTR) / 2 - kickedobj->owt / 40);
isgold = (kickedobj->oclass == COIN_CLASS);
{
int k_owt = (int) kickedobj->owt;
/* for non-gold stack, 1 item will be split off below (unless an
early return occurs, so we aren't moving the split to here);
calculate the range for that 1 rather than for the whole stack */
if (kickedobj->quan > 1L && !isgold) {
long save_quan = kickedobj->quan;
kickedobj->quan = 1L;
k_owt = weight(kickedobj);
kickedobj->quan = save_quan;
}
/* range < 2 means the object will not move
(maybe dexterity should also figure here) */
range = ((int) ACURRSTR) / 2 - k_owt / 40;
}
if (martial())
range += rnd(3);
@@ -561,7 +577,6 @@ xchar x, y;
costly = (!(kickedobj->no_charge && !Has_contents(kickedobj))
&& (shkp = shop_keeper(*in_rooms(x, y, SHOPBASE))) != 0
&& costly_spot(x, y));
isgold = (kickedobj->oclass == COIN_CLASS);
if (IS_ROCK(levl[x][y].typ) || closed_door(x, y)) {
if ((!martial() && rn2(20) > ACURR(A_DEX))