fix issue #1455 - fully thrown quiver stack won't
autoquiver when picked back up
Issue reported by ars3niy: empty quiver used to be refilled when
picking a thrown item or stack up. Bug introduced by a previous fix
(commit 593a93d254) dealing with the
post-3.6 obj->how_lost field.
As with the last time I dealt with this, there was a lot of trial
and error involved. This fixes the quiver issue without bringing
the earlier problem back. This time the problem was that how_lost
got cleared before it was used to check whether an item being picked
up had been thrown.
Dropping part of a stack and throwing another part of the same stack
may behave oddly if a monster picks both up. I am not going to try
to figure that out.
Fixes #1466
This commit is contained in:
@@ -2177,6 +2177,8 @@ livelog/#chronicle for saving-grace: if saving-grace prevents hero's death,
|
||||
naming a type of item, unnaming it (with name of <space>), naming it again
|
||||
(new name or re-use of old one), then unnaming it again would issue
|
||||
impossible: "named object not in disco"
|
||||
throwing entire quiver and then picking the stack back up was not putting it
|
||||
back into quiver
|
||||
|
||||
|
||||
Fixes to 3.7.0-x Platform and/or Interface Problems Exposed Via git Repository
|
||||
|
||||
22
src/invent.c
22
src/invent.c
@@ -1063,8 +1063,9 @@ addinv_core2(struct obj *obj)
|
||||
* Adjust hero attributes as necessary.
|
||||
*/
|
||||
staticfn struct obj *
|
||||
addinv_core0(struct obj *obj, struct obj *other_obj,
|
||||
boolean update_perm_invent)
|
||||
addinv_core0(
|
||||
struct obj *obj, struct obj *other_obj,
|
||||
boolean update_perm_invent)
|
||||
{
|
||||
struct obj *otmp, *prev;
|
||||
int saved_otyp = (int) obj->otyp; /* for panic */
|
||||
@@ -1072,6 +1073,9 @@ addinv_core0(struct obj *obj, struct obj *other_obj,
|
||||
|
||||
if (obj->where != OBJ_FREE)
|
||||
panic("addinv: obj not free");
|
||||
if (obj->how_lost == LOST_EXPLODING)
|
||||
return (struct obj *) NULL;
|
||||
|
||||
/* normally addtobill() clears no_charge when items in a shop are
|
||||
picked up, but won't do so if the shop has become untended */
|
||||
obj->no_charge = 0; /* should not be set in hero's invent */
|
||||
@@ -1146,6 +1150,7 @@ addinv_core0(struct obj *obj, struct obj *other_obj,
|
||||
setuqwep(obj);
|
||||
added:
|
||||
obj->pickup_prev = 1;
|
||||
obj->how_lost = 0;
|
||||
addinv_core2(obj); /* handle extrinsics conferred by carrying obj */
|
||||
carry_obj_effects(obj); /* carrying affects the obj */
|
||||
if (update_perm_invent)
|
||||
@@ -1163,7 +1168,8 @@ addinv(struct obj *obj)
|
||||
/* add obj to the hero's inventory by inserting in front of a specific item;
|
||||
used for throw-and-return in case '!fixinv' is in effect */
|
||||
struct obj *
|
||||
addinv_before(struct obj *obj, struct obj *other_obj)
|
||||
addinv_before(
|
||||
struct obj *obj, struct obj *other_obj)
|
||||
{
|
||||
/* if 'other_obj' is present this will implicitly be 'nomerge' */
|
||||
return addinv_core0(obj, other_obj, TRUE);
|
||||
@@ -5094,7 +5100,12 @@ mergable(
|
||||
|
||||
if (obj->cursed != otmp->cursed || obj->blessed != otmp->blessed)
|
||||
return FALSE;
|
||||
if ((obj->how_lost & ~LOSTOVERRIDEMASK) != 0)
|
||||
|
||||
if (obj->how_lost == LOST_EXPLODING
|
||||
|| otmp->how_lost == LOST_EXPLODING)
|
||||
return FALSE;
|
||||
if ((obj->how_lost & ~LOSTOVERRIDEMASK)
|
||||
!= (otmp->how_lost & ~LOSTOVERRIDEMASK))
|
||||
return FALSE;
|
||||
#if 0 /* don't require 'bypass' to match; that results in items dropped
|
||||
* via 'D' not stacking with compatible items already on the floor;
|
||||
@@ -5111,8 +5122,7 @@ mergable(
|
||||
|
||||
if (obj->unpaid != otmp->unpaid || obj->spe != otmp->spe
|
||||
|| obj->no_charge != otmp->no_charge || obj->obroken != otmp->obroken
|
||||
|| obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit
|
||||
|| obj->how_lost != otmp->how_lost)
|
||||
|| obj->otrapped != otmp->otrapped || obj->lamplit != otmp->lamplit)
|
||||
return FALSE;
|
||||
|
||||
if (obj->oclass == FOOD_CLASS
|
||||
|
||||
14
src/pickup.c
14
src/pickup.c
@@ -1805,7 +1805,6 @@ pickup_object(
|
||||
long count, /* if non-zero, pick up a subset of this amount */
|
||||
boolean telekinesis) /* not picking it up directly by hand */
|
||||
{
|
||||
unsigned save_how_lost;
|
||||
int res;
|
||||
|
||||
if (obj->quan < count) {
|
||||
@@ -1862,16 +1861,12 @@ pickup_object(
|
||||
}
|
||||
}
|
||||
|
||||
save_how_lost = obj->how_lost;
|
||||
/* obj has either already passed autopick_testobj or we are explicitly
|
||||
picking it off the floor, so override obj->how_lost; otherwise we
|
||||
couldn't pick up a thrown, stolen, or dropped item that was split
|
||||
off from a carried stack even while still carrying the rest of the
|
||||
stack unless we have at least one free slot available */
|
||||
obj->how_lost &= ~LOSTOVERRIDEMASK; /* affects merge_choice() */
|
||||
picking it off the floor, so addinv() will override obj->how_lost;
|
||||
otherwise we couldn't pick up a thrown, stolen, or dropped item that
|
||||
was split off from a carried stack even while still carrying the
|
||||
rest of the stack unless we have at least one free slot available */
|
||||
res = lift_object(obj, (struct obj *) 0, &count, telekinesis);
|
||||
obj->how_lost = save_how_lost; /* even when res > 0,
|
||||
* in case we call splitobj() below */
|
||||
if (res <= 0)
|
||||
return res;
|
||||
|
||||
@@ -1881,7 +1876,6 @@ pickup_object(
|
||||
if (obj->quan != count && obj->otyp != LOADSTONE)
|
||||
obj = splitobj(obj, count);
|
||||
|
||||
obj->how_lost &= ~LOSTOVERRIDEMASK;
|
||||
obj = pick_obj(obj);
|
||||
|
||||
if (uwep && uwep == obj)
|
||||
|
||||
Reference in New Issue
Block a user