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:
PatR
2024-12-11 12:38:28 -08:00
parent e08bd9ef8a
commit aedb24d343
3 changed files with 41 additions and 27 deletions

View File

@@ -1484,9 +1484,8 @@ when hero who is poly'd into metallivore form eats a tin, bypass "smells like
digging in ice was handled inconsistently, particularly if done at the span
spot in front of closed drawbridge
angry god may remove an intrinsic
blessed scroll of destroy armor asks which armor to destroy
archeologists' fedora is lucky
gelatinous cubes eat organic objects inside them
pets with reflection were unwilling to attack floating eyes
Fixes to 3.7.0-x General Problems Exposed Via git Repository
@@ -2734,6 +2733,8 @@ enlightenment/attribute disclosure for saving-grace: include a line for have
tourists gain experience by seeing new types of creatures up close, and
going to new dungeon levels
healers gain experience by healing pets
blessed scroll of destroy armor asks which armor to destroy
archeologists' fedora is lucky
Platform- and/or Interface-Specific New Features

View File

@@ -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;

View File

@@ -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;