fix B17005 - autoquiver bug
hold_another_object() will try to quiver the object being held if
it's a weapon (or gem/rock ammo) and the autoquiver option is enabled and
the quiver is empty. It was doing that even if the object had just merged
with primary or secondary weapon, resulting in it being equipped in two
slots at once. (Easiest way to reproduce it is via wish+wield+wish for
similar item, but it could also occur when stealing while in nymph form.)
This also addresses one of the old items on <Someone>'s list: if you
carry a sling equipped in the alternate weapon slot, include gems and
rocks as likely candidates for quivering same as when wielding a sling.
This extends that to autoquivering; ammo appropriate for your alternate
is now given preference over arbitrary weapons (ammo for your wielded
weapon and arbitrary missiles still take precedence over alternate ammo).
Bug? pickup_object() is not autoquiver aware, hence autopickup isn't
either.
Bug too (perhaps moot if the above is changed)? Snagging a monster's
weapon with a bullwhip uses hold_another_object() so possibly autoquivers;
snagging an object off the floor with a grappling hook uses pickup_object()
so doesn't.
This commit is contained in:
@@ -362,6 +362,9 @@ engraving on headstone will appropriately dull your weapon
|
|||||||
certain types of golems should not "catch fire" so adjust the messages
|
certain types of golems should not "catch fire" so adjust the messages
|
||||||
no longer need to manually examine inventory after regaining sight in order
|
no longer need to manually examine inventory after regaining sight in order
|
||||||
to give a type name to an object picked up while blind
|
to give a type name to an object picked up while blind
|
||||||
|
when adding an object to inventory, it is possible for it to becomed both
|
||||||
|
wielded and quivered if it merges with weapon and autoquiver is enabled
|
||||||
|
include rocks as likely candidates for quivering if alternate weapon is a sling
|
||||||
|
|
||||||
|
|
||||||
Platform- and/or Interface-Specific Fixes
|
Platform- and/or Interface-Specific Fixes
|
||||||
|
|||||||
+8
-2
@@ -1,4 +1,4 @@
|
|||||||
/* SCCS Id: @(#)dothrow.c 3.4 2003/01/08 */
|
/* SCCS Id: @(#)dothrow.c 3.4 2003/01/24 */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -215,7 +215,7 @@ dothrow()
|
|||||||
static void
|
static void
|
||||||
autoquiver()
|
autoquiver()
|
||||||
{
|
{
|
||||||
register struct obj *otmp, *oammo = 0, *omissile = 0, *omisc = 0;
|
struct obj *otmp, *oammo = 0, *omissile = 0, *omisc = 0, *altammo = 0;
|
||||||
|
|
||||||
if (uquiver)
|
if (uquiver)
|
||||||
return;
|
return;
|
||||||
@@ -233,6 +233,8 @@ autoquiver()
|
|||||||
objects[otmp->otyp].oc_material == GLASS)) {
|
objects[otmp->otyp].oc_material == GLASS)) {
|
||||||
if (uslinging())
|
if (uslinging())
|
||||||
oammo = otmp;
|
oammo = otmp;
|
||||||
|
else if (ammo_and_launcher(otmp, uswapwep))
|
||||||
|
altammo = otmp;
|
||||||
else if (!omisc)
|
else if (!omisc)
|
||||||
omisc = otmp;
|
omisc = otmp;
|
||||||
} else if (otmp->oclass == GEM_CLASS) {
|
} else if (otmp->oclass == GEM_CLASS) {
|
||||||
@@ -242,6 +244,8 @@ autoquiver()
|
|||||||
if (ammo_and_launcher(otmp, uwep))
|
if (ammo_and_launcher(otmp, uwep))
|
||||||
/* Ammo matched with launcher (bow and arrow, crossbow and bolt) */
|
/* Ammo matched with launcher (bow and arrow, crossbow and bolt) */
|
||||||
oammo = otmp;
|
oammo = otmp;
|
||||||
|
else if (ammo_and_launcher(otmp, uswapwep))
|
||||||
|
altammo = otmp;
|
||||||
else
|
else
|
||||||
/* Mismatched ammo (no better than an ordinary weapon) */
|
/* Mismatched ammo (no better than an ordinary weapon) */
|
||||||
omisc = otmp;
|
omisc = otmp;
|
||||||
@@ -263,6 +267,8 @@ autoquiver()
|
|||||||
setuqwep(oammo);
|
setuqwep(oammo);
|
||||||
else if (omissile)
|
else if (omissile)
|
||||||
setuqwep(omissile);
|
setuqwep(omissile);
|
||||||
|
else if (altammo)
|
||||||
|
setuqwep(altammo);
|
||||||
else if (omisc)
|
else if (omisc)
|
||||||
setuqwep(omisc);
|
setuqwep(omisc);
|
||||||
|
|
||||||
|
|||||||
+26
-30
@@ -1,4 +1,4 @@
|
|||||||
/* SCCS Id: @(#)invent.c 3.4 2002/12/13 */
|
/* SCCS Id: @(#)invent.c 3.4 2003/01/24 */
|
||||||
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
|
||||||
/* NetHack may be freely redistributed. See license for details. */
|
/* NetHack may be freely redistributed. See license for details. */
|
||||||
|
|
||||||
@@ -405,39 +405,35 @@ const char *drop_fmt, *drop_arg, *hold_msg;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (Fumbling) {
|
if (Fumbling) {
|
||||||
if (drop_fmt) pline(drop_fmt, drop_arg);
|
if (drop_fmt) pline(drop_fmt, drop_arg);
|
||||||
dropy(obj);
|
dropy(obj);
|
||||||
} else {
|
} else {
|
||||||
long oquan = obj->quan;
|
long oquan = obj->quan;
|
||||||
int prev_encumbr = near_capacity(); /* before addinv() */
|
int prev_encumbr = near_capacity(); /* before addinv() */
|
||||||
|
|
||||||
/* encumbrance only matters if it would now become worse
|
/* encumbrance only matters if it would now become worse
|
||||||
than max( current_value, stressed ) */
|
than max( current_value, stressed ) */
|
||||||
if (prev_encumbr < MOD_ENCUMBER) prev_encumbr = MOD_ENCUMBER;
|
if (prev_encumbr < MOD_ENCUMBER) prev_encumbr = MOD_ENCUMBER;
|
||||||
if (drop_arg) {
|
/* addinv() may redraw the entire inventory, overwriting
|
||||||
/* addinv() may redraw the entire inventory, overwriting
|
drop_arg when it comes from something like doname() */
|
||||||
* drop_arg when it comes from something like doname()
|
if (drop_arg) drop_arg = strcpy(buf, drop_arg);
|
||||||
*/
|
|
||||||
Strcpy(buf, drop_arg);
|
obj = addinv(obj);
|
||||||
drop_arg = buf;
|
if (inv_cnt() > 52
|
||||||
}
|
|
||||||
obj = addinv(obj);
|
|
||||||
if (inv_cnt() > 52
|
|
||||||
|| ((obj->otyp != LOADSTONE || !obj->cursed)
|
|| ((obj->otyp != LOADSTONE || !obj->cursed)
|
||||||
&& near_capacity() > prev_encumbr)) {
|
&& near_capacity() > prev_encumbr)) {
|
||||||
if (drop_fmt) pline(drop_fmt, drop_arg);
|
if (drop_fmt) pline(drop_fmt, drop_arg);
|
||||||
/* undo any merge which took place */
|
/* undo any merge which took place */
|
||||||
if (obj->quan > oquan) {
|
if (obj->quan > oquan) obj = splitobj(obj, oquan);
|
||||||
obj = splitobj(obj, oquan);
|
dropx(obj);
|
||||||
}
|
} else {
|
||||||
dropx(obj);
|
if (flags.autoquiver && !uquiver && !obj->owornmask &&
|
||||||
} else {
|
(is_missile(obj) ||
|
||||||
if (flags.autoquiver && !uquiver &&
|
ammo_and_launcher(obj, uwep) ||
|
||||||
(is_missile(obj) ||
|
ammo_and_launcher(obj, uswapwep)))
|
||||||
(uwep && ammo_and_launcher(obj, uwep))))
|
setuqwep(obj);
|
||||||
setuqwep(obj);
|
if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan);
|
||||||
if (hold_msg || drop_fmt) prinv(hold_msg, obj, oquan);
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-3
@@ -331,18 +331,20 @@ int
|
|||||||
dowieldquiver()
|
dowieldquiver()
|
||||||
{
|
{
|
||||||
register struct obj *newquiver;
|
register struct obj *newquiver;
|
||||||
|
const char *quivee_types = (uslinging() ||
|
||||||
|
(uswapwep && objects[uswapwep->otyp].oc_skill == P_SLING)) ?
|
||||||
|
bullets : ready_objs;
|
||||||
|
|
||||||
/* Since the quiver isn't in your hands, don't check cantwield(), */
|
/* Since the quiver isn't in your hands, don't check cantwield(), */
|
||||||
/* will_weld(), touch_petrifies(), etc. */
|
/* will_weld(), touch_petrifies(), etc. */
|
||||||
multi = 0;
|
multi = 0;
|
||||||
|
|
||||||
/* Because 'Q' used to be quit... */
|
/* Because 'Q' used to be quit... */
|
||||||
if (!flags.suppress_alert || flags.suppress_alert < FEATURE_NOTICE_VER(3,3,0))
|
if (flags.suppress_alert < FEATURE_NOTICE_VER(3,3,0))
|
||||||
pline("Note: Please use #quit if you wish to exit the game.");
|
pline("Note: Please use #quit if you wish to exit the game.");
|
||||||
|
|
||||||
/* Prompt for a new quiver */
|
/* Prompt for a new quiver */
|
||||||
if (!(newquiver = getobj(uslinging() ? bullets : ready_objs, "ready")))
|
if (!(newquiver = getobj(quivee_types, "ready")))
|
||||||
/* Cancelled */
|
/* Cancelled */
|
||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user