OSDN Git Service

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