f-iring without ammo
There was a suggestion in the newsgroup that if you use the 'f'
command when your quiver is empty, that whatever missile you supply to the
"what do you want to throw?" prompt be automatically put into the quiver.
This implements that, and separates most of the common code from dothrow()
and dofire() into a separate routine. A post-3.4.3 change to dothrow() to
require hands for throwing wasn't propagated to dofire(). With the common
routine, they're much less likely to get out of sync like that.
This is going into the branch as well as the trunk because the hands
checking mismatch was added there too.
This commit is contained in:
@@ -387,6 +387,8 @@ intelligent pets will use keys to unlock doors
|
||||
destroyed drawbridge leaves some iron chains
|
||||
give feedback when a nearby monster grows into a stronger form
|
||||
familiars are now created without any starting inventory
|
||||
using the 'f' command when quiver is empty will fill quiver if player selects
|
||||
a stack of 2 or more items in response to the "what to throw?" prompt
|
||||
|
||||
|
||||
Platform- and/or Interface-Specific New Features
|
||||
|
||||
109
src/dothrow.c
109
src/dothrow.c
@@ -7,6 +7,7 @@
|
||||
#include "hack.h"
|
||||
|
||||
STATIC_DCL int FDECL(throw_obj, (struct obj *,int));
|
||||
STATIC_DCL boolean FDECL(ok_to_throw, (int *));
|
||||
STATIC_DCL void NDECL(autoquiver);
|
||||
STATIC_DCL int FDECL(gem_accept, (struct monst *, struct obj *));
|
||||
STATIC_DCL void FDECL(tmiss, (struct obj *, struct monst *,BOOLEAN_P));
|
||||
@@ -208,6 +209,28 @@ int shotlimit;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* common to dothrow() and dofire() */
|
||||
STATIC_OVL boolean
|
||||
ok_to_throw(shotlimit_p)
|
||||
int *shotlimit_p; /* (see dothrow()) */
|
||||
{
|
||||
/* kludge to work around parse()'s pre-decrement of `multi' */
|
||||
*shotlimit_p = (multi || save_cm) ? multi + 1 : 0;
|
||||
multi = 0; /* reset; it's been used up */
|
||||
|
||||
if (notake(youmonst.data)) {
|
||||
You("are physically incapable of throwing or shooting anything.");
|
||||
return FALSE;
|
||||
} else if (nohands(youmonst.data)) {
|
||||
You_cant("throw or shoot without hands."); /* not body_part(HAND) */
|
||||
return FALSE;
|
||||
/*[what about !freehand(), aside from cursed missile launcher?]*/
|
||||
}
|
||||
if (check_capacity((char *)0)) return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* t command - throw */
|
||||
int
|
||||
dothrow()
|
||||
{
|
||||
@@ -222,27 +245,16 @@ dothrow()
|
||||
*
|
||||
* Prior to 3.3.0, command ``3t'' meant ``t(shoot) t(shoot) t(shoot)''
|
||||
* and took 3 turns. Now it means ``t(shoot at most 3 missiles)''.
|
||||
*
|
||||
* [3.5.0: shot count setup has been moved into ok_to_throw().]
|
||||
*/
|
||||
/* kludge to work around parse()'s pre-decrement of `multi' */
|
||||
shotlimit = (multi || save_cm) ? multi + 1 : 0;
|
||||
multi = 0; /* reset; it's been used up */
|
||||
if (!ok_to_throw(&shotlimit)) return 0;
|
||||
|
||||
if (notake(youmonst.data)) {
|
||||
You("are physically incapable of throwing anything.");
|
||||
return 0;
|
||||
} else if (nohands(youmonst.data)) {
|
||||
You_cant("throw without hands."); /* not `body_part(HAND)' */
|
||||
return 0;
|
||||
/*[what about !freehand(), aside from cursed missile launcher?]*/
|
||||
}
|
||||
|
||||
if(check_capacity((char *)0)) return(0);
|
||||
obj = getobj(uslinging() ? bullets : toss_objs, "throw");
|
||||
/* it is also possible to throw food */
|
||||
/* (or jewels, or iron balls... ) */
|
||||
|
||||
if (!obj) return(0);
|
||||
return throw_obj(obj, shotlimit);
|
||||
return obj ? throw_obj(obj, shotlimit) : 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -311,50 +323,47 @@ autoquiver()
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Throw from the quiver */
|
||||
/* f command -- fire: throw from the quiver */
|
||||
int
|
||||
dofire()
|
||||
{
|
||||
int shotlimit;
|
||||
|
||||
if (notake(youmonst.data)) {
|
||||
You("are physically incapable of doing that.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(check_capacity((char *)0)) return(0);
|
||||
if (!uquiver) {
|
||||
if (!flags.autoquiver) {
|
||||
/* Don't automatically fill the quiver */
|
||||
You("have no ammunition readied!");
|
||||
return(dothrow());
|
||||
}
|
||||
autoquiver();
|
||||
if (!uquiver) {
|
||||
You("have nothing appropriate for your quiver!");
|
||||
return(dothrow());
|
||||
} else {
|
||||
You("fill your quiver:");
|
||||
prinv((char *)0, uquiver, 0L);
|
||||
}
|
||||
}
|
||||
struct obj *obj;
|
||||
|
||||
/*
|
||||
* Since some characters shoot multiple missiles at one time,
|
||||
* allow user to specify a count prefix for 'f' or 't' to limit
|
||||
* number of items thrown (to avoid possibly hitting something
|
||||
* behind target after killing it, or perhaps to conserve ammo).
|
||||
* Same as dothrow(), except we use quivered missile instead
|
||||
* of asking what to throw/shoot.
|
||||
*
|
||||
* The number specified can never increase the number of missiles.
|
||||
* Using ``5f'' when the shooting skill (plus RNG) dictates launch
|
||||
* of 3 projectiles will result in 3 being shot, not 5.
|
||||
* If quiver is empty, we use autoquiver to fill it when the
|
||||
* corresponding option is on. If the option is off or if
|
||||
* autoquiver doesn't select anything, we ask what to throw.
|
||||
* For the last, if player's response is a stack, we put
|
||||
* that stack into quiver slot provided it's not wielded.
|
||||
*/
|
||||
/* kludge to work around parse()'s pre-decrement of `multi' */
|
||||
shotlimit = (multi || save_cm) ? multi + 1 : 0;
|
||||
multi = 0; /* reset; it's been used up */
|
||||
if (!ok_to_throw(&shotlimit)) return 0;
|
||||
|
||||
return throw_obj(uquiver, shotlimit);
|
||||
if ((obj = uquiver) == 0) {
|
||||
if (!flags.autoquiver) {
|
||||
You("have no ammunition readied.");
|
||||
} else {
|
||||
autoquiver();
|
||||
if ((obj = uquiver) == 0)
|
||||
You("have nothing appropriate for your quiver.");
|
||||
}
|
||||
/* if autoquiver is disabled or has failed, prompt for missile;
|
||||
fill quiver with it if it's a stack that's not wielded */
|
||||
if (!obj) {
|
||||
obj = getobj(uslinging() ? bullets : toss_objs, "throw");
|
||||
if (obj && obj->quan > 1L && !obj->owornmask &&
|
||||
/* Q command doesn't allow gold in quiver */
|
||||
obj->oclass != COIN_CLASS)
|
||||
setuqwep(obj); /* demi-autoquiver */
|
||||
}
|
||||
/* give feedback if quiver has now been filled */
|
||||
if (uquiver) prinv("You ready:", uquiver, 0L);
|
||||
}
|
||||
|
||||
return obj ? throw_obj(obj, shotlimit) : 0;
|
||||
}
|
||||
|
||||
/* if in midst of multishot shooting/throwing, stop early */
|
||||
|
||||
Reference in New Issue
Block a user