E int FDECL(curr_mon_load, (struct monst *));
E int FDECL(max_mon_load, (struct monst *));
E int FDECL(can_carry, (struct monst *, struct obj *));
+E long FDECL(mon_allowflags, (struct monst *));
E int FDECL(mfndpos, (struct monst *, coord *, long *, long));
E boolean FDECL(monnear, (struct monst *, int, int));
E void NDECL(dmonsfree);
if (appr == -2)
return 0;
- allowflags = ALLOW_M | ALLOW_TRAPS | ALLOW_SSM | ALLOW_SANCT;
- if (passes_walls(mtmp->data))
- allowflags |= (ALLOW_ROCK | ALLOW_WALL);
- if (passes_bars(mtmp->data))
- allowflags |= ALLOW_BARS;
- if (throws_rocks(mtmp->data))
- allowflags |= ALLOW_ROCK;
- if (is_displacer(mtmp->data))
- allowflags |= ALLOW_MDISP;
if (Conflict && !resist(mtmp, RING_CLASS, 0, 0)) {
- allowflags |= ALLOW_U;
if (!has_edog) {
/* Guardian angel refuses to be conflicted; rather,
* it disappears, angrily, and sends in some nasties
You("get released!");
}
#endif
- if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
- allowflags |= OPENDOOR;
- if (monhaskey(mtmp, TRUE))
- allowflags |= UNLOCKDOOR;
- /* note: the Wizard and Riders can unlock doors without a key;
- they won't use that ability if someone manages to tame them */
- }
- if (is_giant(mtmp->data))
- allowflags |= BUSTDOOR;
- if (tunnels(mtmp->data)
- && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */
- allowflags |= ALLOW_DIG;
+ allowflags = mon_allowflags(mtmp);
cnt = mfndpos(mtmp, poss, info, allowflags);
/* Normally dogs don't step on cursed items, but if they have no
return iquan;
}
+/* return flags based on monster data, for mfndpos() */
+long
+mon_allowflags(mtmp)
+struct monst *mtmp;
+{
+ long flags = 0L;
+ boolean can_open = !(nohands(mtmp->data) || verysmall(mtmp->data));
+ boolean can_unlock = ((can_open && monhaskey(mtmp, TRUE))
+ || mtmp->iswiz || is_rider(mtmp->data));
+ boolean doorbuster = is_giant(mtmp->data);
+
+ if (mtmp->mtame)
+ flags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM;
+ else if (mtmp->mpeaceful)
+ flags |= ALLOW_SANCT | ALLOW_SSM;
+ else
+ flags |= ALLOW_U;
+ if (Conflict && !resist(mtmp, RING_CLASS, 0, 0))
+ flags |= ALLOW_U;
+ if (mtmp->isshk)
+ flags |= ALLOW_SSM;
+ if (mtmp->ispriest)
+ flags |= ALLOW_SSM | ALLOW_SANCT;
+ if (passes_walls(mtmp->data))
+ flags |= (ALLOW_ROCK | ALLOW_WALL);
+ if (throws_rocks(mtmp->data))
+ flags |= ALLOW_ROCK;
+ if (tunnels(mtmp->data)
+ && !Is_rogue_level(&u.uz)) /* same restriction as m_move() */
+ flags |= ALLOW_DIG;
+ if (doorbuster)
+ flags |= BUSTDOOR;
+ if (can_open)
+ flags |= OPENDOOR;
+ if (can_unlock)
+ flags |= UNLOCKDOOR;
+ if (passes_bars(mtmp->data))
+ flags |= ALLOW_BARS;
+ if (is_displacer(mtmp->data))
+ flags |= ALLOW_MDISP;
+ if (is_minion(mtmp->data) || is_rider(mtmp->data))
+ flags |= ALLOW_SANCT;
+ /* unicorn may not be able to avoid hero on a noteleport level */
+ if (is_unicorn(mtmp->data) && !noteleport_level(mtmp))
+ flags |= NOTONL;
+ if (passes_walls(mtmp->data))
+ flags |= (ALLOW_WALL | ALLOW_ROCK);
+ if (passes_bars(mtmp->data))
+ flags |= ALLOW_BARS;
+ if (is_human(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR])
+ flags |= ALLOW_SSM;
+ if ((is_undead(mtmp->data) && mtmp->data->mlet != S_GHOST) || is_vampshifter(mtmp))
+ flags |= NOGARLIC;
+ if (throws_rocks(mtmp->data))
+ flags |= ALLOW_ROCK;
+
+ return flags;
+}
+
/* return number of acceptable neighbour positions */
int
mfndpos(mon, poss, info, flag)
nix = omx;
niy = omy;
- flag = 0L;
- if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))
- flag |= (ALLOW_SANCT | ALLOW_SSM);
- else
- flag |= ALLOW_U;
- if (is_minion(ptr) || is_rider(ptr))
- flag |= ALLOW_SANCT;
- /* unicorn may not be able to avoid hero on a noteleport level */
- if (is_unicorn(ptr) && !noteleport_level(mtmp))
- flag |= NOTONL;
- if (passes_walls(ptr))
- flag |= (ALLOW_WALL | ALLOW_ROCK);
- if (passes_bars(ptr))
- flag |= ALLOW_BARS;
- if (can_tunnel)
- flag |= ALLOW_DIG;
- if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
- flag |= ALLOW_SSM;
- if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp))
- flag |= NOGARLIC;
- if (throws_rocks(ptr))
- flag |= ALLOW_ROCK;
- if (can_open)
- flag |= OPENDOOR;
- if (can_unlock)
- flag |= UNLOCKDOOR;
- if (doorbuster)
- flag |= BUSTDOOR;
+ flag = mon_allowflags(mtmp);
{
register int i, j, nx, ny, nearer;
int jcnt, cnt;
nix = omx;
niy = omy;
- if (mtmp->isshk)
- allowflags = ALLOW_SSM;
- else
- allowflags = ALLOW_SSM | ALLOW_SANCT;
- if (passes_walls(mtmp->data))
- allowflags |= (ALLOW_ROCK | ALLOW_WALL);
- if (throws_rocks(mtmp->data))
- allowflags |= ALLOW_ROCK;
- if (tunnels(mtmp->data))
- allowflags |= ALLOW_DIG;
- if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
- allowflags |= OPENDOOR;
- if (monhaskey(mtmp, TRUE))
- allowflags |= UNLOCKDOOR;
- }
- if (is_giant(mtmp->data))
- allowflags |= BUSTDOOR;
+ allowflags = mon_allowflags(mtmp);
cnt = mfndpos(mtmp, poss, info, allowflags);
if (mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */