OSDN Git Service

update year to 2020
[jnethack/source.git] / src / monmove.c
1 /* NetHack 3.6  monmove.c       $NHDT-Date: 1575245074 2019/12/02 00:04:34 $  $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2006. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12 #include "mfndpos.h"
13 #include "artifact.h"
14
15 extern boolean notonhead;
16
17 STATIC_DCL void FDECL(watch_on_duty, (struct monst *));
18 STATIC_DCL int FDECL(disturb, (struct monst *));
19 STATIC_DCL void FDECL(release_hero, (struct monst *));
20 STATIC_DCL void FDECL(distfleeck, (struct monst *, int *, int *, int *));
21 STATIC_DCL int FDECL(m_arrival, (struct monst *));
22 STATIC_DCL boolean FDECL(stuff_prevents_passage, (struct monst *));
23 STATIC_DCL int FDECL(vamp_shift, (struct monst *, struct permonst *,
24                                   BOOLEAN_P));
25
26 /* True if mtmp died */
27 boolean
28 mb_trapped(mtmp)
29 struct monst *mtmp;
30 {
31     if (flags.verbose) {
32         if (cansee(mtmp->mx, mtmp->my) && !Unaware)
33 /*JP
34             pline("KABOOM!!  You see a door explode.");
35 */
36             pline("\82¿\82ã\82Ç\81[\82ñ\81I\83h\83A\82ª\94\9a\94­\82·\82é\82Ì\82ð\8c©\82½\81D");
37         else if (!Deaf)
38 /*JP
39             You_hear("a distant explosion.");
40 */
41             You_hear("\89\93\95û\82Å\94\9a\94­\82·\82é\89¹\82ð\95·\82¢\82½\81D");
42     }
43     wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
44     mtmp->mstun = 1;
45     mtmp->mhp -= rnd(15);
46     if (DEADMONSTER(mtmp)) {
47         mondied(mtmp);
48         if (!DEADMONSTER(mtmp)) /* lifesaved */
49             return FALSE;
50         else
51             return TRUE;
52     }
53     return FALSE;
54 }
55
56 /* check whether a monster is carrying a locking/unlocking tool */
57 boolean
58 monhaskey(mon, for_unlocking)
59 struct monst *mon;
60 boolean for_unlocking; /* true => credit card ok, false => not ok */
61 {
62     if (for_unlocking && m_carrying(mon, CREDIT_CARD))
63         return TRUE;
64     return m_carrying(mon, SKELETON_KEY) || m_carrying(mon, LOCK_PICK);
65 }
66
67 void
68 mon_yells(mon, shout)
69 struct monst *mon;
70 const char *shout;
71 {
72     if (Deaf) {
73         if (canspotmon(mon))
74             /* Sidenote on "A watchman angrily waves her arms!"
75              * Female being called watchman is correct (career name).
76              */
77 #if 0 /*JP:T*/
78             pline("%s angrily %s %s %s!",
79                 Amonnam(mon),
80                 nolimbs(mon->data) ? "shakes" : "waves",
81                 mhis(mon),
82                 nolimbs(mon->data) ? mbodypart(mon, HEAD)
83                                    : makeplural(mbodypart(mon, ARM)));
84 #else
85             pline("%s\82Í\93{\82Á\82Ä%s\82ð\90U\82Á\82½\81I",
86                 Amonnam(mon),
87                 nolimbs(mon->data) ? mbodypart(mon, HEAD)
88                                    : makeplural(mbodypart(mon, ARM)));
89 #endif
90     } else {
91         if (canspotmon(mon))
92 /*JP
93             pline("%s yells:", Amonnam(mon));
94 */
95             pline("%s\82Í\8b©\82ñ\82¾\81F", Amonnam(mon));
96         else
97 /*JP
98             You_hear("someone yell:");
99 */
100             pline("\89½\8eÒ\82©\82Í\8b©\82ñ\82¾\81F");
101         verbalize1(shout);
102     }
103 }
104
105 STATIC_OVL void
106 watch_on_duty(mtmp)
107 register struct monst *mtmp;
108 {
109     int x, y;
110
111     if (mtmp->mpeaceful && in_town(u.ux + u.dx, u.uy + u.dy)
112         && mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
113         if (picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ)
114             && (levl[x][y].doormask & D_LOCKED)) {
115             if (couldsee(mtmp->mx, mtmp->my)) {
116                 if (levl[x][y].looted & D_WARNED) {
117 /*JP
118                     mon_yells(mtmp, "Halt, thief!  You're under arrest!");
119 */
120                     verbalize("\91Ò\82Ä\81I\82Ê\82·\82Á\82Æ\81I\82¨\82Ü\82¦\82ð\91ß\95ß\82·\82é\81I");
121                     (void) angry_guards(!!Deaf);
122                 } else {
123 /*JP
124                     mon_yells(mtmp, "Hey, stop picking that lock!");
125 */
126                     verbalize("\82¨\82¢\81C\8c®\82ð\8f\9f\8eè\82É\8aJ\82¯\82é\82ñ\82\82á\82È\82¢\81I");
127                     levl[x][y].looted |= D_WARNED;
128                 }
129                 stop_occupation();
130             }
131         } else if (is_digging()) {
132             /* chewing, wand/spell of digging are checked elsewhere */
133             watch_dig(mtmp, context.digging.pos.x, context.digging.pos.y,
134                       FALSE);
135         }
136     }
137 }
138
139 int
140 dochugw(mtmp)
141 register struct monst *mtmp;
142 {
143     int x = mtmp->mx, y = mtmp->my;
144     boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp);
145     int rd = dochug(mtmp);
146
147     /* a similar check is in monster_nearby() in hack.c */
148     /* check whether hero notices monster and stops current activity */
149     if (occupation && !rd && !Confusion && (!mtmp->mpeaceful || Hallucination)
150         /* it's close enough to be a threat */
151         && distu(x, y) <= (BOLT_LIM + 1) * (BOLT_LIM + 1)
152         /* and either couldn't see it before, or it was too far away */
153         && (!already_saw_mon || !couldsee(x, y)
154             || distu(x, y) > (BOLT_LIM + 1) * (BOLT_LIM + 1))
155         /* can see it now, or sense it and would normally see it */
156         && (canseemon(mtmp) || (sensemon(mtmp) && couldsee(x, y)))
157         && mtmp->mcanmove && !noattacks(mtmp->data)
158         && !onscary(u.ux, u.uy, mtmp))
159         stop_occupation();
160
161     return rd;
162 }
163
164 boolean
165 onscary(x, y, mtmp)
166 int x, y;
167 struct monst *mtmp;
168 {
169     /* creatures who are directly resistant to magical scaring:
170      * Rodney, lawful minions, Angels, the Riders, shopkeepers
171      * inside their own shop, priests inside their own temple */
172     if (mtmp->iswiz || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL]
173         || is_rider(mtmp->data)
174         || (mtmp->isshk && inhishop(mtmp))
175         || (mtmp->ispriest && inhistemple(mtmp)))
176         return FALSE;
177
178     /* <0,0> is used by musical scaring to check for the above;
179      * it doesn't care about scrolls or engravings or dungeon branch */
180     if (x == 0 && y == 0)
181         return TRUE;
182
183     /* should this still be true for defiled/molochian altars? */
184     if (IS_ALTAR(levl[x][y].typ)
185         && (mtmp->data->mlet == S_VAMPIRE || is_vampshifter(mtmp)))
186         return TRUE;
187
188     /* the scare monster scroll doesn't have any of the below
189      * restrictions, being its own source of power */
190     if (sobj_at(SCR_SCARE_MONSTER, x, y))
191         return TRUE;
192
193     /*
194      * Creatures who don't (or can't) fear a written Elbereth:
195      * all the above plus shopkeepers (even if poly'd into non-human),
196      * vault guards (also even if poly'd), blind or peaceful monsters,
197      * humans and elves, and minotaurs.
198      *
199      * If the player isn't actually on the square OR the player's image
200      * isn't displaced to the square, no protection is being granted.
201      *
202      * Elbereth doesn't work in Gehennom, the Elemental Planes, or the
203      * Astral Plane; the influence of the Valar only reaches so far.
204      */
205     return (sengr_at("Elbereth", x, y, TRUE)
206             && ((u.ux == x && u.uy == y)
207                 || (Displaced && mtmp->mux == x && mtmp->muy == y))
208             && !(mtmp->isshk || mtmp->isgd || !mtmp->mcansee
209                  || mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN
210                  || mtmp->data == &mons[PM_MINOTAUR]
211                  || Inhell || In_endgame(&u.uz)));
212 }
213
214
215 /* regenerate lost hit points */
216 void
217 mon_regen(mon, digest_meal)
218 struct monst *mon;
219 boolean digest_meal;
220 {
221     if (mon->mhp < mon->mhpmax && (moves % 20 == 0 || regenerates(mon->data)))
222         mon->mhp++;
223     if (mon->mspec_used)
224         mon->mspec_used--;
225     if (digest_meal) {
226         if (mon->meating) {
227             mon->meating--;
228             if (mon->meating <= 0)
229                 finish_meating(mon);
230         }
231     }
232 }
233
234 /*
235  * Possibly awaken the given monster.  Return a 1 if the monster has been
236  * jolted awake.
237  */
238 STATIC_OVL int
239 disturb(mtmp)
240 register struct monst *mtmp;
241 {
242     /*
243      * + Ettins are hard to surprise.
244      * + Nymphs, jabberwocks, and leprechauns do not easily wake up.
245      *
246      * Wake up if:
247      *  in direct LOS                                           AND
248      *  within 10 squares                                       AND
249      *  not stealthy or (mon is an ettin and 9/10)              AND
250      *  (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND
251      *  Aggravate or mon is (dog or human) or
252      *      (1/7 and mon is not mimicing furniture or object)
253      */
254     if (couldsee(mtmp->mx, mtmp->my) && distu(mtmp->mx, mtmp->my) <= 100
255         && (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10)))
256         && (!(mtmp->data->mlet == S_NYMPH
257               || mtmp->data == &mons[PM_JABBERWOCK]
258 #if 0 /* DEFERRED */
259               || mtmp->data == &mons[PM_VORPAL_JABBERWOCK]
260 #endif
261               || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50))
262         && (Aggravate_monster
263             || (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_HUMAN)
264             || (!rn2(7) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
265                 && M_AP_TYPE(mtmp) != M_AP_OBJECT))) {
266         mtmp->msleeping = 0;
267         return 1;
268     }
269     return 0;
270 }
271
272 /* ungrab/expel held/swallowed hero */
273 STATIC_OVL void
274 release_hero(mon)
275 struct monst *mon;
276 {
277     if (mon == u.ustuck) {
278         if (u.uswallow) {
279             expels(mon, mon->data, TRUE);
280         } else if (!sticks(youmonst.data)) {
281             unstuck(mon); /* let go */
282 /*JP
283             You("get released!");
284 */
285             You("\89ð\95ú\82³\82ê\82½\81I");
286         }
287     }
288 }
289
290 #define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN]     \
291                           && (uwep && artifact_light(uwep) && uwep->lamplit))
292 /* we could include this in the above macro, but probably overkill/overhead */
293 /*      && (!(which_armor((mon), W_ARMC) != 0                               */
294 /*            && which_armor((mon), W_ARMH) != 0))                          */
295
296 /* monster begins fleeing for the specified time, 0 means untimed flee
297  * if first, only adds fleetime if monster isn't already fleeing
298  * if fleemsg, prints a message about new flight, otherwise, caller should */
299 void
300 monflee(mtmp, fleetime, first, fleemsg)
301 struct monst *mtmp;
302 int fleetime;
303 boolean first;
304 boolean fleemsg;
305 {
306     /* shouldn't happen; maybe warrants impossible()? */
307     if (DEADMONSTER(mtmp))
308         return;
309
310     if (mtmp == u.ustuck)
311         release_hero(mtmp); /* expels/unstuck */
312
313     if (!first || !mtmp->mflee) {
314         /* don't lose untimed scare */
315         if (!fleetime)
316             mtmp->mfleetim = 0;
317         else if (!mtmp->mflee || mtmp->mfleetim) {
318             fleetime += (int) mtmp->mfleetim;
319             /* ensure monster flees long enough to visibly stop fighting */
320             if (fleetime == 1)
321                 fleetime++;
322             mtmp->mfleetim = (unsigned) min(fleetime, 127);
323         }
324         if (!mtmp->mflee && fleemsg && canseemon(mtmp)
325             && M_AP_TYPE(mtmp) != M_AP_FURNITURE
326             && M_AP_TYPE(mtmp) != M_AP_OBJECT) {
327             /* unfortunately we can't distinguish between temporary
328                sleep and temporary paralysis, so both conditions
329                receive the same alternate message */
330             if (!mtmp->mcanmove || !mtmp->data->mmove) {
331 /*JP
332                 pline("%s seems to flinch.", Adjmonnam(mtmp, "immobile"));
333 */
334                 pline("%s\82Í\82µ\82è\82²\82Ý\82µ\82Ä\82¢\82é\82æ\82¤\82¾\81D", Monnam(mtmp));
335             } else if (flees_light(mtmp)) {
336                 if (rn2(10) || Deaf)
337 #if 0 /*JP*/
338                     pline("%s flees from the painful light of %s.",
339                           Monnam(mtmp), bare_artifactname(uwep));
340 #else
341                     pline("%s\82Í%s\82Ì\8cõ\82É\82¨\82Ñ\82¦\82½\81D",
342                           Monnam(mtmp), bare_artifactname(uwep));
343 #endif
344                 else
345 /*JP
346                     verbalize("Bright light!");
347 */
348                     verbalize("\8bP\82­\8cõ\81I");
349             } else
350 /*JP
351                 pline("%s turns to flee.", Monnam(mtmp));
352 */
353                 pline("%s\82Í\82¨\82Ñ\82¦\82Ä\93¦\82°\8fo\82µ\82½\81I", Monnam(mtmp));
354         }
355         mtmp->mflee = 1;
356     }
357     /* ignore recently-stepped spaces when made to flee */
358     memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
359 }
360
361 STATIC_OVL void
362 distfleeck(mtmp, inrange, nearby, scared)
363 register struct monst *mtmp;
364 int *inrange, *nearby, *scared;
365 {
366     int seescaryx, seescaryy;
367     boolean sawscary = FALSE, bravegremlin = (rn2(5) == 0);
368
369     *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
370                 <= (BOLT_LIM * BOLT_LIM));
371     *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy);
372
373     /* Note: if your image is displaced, the monster sees the Elbereth
374      * at your displaced position, thus never attacking your displaced
375      * position, but possibly attacking you by accident.  If you are
376      * invisible, it sees the Elbereth at your real position, thus never
377      * running into you by accident but possibly attacking the spot
378      * where it guesses you are.
379      */
380     if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
381         seescaryx = mtmp->mux;
382         seescaryy = mtmp->muy;
383     } else {
384         seescaryx = u.ux;
385         seescaryy = u.uy;
386     }
387
388     sawscary = onscary(seescaryx, seescaryy, mtmp);
389     if (*nearby && (sawscary
390                     || (flees_light(mtmp) && !bravegremlin)
391                     || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
392         *scared = 1;
393         monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
394     } else
395         *scared = 0;
396 }
397
398 #undef flees_light
399
400 /* perform a special one-time action for a monster; returns -1 if nothing
401    special happened, 0 if monster uses up its turn, 1 if monster is killed */
402 STATIC_OVL int
403 m_arrival(mon)
404 struct monst *mon;
405 {
406     mon->mstrategy &= ~STRAT_ARRIVE; /* always reset */
407
408     return -1;
409 }
410
411 /* returns 1 if monster died moving, 0 otherwise */
412 /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti
413  * code. --KAA
414  */
415 int
416 dochug(mtmp)
417 register struct monst *mtmp;
418 {
419     register struct permonst *mdat;
420     register int tmp = 0;
421     int inrange, nearby, scared;
422
423     /*  Pre-movement adjustments
424      */
425
426     mdat = mtmp->data;
427
428     if (mtmp->mstrategy & STRAT_ARRIVE) {
429         int res = m_arrival(mtmp);
430         if (res >= 0)
431             return res;
432     }
433
434     /* check for waitmask status change */
435     if ((mtmp->mstrategy & STRAT_WAITFORU)
436         && (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax))
437         mtmp->mstrategy &= ~STRAT_WAITFORU;
438
439     /* update quest status flags */
440     quest_stat_check(mtmp);
441
442     if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) {
443         if (Hallucination)
444             newsym(mtmp->mx, mtmp->my);
445         if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE)
446             && !mtmp->msleeping && monnear(mtmp, u.ux, u.uy))
447             quest_talk(mtmp); /* give the leaders a chance to speak */
448         return 0;             /* other frozen monsters can't do anything */
449     }
450
451     /* there is a chance we will wake it */
452     if (mtmp->msleeping && !disturb(mtmp)) {
453         if (Hallucination)
454             newsym(mtmp->mx, mtmp->my);
455         return 0;
456     }
457
458     /* not frozen or sleeping: wipe out texts written in the dust */
459     wipe_engr_at(mtmp->mx, mtmp->my, 1, FALSE);
460
461     /* confused monsters get unconfused with small probability */
462     if (mtmp->mconf && !rn2(50))
463         mtmp->mconf = 0;
464
465     /* stunned monsters get un-stunned with larger probability */
466     if (mtmp->mstun && !rn2(10))
467         mtmp->mstun = 0;
468
469     /* some monsters teleport */
470     if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz
471         && !level.flags.noteleport) {
472         (void) rloc(mtmp, TRUE);
473         return 0;
474     }
475     if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1))
476         m_respond(mtmp);
477     if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my))
478         m_respond(mtmp);
479     if (DEADMONSTER(mtmp))
480         return 1; /* m_respond gaze can kill medusa */
481
482     /* fleeing monsters might regain courage */
483     if (mtmp->mflee && !mtmp->mfleetim && mtmp->mhp == mtmp->mhpmax
484         && !rn2(25))
485         mtmp->mflee = 0;
486
487     /* cease conflict-induced swallow/grab if conflict has ended */
488     if (mtmp == u.ustuck && mtmp->mpeaceful && !mtmp->mconf && !Conflict) {
489         release_hero(mtmp);
490         return 0; /* uses up monster's turn */
491     }
492
493     set_apparxy(mtmp);
494     /* Must be done after you move and before the monster does.  The
495      * set_apparxy() call in m_move() doesn't suffice since the variables
496      * inrange, etc. all depend on stuff set by set_apparxy().
497      */
498
499     /* Monsters that want to acquire things */
500     /* may teleport, so do it before inrange is set */
501     if (is_covetous(mdat))
502         (void) tactics(mtmp);
503
504     /* check distance and scariness of attacks */
505     distfleeck(mtmp, &inrange, &nearby, &scared);
506
507     if (find_defensive(mtmp)) {
508         if (use_defensive(mtmp) != 0)
509             return 1;
510     } else if (find_misc(mtmp)) {
511         if (use_misc(mtmp) != 0)
512             return 1;
513     }
514
515     /* Demonic Blackmail! */
516     if (nearby && mdat->msound == MS_BRIBE && mtmp->mpeaceful && !mtmp->mtame
517         && !u.uswallow) {
518         if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
519 #if 0 /*JP:T*/
520             pline("%s whispers at thin air.",
521                   cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
522 #else
523             pline("%s\82ª\82³\82³\82â\82¢\82½\81D",
524                   cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "\89½\82©");
525 #endif
526
527             if (is_demon(youmonst.data)) {
528                 /* "Good hunting, brother" */
529                 if (!tele_restrict(mtmp))
530                     (void) rloc(mtmp, TRUE);
531             } else {
532                 mtmp->minvis = mtmp->perminvis = 0;
533                 /* Why?  For the same reason in real demon talk */
534 /*JP
535                 pline("%s gets angry!", Amonnam(mtmp));
536 */
537                 pline("%s\82Í\93{\82Á\82½\81I", Amonnam(mtmp));
538                 mtmp->mpeaceful = 0;
539                 set_malign(mtmp);
540                 /* since no way is an image going to pay it off */
541             }
542         } else if (demon_talk(mtmp))
543             return 1; /* you paid it off */
544     }
545
546     /* the watch will look around and see if you are up to no good :-) */
547     if (is_watch(mdat)) {
548         watch_on_duty(mtmp);
549
550     } else if (is_mind_flayer(mdat) && !rn2(20)) {
551         struct monst *m2, *nmon = (struct monst *) 0;
552
553         if (canseemon(mtmp))
554 /*JP
555             pline("%s concentrates.", Monnam(mtmp));
556 */
557             pline("%s\82Í\90¸\90_\82ð\8fW\92\86\82µ\82Ä\82¢\82é\81D", Monnam(mtmp));
558         if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) {
559 /*JP
560             You("sense a faint wave of psychic energy.");
561 */
562             You("\83T\83C\83R\83G\83l\83\8b\83M\81[\82Ì\94g\93®\82ð\8a´\82\82½\81D");
563             goto toofar;
564         }
565 /*JP
566         pline("A wave of psychic energy pours over you!");
567 */
568         pline("\82 \82È\82½\82Í\83T\83C\83R\83G\83l\83\8b\83M\81[\82Ì\94g\93®\82ð\97\81\82Ñ\82½\81I");
569         if (mtmp->mpeaceful
570             && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) {
571 /*JP
572             pline("It feels quite soothing.");
573 */
574             pline("\90S\82ª\82È\82²\82ñ\82¾\81D");
575         } else if (!u.uinvulnerable) {
576             register boolean m_sen = sensemon(mtmp);
577
578             if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) {
579                 int dmg;
580 #if 0 /*JP:T*/
581                 pline("It locks on to your %s!",
582                       m_sen ? "telepathy" : Blind_telepat ? "latent telepathy"
583                                                           : "mind");
584 #else
585                 pline("\82»\82ê\82Í\82 \82È\82½\82Ì%s\82ð\92¼\8c\82\82µ\82½\81I",
586                       m_sen ? "\83e\83\8c\83p\83V\81[\94\\97Í" : Blind_telepat ? "\90ö\8dÝ\94\\97Í"
587                                                                : "\90¸\90_");
588 #endif
589                 dmg = rnd(15);
590                 if (Half_spell_damage)
591                     dmg = (dmg + 1) / 2;
592 /*JP
593                 losehp(dmg, "psychic blast", KILLED_BY_AN);
594 */
595                 losehp(dmg, "\83T\83C\83R\8dU\8c\82\82Å", KILLED_BY_AN);
596             }
597         }
598         for (m2 = fmon; m2; m2 = nmon) {
599             nmon = m2->nmon;
600             if (DEADMONSTER(m2))
601                 continue;
602             if (m2->mpeaceful == mtmp->mpeaceful)
603                 continue;
604             if (mindless(m2->data))
605                 continue;
606             if (m2 == mtmp)
607                 continue;
608             if ((telepathic(m2->data) && (rn2(2) || m2->mblinded))
609                 || !rn2(10)) {
610                 if (cansee(m2->mx, m2->my))
611 /*JP
612                     pline("It locks on to %s.", mon_nam(m2));
613 */
614                     pline("%s\82ð\92¼\8c\82\82µ\82½\81D", mon_nam(m2));
615                 m2->mhp -= rnd(15);
616                 if (DEADMONSTER(m2))
617                     monkilled(m2, "", AD_DRIN);
618                 else
619                     m2->msleeping = 0;
620             }
621         }
622     }
623  toofar:
624
625     /* If monster is nearby you, and has to wield a weapon, do so.   This
626      * costs the monster a move, of course.
627      */
628     if ((!mtmp->mpeaceful || Conflict) && inrange
629         && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8
630         && attacktype(mdat, AT_WEAP)) {
631         struct obj *mw_tmp;
632
633         /* The scared check is necessary.  Otherwise a monster that is
634          * one square near the player but fleeing into a wall would keep
635          * switching between pick-axe and weapon.  If monster is stuck
636          * in a trap, prefer ranged weapon (wielding is done in thrwmu).
637          * This may cost the monster an attack, but keeps the monster
638          * from switching back and forth if carrying both.
639          */
640         mw_tmp = MON_WEP(mtmp);
641         if (!(scared && mw_tmp && is_pick(mw_tmp))
642             && mtmp->weapon_check == NEED_WEAPON
643             && !(mtmp->mtrapped && !nearby && select_rwep(mtmp))) {
644             mtmp->weapon_check = NEED_HTH_WEAPON;
645             if (mon_wield_item(mtmp) != 0)
646                 return 0;
647         }
648     }
649
650     /*  Now the actual movement phase
651      */
652
653     if (!nearby || mtmp->mflee || scared || mtmp->mconf || mtmp->mstun
654         || (mtmp->minvis && !rn2(3))
655         || (mdat->mlet == S_LEPRECHAUN && !findgold(invent)
656             && (findgold(mtmp->minvent) || rn2(2)))
657         || (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz)
658         || (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
659         /* Possibly cast an undirected spell if not attacking you */
660         /* note that most of the time castmu() will pick a directed
661            spell and do nothing, so the monster moves normally */
662         /* arbitrary distance restriction to keep monster far away
663            from you from having cast dozens of sticks-to-snakes
664            or similar spells by the time you reach it */
665         if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49
666             && !mtmp->mspec_used) {
667             struct attack *a;
668
669             for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) {
670                 if (a->aatyp == AT_MAGC
671                     && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) {
672                     if (castmu(mtmp, a, FALSE, FALSE)) {
673                         tmp = 3;
674                         break;
675                     }
676                 }
677             }
678         }
679
680         tmp = m_move(mtmp, 0);
681         if (tmp != 2)
682             distfleeck(mtmp, &inrange, &nearby, &scared); /* recalc */
683
684         switch (tmp) { /* for pets, cases 0 and 3 are equivalent */
685         case 0: /* no movement, but it can still attack you */
686         case 3: /* absolutely no movement */
687             /* vault guard might have vanished */
688             if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0))
689                 return 1; /* behave as if it died */
690             /* During hallucination, monster appearance should
691              * still change - even if it doesn't move.
692              */
693             if (Hallucination)
694                 newsym(mtmp->mx, mtmp->my);
695             break;
696         case 1: /* monster moved */
697             /* Maybe it stepped on a trap and fell asleep... */
698             if (mtmp->msleeping || !mtmp->mcanmove)
699                 return 0;
700             /* Monsters can move and then shoot on same turn;
701                our hero can't.  Is that fair? */
702             if (!nearby && (ranged_attk(mdat) || find_offensive(mtmp)))
703                 break;
704             /* engulfer/grabber checks */
705             if (mtmp == u.ustuck) {
706                 /* a monster that's digesting you can move at the
707                  * same time -dlc
708                  */
709                 if (u.uswallow)
710                     return mattacku(mtmp);
711                 /* if confused grabber has wandered off, let go */
712                 if (distu(mtmp->mx, mtmp->my) > 2)
713                     unstuck(mtmp);
714             }
715             return 0;
716         case 2: /* monster died */
717             return 1;
718         }
719     }
720
721     /*  Now, attack the player if possible - one attack set per monst
722      */
723
724     if (!mtmp->mpeaceful || (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {
725         if (inrange && !noattacks(mdat)
726             && (Upolyd ? u.mh : u.uhp) > 0 && !scared && tmp != 3)
727             if (mattacku(mtmp))
728                 return 1; /* monster died (e.g. exploded) */
729
730         if (mtmp->wormno)
731             wormhitu(mtmp);
732     }
733     /* special speeches for quest monsters */
734     if (!mtmp->msleeping && mtmp->mcanmove && nearby)
735         quest_talk(mtmp);
736     /* extra emotional attack for vile monsters */
737     if (inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful
738         && couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5))
739         cuss(mtmp);
740
741     return (tmp == 2);
742 }
743
744 static NEARDATA const char practical[] = { WEAPON_CLASS, ARMOR_CLASS,
745                                            GEM_CLASS, FOOD_CLASS, 0 };
746 static NEARDATA const char magical[] = { AMULET_CLASS, POTION_CLASS,
747                                          SCROLL_CLASS, WAND_CLASS,
748                                          RING_CLASS,   SPBOOK_CLASS, 0 };
749 static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
750 static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };
751 static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };
752
753 boolean
754 itsstuck(mtmp)
755 register struct monst *mtmp;
756 {
757     if (sticks(youmonst.data) && mtmp == u.ustuck && !u.uswallow) {
758 /*JP
759         pline("%s cannot escape from you!", Monnam(mtmp));
760 */
761         pline("%s\82Í\82 \82È\82½\82©\82ç\93¦\82°\82ç\82ê\82È\82¢\81I", Monnam(mtmp));
762         return TRUE;
763     }
764     return FALSE;
765 }
766
767 /*
768  * should_displace()
769  *
770  * Displacement of another monster is a last resort and only
771  * used on approach. If there are better ways to get to target,
772  * those should be used instead. This function does that evaluation.
773  */
774 boolean
775 should_displace(mtmp, poss, info, cnt, gx, gy)
776 struct monst *mtmp;
777 coord *poss; /* coord poss[9] */
778 long *info;  /* long info[9] */
779 int cnt;
780 xchar gx, gy;
781 {
782     int shortest_with_displacing = -1;
783     int shortest_without_displacing = -1;
784     int count_without_displacing = 0;
785     register int i, nx, ny;
786     int ndist;
787
788     for (i = 0; i < cnt; i++) {
789         nx = poss[i].x;
790         ny = poss[i].y;
791         ndist = dist2(nx, ny, gx, gy);
792         if (MON_AT(nx, ny) && (info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M)
793             && !undesirable_disp(mtmp, nx, ny)) {
794             if (shortest_with_displacing == -1
795                 || (ndist < shortest_with_displacing))
796                 shortest_with_displacing = ndist;
797         } else {
798             if ((shortest_without_displacing == -1)
799                 || (ndist < shortest_without_displacing))
800                 shortest_without_displacing = ndist;
801             count_without_displacing++;
802         }
803     }
804     if (shortest_with_displacing > -1
805         && (shortest_with_displacing < shortest_without_displacing
806             || !count_without_displacing))
807         return TRUE;
808     return FALSE;
809 }
810
811 boolean
812 m_digweapon_check(mtmp, nix, niy)
813 struct monst *mtmp;
814 xchar nix,niy;
815 {
816     boolean can_tunnel = 0;
817     struct obj *mw_tmp = MON_WEP(mtmp);
818
819     if (!Is_rogue_level(&u.uz))
820         can_tunnel = tunnels(mtmp->data);
821
822     if (can_tunnel && needspick(mtmp->data) && !mwelded(mw_tmp)
823         && (may_dig(nix, niy) || closed_door(nix, niy))) {
824         /* may_dig() is either IS_STWALL or IS_TREE */
825         if (closed_door(nix, niy)) {
826             if (!mw_tmp
827                 || !is_pick(mw_tmp)
828                 || !is_axe(mw_tmp))
829                 mtmp->weapon_check = NEED_PICK_OR_AXE;
830         } else if (IS_TREE(levl[nix][niy].typ)) {
831             if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
832                 mtmp->weapon_check = NEED_AXE;
833         } else if (IS_STWALL(levl[nix][niy].typ)) {
834             if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))
835                 mtmp->weapon_check = NEED_PICK_AXE;
836         }
837         if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp))
838             return TRUE;
839     }
840     return FALSE;
841 }
842
843 /* Return values:
844  * 0: did not move, but can still attack and do other stuff.
845  * 1: moved, possibly can attack.
846  * 2: monster died.
847  * 3: did not move, and can't do anything else either.
848  */
849 int
850 m_move(mtmp, after)
851 register struct monst *mtmp;
852 register int after;
853 {
854     register int appr;
855     xchar gx, gy, nix, niy, chcnt;
856     int chi; /* could be schar except for stupid Sun-2 compiler */
857     boolean likegold = 0, likegems = 0, likeobjs = 0, likemagic = 0,
858             conceals = 0;
859     boolean likerock = 0, can_tunnel = 0;
860     boolean can_open = 0, can_unlock = 0, doorbuster = 0;
861     boolean uses_items = 0, setlikes = 0;
862     boolean avoid = FALSE;
863     boolean better_with_displacing = FALSE;
864     boolean sawmon = canspotmon(mtmp); /* before it moved */
865     struct permonst *ptr;
866     struct monst *mtoo;
867     schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
868     long info[9];
869     long flag;
870     int omx = mtmp->mx, omy = mtmp->my;
871
872     if (mtmp->mtrapped) {
873         int i = mintrap(mtmp);
874
875         if (i >= 2) {
876             newsym(mtmp->mx, mtmp->my);
877             return 2;
878         } /* it died */
879         if (i == 1)
880             return 0; /* still in trap, so didn't move */
881     }
882     ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */
883
884     if (mtmp->meating) {
885         mtmp->meating--;
886         if (mtmp->meating <= 0)
887             finish_meating(mtmp);
888         return 3; /* still eating */
889     }
890     if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
891         return 0; /* do not leave hiding place */
892
893     set_apparxy(mtmp);
894     /* where does mtmp think you are? */
895     /* Not necessary if m_move called from this file, but necessary in
896      * other calls of m_move (ex. leprechauns dodging)
897      */
898     if (!Is_rogue_level(&u.uz))
899         can_tunnel = tunnels(ptr);
900     can_open = !(nohands(ptr) || verysmall(ptr));
901     can_unlock =
902         ((can_open && monhaskey(mtmp, TRUE)) || mtmp->iswiz || is_rider(ptr));
903     doorbuster = is_giant(ptr);
904     if (mtmp->wormno)
905         goto not_special;
906     /* my dog gets special treatment */
907     if (mtmp->mtame) {
908         mmoved = dog_move(mtmp, after);
909         goto postmov;
910     }
911
912     /* likewise for shopkeeper */
913     if (mtmp->isshk) {
914         mmoved = shk_move(mtmp);
915         if (mmoved == -2)
916             return 2;
917         if (mmoved >= 0)
918             goto postmov;
919         mmoved = 0; /* follow player outside shop */
920     }
921
922     /* and for the guard */
923     if (mtmp->isgd) {
924         mmoved = gd_move(mtmp);
925         if (mmoved == -2)
926             return 2;
927         if (mmoved >= 0)
928             goto postmov;
929         mmoved = 0;
930     }
931
932     /* and the acquisitive monsters get special treatment */
933     if (is_covetous(ptr)) {
934         xchar tx = STRAT_GOALX(mtmp->mstrategy),
935               ty = STRAT_GOALY(mtmp->mstrategy);
936         struct monst *intruder = m_at(tx, ty);
937         /*
938          * if there's a monster on the object or in possession of it,
939          * attack it.
940          */
941         if ((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) && intruder
942             && (intruder != mtmp)) {
943             notonhead = (intruder->mx != tx || intruder->my != ty);
944             if (mattackm(mtmp, intruder) == 2)
945                 return 2;
946             mmoved = 1;
947         } else
948             mmoved = 0;
949         goto postmov;
950     }
951
952     /* and for the priest */
953     if (mtmp->ispriest) {
954         mmoved = pri_move(mtmp);
955         if (mmoved == -2)
956             return 2;
957         if (mmoved >= 0)
958             goto postmov;
959         mmoved = 0;
960     }
961
962 #ifdef MAIL
963     if (ptr == &mons[PM_MAIL_DAEMON]) {
964         if (!Deaf && canseemon(mtmp))
965 /*JP
966             verbalize("I'm late!");
967 */
968             verbalize("\92x\82­\82È\82Á\82Ä\82·\82Ü\82È\82¢\81I");
969         mongone(mtmp);
970         return 2;
971     }
972 #endif
973
974     /* teleport if that lies in our nature */
975     if (ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan
976         && !tele_restrict(mtmp)) {
977         if (mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
978             (void) rloc(mtmp, TRUE);
979         else
980             mnexto(mtmp);
981         mmoved = 1;
982         goto postmov;
983     }
984  not_special:
985     if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp)
986         return 1;
987     omx = mtmp->mx;
988     omy = mtmp->my;
989     gx = mtmp->mux;
990     gy = mtmp->muy;
991     appr = mtmp->mflee ? -1 : 1;
992     if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck)) {
993         appr = 0;
994     } else {
995         struct obj *lepgold, *ygold;
996         boolean should_see = (couldsee(omx, omy)
997                               && (levl[gx][gy].lit || !levl[omx][omy].lit)
998                               && (dist2(omx, omy, gx, gy) <= 36));
999
1000         if (!mtmp->mcansee
1001             || (should_see && Invis && !perceives(ptr) && rn2(11))
1002             || is_obj_mappear(&youmonst,STRANGE_OBJECT) || u.uundetected
1003             || (is_obj_mappear(&youmonst,GOLD_PIECE) && !likes_gold(ptr))
1004             || (mtmp->mpeaceful && !mtmp->isshk) /* allow shks to follow */
1005             || ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT
1006                  || ptr->mlet == S_LIGHT) && !rn2(3)))
1007             appr = 0;
1008
1009         if (monsndx(ptr) == PM_LEPRECHAUN && (appr == 1)
1010             && ((lepgold = findgold(mtmp->minvent))
1011                 && (lepgold->quan
1012                     > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
1013             appr = -1;
1014
1015         if (!should_see && can_track(ptr)) {
1016             register coord *cp;
1017
1018             cp = gettrack(omx, omy);
1019             if (cp) {
1020                 gx = cp->x;
1021                 gy = cp->y;
1022             }
1023         }
1024     }
1025
1026     if ((!mtmp->mpeaceful || !rn2(10)) && (!Is_rogue_level(&u.uz))) {
1027         boolean in_line = (lined_up(mtmp)
1028                && (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
1029                    <= (throws_rocks(youmonst.data) ? 20 : ACURRSTR / 2 + 1)));
1030
1031         if (appr != 1 || !in_line) {
1032             /* Monsters in combat won't pick stuff up, avoiding the
1033              * situation where you toss arrows at it and it has nothing
1034              * better to do than pick the arrows up.
1035              */
1036             register int pctload =
1037                 (curr_mon_load(mtmp) * 100) / max_mon_load(mtmp);
1038
1039             /* look for gold or jewels nearby */
1040             likegold = (likes_gold(ptr) && pctload < 95);
1041             likegems = (likes_gems(ptr) && pctload < 85);
1042             uses_items = (!mindless(ptr) && !is_animal(ptr) && pctload < 75);
1043             likeobjs = (likes_objs(ptr) && pctload < 75);
1044             likemagic = (likes_magic(ptr) && pctload < 85);
1045             likerock = (throws_rocks(ptr) && pctload < 50 && !Sokoban);
1046             conceals = hides_under(ptr);
1047             setlikes = TRUE;
1048         }
1049     }
1050
1051 #define SQSRCHRADIUS 5
1052
1053     {
1054         register int minr = SQSRCHRADIUS; /* not too far away */
1055         register struct obj *otmp;
1056         register int xx, yy;
1057         int oomx, oomy, lmx, lmy;
1058
1059         /* cut down the search radius if it thinks character is closer. */
1060         if (distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS
1061             && !mtmp->mpeaceful)
1062             minr--;
1063         /* guards shouldn't get too distracted */
1064         if (!mtmp->mpeaceful && is_mercenary(ptr))
1065             minr = 1;
1066
1067         if ((likegold || likegems || likeobjs || likemagic || likerock
1068              || conceals) && (!*in_rooms(omx, omy, SHOPBASE)
1069                               || (!rn2(25) && !mtmp->isshk))) {
1070  look_for_obj:
1071             oomx = min(COLNO - 1, omx + minr);
1072             oomy = min(ROWNO - 1, omy + minr);
1073             lmx = max(1, omx - minr);
1074             lmy = max(0, omy - minr);
1075             for (otmp = fobj; otmp; otmp = otmp->nobj) {
1076                 /* monsters may pick rocks up, but won't go out of their way
1077                    to grab them; this might hamper sling wielders, but it cuts
1078                    down on move overhead by filtering out most common item */
1079                 if (otmp->otyp == ROCK)
1080                     continue;
1081                 xx = otmp->ox;
1082                 yy = otmp->oy;
1083                 /* Nymphs take everything.  Most other creatures should not
1084                  * pick up corpses except as a special case like in
1085                  * searches_for_item().  We need to do this check in
1086                  * mpickstuff() as well.
1087                  */
1088                 if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
1089                     /* don't get stuck circling around object that's
1090                        underneath an immobile or hidden monster;
1091                        paralysis victims excluded */
1092                     if ((mtoo = m_at(xx, yy)) != 0
1093                         && (mtoo->msleeping || mtoo->mundetected
1094                             || (mtoo->mappearance && !mtoo->iswiz)
1095                             || !mtoo->data->mmove))
1096                         continue;
1097                     /* the mfndpos() test for whether to allow a move to a
1098                        water location accepts flyers, but they can't reach
1099                        underwater objects, so being able to move to a spot
1100                        is insufficient for deciding whether to do so */
1101                     if ((is_pool(xx, yy) && !is_swimmer(ptr))
1102                         || (is_lava(xx, yy) && !likes_lava(ptr)))
1103                         continue;
1104
1105                     if (((likegold && otmp->oclass == COIN_CLASS)
1106                          || (likeobjs && index(practical, otmp->oclass)
1107                              && (otmp->otyp != CORPSE
1108                                  || (ptr->mlet == S_NYMPH
1109                                      && !is_rider(&mons[otmp->corpsenm]))))
1110                          || (likemagic && index(magical, otmp->oclass))
1111                          || (uses_items && searches_for_item(mtmp, otmp))
1112                          || (likerock && otmp->otyp == BOULDER)
1113                          || (likegems && otmp->oclass == GEM_CLASS
1114                              && objects[otmp->otyp].oc_material != MINERAL)
1115                          || (conceals && !cansee(otmp->ox, otmp->oy))
1116                          || (ptr == &mons[PM_GELATINOUS_CUBE]
1117                              && !index(indigestion, otmp->oclass)
1118                              && !(otmp->otyp == CORPSE
1119                                   && touch_petrifies(&mons[otmp->corpsenm]))))
1120                         && touch_artifact(otmp, mtmp)) {
1121                         if (can_carry(mtmp, otmp) > 0
1122                             && (throws_rocks(ptr) || !sobj_at(BOULDER, xx, yy))
1123                             && (!is_unicorn(ptr)
1124                                 || objects[otmp->otyp].oc_material == GEMSTONE)
1125                             /* Don't get stuck circling an Elbereth */
1126                             && !onscary(xx, yy, mtmp)) {
1127                             minr = distmin(omx, omy, xx, yy);
1128                             oomx = min(COLNO - 1, omx + minr);
1129                             oomy = min(ROWNO - 1, omy + minr);
1130                             lmx = max(1, omx - minr);
1131                             lmy = max(0, omy - minr);
1132                             gx = otmp->ox;
1133                             gy = otmp->oy;
1134                             if (gx == omx && gy == omy) {
1135                                 mmoved = 3; /* actually unnecessary */
1136                                 goto postmov;
1137                             }
1138                         }
1139                     }
1140                 }
1141             }
1142         } else if (likegold) {
1143             /* don't try to pick up anything else, but use the same loop */
1144             uses_items = 0;
1145             likegems = likeobjs = likemagic = likerock = conceals = 0;
1146             goto look_for_obj;
1147         }
1148
1149         if (minr < SQSRCHRADIUS && appr == -1) {
1150             if (distmin(omx, omy, mtmp->mux, mtmp->muy) <= 3) {
1151                 gx = mtmp->mux;
1152                 gy = mtmp->muy;
1153             } else
1154                 appr = 1;
1155         }
1156     }
1157
1158     /* don't tunnel if hostile and close enough to prefer a weapon */
1159     if (can_tunnel && needspick(ptr)
1160         && ((!mtmp->mpeaceful || Conflict)
1161             && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8))
1162         can_tunnel = FALSE;
1163
1164     nix = omx;
1165     niy = omy;
1166     flag = 0L;
1167     if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))
1168         flag |= (ALLOW_SANCT | ALLOW_SSM);
1169     else
1170         flag |= ALLOW_U;
1171     if (is_minion(ptr) || is_rider(ptr))
1172         flag |= ALLOW_SANCT;
1173     /* unicorn may not be able to avoid hero on a noteleport level */
1174     if (is_unicorn(ptr) && !level.flags.noteleport)
1175         flag |= NOTONL;
1176     if (passes_walls(ptr))
1177         flag |= (ALLOW_WALL | ALLOW_ROCK);
1178     if (passes_bars(ptr))
1179         flag |= ALLOW_BARS;
1180     if (can_tunnel)
1181         flag |= ALLOW_DIG;
1182     if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
1183         flag |= ALLOW_SSM;
1184     if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp))
1185         flag |= NOGARLIC;
1186     if (throws_rocks(ptr))
1187         flag |= ALLOW_ROCK;
1188     if (can_open)
1189         flag |= OPENDOOR;
1190     if (can_unlock)
1191         flag |= UNLOCKDOOR;
1192     if (doorbuster)
1193         flag |= BUSTDOOR;
1194     {
1195         register int i, j, nx, ny, nearer;
1196         int jcnt, cnt;
1197         int ndist, nidist;
1198         register coord *mtrk;
1199         coord poss[9];
1200
1201         cnt = mfndpos(mtmp, poss, info, flag);
1202         chcnt = 0;
1203         jcnt = min(MTSZ, cnt - 1);
1204         chi = -1;
1205         nidist = dist2(nix, niy, gx, gy);
1206         /* allow monsters be shortsighted on some levels for balance */
1207         if (!mtmp->mpeaceful && level.flags.shortsighted
1208             && nidist > (couldsee(nix, niy) ? 144 : 36) && appr == 1)
1209             appr = 0;
1210         if (is_unicorn(ptr) && level.flags.noteleport) {
1211             /* on noteleport levels, perhaps we cannot avoid hero */
1212             for (i = 0; i < cnt; i++)
1213                 if (!(info[i] & NOTONL))
1214                     avoid = TRUE;
1215         }
1216         better_with_displacing =
1217             should_displace(mtmp, poss, info, cnt, gx, gy);
1218         for (i = 0; i < cnt; i++) {
1219             if (avoid && (info[i] & NOTONL))
1220                 continue;
1221             nx = poss[i].x;
1222             ny = poss[i].y;
1223
1224             if (MON_AT(nx, ny) && (info[i] & ALLOW_MDISP)
1225                 && !(info[i] & ALLOW_M) && !better_with_displacing)
1226                 continue;
1227             if (appr != 0) {
1228                 mtrk = &mtmp->mtrack[0];
1229                 for (j = 0; j < jcnt; mtrk++, j++)
1230                     if (nx == mtrk->x && ny == mtrk->y)
1231                         if (rn2(4 * (cnt - j)))
1232                             goto nxti;
1233             }
1234
1235             nearer = ((ndist = dist2(nx, ny, gx, gy)) < nidist);
1236
1237             if ((appr == 1 && nearer) || (appr == -1 && !nearer)
1238                 || (!appr && !rn2(++chcnt)) || !mmoved) {
1239                 nix = nx;
1240                 niy = ny;
1241                 nidist = ndist;
1242                 chi = i;
1243                 mmoved = 1;
1244             }
1245  nxti:
1246             ;
1247         }
1248     }
1249
1250     if (mmoved) {
1251         register int j;
1252
1253         if (mmoved == 1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
1254             return 3;
1255
1256         if (mmoved == 1 && m_digweapon_check(mtmp, nix,niy))
1257             return 3;
1258
1259         /* If ALLOW_U is set, either it's trying to attack you, or it
1260          * thinks it is.  In either case, attack this spot in preference to
1261          * all others.
1262          */
1263         /* Actually, this whole section of code doesn't work as you'd expect.
1264          * Most attacks are handled in dochug().  It calls distfleeck(), which
1265          * among other things sets nearby if the monster is near you--and if
1266          * nearby is set, we never call m_move unless it is a special case
1267          * (confused, stun, etc.)  The effect is that this ALLOW_U (and
1268          * mfndpos) has no effect for normal attacks, though it lets a
1269          * confused monster attack you by accident.
1270          */
1271         if (info[chi] & ALLOW_U) {
1272             nix = mtmp->mux;
1273             niy = mtmp->muy;
1274         }
1275         if (nix == u.ux && niy == u.uy) {
1276             mtmp->mux = u.ux;
1277             mtmp->muy = u.uy;
1278             return 0;
1279         }
1280         /* The monster may attack another based on 1 of 2 conditions:
1281          * 1 - It may be confused.
1282          * 2 - It may mistake the monster for your (displaced) image.
1283          * Pets get taken care of above and shouldn't reach this code.
1284          * Conflict gets handled even farther away (movemon()).
1285          */
1286         if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) {
1287             struct monst *mtmp2;
1288             int mstatus;
1289
1290             mtmp2 = m_at(nix, niy);
1291
1292             notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my);
1293             /* note: mstatus returns 0 if mtmp2 is nonexistent */
1294             mstatus = mattackm(mtmp, mtmp2);
1295
1296             if (mstatus & MM_AGR_DIED) /* aggressor died */
1297                 return 2;
1298
1299             if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) && rn2(4)
1300                 && mtmp2->movement >= NORMAL_SPEED) {
1301                 mtmp2->movement -= NORMAL_SPEED;
1302                 notonhead = 0;
1303                 mstatus = mattackm(mtmp2, mtmp); /* return attack */
1304                 if (mstatus & MM_DEF_DIED)
1305                     return 2;
1306             }
1307             return 3;
1308         }
1309
1310         if ((info[chi] & ALLOW_MDISP)) {
1311             struct monst *mtmp2;
1312             int mstatus;
1313
1314             mtmp2 = m_at(nix, niy);
1315             mstatus = mdisplacem(mtmp, mtmp2, FALSE);
1316             if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED))
1317                 return 2;
1318             if (mstatus & MM_HIT)
1319                 return 1;
1320             return 3;
1321         }
1322
1323         if (!m_in_out_region(mtmp, nix, niy))
1324             return 3;
1325
1326         remove_monster(omx, omy);
1327         place_monster(mtmp, nix, niy);
1328         for (j = MTSZ - 1; j > 0; j--)
1329             mtmp->mtrack[j] = mtmp->mtrack[j - 1];
1330         mtmp->mtrack[0].x = omx;
1331         mtmp->mtrack[0].y = omy;
1332         /* Place a segment at the old position. */
1333         if (mtmp->wormno)
1334             worm_move(mtmp);
1335     } else {
1336         if (is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) {
1337             (void) rloc(mtmp, TRUE);
1338             return 1;
1339         }
1340         if (mtmp->wormno)
1341             worm_nomove(mtmp);
1342     }
1343  postmov:
1344     if (mmoved == 1 || mmoved == 3) {
1345         boolean canseeit = cansee(mtmp->mx, mtmp->my);
1346
1347         if (mmoved == 1) {
1348             /* normal monster move will already have <nix,niy>,
1349                but pet dog_move() with 'goto postmov' won't */
1350             nix = mtmp->mx, niy = mtmp->my;
1351             /* sequencing issue:  when monster movement decides that a
1352                monster can move to a door location, it moves the monster
1353                there before dealing with the door rather than after;
1354                so a vampire/bat that is going to shift to fog cloud and
1355                pass under the door is already there but transformation
1356                into fog form--and its message, when in sight--has not
1357                happened yet; we have to move monster back to previous
1358                location before performing the vamp_shift() to make the
1359                message happen at right time, then back to the door again
1360                [if we did the shift above, before moving the monster,
1361                we would need to duplicate it in dog_move()...] */
1362             if (is_vampshifter(mtmp) && !amorphous(mtmp->data)
1363                 && IS_DOOR(levl[nix][niy].typ)
1364                 && ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0)
1365                 && can_fog(mtmp)) {
1366                 if (sawmon) {
1367                     remove_monster(nix, niy);
1368                     place_monster(mtmp, omx, omy);
1369                     newsym(nix, niy), newsym(omx, omy);
1370                 }
1371                 if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) {
1372                     ptr = mtmp->data; /* update cached value */
1373                 }
1374                 if (sawmon) {
1375                     remove_monster(omx, omy);
1376                     place_monster(mtmp, nix, niy);
1377                     newsym(omx, omy), newsym(nix, niy);
1378                 }
1379             }
1380
1381             newsym(omx, omy); /* update the old position */
1382             if (mintrap(mtmp) >= 2) {
1383                 if (mtmp->mx)
1384                     newsym(mtmp->mx, mtmp->my);
1385                 return 2; /* it died */
1386             }
1387             ptr = mtmp->data; /* in case mintrap() caused polymorph */
1388
1389             /* open a door, or crash through it, if 'mtmp' can */
1390             if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
1391                 && !passes_walls(ptr) /* doesn't need to open doors */
1392                 && !can_tunnel) {     /* taken care of below */
1393                 struct rm *here = &levl[mtmp->mx][mtmp->my];
1394                 boolean btrapped = (here->doormask & D_TRAPPED) != 0,
1395                         observeit = canseeit && canspotmon(mtmp);
1396
1397                 /* if mon has MKoT, disarm door trap; no message given */
1398                 if (btrapped && has_magic_key(mtmp)) {
1399                     /* BUG: this lets a vampire or blob or a doorbuster
1400                        holding the Key disarm the trap even though it isn't
1401                        using that Key when squeezing under or smashing the
1402                        door.  Not significant enough to worry about; perhaps
1403                        the Key's magic is more powerful for monsters? */
1404                     here->doormask &= ~D_TRAPPED;
1405                     btrapped = FALSE;
1406                 }
1407                 if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
1408                     && amorphous(ptr)) {
1409                     if (flags.verbose && canseemon(mtmp))
1410 #if 0 /*JP:T*/
1411                         pline("%s %s under the door.", Monnam(mtmp),
1412                               (ptr == &mons[PM_FOG_CLOUD]
1413                                || ptr->mlet == S_LIGHT) ? "flows" : "oozes");
1414 #else
1415                         pline("%s\82Í\94à\82Ì\89º\82©\82ç%s\82Å\82½\81D", Monnam(mtmp),
1416                               (ptr == &mons[PM_FOG_CLOUD]
1417                                || ptr->mlet == S_LIGHT) ? "\97¬\82ê" : "\82É\82\82Ý");
1418 #endif
1419                 } else if (here->doormask & D_LOCKED && can_unlock) {
1420                     if (btrapped) {
1421                         here->doormask = D_NODOOR;
1422                         newsym(mtmp->mx, mtmp->my);
1423                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1424                         if (mb_trapped(mtmp))
1425                             return 2;
1426                     } else {
1427                         if (flags.verbose) {
1428                             if (observeit)
1429 /*JP
1430                                 pline("%s unlocks and opens a door.",
1431 */
1432                                 pline("%s\82Í\8c®\82ð\82Í\82¸\82µ\82Ä\94à\82ð\8aJ\82¯\82½\81D",
1433                                       Monnam(mtmp));
1434                             else if (canseeit)
1435 /*JP
1436                                 You_see("a door unlock and open.");
1437 */
1438                                 You("\94à\82Ì\8c®\82ª\82Í\82¸\82ê\81C\8aJ\82­\82Ì\82ð\8c©\82½\81D");
1439                             else if (!Deaf)
1440 /*JP
1441                                 You_hear("a door unlock and open.");
1442 */
1443                                 You_hear("\94à\82Ì\8c®\82ª\82Í\82¸\82ê\81C\8aJ\82­\89¹\82ð\95·\82¢\82½\81D");
1444                         }
1445                         here->doormask = D_ISOPEN;
1446                         /* newsym(mtmp->mx, mtmp->my); */
1447                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1448                     }
1449                 } else if (here->doormask == D_CLOSED && can_open) {
1450                     if (btrapped) {
1451                         here->doormask = D_NODOOR;
1452                         newsym(mtmp->mx, mtmp->my);
1453                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1454                         if (mb_trapped(mtmp))
1455                             return 2;
1456                     } else {
1457                         if (flags.verbose) {
1458                             if (observeit)
1459 /*JP
1460                                 pline("%s opens a door.", Monnam(mtmp));
1461 */
1462                                 pline("%s\82Í\94à\82ð\8aJ\82¯\82½\81D", Monnam(mtmp));
1463                             else if (canseeit)
1464 /*JP
1465                                 You_see("a door open.");
1466 */
1467                                 You("\94à\82ª\8aJ\82­\82Ì\82ð\8c©\82½\81D");
1468                             else if (!Deaf)
1469 /*JP
1470                                 You_hear("a door open.");
1471 */
1472                                 You_hear("\94à\82ª\8aJ\82­\89¹\82ð\95·\82¢\82½\81D");
1473                         }
1474                         here->doormask = D_ISOPEN;
1475                         /* newsym(mtmp->mx, mtmp->my); */  /* done below */
1476                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1477                     }
1478                 } else if (here->doormask & (D_LOCKED | D_CLOSED)) {
1479                     /* mfndpos guarantees this must be a doorbuster */
1480                     if (btrapped) {
1481                         here->doormask = D_NODOOR;
1482                         newsym(mtmp->mx, mtmp->my);
1483                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1484                         if (mb_trapped(mtmp))
1485                             return 2;
1486                     } else {
1487                         if (flags.verbose) {
1488                             if (observeit)
1489 /*JP
1490                                 pline("%s smashes down a door.",
1491 */
1492                                 pline("%s\82Í\94à\82ð\94j\89ó\82µ\82½\81D",
1493                                       Monnam(mtmp));
1494                             else if (canseeit)
1495 /*JP
1496                                 You_see("a door crash open.");
1497 */
1498                                 You("\94à\82ª\94j\89ó\82³\82ê\82é\82Ì\82ð\8c©\82½\81D");
1499                             else if (!Deaf)
1500 /*JP
1501                                 You_hear("a door crash open.");
1502 */
1503                                 You_hear("\94à\82ª\94j\89ó\82³\82ê\82é\89¹\82ð\95·\82¢\82½\81D");
1504                         }
1505                         if ((here->doormask & D_LOCKED) != 0 && !rn2(2))
1506                             here->doormask = D_NODOOR;
1507                         else
1508                             here->doormask = D_BROKEN;
1509                         /* newsym(mtmp->mx, mtmp->my); */  /* done below */
1510                         unblock_point(mtmp->mx, mtmp->my); /* vision */
1511                     }
1512                     /* if it's a shop door, schedule repair */
1513                     if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1514                         add_damage(mtmp->mx, mtmp->my, 0L);
1515                 }
1516             } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
1517                 /* As of 3.6.2: was using may_dig() but it doesn't handle bars */
1518                 if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE)
1519                     && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) {
1520                     if (canseemon(mtmp))
1521 /*JP
1522                         pline("%s eats through the iron bars.", Monnam(mtmp));
1523 */
1524                         pline("%s\82Í\93S\82Ì\96_\82ð\90H\82×\82Ä\92Ê\82è\94²\82¯\82½\81D", Monnam(mtmp));
1525                     dissolve_bars(mtmp->mx, mtmp->my);
1526                     return 3;
1527                 } else if (flags.verbose && canseemon(mtmp))
1528 #if 0 /*JP*/
1529                     Norep("%s %s %s the iron bars.", Monnam(mtmp),
1530                           /* pluralization fakes verb conjugation */
1531                           makeplural(locomotion(ptr, "pass")),
1532                           passes_walls(ptr) ? "through" : "between");
1533 #else
1534                     Norep("%s\82Í\93S\82Ì\96_%s\82ð\82·\82è\94²\82¯\82½\81D", Monnam(mtmp),
1535                           passes_walls(ptr) ? "" : "\82Ì\8aÔ");
1536 #endif
1537             }
1538
1539             /* possibly dig */
1540             if (can_tunnel && mdig_tunnel(mtmp))
1541                 return 2; /* mon died (position already updated) */
1542
1543             /* set also in domove(), hack.c */
1544             if (u.uswallow && mtmp == u.ustuck
1545                 && (mtmp->mx != omx || mtmp->my != omy)) {
1546                 /* If the monster moved, then update */
1547                 u.ux0 = u.ux;
1548                 u.uy0 = u.uy;
1549                 u.ux = mtmp->mx;
1550                 u.uy = mtmp->my;
1551                 swallowed(0);
1552             } else
1553                 newsym(mtmp->mx, mtmp->my);
1554         }
1555         if (OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
1556             /* recompute the likes tests, in case we polymorphed
1557              * or if the "likegold" case got taken above */
1558             if (setlikes) {
1559                 int pctload = (curr_mon_load(mtmp) * 100) / max_mon_load(mtmp);
1560
1561                 /* look for gold or jewels nearby */
1562                 likegold = (likes_gold(ptr) && pctload < 95);
1563                 likegems = (likes_gems(ptr) && pctload < 85);
1564                 uses_items =
1565                     (!mindless(ptr) && !is_animal(ptr) && pctload < 75);
1566                 likeobjs = (likes_objs(ptr) && pctload < 75);
1567                 likemagic = (likes_magic(ptr) && pctload < 85);
1568                 likerock = (throws_rocks(ptr) && pctload < 50 && !Sokoban);
1569                 conceals = hides_under(ptr);
1570             }
1571
1572             /* Maybe a rock mole just ate some metal object */
1573             if (metallivorous(ptr)) {
1574                 if (meatmetal(mtmp) == 2)
1575                     return 2; /* it died */
1576             }
1577
1578             if (g_at(mtmp->mx, mtmp->my) && likegold)
1579                 mpickgold(mtmp);
1580
1581             /* Maybe a cube ate just about anything */
1582             if (ptr == &mons[PM_GELATINOUS_CUBE]) {
1583                 if (meatobj(mtmp) == 2)
1584                     return 2; /* it died */
1585             }
1586
1587             if (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
1588                 boolean picked = FALSE;
1589
1590                 if (likeobjs)
1591                     picked |= mpickstuff(mtmp, practical);
1592                 if (likemagic)
1593                     picked |= mpickstuff(mtmp, magical);
1594                 if (likerock)
1595                     picked |= mpickstuff(mtmp, boulder_class);
1596                 if (likegems)
1597                     picked |= mpickstuff(mtmp, gem_class);
1598                 if (uses_items)
1599                     picked |= mpickstuff(mtmp, (char *) 0);
1600                 if (picked)
1601                     mmoved = 3;
1602             }
1603
1604             if (mtmp->minvis) {
1605                 newsym(mtmp->mx, mtmp->my);
1606                 if (mtmp->wormno)
1607                     see_wsegs(mtmp);
1608             }
1609         }
1610
1611         if (hides_under(ptr) || ptr->mlet == S_EEL) {
1612             /* Always set--or reset--mundetected if it's already hidden
1613                (just in case the object it was hiding under went away);
1614                usually set mundetected unless monster can't move.  */
1615             if (mtmp->mundetected
1616                 || (mtmp->mcanmove && !mtmp->msleeping && rn2(5)))
1617                 (void) hideunder(mtmp);
1618             newsym(mtmp->mx, mtmp->my);
1619         }
1620         if (mtmp->isshk) {
1621             after_shk_move(mtmp);
1622         }
1623     }
1624     return mmoved;
1625 }
1626
1627 void
1628 dissolve_bars(x, y)
1629 register int x, y;
1630 {
1631     levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x, y, 0)) ? ROOM : CORR;
1632     levl[x][y].flags = 0;
1633     newsym(x, y);
1634 }
1635
1636 boolean
1637 closed_door(x, y)
1638 register int x, y;
1639 {
1640     return (boolean) (IS_DOOR(levl[x][y].typ)
1641                       && (levl[x][y].doormask & (D_LOCKED | D_CLOSED)));
1642 }
1643
1644 boolean
1645 accessible(x, y)
1646 register int x, y;
1647 {
1648     int levtyp = levl[x][y].typ;
1649
1650     /* use underlying terrain in front of closed drawbridge */
1651     if (levtyp == DRAWBRIDGE_UP)
1652         levtyp = db_under_typ(levl[x][y].drawbridgemask);
1653
1654     return (boolean) (ACCESSIBLE(levtyp) && !closed_door(x, y));
1655 }
1656
1657 /* decide where the monster thinks you are standing */
1658 void
1659 set_apparxy(mtmp)
1660 register struct monst *mtmp;
1661 {
1662     boolean notseen, gotu;
1663     register int disp, mx = mtmp->mux, my = mtmp->muy;
1664     long umoney = money_cnt(invent);
1665
1666     /*
1667      * do cheapest and/or most likely tests first
1668      */
1669
1670     /* pet knows your smell; grabber still has hold of you */
1671     if (mtmp->mtame || mtmp == u.ustuck)
1672         goto found_you;
1673
1674     /* monsters which know where you are don't suddenly forget,
1675        if you haven't moved away */
1676     if (mx == u.ux && my == u.uy)
1677         goto found_you;
1678
1679     notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data)));
1680     /* add cases as required.  eg. Displacement ... */
1681     if (notseen || Underwater) {
1682         /* Xorns can smell quantities of valuable metal
1683             like that in solid gold coins, treat as seen */
1684         if ((mtmp->data == &mons[PM_XORN]) && umoney && !Underwater)
1685             disp = 0;
1686         else
1687             disp = 1;
1688     } else if (Displaced) {
1689         disp = couldsee(mx, my) ? 2 : 1;
1690     } else
1691         disp = 0;
1692     if (!disp)
1693         goto found_you;
1694
1695     /* without something like the following, invisibility and displacement
1696        are too powerful */
1697     gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE;
1698
1699     if (!gotu) {
1700         register int try_cnt = 0;
1701
1702         do {
1703             if (++try_cnt > 200)
1704                 goto found_you; /* punt */
1705             mx = u.ux - disp + rn2(2 * disp + 1);
1706             my = u.uy - disp + rn2(2 * disp + 1);
1707         } while (!isok(mx, my)
1708                  || (disp != 2 && mx == mtmp->mx && my == mtmp->my)
1709                  || ((mx != u.ux || my != u.uy) && !passes_walls(mtmp->data)
1710                      && !(accessible(mx, my)
1711                           || (closed_door(mx, my)
1712                               && (can_ooze(mtmp) || can_fog(mtmp)))))
1713                  || !couldsee(mx, my));
1714     } else {
1715  found_you:
1716         mx = u.ux;
1717         my = u.uy;
1718     }
1719
1720     mtmp->mux = mx;
1721     mtmp->muy = my;
1722 }
1723
1724 /*
1725  * mon-to-mon displacement is a deliberate "get out of my way" act,
1726  * not an accidental bump, so we don't consider mstun or mconf in
1727  * undesired_disp().
1728  *
1729  * We do consider many other things about the target and its
1730  * location however.
1731  */
1732 boolean
1733 undesirable_disp(mtmp, x, y)
1734 struct monst *mtmp; /* barging creature */
1735 xchar x, y; /* spot 'mtmp' is considering moving to */
1736 {
1737     boolean is_pet = (mtmp && mtmp->mtame && !mtmp->isminion);
1738     struct trap *trap = t_at(x, y);
1739
1740     if (is_pet) {
1741         /* Pets avoid a trap if you've seen it usually. */
1742         if (trap && trap->tseen && rn2(40))
1743             return TRUE;
1744         /* Pets avoid cursed locations */
1745         if (cursed_object_at(x, y))
1746             return TRUE;
1747
1748     /* Monsters avoid a trap if they've seen that type before */
1749     } else if (trap && rn2(40)
1750                && (mtmp->mtrapseen & (1 << (trap->ttyp - 1))) != 0) {
1751         return TRUE;
1752     }
1753
1754     /* oversimplification:  creatures that bargethrough can't swap places
1755        when target monster is in rock or closed door or water (in particular,
1756        avoid moving to spots where mondied() won't leave a corpse; doesn't
1757        matter whether barger is capable of moving to such a target spot if
1758        it were unoccupied) */
1759     if (!accessible(x, y)
1760         /* mondied() allows is_pool() as an exception to !accessible(),
1761            but we'll only do that if 'mtmp' is already at a water location
1762            so that we don't swap a water critter onto land */
1763         && !(is_pool(x, y) && is_pool(mtmp->mx, mtmp->my)))
1764         return TRUE;
1765
1766     return FALSE;
1767 }
1768
1769 /*
1770  * Inventory prevents passage under door.
1771  * Used by can_ooze() and can_fog().
1772  */
1773 STATIC_OVL boolean
1774 stuff_prevents_passage(mtmp)
1775 struct monst *mtmp;
1776 {
1777     struct obj *chain, *obj;
1778
1779     if (mtmp == &youmonst) {
1780         chain = invent;
1781     } else {
1782         chain = mtmp->minvent;
1783     }
1784     for (obj = chain; obj; obj = obj->nobj) {
1785         int typ = obj->otyp;
1786
1787         if (typ == COIN_CLASS && obj->quan > 100L)
1788             return TRUE;
1789         if (obj->oclass != GEM_CLASS && !(typ >= ARROW && typ <= BOOMERANG)
1790             && !(typ >= DAGGER && typ <= CRYSKNIFE) && typ != SLING
1791             && !is_cloak(obj) && typ != FEDORA && !is_gloves(obj)
1792             && typ != LEATHER_JACKET && typ != CREDIT_CARD && !is_shirt(obj)
1793             && !(typ == CORPSE && verysmall(&mons[obj->corpsenm]))
1794             && typ != FORTUNE_COOKIE && typ != CANDY_BAR && typ != PANCAKE
1795             && typ != LEMBAS_WAFER && typ != LUMP_OF_ROYAL_JELLY
1796             && obj->oclass != AMULET_CLASS && obj->oclass != RING_CLASS
1797             && obj->oclass != VENOM_CLASS && typ != SACK
1798             && typ != BAG_OF_HOLDING && typ != BAG_OF_TRICKS
1799             && !Is_candle(obj) && typ != OILSKIN_SACK && typ != LEASH
1800             && typ != STETHOSCOPE && typ != BLINDFOLD && typ != TOWEL
1801             && typ != TIN_WHISTLE && typ != MAGIC_WHISTLE
1802             && typ != MAGIC_MARKER && typ != TIN_OPENER && typ != SKELETON_KEY
1803             && typ != LOCK_PICK)
1804             return TRUE;
1805         if (Is_container(obj) && obj->cobj)
1806             return TRUE;
1807     }
1808     return FALSE;
1809 }
1810
1811 boolean
1812 can_ooze(mtmp)
1813 struct monst *mtmp;
1814 {
1815     if (!amorphous(mtmp->data) || stuff_prevents_passage(mtmp))
1816         return FALSE;
1817     return TRUE;
1818 }
1819
1820 /* monster can change form into a fog if necessary */
1821 boolean
1822 can_fog(mtmp)
1823 struct monst *mtmp;
1824 {
1825     if (!(mvitals[PM_FOG_CLOUD].mvflags & G_GENOD) && is_vampshifter(mtmp)
1826         && !Protection_from_shape_changers && !stuff_prevents_passage(mtmp))
1827         return TRUE;
1828     return FALSE;
1829 }
1830
1831 STATIC_OVL int
1832 vamp_shift(mon, ptr, domsg)
1833 struct monst *mon;
1834 struct permonst *ptr;
1835 boolean domsg;
1836 {
1837     int reslt = 0;
1838     char oldmtype[BUFSZ];
1839
1840     /* remember current monster type before shapechange */
1841     Strcpy(oldmtype, domsg ? noname_monnam(mon, ARTICLE_THE) : "");
1842
1843     if (mon->data == ptr) {
1844         /* already right shape */
1845         reslt = 1;
1846         domsg = FALSE;
1847     } else if (is_vampshifter(mon)) {
1848         reslt = newcham(mon, ptr, FALSE, FALSE);
1849     }
1850
1851     if (reslt && domsg) {
1852 #if 0 /*JP:T*/
1853         pline("You %s %s where %s was.",
1854               !canseemon(mon) ? "now detect" : "observe",
1855               noname_monnam(mon, ARTICLE_A), oldmtype);
1856 #else
1857         pline("\82 \82È\82½\82Í%s\82ª\82¢\82½\8fê\8f\8a\82É%s\82ð%s\81D",
1858               oldmtype, noname_monnam(mon, ARTICLE_A),
1859               !canseemon(mon) ? "\8a´\92m\82µ\82½" : "\8c©\82Â\82¯\82½");
1860 #endif
1861         /* this message is given when it turns into a fog cloud
1862            in order to move under a closed door */
1863         display_nhwindow(WIN_MESSAGE, FALSE);
1864     }
1865
1866     return reslt;
1867 }
1868
1869 /*monmove.c*/