crossing long worms' tails (trunk only)
This is one of the items from "#Q397: List of Bugs from #nethack" sent
in Janurary by <email deleted> and containing a list
of things collected from the IRC channel associated with nethack.alt.org's
public server. Moving diagonally between segments of a worm tail is
conceptually passing right through the worm's body. This patch prevents
moving in such a fashion for both the hero and monsters (it's still
possible to fight in that position though). It only applies when the two
tail segments are consecutive.
|...... In the diagram here, where tail segments are represented by
|.w1?.. digits indicating relative sequence number, the @ can still
|..@2.. move between segments 2 and 5 to reach !, but can no longer
|.65!3. move between 1 and 2 to reach ?. [However, if there is a
|...4.. monster at the ? spot, it can still hit @ and vice versa.]
Missiles and wand zaps still pass through such diagonals without
noticing or affecting the worm. I'm not sure whether this ought to be
extended to change that--it might get pretty messy since it would need
to be considered during monsters' targetting as well as during the path
traversal itself.
This commit is contained in:
32
src/mon.c
32
src/mon.c
@@ -1018,7 +1018,7 @@ mfndpos(mon, poss, info, flag)
|
||||
y = mon->my;
|
||||
nowtyp = levl[x][y].typ;
|
||||
|
||||
nodiag = (mdat == &mons[PM_GRID_BUG]);
|
||||
nodiag = NODIAG(mdat - mons);
|
||||
wantpool = mdat->mlet == S_EEL;
|
||||
poolok = is_flyer(mdat) || is_clinger(mdat) ||
|
||||
(is_swimmer(mdat) && !wantpool);
|
||||
@@ -1063,21 +1063,23 @@ nexttry: /* eels prefer the water, but if there is no water nearby,
|
||||
!((IS_TREE(ntyp) ? treeok : rockok) && may_dig(nx,ny))) continue;
|
||||
/* KMH -- Added iron bars */
|
||||
if (ntyp == IRONBARS && !(flag & ALLOW_BARS)) continue;
|
||||
if(IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon)) &&
|
||||
((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
|
||||
(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
|
||||
!thrudoor) continue;
|
||||
if(nx != x && ny != y && (nodiag ||
|
||||
if (IS_DOOR(ntyp) && !(amorphous(mdat) || can_fog(mon)) &&
|
||||
(((levl[nx][ny].doormask & D_CLOSED) &&
|
||||
!(flag & OPENDOOR)) ||
|
||||
((levl[nx][ny].doormask & D_LOCKED) &&
|
||||
!(flag & UNLOCKDOOR))) &&
|
||||
!thrudoor) continue;
|
||||
/* first diagonal checks (tight squeezes handled below) */
|
||||
if (nx != x && ny != y && (nodiag ||
|
||||
(IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
|
||||
(IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)) ||
|
||||
#ifdef REINCARNATION
|
||||
((IS_DOOR(nowtyp) &&
|
||||
((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) ||
|
||||
(IS_DOOR(ntyp) &&
|
||||
((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))))
|
||||
#else
|
||||
((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) ||
|
||||
(IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN)))
|
||||
((IS_DOOR(nowtyp) || IS_DOOR(ntyp)) && Is_rogue_level(&u.uz)) ||
|
||||
#endif
|
||||
))
|
||||
/* mustn't pass between adjacent long worm segments,
|
||||
but can attack that way */
|
||||
(m_at(x, ny) && m_at(nx, y) && worm_cross(x, y, nx, ny) &&
|
||||
!m_at(nx, ny) && (nx != u.ux || ny != u.uy))))
|
||||
continue;
|
||||
if((is_pool(nx,ny) == wantpool || poolok) &&
|
||||
(lavaok || !is_lava(nx,ny))) {
|
||||
@@ -1279,7 +1281,7 @@ register int x,y;
|
||||
{
|
||||
register int distance = dist2(mon->mx, mon->my, x, y);
|
||||
|
||||
if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0;
|
||||
if (distance == 2 && NODIAG(mon->data - mons)) return 0;
|
||||
return((boolean)(distance < 3));
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user