decide where the monster thinks you are standing */
| 2195 | |
| 2196 | /* decide where the monster thinks you are standing */ |
| 2197 | void |
| 2198 | set_apparxy(struct monst *mtmp) |
| 2199 | { |
| 2200 | boolean notseen, notthere, gotu; |
| 2201 | int displ; |
| 2202 | coordxy mx = mtmp->mux, my = mtmp->muy; |
| 2203 | long umoney = money_cnt(gi.invent); |
| 2204 | |
| 2205 | /* |
| 2206 | * do cheapest and/or most likely tests first |
| 2207 | */ |
| 2208 | |
| 2209 | /* pet knows your smell; grabber still has hold of you; monsters which |
| 2210 | know where you are don't suddenly forget, if you haven't moved away */ |
| 2211 | if (mtmp->mtame || mtmp == u.ustuck || u_at(mx, my)) { |
| 2212 | mtmp->mux = u.ux; |
| 2213 | mtmp->muy = u.uy; |
| 2214 | return; |
| 2215 | } |
| 2216 | |
| 2217 | notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data))); |
| 2218 | notthere = (Displaced && mtmp->data != &mons[PM_DISPLACER_BEAST]); |
| 2219 | /* add cases as required. eg. Displacement ... */ |
| 2220 | if (Underwater) { |
| 2221 | displ = 1; |
| 2222 | } else if (notseen) { |
| 2223 | /* Xorns can smell quantities of valuable metal |
| 2224 | like that in solid gold coins, treat as seen */ |
| 2225 | displ = (mtmp->data == &mons[PM_XORN] && umoney) ? 0 : 1; |
| 2226 | } else if (notthere) { |
| 2227 | displ = couldsee(mx, my) ? 2 : 1; |
| 2228 | } else { |
| 2229 | displ = 0; |
| 2230 | } |
| 2231 | if (!displ) { |
| 2232 | mtmp->mux = u.ux; |
| 2233 | mtmp->muy = u.uy; |
| 2234 | return; |
| 2235 | } |
| 2236 | |
| 2237 | /* without something like the following, invisibility and displacement |
| 2238 | are too powerful */ |
| 2239 | gotu = notseen ? !rn2(3) : notthere ? !rn2(4) : FALSE; |
| 2240 | |
| 2241 | if (!gotu) { |
| 2242 | int try_cnt = 0; |
| 2243 | |
| 2244 | do { |
| 2245 | if (++try_cnt > 200) { |
| 2246 | mx = u.ux; |
| 2247 | my = u.uy; |
| 2248 | break; /* punt */ |
| 2249 | } |
| 2250 | mx = u.ux - displ + rn2(2 * displ + 1); |
| 2251 | my = u.uy - displ + rn2(2 * displ + 1); |
| 2252 | } while (!isok(mx, my) |
| 2253 | || (displ != 2 && mx == mtmp->mx && my == mtmp->my) |
| 2254 | || ((mx != u.ux || my != u.uy) && !passes_walls(mtmp->data) |
no test coverage detected