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