Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Chris-plus-alphanumericgibberish/56b83dcd1fcc0f102c40 to your computer and use it in GitHub Desktop.
Save Chris-plus-alphanumericgibberish/56b83dcd1fcc0f102c40 to your computer and use it in GitHub Desktop.
NAO vanilla mfndpos
/* return number of acceptable neighbour positions */
int
mfndpos(mon, poss, info, flag)
register struct monst *mon;
coord *poss; /* coord poss[9] */
long *info; /* long info[9] */
long flag;
{
struct permonst *mdat = mon->data;
register xchar x,y,nx,ny;
register int cnt = 0;
register uchar ntyp;
uchar nowtyp;
boolean wantpool,poolok,lavaok,nodiag;
boolean rockok = FALSE, treeok = FALSE, thrudoor;
int maxx, maxy;
x = mon->mx;
y = mon->my;
nowtyp = levl[x][y].typ;
nodiag = (mdat == &mons[PM_GRID_BUG]);
wantpool = mdat->mlet == S_EEL;
poolok = is_flyer(mdat) || is_clinger(mdat) ||
(is_swimmer(mdat) && !wantpool);
lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat);
thrudoor = ((flag & (ALLOW_WALL|BUSTDOOR)) != 0L);
if (flag & ALLOW_DIG) {
struct obj *mw_tmp;
/* need to be specific about what can currently be dug */
if (!needspick(mdat)) {
rockok = treeok = TRUE;
} else if ((mw_tmp = MON_WEP(mon)) && mw_tmp->cursed &&
mon->weapon_check == NO_WEAPON_WANTED) {
rockok = is_pick(mw_tmp);
treeok = is_axe(mw_tmp);
} else {
rockok = (m_carrying(mon, PICK_AXE) ||
(m_carrying(mon, DWARVISH_MATTOCK) &&
!which_armor(mon, W_ARMS)));
treeok = (m_carrying(mon, AXE) ||
(m_carrying(mon, BATTLE_AXE) &&
!which_armor(mon, W_ARMS)));
}
thrudoor |= rockok || treeok;
}
nexttry: /* eels prefer the water, but if there is no water nearby,
they will crawl over land */
if(mon->mconf) {
flag |= ALLOW_ALL;
flag &= ~NOTONL;
}
if(!mon->mcansee)
flag |= ALLOW_SSM;
maxx = min(x+1,COLNO-1);
maxy = min(y+1,ROWNO-1);
for(nx = max(1,x-1); nx <= maxx; nx++)
for(ny = max(0,y-1); ny <= maxy; ny++) {
if(nx == x && ny == y) continue;
if(IS_ROCK(ntyp = levl[nx][ny].typ) &&
!((flag & ALLOW_WALL) && may_passwall(nx,ny)) &&
!((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) &&
((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) ||
(levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR))) &&
!thrudoor) continue;
if(nx != x && ny != y && (nodiag ||
#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)))
#endif
))
continue;
if((is_pool(nx,ny) == wantpool || poolok) &&
(lavaok || !is_lava(nx,ny))) {
int dispx, dispy;
boolean monseeu = (mon->mcansee && (!Invis || perceives(mdat)));
boolean checkobj = OBJ_AT(nx,ny);
/* Displacement also displaces the Elbereth/scare monster,
* as long as you are visible.
*/
if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) {
dispx = u.ux;
dispy = u.uy;
} else {
dispx = nx;
dispy = ny;
}
info[cnt] = 0;
if ((checkobj || Displaced) && onscary(dispx, dispy, mon)) {
if(!(flag & ALLOW_SSM)) continue;
info[cnt] |= ALLOW_SSM;
}
if((nx == u.ux && ny == u.uy) ||
(nx == mon->mux && ny == mon->muy)) {
if (nx == u.ux && ny == u.uy) {
/* If it's right next to you, it found you,
* displaced or no. We must set mux and muy
* right now, so when we return we can tell
* that the ALLOW_U means to attack _you_ and
* not the image.
*/
mon->mux = u.ux;
mon->muy = u.uy;
}
if(!(flag & ALLOW_U)) continue;
info[cnt] |= ALLOW_U;
} else {
if(MON_AT(nx, ny)) {
struct monst *mtmp2 = m_at(nx, ny);
long mmflag = flag | mm_aggression(mon, mtmp2);
if (!(mmflag & ALLOW_M)) continue;
info[cnt] |= ALLOW_M;
if (mtmp2->mtame) {
if (!(mmflag & ALLOW_TM)) continue;
info[cnt] |= ALLOW_TM;
}
}
/* Note: ALLOW_SANCT only prevents movement, not */
/* attack, into a temple. */
if(level.flags.has_temple &&
*in_rooms(nx, ny, TEMPLE) &&
!*in_rooms(x, y, TEMPLE) &&
in_your_sanctuary((struct monst *)0, nx, ny)) {
if(!(flag & ALLOW_SANCT)) continue;
info[cnt] |= ALLOW_SANCT;
}
}
if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) {
if(flag & NOGARLIC) continue;
info[cnt] |= NOGARLIC;
}
if(checkobj && sobj_at(BOULDER, nx, ny)) {
if(!(flag & ALLOW_ROCK)) continue;
info[cnt] |= ALLOW_ROCK;
}
if (monseeu && onlineu(nx,ny)) {
if(flag & NOTONL) continue;
info[cnt] |= NOTONL;
}
if (nx != x && ny != y && bad_rock(mdat, x, ny)
&& bad_rock(mdat, nx, y)
&& (bigmonst(mdat) || (curr_mon_load(mon) > 600)))
continue;
/* The monster avoids a particular type of trap if it's familiar
* with the trap type. Pets get ALLOW_TRAPS and checking is
* done in dogmove.c. In either case, "harmless" traps are
* neither avoided nor marked in info[].
*/
{ register struct trap *ttmp = t_at(nx, ny);
if(ttmp) {
if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) {
impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp);
continue;
}
if ((ttmp->ttyp != RUST_TRAP
|| mdat == &mons[PM_IRON_GOLEM])
&& ttmp->ttyp != STATUE_TRAP
&& ((ttmp->ttyp != PIT
&& ttmp->ttyp != SPIKED_PIT
&& ttmp->ttyp != TRAPDOOR
&& ttmp->ttyp != HOLE)
|| (!is_flyer(mdat)
&& !is_floater(mdat)
&& !is_clinger(mdat))
|| In_sokoban(&u.uz))
&& (ttmp->ttyp != SLP_GAS_TRAP ||
!resists_sleep(mon))
&& (ttmp->ttyp != BEAR_TRAP ||
(mdat->msize > MZ_SMALL &&
!amorphous(mdat) && !is_flyer(mdat)))
&& (ttmp->ttyp != FIRE_TRAP ||
!resists_fire(mon))
&& (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat))
&& (ttmp->ttyp != WEB || (!amorphous(mdat) &&
!webmaker(mdat)))
) {
if (!(flag & ALLOW_TRAPS)) {
if (mon->mtrapseen & (1L << (ttmp->ttyp - 1)))
continue;
}
info[cnt] |= ALLOW_TRAPS;
}
}
}
poss[cnt].x = nx;
poss[cnt].y = ny;
cnt++;
}
}
if(!cnt && wantpool && !is_pool(x,y)) {
wantpool = FALSE;
goto nexttry;
}
return(cnt);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment