OSDN Git Service

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