multishot by monsters, plus reformatting

Some reformatting of the recently added pet ranged attack code.

The redundant--but different--multishot volley code has been replaced
so that there are only two versions (hero and monster) instead of
three (hero and monster vs hero and pet vs other monster).  The monst
version was out of date relative to post-3.4.3 changes to the hero one.
The pet version was way out of date and had some bugs:  wielding an
elven bow gave a +1 multishot increment to volley count for fast weapon
even when throwing something rather than shooting arrows, wielding any
weapon which had at least +2 enchantment gave 1/3 enchantment bonus to
volley count when throwing instead of shooting shoot ammo, and a pet
which got killed in the midst of a multishot volley--perhaps by a gas
spore explosion or some other passive counterattack--would keep on
shooting/throwing until the volley count was exhausted.

Pet use of ranged weapons is not ready for prime-time.  Pets don't
hang on to missiles or launchers+ammo, they just drop them if there is
no target immediately available.
This commit is contained in:
PatR
2016-06-06 17:42:58 -07:00
parent e276540230
commit 8c0810f687
5 changed files with 333 additions and 367 deletions

View File

@@ -356,15 +356,13 @@ register struct monst *magr, *mdef;
attk = 1;
switch (mattk->aatyp) {
case AT_WEAP: /* "hand to hand" attacks */
if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1) {
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1) {
/* D: Do a ranged attack here! */
strike = thrwmm(magr, mdef);
if (DEADMONSTER(mdef))
res[i] = MM_DEF_DIED;
if (DEADMONSTER(magr))
res[i] |= MM_AGR_DIED;
break;
}
if (magr->weapon_check == NEED_WEAPON || !MON_WEP(magr)) {
@@ -390,8 +388,7 @@ register struct monst *magr, *mdef;
case AT_TENT:
/* Nymph that teleported away on first attack? */
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
/* Continue because the monster may have a ranged
* attack */
/* Continue because the monster may have a ranged attack. */
continue;
/* Monsters won't attack cockatrices physically if they
* have a weapon instead. This instinct doesn't work for
@@ -454,50 +451,52 @@ register struct monst *magr, *mdef;
break;
case AT_ENGL:
if (u.usteed && (mdef == u.usteed)) {
if (u.usteed && mdef == u.usteed) {
strike = 0;
break;
}
/* D: Prevent engulf from a distance */
if (distmin(magr->mx,magr->my,mdef->mx,mdef->my) > 1)
if (distmin(magr->mx, magr->my, mdef->mx, mdef->my) > 1)
continue;
/* Engulfing attacks are directed at the hero if
* possible. -dlc
*/
/* Engulfing attacks are directed at the hero if possible. -dlc */
if (u.uswallow && magr == u.ustuck)
strike = 0;
else {
if ((strike = (tmp > rnd(20 + i))))
res[i] = gulpmm(magr, mdef, mattk);
else
missmm(magr, mdef, mattk);
}
else if ((strike = (tmp > rnd(20 + i))) != 0)
res[i] = gulpmm(magr, mdef, mattk);
else
missmm(magr, mdef, mattk);
break;
case AT_BREA:
if (!monnear(magr, mdef->mx, mdef->my)) {
strike = breamm(magr, mattk, mdef);
/* We don't really know if we hit or not, but pretend
* we did */
if (strike) res[i] |= MM_HIT;
if (DEADMONSTER(mdef)) res[i] = MM_DEF_DIED;
if (DEADMONSTER(magr)) res[i] |= MM_AGR_DIED;
/* We don't really know if we hit or not; pretend we did. */
if (strike)
res[i] |= MM_HIT;
if (DEADMONSTER(mdef))
res[i] = MM_DEF_DIED;
if (DEADMONSTER(magr))
res[i] |= MM_AGR_DIED;
}
else
strike = 0;
break;
case AT_SPIT:
if (!monnear(magr, mdef->mx, mdef->my)) {
strike = spitmm(magr, mattk, mdef);
/* We don't really know if we hit or not, but pretend
* we did */
if (strike) res[i] |= MM_HIT;
if (DEADMONSTER(mdef)) res[i] = MM_DEF_DIED;
if (DEADMONSTER(magr)) res[i] |= MM_AGR_DIED;
/* We don't really know if we hit or not; pretend we did. */
if (strike)
res[i] |= MM_HIT;
if (DEADMONSTER(mdef))
res[i] = MM_DEF_DIED;
if (DEADMONSTER(magr))
res[i] |= MM_AGR_DIED;
}
break;
default: /* no attack */
strike = 0;
attk = 0;
@@ -505,12 +504,11 @@ register struct monst *magr, *mdef;
}
if (attk && !(res[i] & MM_AGR_DIED)
&& distmin(magr->mx,magr->my,mdef->mx,mdef->my) <= 1)
&& distmin(magr->mx, magr->my, mdef->mx, mdef->my) <= 1)
res[i] = passivemm(magr, mdef, strike, res[i] & MM_DEF_DIED);
if (res[i] & MM_DEF_DIED)
return res[i];
if (res[i] & MM_AGR_DIED)
return res[i];
/* return if aggressor can no longer attack */
@@ -595,9 +593,8 @@ struct attack *mattk;
pline("%s %s...", buf, mon_nam(mdef));
}
if (magr->mcan || !magr->mcansee
|| (magr->minvis && !perceives(mdef->data)) || !mdef->mcansee
|| mdef->msleeping) {
if (magr->mcan || !magr->mcansee || !mdef->mcansee
|| (magr->minvis && !perceives(mdef->data)) || mdef->msleeping) {
if (vis)
pline("but nothing happens.");
return MM_MISS;
@@ -609,8 +606,8 @@ struct attack *mattk;
if (mdef->mcansee) {
if (mon_reflects(magr, (char *) 0)) {
if (canseemon(magr))
(void) mon_reflects(
magr, "The gaze is reflected away by %s %s.");
(void) mon_reflects(magr,
"The gaze is reflected away by %s %s.");
return MM_MISS;
}
if (mdef->minvis && !perceives(magr->data)) {
@@ -723,7 +720,7 @@ register struct attack *mattk;
} else if (status & MM_AGR_DIED) { /* aggressor died */
place_monster(mdef, dx, dy);
newsym(dx, dy);
} else { /* both alive, put them back */
} else { /* both alive, put them back */
if (cansee(dx, dy))
pline("%s is regurgitated!", Monnam(mdef));
@@ -1174,6 +1171,7 @@ register struct attack *mattk;
*/
{
struct obj *gold = findgold(mdef->minvent);
if (!gold)
break;
obj_extract_self(gold);