diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 13d11bcca..362cd6c7e 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -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 diff --git a/src/dogmove.c b/src/dogmove.c index 29c0d9bc1..1694eb8a6 100644 --- a/src/dogmove.c +++ b/src/dogmove.c @@ -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; diff --git a/src/mhitm.c b/src/mhitm.c index f54dc4ad2..3ea3b3643 100644 --- a/src/mhitm.c +++ b/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;