1
0
Fork 0
mirror of https://codeberg.org/noisytoot/notnotdnethack.git synced 2025-08-10 22:51:38 +01:00

Merge pull request #1337 from NeroOneTrueKing/patch-at-arrw

Fix monsters with AT_ARRW attacks "shoot!"ing nothing
This commit is contained in:
Chris-plus-alphanumericgibberish 2020-12-26 10:45:35 -05:00 committed by GitHub
commit 87b0f4a479
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 59 additions and 48 deletions

View file

@ -2167,21 +2167,17 @@ dofire()
if (attacktype(youracedata, AT_ARRW)) {
struct attack * attk = attacktype_fordmg(youracedata, AT_ARRW, AD_ANY);
int n;
if (getdir((char *)0)) {
/* actually have to message in this function */
You("shoot!");
/* fire d(n,d) projectiles */
for (n = d(attk->damn, attk->damd); n > 0; n--)
result |= xfirey(&youmonst, attk, 0, 0);
result |= xfirey(&youmonst, attk, 0, 0, d(attk->damn, attk->damd));
if (result) {
return 1;
}
else {
/* nothing shot, but we messaged, so we have to end here */
pline("...or not. Awkward.");
return 1;
pline("You have nothing to intrinsically shoot!");
return 0;
}
}
}
@ -2852,15 +2848,14 @@ int tary;
* xfirey()
*
* magr is inherently shooting at (tarx, tary)
*
* TODO: make 'f'ire use this function
*/
boolean
xfirey(magr, attk, tarx, tary) /* monster fires arrows at you */
xfirey(magr, attk, tarx, tary, n) /* monster fires arrows at you */
struct monst * magr;
struct attack * attk;
int tarx;
int tary;
int n; /* number to try to fire */
{
struct obj * qvr = (struct obj *)0; /* quiver of projectiles to use */
boolean youagr = (magr == &youmonst);
@ -2870,6 +2865,7 @@ int tary;
int yadj = 0;
int rngmod = 0;
boolean portal_projectile = FALSE; /* if TRUE, teleports projectile directly to target */
boolean from_pack = FALSE;
int ammo_type;
int dx, dy, dz;
@ -2986,6 +2982,14 @@ int tary;
/* No ammo of the right type found, nothing happened, took no time */
if (!qvr)
return FALSE;
else {
from_pack = TRUE;
n = min(n, qvr->quan);
}
}
else {
/* create enough ammo */
qvr->quan = n + 1;
}
/* if the player is using this function, tarx/tary don't exist, which is a problem for portal_projectile */
@ -3011,41 +3015,55 @@ int tary;
}
}
/* don't message here , because this function is often called several times :( */
/* Fire the projectile */
if (portal_projectile) {
/* start the projectile adjacent to the target */
projectile(magr, qvr, (void *)0, HMON_FIRED,
tarx-dx, tary-dy, dx, dy, dz,
1, TRUE, youagr, FALSE);
}
else {
/* start the projectile at magr's location, modified by xadj and yadj */
projectile(magr, qvr, (void *)0, HMON_FIRED,
x(magr)+xadj, y(magr)+yadj, dx, dy, dz,
BOLT_LIM+rngmod, TRUE, youagr, FALSE);
/* print appropriate message */
if (youagr || canseemon(magr)) {
char buf[BUFSZ];
if (n>1) Sprintf(buf, " %d times", n);
else Strcpy(buf, "");
pline("%s shoot%s%s!",
(youagr ? "You" : Monnam(magr)),
(youagr ? "" : "s"),
(buf));
}
/* shadow bolts web the target hit */
if (typ == AD_SHDW) {
struct trap *ttmp2;
ttmp2 = maketrap(bhitpos.x, bhitpos.y, WEB);
if (bhitpos.x == u.ux && bhitpos.y == u.uy && ttmp2) {
pline_The("webbing sticks to you. You're caught!");
dotrap(ttmp2, NOWEBMSG);
/* Fire the projectile(s) */
while (n-- && qvr->quan > 0) {
if (portal_projectile) {
/* start the projectile adjacent to the target */
projectile(magr, qvr, (void *)0, HMON_FIRED,
tarx-dx, tary-dy, dx, dy, dz,
1, !from_pack, youagr, FALSE);
}
else {
/* start the projectile at magr's location, modified by xadj and yadj */
projectile(magr, qvr, (void *)0, HMON_FIRED,
x(magr)+xadj, y(magr)+yadj, dx, dy, dz,
BOLT_LIM+rngmod, !from_pack, youagr, FALSE);
}
/* shadow bolts web the target hit */
if (typ == AD_SHDW) {
struct trap *ttmp2;
ttmp2 = maketrap(bhitpos.x, bhitpos.y, WEB);
if (bhitpos.x == u.ux && bhitpos.y == u.uy && ttmp2) {
pline_The("webbing sticks to you. You're caught!");
dotrap(ttmp2, NOWEBMSG);
#ifdef STEED
if (u.usteed && u.utrap) {
/* you, not steed, are trapped */
dismount_steed(DISMOUNT_FELL);
}
if (u.usteed && u.utrap) {
/* you, not steed, are trapped */
dismount_steed(DISMOUNT_FELL);
}
#endif
}
else if (ttmp2) {
struct monst * mdef = m_at(bhitpos.x, bhitpos.y);
if (mdef)
mintrap(mdef);
}
}
else if (ttmp2) {
struct monst * mdef = m_at(bhitpos.x, bhitpos.y);
if (mdef)
mintrap(mdef);
}
}
if (!from_pack) {
delobj(qvr);
}
/* interrupt player if they were targetted */

View file

@ -1065,15 +1065,8 @@ int tary;
break;
case AT_ARRW:
if ((adtyp != AD_SHDW || ranged)) { // can be used in melee range, except for shadow
int n;
/* message -- done outside of xfirey to only print 1 message for d(n,d) function calls */
/* potential change: pass a domessage variable to xfirey */
if (canseemon(magr)) {
pline("%s shoots!", Monnam(magr));
}
/* fire d(n,d) projectiles */
for (n = d(attk->damn, attk->damd); n > 0; n--)
result |= xfirey(magr, attk, tarx, tary);
result |= xfirey(magr, attk, tarx, tary, d(attk->damn, attk->damd));
if (result) {
/* they did fire at least one projectile */
mon_ranged_gazeonly = FALSE;