partly fix issue #1336 - pets vs floating eyes
Issue reported by ars3niy: pets with reflection or ranged attacks would only attack floating eyes when rolling the 10% random chance that other pets have even though they could have always safely attacked. This fixes the situation for melee attacks by pets who have reflection. dog_move() is too complicated for my feeble brain to cope with the ranged attack aspect. Pets still won't use ranged attacks against floating eyes. With the fix for reflection, I discovered that silver dragons would be subjected to floating eyes' passive paralysis even when their breath attack was suppressed. (It wouldn't impact them, due to reflection, but the message about the floating eye being hit by its reflected gaze was being delivered without being preceded by any message since no attack had taken place yet.) This fixes that. \#1336 is still open
This commit is contained in:
@@ -968,7 +968,7 @@ dog_move(
|
||||
struct obj *obj = (struct obj *) 0;
|
||||
xint16 otyp;
|
||||
boolean cursemsg[9], do_eat = FALSE;
|
||||
boolean better_with_displacing = FALSE;
|
||||
boolean better_with_displacing = FALSE, ranged_only;
|
||||
coordxy nix, niy; /* position mtmp is (considering) moving to */
|
||||
coordxy nx, ny; /* temporary coordinates */
|
||||
xint16 cnt, uncursedcnt, chcnt;
|
||||
@@ -1081,6 +1081,8 @@ dog_move(
|
||||
if (!edog && (j = distu(nx, ny)) > 16 && j >= udist)
|
||||
continue;
|
||||
|
||||
ranged_only = FALSE;
|
||||
|
||||
if ((info[i] & ALLOW_M) && MON_AT(nx, ny)) {
|
||||
int mstatus;
|
||||
struct monst *mtmp2 = m_at(nx, ny);
|
||||
@@ -1101,16 +1103,28 @@ dog_move(
|
||||
int balk = mtmp->m_lev + ((5 * mtmp->mhp) / mtmp->mhpmax) - 2;
|
||||
|
||||
if ((int) mtmp2->m_lev >= balk
|
||||
|| (mtmp2->data == &mons[PM_FLOATING_EYE] && rn2(10)
|
||||
&& mtmp->mcansee && haseyes(mtmp->data) && mtmp2->mcansee
|
||||
&& (perceives(mtmp->data) || !mtmp2->minvis))
|
||||
|| (mtmp2->data == &mons[PM_GELATINOUS_CUBE] && rn2(10))
|
||||
|| (mtmp2->mtame && mtmp->mtame && !Conflict)
|
||||
|| (max_passive_dmg(mtmp2, mtmp) >= mtmp->mhp)
|
||||
|| ((mtmp->mhp * 4 < mtmp->mhpmax
|
||||
|| mtmp2->data->msound == MS_GUARDIAN
|
||||
|| mtmp2->data->msound == MS_LEADER) && mtmp2->mpeaceful
|
||||
&& !Conflict)
|
||||
|| (touch_petrifies(mtmp2->data) && !resists_ston(mtmp)))
|
||||
|| mtmp2->data->msound == MS_LEADER)
|
||||
&& mtmp2->mpeaceful && !Conflict)) {
|
||||
continue;
|
||||
}
|
||||
if ((mtmp2->data == &mons[PM_FLOATING_EYE] && rn2(10)
|
||||
&& mtmp->mcansee && haseyes(mtmp->data) && mtmp2->mcansee
|
||||
&& (!mtmp2->minvis || perceives(mtmp->data))
|
||||
&& !mon_reflects(mtmp, (char *) NULL))
|
||||
|| (mtmp2->data == &mons[PM_GELATINOUS_CUBE] && rn2(10))
|
||||
|| (touch_petrifies(mtmp2->data) && !resists_ston(mtmp))) {
|
||||
/* only skip this foe if a ranged attack isn't viable */
|
||||
if (dist2(mtmp->mx, mtmp->my, mtmp2->mx, mtmp2->my) <= 2
|
||||
|| best_target(mtmp) != mtmp2)
|
||||
continue;
|
||||
ranged_only = TRUE;
|
||||
}
|
||||
/** FIXME: 'ranged_only' isn't used as intended yet **/
|
||||
if (ranged_only)
|
||||
continue;
|
||||
|
||||
if (after)
|
||||
@@ -1183,6 +1197,7 @@ dog_move(
|
||||
/* (minion isn't interested; `cursemsg' stays FALSE) */
|
||||
if (edog) {
|
||||
boolean can_reach_food = could_reach_item(mtmp, nx, ny);
|
||||
|
||||
for (obj = svl.level.objects[nx][ny]; obj; obj = obj->nexthere) {
|
||||
if (obj->cursed) {
|
||||
cursemsg[i] = TRUE;
|
||||
|
||||
32
src/mhitm.c
32
src/mhitm.c
@@ -485,7 +485,7 @@ mattackm(
|
||||
|
||||
case AT_EXPL:
|
||||
/* D: Prevent explosions 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;
|
||||
|
||||
res[i] = explmm(magr, mdef, mattk);
|
||||
@@ -525,25 +525,20 @@ mattackm(
|
||||
break;
|
||||
|
||||
case AT_BREA:
|
||||
if (!monnear(magr, mdef->mx, mdef->my)) {
|
||||
strike = (breamm(magr, mattk, mdef) == M_ATTK_MISS) ? 0 : 1;
|
||||
|
||||
/* We don't really know if we hit or not; pretend we did. */
|
||||
if (strike)
|
||||
res[i] |= M_ATTK_HIT;
|
||||
if (DEADMONSTER(mdef))
|
||||
res[i] = M_ATTK_DEF_DIED;
|
||||
if (DEADMONSTER(magr))
|
||||
res[i] |= M_ATTK_AGR_DIED;
|
||||
}
|
||||
else
|
||||
strike = 0;
|
||||
break;
|
||||
|
||||
case AT_SPIT:
|
||||
/*
|
||||
* Ranged attacks aren't allowed at point blank range.
|
||||
*
|
||||
* That impacts pet use of ranged attacks. It's rather arbitrary
|
||||
* but various parts of the code assume it to be the case, not to
|
||||
* mention a part of player strategy when fighting dragons.
|
||||
*/
|
||||
if (!monnear(magr, mdef->mx, mdef->my)) {
|
||||
strike = (spitmm(magr, mattk, mdef) == M_ATTK_MISS) ? 0 : 1;
|
||||
int mmtmp = ((mattk->aatyp == AT_BREA)
|
||||
? breamm(magr, mattk, mdef)
|
||||
: spitmm(magr, mattk, mdef));
|
||||
|
||||
strike = (mmtmp == M_ATTK_MISS) ? 0 : 1;
|
||||
/* We don't really know if we hit or not; pretend we did. */
|
||||
if (strike)
|
||||
res[i] |= M_ATTK_HIT;
|
||||
@@ -551,6 +546,9 @@ mattackm(
|
||||
res[i] = M_ATTK_DEF_DIED;
|
||||
if (DEADMONSTER(magr))
|
||||
res[i] |= M_ATTK_AGR_DIED;
|
||||
} else {
|
||||
strike = 0;
|
||||
attk = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user