OSDN Git Service

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