return flags based on monster data, for mfndpos() */
| 2061 | |
| 2062 | /* return flags based on monster data, for mfndpos() */ |
| 2063 | long |
| 2064 | mon_allowflags(struct monst *mtmp) |
| 2065 | { |
| 2066 | long allowflags = 0L; |
| 2067 | boolean can_open = !(nohands(mtmp->data) || verysmall(mtmp->data)); |
| 2068 | boolean can_unlock = ((can_open && monhaskey(mtmp, TRUE)) |
| 2069 | || mtmp->iswiz || is_rider(mtmp->data)); |
| 2070 | boolean doorbuster = is_giant(mtmp->data); |
| 2071 | /* don't tunnel if on rogue level or if hostile and close enough |
| 2072 | to prefer a weapon; same criteria as in m_move() */ |
| 2073 | boolean can_tunnel = (tunnels(mtmp->data) && !Is_rogue_level(&u.uz)); |
| 2074 | |
| 2075 | if (can_tunnel && needspick(mtmp->data) |
| 2076 | && ((!mtmp->mpeaceful || Conflict) |
| 2077 | && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8)) |
| 2078 | can_tunnel = FALSE; |
| 2079 | |
| 2080 | if (mtmp->mtame) |
| 2081 | allowflags |= ALLOW_M | ALLOW_TRAPS | ALLOW_SANCT | ALLOW_SSM; |
| 2082 | else if (mtmp->mpeaceful) |
| 2083 | allowflags |= ALLOW_SANCT | ALLOW_SSM; |
| 2084 | else |
| 2085 | allowflags |= ALLOW_U; |
| 2086 | if (Conflict && !resist_conflict(mtmp)) |
| 2087 | allowflags |= ALLOW_U; |
| 2088 | if (mtmp->isshk) |
| 2089 | allowflags |= ALLOW_SSM; |
| 2090 | if (mtmp->ispriest) |
| 2091 | allowflags |= ALLOW_SSM | ALLOW_SANCT; |
| 2092 | if (passes_walls(mtmp->data)) |
| 2093 | allowflags |= (ALLOW_ROCK | ALLOW_WALL); |
| 2094 | if (throws_rocks(mtmp->data) || m_can_break_boulder(mtmp)) |
| 2095 | allowflags |= ALLOW_ROCK; |
| 2096 | if (can_tunnel) |
| 2097 | allowflags |= ALLOW_DIG; |
| 2098 | if (doorbuster) |
| 2099 | allowflags |= BUSTDOOR; |
| 2100 | if (can_open) |
| 2101 | allowflags |= OPENDOOR; |
| 2102 | if (can_unlock) |
| 2103 | allowflags |= UNLOCKDOOR; |
| 2104 | if (passes_bars(mtmp->data) |
| 2105 | /* restrict engulfer or holder who might try to pass iron bars while |
| 2106 | carrying hero; accept small subset for poly'd hero passes_bars() */ |
| 2107 | && (mtmp != u.ustuck || (unsolid(gy.youmonst.data) |
| 2108 | || verysmall(gy.youmonst.data)))) |
| 2109 | allowflags |= ALLOW_BARS; |
| 2110 | #if 0 /* can't do this here; leave it for mfndpos() */ |
| 2111 | if (is_displacer(mtmp->data)) |
| 2112 | allowflags |= ALLOW_MDISP; |
| 2113 | #endif |
| 2114 | if (is_minion(mtmp->data) || is_rider(mtmp->data)) |
| 2115 | allowflags |= ALLOW_SANCT; |
| 2116 | /* unicorn may not be able to avoid hero on a noteleport level */ |
| 2117 | if (is_unicorn(mtmp->data) && !noteleport_level(mtmp)) |
| 2118 | allowflags |= NOTONL; |
| 2119 | if (is_human(mtmp->data) || mtmp->data == &mons[PM_MINOTAUR]) |
| 2120 | allowflags |= ALLOW_SSM; |
no test coverage detected