1 /* NetHack 3.6 monmove.c $NHDT-Date: 1575245074 2019/12/02 00:04:34 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.116 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Michael Allison, 2006. */
4 /* NetHack may be freely redistributed. See license for details. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020 */
9 /* JNetHack may be freely redistributed. See license for details. */
15 extern boolean notonhead;
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 *,
26 /* True if mtmp died */
32 if (cansee(mtmp->mx, mtmp->my) && !Unaware)
34 pline("KABOOM!! You see a door explode.");
36 pline("
\82¿
\82ã
\82Ç
\81[
\82ñ
\81I
\83h
\83A
\82ª
\94\9a\94
\82·
\82é
\82Ì
\82ð
\8c©
\82½
\81D");
39 You_hear("a distant explosion.");
41 You_hear("
\89\93\95û
\82Å
\94\9a\94
\82·
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
43 wake_nearto(mtmp->mx, mtmp->my, 7 * 7);
46 if (DEADMONSTER(mtmp)) {
48 if (!DEADMONSTER(mtmp)) /* lifesaved */
56 /* check whether a monster is carrying a locking/unlocking tool */
58 monhaskey(mon, for_unlocking)
60 boolean for_unlocking; /* true => credit card ok, false => not ok */
62 if (for_unlocking && m_carrying(mon, CREDIT_CARD))
64 return m_carrying(mon, SKELETON_KEY) || m_carrying(mon, LOCK_PICK);
74 /* Sidenote on "A watchman angrily waves her arms!"
75 * Female being called watchman is correct (career name).
78 pline("%s angrily %s %s %s!",
80 nolimbs(mon->data) ? "shakes" : "waves",
82 nolimbs(mon->data) ? mbodypart(mon, HEAD)
83 : makeplural(mbodypart(mon, ARM)));
85 pline("%s
\82Í
\93{
\82Á
\82Ä%s
\82ð
\90U
\82Á
\82½
\81I",
87 nolimbs(mon->data) ? mbodypart(mon, HEAD)
88 : makeplural(mbodypart(mon, ARM)));
93 pline("%s yells:", Amonnam(mon));
95 pline("%s
\82Í
\8b©
\82ñ
\82¾
\81F", Amonnam(mon));
98 You_hear("someone yell:");
100 pline("
\89½
\8eÒ
\82©
\82Í
\8b©
\82ñ
\82¾
\81F");
107 register struct monst *mtmp;
111 if (mtmp->mpeaceful && in_town(u.ux + u.dx, u.uy + u.dy)
112 && mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
113 if (picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ)
114 && (levl[x][y].doormask & D_LOCKED)) {
115 if (couldsee(mtmp->mx, mtmp->my)) {
116 if (levl[x][y].looted & D_WARNED) {
118 mon_yells(mtmp, "Halt, thief! You're under arrest!");
120 verbalize("
\91Ò
\82Ä
\81I
\82Ê
\82·
\82Á
\82Æ
\81I
\82¨
\82Ü
\82¦
\82ð
\91ß
\95ß
\82·
\82é
\81I");
121 (void) angry_guards(!!Deaf);
124 mon_yells(mtmp, "Hey, stop picking that lock!");
126 verbalize("
\82¨
\82¢
\81C
\8c®
\82ð
\8f\9f\8eè
\82É
\8aJ
\82¯
\82é
\82ñ
\82¶
\82á
\82È
\82¢
\81I");
127 levl[x][y].looted |= D_WARNED;
131 } else if (is_digging()) {
132 /* chewing, wand/spell of digging are checked elsewhere */
133 watch_dig(mtmp, context.digging.pos.x, context.digging.pos.y,
141 register struct monst *mtmp;
143 int x = mtmp->mx, y = mtmp->my;
144 boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp);
145 int rd = dochug(mtmp);
147 /* a similar check is in monster_nearby() in hack.c */
148 /* check whether hero notices monster and stops current activity */
149 if (occupation && !rd && !Confusion && (!mtmp->mpeaceful || Hallucination)
150 /* it's close enough to be a threat */
151 && distu(x, y) <= (BOLT_LIM + 1) * (BOLT_LIM + 1)
152 /* and either couldn't see it before, or it was too far away */
153 && (!already_saw_mon || !couldsee(x, y)
154 || distu(x, y) > (BOLT_LIM + 1) * (BOLT_LIM + 1))
155 /* can see it now, or sense it and would normally see it */
156 && (canseemon(mtmp) || (sensemon(mtmp) && couldsee(x, y)))
157 && mtmp->mcanmove && !noattacks(mtmp->data)
158 && !onscary(u.ux, u.uy, mtmp))
169 /* creatures who are directly resistant to magical scaring:
170 * Rodney, lawful minions, Angels, the Riders, shopkeepers
171 * inside their own shop, priests inside their own temple */
172 if (mtmp->iswiz || is_lminion(mtmp) || mtmp->data == &mons[PM_ANGEL]
173 || is_rider(mtmp->data)
174 || (mtmp->isshk && inhishop(mtmp))
175 || (mtmp->ispriest && inhistemple(mtmp)))
178 /* <0,0> is used by musical scaring to check for the above;
179 * it doesn't care about scrolls or engravings or dungeon branch */
180 if (x == 0 && y == 0)
183 /* should this still be true for defiled/molochian altars? */
184 if (IS_ALTAR(levl[x][y].typ)
185 && (mtmp->data->mlet == S_VAMPIRE || is_vampshifter(mtmp)))
188 /* the scare monster scroll doesn't have any of the below
189 * restrictions, being its own source of power */
190 if (sobj_at(SCR_SCARE_MONSTER, x, y))
194 * Creatures who don't (or can't) fear a written Elbereth:
195 * all the above plus shopkeepers (even if poly'd into non-human),
196 * vault guards (also even if poly'd), blind or peaceful monsters,
197 * humans and elves, and minotaurs.
199 * If the player isn't actually on the square OR the player's image
200 * isn't displaced to the square, no protection is being granted.
202 * Elbereth doesn't work in Gehennom, the Elemental Planes, or the
203 * Astral Plane; the influence of the Valar only reaches so far.
205 return (sengr_at("Elbereth", x, y, TRUE)
206 && ((u.ux == x && u.uy == y)
207 || (Displaced && mtmp->mux == x && mtmp->muy == y))
208 && !(mtmp->isshk || mtmp->isgd || !mtmp->mcansee
209 || mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN
210 || mtmp->data == &mons[PM_MINOTAUR]
211 || Inhell || In_endgame(&u.uz)));
215 /* regenerate lost hit points */
217 mon_regen(mon, digest_meal)
221 if (mon->mhp < mon->mhpmax && (moves % 20 == 0 || regenerates(mon->data)))
228 if (mon->meating <= 0)
235 * Possibly awaken the given monster. Return a 1 if the monster has been
240 register struct monst *mtmp;
243 * + Ettins are hard to surprise.
244 * + Nymphs, jabberwocks, and leprechauns do not easily wake up.
248 * within 10 squares AND
249 * not stealthy or (mon is an ettin and 9/10) AND
250 * (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND
251 * Aggravate or mon is (dog or human) or
252 * (1/7 and mon is not mimicing furniture or object)
254 if (couldsee(mtmp->mx, mtmp->my) && distu(mtmp->mx, mtmp->my) <= 100
255 && (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10)))
256 && (!(mtmp->data->mlet == S_NYMPH
257 || mtmp->data == &mons[PM_JABBERWOCK]
259 || mtmp->data == &mons[PM_VORPAL_JABBERWOCK]
261 || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50))
262 && (Aggravate_monster
263 || (mtmp->data->mlet == S_DOG || mtmp->data->mlet == S_HUMAN)
264 || (!rn2(7) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
265 && M_AP_TYPE(mtmp) != M_AP_OBJECT))) {
272 /* ungrab/expel held/swallowed hero */
277 if (mon == u.ustuck) {
279 expels(mon, mon->data, TRUE);
280 } else if (!sticks(youmonst.data)) {
281 unstuck(mon); /* let go */
283 You("get released!");
285 You("
\89ð
\95ú
\82³
\82ê
\82½
\81I");
290 #define flees_light(mon) ((mon)->data == &mons[PM_GREMLIN] \
291 && (uwep && artifact_light(uwep) && uwep->lamplit))
292 /* we could include this in the above macro, but probably overkill/overhead */
293 /* && (!(which_armor((mon), W_ARMC) != 0 */
294 /* && which_armor((mon), W_ARMH) != 0)) */
296 /* monster begins fleeing for the specified time, 0 means untimed flee
297 * if first, only adds fleetime if monster isn't already fleeing
298 * if fleemsg, prints a message about new flight, otherwise, caller should */
300 monflee(mtmp, fleetime, first, fleemsg)
306 /* shouldn't happen; maybe warrants impossible()? */
307 if (DEADMONSTER(mtmp))
310 if (mtmp == u.ustuck)
311 release_hero(mtmp); /* expels/unstuck */
313 if (!first || !mtmp->mflee) {
314 /* don't lose untimed scare */
317 else if (!mtmp->mflee || mtmp->mfleetim) {
318 fleetime += (int) mtmp->mfleetim;
319 /* ensure monster flees long enough to visibly stop fighting */
322 mtmp->mfleetim = (unsigned) min(fleetime, 127);
324 if (!mtmp->mflee && fleemsg && canseemon(mtmp)
325 && M_AP_TYPE(mtmp) != M_AP_FURNITURE
326 && M_AP_TYPE(mtmp) != M_AP_OBJECT) {
327 /* unfortunately we can't distinguish between temporary
328 sleep and temporary paralysis, so both conditions
329 receive the same alternate message */
330 if (!mtmp->mcanmove || !mtmp->data->mmove) {
332 pline("%s seems to flinch.", Adjmonnam(mtmp, "immobile"));
334 pline("%s
\82Í
\82µ
\82è
\82²
\82Ý
\82µ
\82Ä
\82¢
\82é
\82æ
\82¤
\82¾
\81D", Monnam(mtmp));
335 } else if (flees_light(mtmp)) {
338 pline("%s flees from the painful light of %s.",
339 Monnam(mtmp), bare_artifactname(uwep));
341 pline("%s
\82Í%s
\82Ì
\8cõ
\82É
\82¨
\82Ñ
\82¦
\82½
\81D",
342 Monnam(mtmp), bare_artifactname(uwep));
346 verbalize("Bright light!");
348 verbalize("
\8bP
\82
\8cõ
\81I");
351 pline("%s turns to flee.", Monnam(mtmp));
353 pline("%s
\82Í
\82¨
\82Ñ
\82¦
\82Ä
\93¦
\82°
\8fo
\82µ
\82½
\81I", Monnam(mtmp));
357 /* ignore recently-stepped spaces when made to flee */
358 memset(mtmp->mtrack, 0, sizeof(mtmp->mtrack));
362 distfleeck(mtmp, inrange, nearby, scared)
363 register struct monst *mtmp;
364 int *inrange, *nearby, *scared;
366 int seescaryx, seescaryy;
367 boolean sawscary = FALSE, bravegremlin = (rn2(5) == 0);
369 *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
370 <= (BOLT_LIM * BOLT_LIM));
371 *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy);
373 /* Note: if your image is displaced, the monster sees the Elbereth
374 * at your displaced position, thus never attacking your displaced
375 * position, but possibly attacking you by accident. If you are
376 * invisible, it sees the Elbereth at your real position, thus never
377 * running into you by accident but possibly attacking the spot
378 * where it guesses you are.
380 if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
381 seescaryx = mtmp->mux;
382 seescaryy = mtmp->muy;
388 sawscary = onscary(seescaryx, seescaryy, mtmp);
389 if (*nearby && (sawscary
390 || (flees_light(mtmp) && !bravegremlin)
391 || (!mtmp->mpeaceful && in_your_sanctuary(mtmp, 0, 0)))) {
393 monflee(mtmp, rnd(rn2(7) ? 10 : 100), TRUE, TRUE);
400 /* perform a special one-time action for a monster; returns -1 if nothing
401 special happened, 0 if monster uses up its turn, 1 if monster is killed */
406 mon->mstrategy &= ~STRAT_ARRIVE; /* always reset */
411 /* returns 1 if monster died moving, 0 otherwise */
412 /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti
417 register struct monst *mtmp;
419 register struct permonst *mdat;
420 register int tmp = 0;
421 int inrange, nearby, scared;
423 /* Pre-movement adjustments
428 if (mtmp->mstrategy & STRAT_ARRIVE) {
429 int res = m_arrival(mtmp);
434 /* check for waitmask status change */
435 if ((mtmp->mstrategy & STRAT_WAITFORU)
436 && (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax))
437 mtmp->mstrategy &= ~STRAT_WAITFORU;
439 /* update quest status flags */
440 quest_stat_check(mtmp);
442 if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) {
444 newsym(mtmp->mx, mtmp->my);
445 if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE)
446 && !mtmp->msleeping && monnear(mtmp, u.ux, u.uy))
447 quest_talk(mtmp); /* give the leaders a chance to speak */
448 return 0; /* other frozen monsters can't do anything */
451 /* there is a chance we will wake it */
452 if (mtmp->msleeping && !disturb(mtmp)) {
454 newsym(mtmp->mx, mtmp->my);
458 /* not frozen or sleeping: wipe out texts written in the dust */
459 wipe_engr_at(mtmp->mx, mtmp->my, 1, FALSE);
461 /* confused monsters get unconfused with small probability */
462 if (mtmp->mconf && !rn2(50))
465 /* stunned monsters get un-stunned with larger probability */
466 if (mtmp->mstun && !rn2(10))
469 /* some monsters teleport */
470 if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz
471 && !level.flags.noteleport) {
472 (void) rloc(mtmp, TRUE);
475 if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1))
477 if (mdat == &mons[PM_MEDUSA] && couldsee(mtmp->mx, mtmp->my))
479 if (DEADMONSTER(mtmp))
480 return 1; /* m_respond gaze can kill medusa */
482 /* fleeing monsters might regain courage */
483 if (mtmp->mflee && !mtmp->mfleetim && mtmp->mhp == mtmp->mhpmax
487 /* cease conflict-induced swallow/grab if conflict has ended */
488 if (mtmp == u.ustuck && mtmp->mpeaceful && !mtmp->mconf && !Conflict) {
490 return 0; /* uses up monster's turn */
494 /* Must be done after you move and before the monster does. The
495 * set_apparxy() call in m_move() doesn't suffice since the variables
496 * inrange, etc. all depend on stuff set by set_apparxy().
499 /* Monsters that want to acquire things */
500 /* may teleport, so do it before inrange is set */
501 if (is_covetous(mdat))
502 (void) tactics(mtmp);
504 /* check distance and scariness of attacks */
505 distfleeck(mtmp, &inrange, &nearby, &scared);
507 if (find_defensive(mtmp)) {
508 if (use_defensive(mtmp) != 0)
510 } else if (find_misc(mtmp)) {
511 if (use_misc(mtmp) != 0)
515 /* Demonic Blackmail! */
516 if (nearby && mdat->msound == MS_BRIBE && mtmp->mpeaceful && !mtmp->mtame
518 if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
520 pline("%s whispers at thin air.",
521 cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
523 pline("%s
\82ª
\82³
\82³
\82â
\82¢
\82½
\81D",
524 cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "
\89½
\82©");
527 if (is_demon(youmonst.data)) {
528 /* "Good hunting, brother" */
529 if (!tele_restrict(mtmp))
530 (void) rloc(mtmp, TRUE);
532 mtmp->minvis = mtmp->perminvis = 0;
533 /* Why? For the same reason in real demon talk */
535 pline("%s gets angry!", Amonnam(mtmp));
537 pline("%s
\82Í
\93{
\82Á
\82½
\81I", Amonnam(mtmp));
540 /* since no way is an image going to pay it off */
542 } else if (demon_talk(mtmp))
543 return 1; /* you paid it off */
546 /* the watch will look around and see if you are up to no good :-) */
547 if (is_watch(mdat)) {
550 } else if (is_mind_flayer(mdat) && !rn2(20)) {
551 struct monst *m2, *nmon = (struct monst *) 0;
555 pline("%s concentrates.", Monnam(mtmp));
557 pline("%s
\82Í
\90¸
\90_
\82ð
\8fW
\92\86\82µ
\82Ä
\82¢
\82é
\81D", Monnam(mtmp));
558 if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) {
560 You("sense a faint wave of psychic energy.");
562 You("
\83T
\83C
\83R
\83G
\83l
\83\8b\83M
\81[
\82Ì
\94g
\93®
\82ð
\8a´
\82¶
\82½
\81D");
566 pline("A wave of psychic energy pours over you!");
568 pline("
\82 \82È
\82½
\82Í
\83T
\83C
\83R
\83G
\83l
\83\8b\83M
\81[
\82Ì
\94g
\93®
\82ð
\97\81\82Ñ
\82½
\81I");
570 && (!Conflict || resist(mtmp, RING_CLASS, 0, 0))) {
572 pline("It feels quite soothing.");
574 pline("
\90S
\82ª
\82È
\82²
\82ñ
\82¾
\81D");
575 } else if (!u.uinvulnerable) {
576 register boolean m_sen = sensemon(mtmp);
578 if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) {
581 pline("It locks on to your %s!",
582 m_sen ? "telepathy" : Blind_telepat ? "latent telepathy"
585 pline("
\82»
\82ê
\82Í
\82 \82È
\82½
\82Ì%s
\82ð
\92¼
\8c\82\82µ
\82½
\81I",
586 m_sen ? "
\83e
\83\8c\83p
\83V
\81[
\94\
\97Í" : Blind_telepat ? "
\90ö
\8dÝ
\94\
\97Í"
590 if (Half_spell_damage)
593 losehp(dmg, "psychic blast", KILLED_BY_AN);
595 losehp(dmg, "
\83T
\83C
\83R
\8dU
\8c\82\82Å", KILLED_BY_AN);
598 for (m2 = fmon; m2; m2 = nmon) {
602 if (m2->mpeaceful == mtmp->mpeaceful)
604 if (mindless(m2->data))
608 if ((telepathic(m2->data) && (rn2(2) || m2->mblinded))
610 if (cansee(m2->mx, m2->my))
612 pline("It locks on to %s.", mon_nam(m2));
614 pline("%s
\82ð
\92¼
\8c\82\82µ
\82½
\81D", mon_nam(m2));
617 monkilled(m2, "", AD_DRIN);
625 /* If monster is nearby you, and has to wield a weapon, do so. This
626 * costs the monster a move, of course.
628 if ((!mtmp->mpeaceful || Conflict) && inrange
629 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8
630 && attacktype(mdat, AT_WEAP)) {
633 /* The scared check is necessary. Otherwise a monster that is
634 * one square near the player but fleeing into a wall would keep
635 * switching between pick-axe and weapon. If monster is stuck
636 * in a trap, prefer ranged weapon (wielding is done in thrwmu).
637 * This may cost the monster an attack, but keeps the monster
638 * from switching back and forth if carrying both.
640 mw_tmp = MON_WEP(mtmp);
641 if (!(scared && mw_tmp && is_pick(mw_tmp))
642 && mtmp->weapon_check == NEED_WEAPON
643 && !(mtmp->mtrapped && !nearby && select_rwep(mtmp))) {
644 mtmp->weapon_check = NEED_HTH_WEAPON;
645 if (mon_wield_item(mtmp) != 0)
650 /* Now the actual movement phase
653 if (!nearby || mtmp->mflee || scared || mtmp->mconf || mtmp->mstun
654 || (mtmp->minvis && !rn2(3))
655 || (mdat->mlet == S_LEPRECHAUN && !findgold(invent)
656 && (findgold(mtmp->minvent) || rn2(2)))
657 || (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz)
658 || (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
659 /* Possibly cast an undirected spell if not attacking you */
660 /* note that most of the time castmu() will pick a directed
661 spell and do nothing, so the monster moves normally */
662 /* arbitrary distance restriction to keep monster far away
663 from you from having cast dozens of sticks-to-snakes
664 or similar spells by the time you reach it */
665 if (dist2(mtmp->mx, mtmp->my, u.ux, u.uy) <= 49
666 && !mtmp->mspec_used) {
669 for (a = &mdat->mattk[0]; a < &mdat->mattk[NATTK]; a++) {
670 if (a->aatyp == AT_MAGC
671 && (a->adtyp == AD_SPEL || a->adtyp == AD_CLRC)) {
672 if (castmu(mtmp, a, FALSE, FALSE)) {
680 tmp = m_move(mtmp, 0);
682 distfleeck(mtmp, &inrange, &nearby, &scared); /* recalc */
684 switch (tmp) { /* for pets, cases 0 and 3 are equivalent */
685 case 0: /* no movement, but it can still attack you */
686 case 3: /* absolutely no movement */
687 /* vault guard might have vanished */
688 if (mtmp->isgd && (DEADMONSTER(mtmp) || mtmp->mx == 0))
689 return 1; /* behave as if it died */
690 /* During hallucination, monster appearance should
691 * still change - even if it doesn't move.
694 newsym(mtmp->mx, mtmp->my);
696 case 1: /* monster moved */
697 /* Maybe it stepped on a trap and fell asleep... */
698 if (mtmp->msleeping || !mtmp->mcanmove)
700 /* Monsters can move and then shoot on same turn;
701 our hero can't. Is that fair? */
702 if (!nearby && (ranged_attk(mdat) || find_offensive(mtmp)))
704 /* engulfer/grabber checks */
705 if (mtmp == u.ustuck) {
706 /* a monster that's digesting you can move at the
710 return mattacku(mtmp);
711 /* if confused grabber has wandered off, let go */
712 if (distu(mtmp->mx, mtmp->my) > 2)
716 case 2: /* monster died */
721 /* Now, attack the player if possible - one attack set per monst
724 if (!mtmp->mpeaceful || (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {
725 if (inrange && !noattacks(mdat)
726 && (Upolyd ? u.mh : u.uhp) > 0 && !scared && tmp != 3)
728 return 1; /* monster died (e.g. exploded) */
733 /* special speeches for quest monsters */
734 if (!mtmp->msleeping && mtmp->mcanmove && nearby)
736 /* extra emotional attack for vile monsters */
737 if (inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful
738 && couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5))
744 static NEARDATA const char practical[] = { WEAPON_CLASS, ARMOR_CLASS,
745 GEM_CLASS, FOOD_CLASS, 0 };
746 static NEARDATA const char magical[] = { AMULET_CLASS, POTION_CLASS,
747 SCROLL_CLASS, WAND_CLASS,
748 RING_CLASS, SPBOOK_CLASS, 0 };
749 static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
750 static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };
751 static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };
755 register struct monst *mtmp;
757 if (sticks(youmonst.data) && mtmp == u.ustuck && !u.uswallow) {
759 pline("%s cannot escape from you!", Monnam(mtmp));
761 pline("%s
\82Í
\82 \82È
\82½
\82©
\82ç
\93¦
\82°
\82ç
\82ê
\82È
\82¢
\81I", Monnam(mtmp));
770 * Displacement of another monster is a last resort and only
771 * used on approach. If there are better ways to get to target,
772 * those should be used instead. This function does that evaluation.
775 should_displace(mtmp, poss, info, cnt, gx, gy)
777 coord *poss; /* coord poss[9] */
778 long *info; /* long info[9] */
782 int shortest_with_displacing = -1;
783 int shortest_without_displacing = -1;
784 int count_without_displacing = 0;
785 register int i, nx, ny;
788 for (i = 0; i < cnt; i++) {
791 ndist = dist2(nx, ny, gx, gy);
792 if (MON_AT(nx, ny) && (info[i] & ALLOW_MDISP) && !(info[i] & ALLOW_M)
793 && !undesirable_disp(mtmp, nx, ny)) {
794 if (shortest_with_displacing == -1
795 || (ndist < shortest_with_displacing))
796 shortest_with_displacing = ndist;
798 if ((shortest_without_displacing == -1)
799 || (ndist < shortest_without_displacing))
800 shortest_without_displacing = ndist;
801 count_without_displacing++;
804 if (shortest_with_displacing > -1
805 && (shortest_with_displacing < shortest_without_displacing
806 || !count_without_displacing))
812 m_digweapon_check(mtmp, nix, niy)
816 boolean can_tunnel = 0;
817 struct obj *mw_tmp = MON_WEP(mtmp);
819 if (!Is_rogue_level(&u.uz))
820 can_tunnel = tunnels(mtmp->data);
822 if (can_tunnel && needspick(mtmp->data) && !mwelded(mw_tmp)
823 && (may_dig(nix, niy) || closed_door(nix, niy))) {
824 /* may_dig() is either IS_STWALL or IS_TREE */
825 if (closed_door(nix, niy)) {
829 mtmp->weapon_check = NEED_PICK_OR_AXE;
830 } else if (IS_TREE(levl[nix][niy].typ)) {
831 if (!(mw_tmp = MON_WEP(mtmp)) || !is_axe(mw_tmp))
832 mtmp->weapon_check = NEED_AXE;
833 } else if (IS_STWALL(levl[nix][niy].typ)) {
834 if (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))
835 mtmp->weapon_check = NEED_PICK_AXE;
837 if (mtmp->weapon_check >= NEED_PICK_AXE && mon_wield_item(mtmp))
844 * 0: did not move, but can still attack and do other stuff.
845 * 1: moved, possibly can attack.
847 * 3: did not move, and can't do anything else either.
851 register struct monst *mtmp;
855 xchar gx, gy, nix, niy, chcnt;
856 int chi; /* could be schar except for stupid Sun-2 compiler */
857 boolean likegold = 0, likegems = 0, likeobjs = 0, likemagic = 0,
859 boolean likerock = 0, can_tunnel = 0;
860 boolean can_open = 0, can_unlock = 0, doorbuster = 0;
861 boolean uses_items = 0, setlikes = 0;
862 boolean avoid = FALSE;
863 boolean better_with_displacing = FALSE;
864 boolean sawmon = canspotmon(mtmp); /* before it moved */
865 struct permonst *ptr;
867 schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
870 int omx = mtmp->mx, omy = mtmp->my;
872 if (mtmp->mtrapped) {
873 int i = mintrap(mtmp);
876 newsym(mtmp->mx, mtmp->my);
880 return 0; /* still in trap, so didn't move */
882 ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */
886 if (mtmp->meating <= 0)
887 finish_meating(mtmp);
888 return 3; /* still eating */
890 if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
891 return 0; /* do not leave hiding place */
894 /* where does mtmp think you are? */
895 /* Not necessary if m_move called from this file, but necessary in
896 * other calls of m_move (ex. leprechauns dodging)
898 if (!Is_rogue_level(&u.uz))
899 can_tunnel = tunnels(ptr);
900 can_open = !(nohands(ptr) || verysmall(ptr));
902 ((can_open && monhaskey(mtmp, TRUE)) || mtmp->iswiz || is_rider(ptr));
903 doorbuster = is_giant(ptr);
906 /* my dog gets special treatment */
908 mmoved = dog_move(mtmp, after);
912 /* likewise for shopkeeper */
914 mmoved = shk_move(mtmp);
919 mmoved = 0; /* follow player outside shop */
922 /* and for the guard */
924 mmoved = gd_move(mtmp);
932 /* and the acquisitive monsters get special treatment */
933 if (is_covetous(ptr)) {
934 xchar tx = STRAT_GOALX(mtmp->mstrategy),
935 ty = STRAT_GOALY(mtmp->mstrategy);
936 struct monst *intruder = m_at(tx, ty);
938 * if there's a monster on the object or in possession of it,
941 if ((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) && intruder
942 && (intruder != mtmp)) {
943 notonhead = (intruder->mx != tx || intruder->my != ty);
944 if (mattackm(mtmp, intruder) == 2)
952 /* and for the priest */
953 if (mtmp->ispriest) {
954 mmoved = pri_move(mtmp);
963 if (ptr == &mons[PM_MAIL_DAEMON]) {
964 if (!Deaf && canseemon(mtmp))
966 verbalize("I'm late!");
968 verbalize("
\92x
\82
\82È
\82Á
\82Ä
\82·
\82Ü
\82È
\82¢
\81I");
974 /* teleport if that lies in our nature */
975 if (ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan
976 && !tele_restrict(mtmp)) {
977 if (mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
978 (void) rloc(mtmp, TRUE);
985 if (u.uswallow && !mtmp->mflee && u.ustuck != mtmp)
991 appr = mtmp->mflee ? -1 : 1;
992 if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck)) {
995 struct obj *lepgold, *ygold;
996 boolean should_see = (couldsee(omx, omy)
997 && (levl[gx][gy].lit || !levl[omx][omy].lit)
998 && (dist2(omx, omy, gx, gy) <= 36));
1001 || (should_see && Invis && !perceives(ptr) && rn2(11))
1002 || is_obj_mappear(&youmonst,STRANGE_OBJECT) || u.uundetected
1003 || (is_obj_mappear(&youmonst,GOLD_PIECE) && !likes_gold(ptr))
1004 || (mtmp->mpeaceful && !mtmp->isshk) /* allow shks to follow */
1005 || ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT
1006 || ptr->mlet == S_LIGHT) && !rn2(3)))
1009 if (monsndx(ptr) == PM_LEPRECHAUN && (appr == 1)
1010 && ((lepgold = findgold(mtmp->minvent))
1012 > ((ygold = findgold(invent)) ? ygold->quan : 0L))))
1015 if (!should_see && can_track(ptr)) {
1018 cp = gettrack(omx, omy);
1026 if ((!mtmp->mpeaceful || !rn2(10)) && (!Is_rogue_level(&u.uz))) {
1027 boolean in_line = (lined_up(mtmp)
1028 && (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy)
1029 <= (throws_rocks(youmonst.data) ? 20 : ACURRSTR / 2 + 1)));
1031 if (appr != 1 || !in_line) {
1032 /* Monsters in combat won't pick stuff up, avoiding the
1033 * situation where you toss arrows at it and it has nothing
1034 * better to do than pick the arrows up.
1036 register int pctload =
1037 (curr_mon_load(mtmp) * 100) / max_mon_load(mtmp);
1039 /* look for gold or jewels nearby */
1040 likegold = (likes_gold(ptr) && pctload < 95);
1041 likegems = (likes_gems(ptr) && pctload < 85);
1042 uses_items = (!mindless(ptr) && !is_animal(ptr) && pctload < 75);
1043 likeobjs = (likes_objs(ptr) && pctload < 75);
1044 likemagic = (likes_magic(ptr) && pctload < 85);
1045 likerock = (throws_rocks(ptr) && pctload < 50 && !Sokoban);
1046 conceals = hides_under(ptr);
1051 #define SQSRCHRADIUS 5
1054 register int minr = SQSRCHRADIUS; /* not too far away */
1055 register struct obj *otmp;
1056 register int xx, yy;
1057 int oomx, oomy, lmx, lmy;
1059 /* cut down the search radius if it thinks character is closer. */
1060 if (distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS
1061 && !mtmp->mpeaceful)
1063 /* guards shouldn't get too distracted */
1064 if (!mtmp->mpeaceful && is_mercenary(ptr))
1067 if ((likegold || likegems || likeobjs || likemagic || likerock
1068 || conceals) && (!*in_rooms(omx, omy, SHOPBASE)
1069 || (!rn2(25) && !mtmp->isshk))) {
1071 oomx = min(COLNO - 1, omx + minr);
1072 oomy = min(ROWNO - 1, omy + minr);
1073 lmx = max(1, omx - minr);
1074 lmy = max(0, omy - minr);
1075 for (otmp = fobj; otmp; otmp = otmp->nobj) {
1076 /* monsters may pick rocks up, but won't go out of their way
1077 to grab them; this might hamper sling wielders, but it cuts
1078 down on move overhead by filtering out most common item */
1079 if (otmp->otyp == ROCK)
1083 /* Nymphs take everything. Most other creatures should not
1084 * pick up corpses except as a special case like in
1085 * searches_for_item(). We need to do this check in
1086 * mpickstuff() as well.
1088 if (xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
1089 /* don't get stuck circling around object that's
1090 underneath an immobile or hidden monster;
1091 paralysis victims excluded */
1092 if ((mtoo = m_at(xx, yy)) != 0
1093 && (mtoo->msleeping || mtoo->mundetected
1094 || (mtoo->mappearance && !mtoo->iswiz)
1095 || !mtoo->data->mmove))
1097 /* the mfndpos() test for whether to allow a move to a
1098 water location accepts flyers, but they can't reach
1099 underwater objects, so being able to move to a spot
1100 is insufficient for deciding whether to do so */
1101 if ((is_pool(xx, yy) && !is_swimmer(ptr))
1102 || (is_lava(xx, yy) && !likes_lava(ptr)))
1105 if (((likegold && otmp->oclass == COIN_CLASS)
1106 || (likeobjs && index(practical, otmp->oclass)
1107 && (otmp->otyp != CORPSE
1108 || (ptr->mlet == S_NYMPH
1109 && !is_rider(&mons[otmp->corpsenm]))))
1110 || (likemagic && index(magical, otmp->oclass))
1111 || (uses_items && searches_for_item(mtmp, otmp))
1112 || (likerock && otmp->otyp == BOULDER)
1113 || (likegems && otmp->oclass == GEM_CLASS
1114 && objects[otmp->otyp].oc_material != MINERAL)
1115 || (conceals && !cansee(otmp->ox, otmp->oy))
1116 || (ptr == &mons[PM_GELATINOUS_CUBE]
1117 && !index(indigestion, otmp->oclass)
1118 && !(otmp->otyp == CORPSE
1119 && touch_petrifies(&mons[otmp->corpsenm]))))
1120 && touch_artifact(otmp, mtmp)) {
1121 if (can_carry(mtmp, otmp) > 0
1122 && (throws_rocks(ptr) || !sobj_at(BOULDER, xx, yy))
1123 && (!is_unicorn(ptr)
1124 || objects[otmp->otyp].oc_material == GEMSTONE)
1125 /* Don't get stuck circling an Elbereth */
1126 && !onscary(xx, yy, mtmp)) {
1127 minr = distmin(omx, omy, xx, yy);
1128 oomx = min(COLNO - 1, omx + minr);
1129 oomy = min(ROWNO - 1, omy + minr);
1130 lmx = max(1, omx - minr);
1131 lmy = max(0, omy - minr);
1134 if (gx == omx && gy == omy) {
1135 mmoved = 3; /* actually unnecessary */
1142 } else if (likegold) {
1143 /* don't try to pick up anything else, but use the same loop */
1145 likegems = likeobjs = likemagic = likerock = conceals = 0;
1149 if (minr < SQSRCHRADIUS && appr == -1) {
1150 if (distmin(omx, omy, mtmp->mux, mtmp->muy) <= 3) {
1158 /* don't tunnel if hostile and close enough to prefer a weapon */
1159 if (can_tunnel && needspick(ptr)
1160 && ((!mtmp->mpeaceful || Conflict)
1161 && dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8))
1167 if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))
1168 flag |= (ALLOW_SANCT | ALLOW_SSM);
1171 if (is_minion(ptr) || is_rider(ptr))
1172 flag |= ALLOW_SANCT;
1173 /* unicorn may not be able to avoid hero on a noteleport level */
1174 if (is_unicorn(ptr) && !level.flags.noteleport)
1176 if (passes_walls(ptr))
1177 flag |= (ALLOW_WALL | ALLOW_ROCK);
1178 if (passes_bars(ptr))
1182 if (is_human(ptr) || ptr == &mons[PM_MINOTAUR])
1184 if ((is_undead(ptr) && ptr->mlet != S_GHOST) || is_vampshifter(mtmp))
1186 if (throws_rocks(ptr))
1195 register int i, j, nx, ny, nearer;
1198 register coord *mtrk;
1201 cnt = mfndpos(mtmp, poss, info, flag);
1203 jcnt = min(MTSZ, cnt - 1);
1205 nidist = dist2(nix, niy, gx, gy);
1206 /* allow monsters be shortsighted on some levels for balance */
1207 if (!mtmp->mpeaceful && level.flags.shortsighted
1208 && nidist > (couldsee(nix, niy) ? 144 : 36) && appr == 1)
1210 if (is_unicorn(ptr) && level.flags.noteleport) {
1211 /* on noteleport levels, perhaps we cannot avoid hero */
1212 for (i = 0; i < cnt; i++)
1213 if (!(info[i] & NOTONL))
1216 better_with_displacing =
1217 should_displace(mtmp, poss, info, cnt, gx, gy);
1218 for (i = 0; i < cnt; i++) {
1219 if (avoid && (info[i] & NOTONL))
1224 if (MON_AT(nx, ny) && (info[i] & ALLOW_MDISP)
1225 && !(info[i] & ALLOW_M) && !better_with_displacing)
1228 mtrk = &mtmp->mtrack[0];
1229 for (j = 0; j < jcnt; mtrk++, j++)
1230 if (nx == mtrk->x && ny == mtrk->y)
1231 if (rn2(4 * (cnt - j)))
1235 nearer = ((ndist = dist2(nx, ny, gx, gy)) < nidist);
1237 if ((appr == 1 && nearer) || (appr == -1 && !nearer)
1238 || (!appr && !rn2(++chcnt)) || !mmoved) {
1253 if (mmoved == 1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
1256 if (mmoved == 1 && m_digweapon_check(mtmp, nix,niy))
1259 /* If ALLOW_U is set, either it's trying to attack you, or it
1260 * thinks it is. In either case, attack this spot in preference to
1263 /* Actually, this whole section of code doesn't work as you'd expect.
1264 * Most attacks are handled in dochug(). It calls distfleeck(), which
1265 * among other things sets nearby if the monster is near you--and if
1266 * nearby is set, we never call m_move unless it is a special case
1267 * (confused, stun, etc.) The effect is that this ALLOW_U (and
1268 * mfndpos) has no effect for normal attacks, though it lets a
1269 * confused monster attack you by accident.
1271 if (info[chi] & ALLOW_U) {
1275 if (nix == u.ux && niy == u.uy) {
1280 /* The monster may attack another based on 1 of 2 conditions:
1281 * 1 - It may be confused.
1282 * 2 - It may mistake the monster for your (displaced) image.
1283 * Pets get taken care of above and shouldn't reach this code.
1284 * Conflict gets handled even farther away (movemon()).
1286 if ((info[chi] & ALLOW_M) || (nix == mtmp->mux && niy == mtmp->muy)) {
1287 struct monst *mtmp2;
1290 mtmp2 = m_at(nix, niy);
1292 notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my);
1293 /* note: mstatus returns 0 if mtmp2 is nonexistent */
1294 mstatus = mattackm(mtmp, mtmp2);
1296 if (mstatus & MM_AGR_DIED) /* aggressor died */
1299 if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) && rn2(4)
1300 && mtmp2->movement >= NORMAL_SPEED) {
1301 mtmp2->movement -= NORMAL_SPEED;
1303 mstatus = mattackm(mtmp2, mtmp); /* return attack */
1304 if (mstatus & MM_DEF_DIED)
1310 if ((info[chi] & ALLOW_MDISP)) {
1311 struct monst *mtmp2;
1314 mtmp2 = m_at(nix, niy);
1315 mstatus = mdisplacem(mtmp, mtmp2, FALSE);
1316 if ((mstatus & MM_AGR_DIED) || (mstatus & MM_DEF_DIED))
1318 if (mstatus & MM_HIT)
1323 if (!m_in_out_region(mtmp, nix, niy))
1326 remove_monster(omx, omy);
1327 place_monster(mtmp, nix, niy);
1328 for (j = MTSZ - 1; j > 0; j--)
1329 mtmp->mtrack[j] = mtmp->mtrack[j - 1];
1330 mtmp->mtrack[0].x = omx;
1331 mtmp->mtrack[0].y = omy;
1332 /* Place a segment at the old position. */
1336 if (is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) {
1337 (void) rloc(mtmp, TRUE);
1344 if (mmoved == 1 || mmoved == 3) {
1345 boolean canseeit = cansee(mtmp->mx, mtmp->my);
1348 /* normal monster move will already have <nix,niy>,
1349 but pet dog_move() with 'goto postmov' won't */
1350 nix = mtmp->mx, niy = mtmp->my;
1351 /* sequencing issue: when monster movement decides that a
1352 monster can move to a door location, it moves the monster
1353 there before dealing with the door rather than after;
1354 so a vampire/bat that is going to shift to fog cloud and
1355 pass under the door is already there but transformation
1356 into fog form--and its message, when in sight--has not
1357 happened yet; we have to move monster back to previous
1358 location before performing the vamp_shift() to make the
1359 message happen at right time, then back to the door again
1360 [if we did the shift above, before moving the monster,
1361 we would need to duplicate it in dog_move()...] */
1362 if (is_vampshifter(mtmp) && !amorphous(mtmp->data)
1363 && IS_DOOR(levl[nix][niy].typ)
1364 && ((levl[nix][niy].doormask & (D_LOCKED | D_CLOSED)) != 0)
1367 remove_monster(nix, niy);
1368 place_monster(mtmp, omx, omy);
1369 newsym(nix, niy), newsym(omx, omy);
1371 if (vamp_shift(mtmp, &mons[PM_FOG_CLOUD], sawmon)) {
1372 ptr = mtmp->data; /* update cached value */
1375 remove_monster(omx, omy);
1376 place_monster(mtmp, nix, niy);
1377 newsym(omx, omy), newsym(nix, niy);
1381 newsym(omx, omy); /* update the old position */
1382 if (mintrap(mtmp) >= 2) {
1384 newsym(mtmp->mx, mtmp->my);
1385 return 2; /* it died */
1387 ptr = mtmp->data; /* in case mintrap() caused polymorph */
1389 /* open a door, or crash through it, if 'mtmp' can */
1390 if (IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
1391 && !passes_walls(ptr) /* doesn't need to open doors */
1392 && !can_tunnel) { /* taken care of below */
1393 struct rm *here = &levl[mtmp->mx][mtmp->my];
1394 boolean btrapped = (here->doormask & D_TRAPPED) != 0,
1395 observeit = canseeit && canspotmon(mtmp);
1397 /* if mon has MKoT, disarm door trap; no message given */
1398 if (btrapped && has_magic_key(mtmp)) {
1399 /* BUG: this lets a vampire or blob or a doorbuster
1400 holding the Key disarm the trap even though it isn't
1401 using that Key when squeezing under or smashing the
1402 door. Not significant enough to worry about; perhaps
1403 the Key's magic is more powerful for monsters? */
1404 here->doormask &= ~D_TRAPPED;
1407 if ((here->doormask & (D_LOCKED | D_CLOSED)) != 0
1408 && amorphous(ptr)) {
1409 if (flags.verbose && canseemon(mtmp))
1411 pline("%s %s under the door.", Monnam(mtmp),
1412 (ptr == &mons[PM_FOG_CLOUD]
1413 || ptr->mlet == S_LIGHT) ? "flows" : "oozes");
1415 pline("%s
\82Í
\94à
\82Ì
\89º
\82©
\82ç%s
\82Å
\82½
\81D", Monnam(mtmp),
1416 (ptr == &mons[PM_FOG_CLOUD]
1417 || ptr->mlet == S_LIGHT) ? "
\97¬
\82ê" : "
\82É
\82¶
\82Ý");
1419 } else if (here->doormask & D_LOCKED && can_unlock) {
1421 here->doormask = D_NODOOR;
1422 newsym(mtmp->mx, mtmp->my);
1423 unblock_point(mtmp->mx, mtmp->my); /* vision */
1424 if (mb_trapped(mtmp))
1427 if (flags.verbose) {
1430 pline("%s unlocks and opens a door.",
1432 pline("%s
\82Í
\8c®
\82ð
\82Í
\82¸
\82µ
\82Ä
\94à
\82ð
\8aJ
\82¯
\82½
\81D",
1436 You_see("a door unlock and open.");
1438 You("
\94à
\82Ì
\8c®
\82ª
\82Í
\82¸
\82ê
\81C
\8aJ
\82
\82Ì
\82ð
\8c©
\82½
\81D");
1441 You_hear("a door unlock and open.");
1443 You_hear("
\94à
\82Ì
\8c®
\82ª
\82Í
\82¸
\82ê
\81C
\8aJ
\82
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1445 here->doormask = D_ISOPEN;
1446 /* newsym(mtmp->mx, mtmp->my); */
1447 unblock_point(mtmp->mx, mtmp->my); /* vision */
1449 } else if (here->doormask == D_CLOSED && can_open) {
1451 here->doormask = D_NODOOR;
1452 newsym(mtmp->mx, mtmp->my);
1453 unblock_point(mtmp->mx, mtmp->my); /* vision */
1454 if (mb_trapped(mtmp))
1457 if (flags.verbose) {
1460 pline("%s opens a door.", Monnam(mtmp));
1462 pline("%s
\82Í
\94à
\82ð
\8aJ
\82¯
\82½
\81D", Monnam(mtmp));
1465 You_see("a door open.");
1467 You("
\94à
\82ª
\8aJ
\82
\82Ì
\82ð
\8c©
\82½
\81D");
1470 You_hear("a door open.");
1472 You_hear("
\94à
\82ª
\8aJ
\82
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1474 here->doormask = D_ISOPEN;
1475 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
1476 unblock_point(mtmp->mx, mtmp->my); /* vision */
1478 } else if (here->doormask & (D_LOCKED | D_CLOSED)) {
1479 /* mfndpos guarantees this must be a doorbuster */
1481 here->doormask = D_NODOOR;
1482 newsym(mtmp->mx, mtmp->my);
1483 unblock_point(mtmp->mx, mtmp->my); /* vision */
1484 if (mb_trapped(mtmp))
1487 if (flags.verbose) {
1490 pline("%s smashes down a door.",
1492 pline("%s
\82Í
\94à
\82ð
\94j
\89ó
\82µ
\82½
\81D",
1496 You_see("a door crash open.");
1498 You("
\94à
\82ª
\94j
\89ó
\82³
\82ê
\82é
\82Ì
\82ð
\8c©
\82½
\81D");
1501 You_hear("a door crash open.");
1503 You_hear("
\94à
\82ª
\94j
\89ó
\82³
\82ê
\82é
\89¹
\82ð
\95·
\82¢
\82½
\81D");
1505 if ((here->doormask & D_LOCKED) != 0 && !rn2(2))
1506 here->doormask = D_NODOOR;
1508 here->doormask = D_BROKEN;
1509 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
1510 unblock_point(mtmp->mx, mtmp->my); /* vision */
1512 /* if it's a shop door, schedule repair */
1513 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1514 add_damage(mtmp->mx, mtmp->my, 0L);
1516 } else if (levl[mtmp->mx][mtmp->my].typ == IRONBARS) {
1517 /* As of 3.6.2: was using may_dig() but it doesn't handle bars */
1518 if (!(levl[mtmp->mx][mtmp->my].wall_info & W_NONDIGGABLE)
1519 && (dmgtype(ptr, AD_RUST) || dmgtype(ptr, AD_CORR))) {
1520 if (canseemon(mtmp))
1522 pline("%s eats through the iron bars.", Monnam(mtmp));
1524 pline("%s
\82Í
\93S
\82Ì
\96_
\82ð
\90H
\82×
\82Ä
\92Ê
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp));
1525 dissolve_bars(mtmp->mx, mtmp->my);
1527 } else if (flags.verbose && canseemon(mtmp))
1529 Norep("%s %s %s the iron bars.", Monnam(mtmp),
1530 /* pluralization fakes verb conjugation */
1531 makeplural(locomotion(ptr, "pass")),
1532 passes_walls(ptr) ? "through" : "between");
1534 Norep("%s
\82Í
\93S
\82Ì
\96_%s
\82ð
\82·
\82è
\94²
\82¯
\82½
\81D", Monnam(mtmp),
1535 passes_walls(ptr) ? "" : "
\82Ì
\8aÔ");
1540 if (can_tunnel && mdig_tunnel(mtmp))
1541 return 2; /* mon died (position already updated) */
1543 /* set also in domove(), hack.c */
1544 if (u.uswallow && mtmp == u.ustuck
1545 && (mtmp->mx != omx || mtmp->my != omy)) {
1546 /* If the monster moved, then update */
1553 newsym(mtmp->mx, mtmp->my);
1555 if (OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
1556 /* recompute the likes tests, in case we polymorphed
1557 * or if the "likegold" case got taken above */
1559 int pctload = (curr_mon_load(mtmp) * 100) / max_mon_load(mtmp);
1561 /* look for gold or jewels nearby */
1562 likegold = (likes_gold(ptr) && pctload < 95);
1563 likegems = (likes_gems(ptr) && pctload < 85);
1565 (!mindless(ptr) && !is_animal(ptr) && pctload < 75);
1566 likeobjs = (likes_objs(ptr) && pctload < 75);
1567 likemagic = (likes_magic(ptr) && pctload < 85);
1568 likerock = (throws_rocks(ptr) && pctload < 50 && !Sokoban);
1569 conceals = hides_under(ptr);
1572 /* Maybe a rock mole just ate some metal object */
1573 if (metallivorous(ptr)) {
1574 if (meatmetal(mtmp) == 2)
1575 return 2; /* it died */
1578 if (g_at(mtmp->mx, mtmp->my) && likegold)
1581 /* Maybe a cube ate just about anything */
1582 if (ptr == &mons[PM_GELATINOUS_CUBE]) {
1583 if (meatobj(mtmp) == 2)
1584 return 2; /* it died */
1587 if (!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
1588 boolean picked = FALSE;
1591 picked |= mpickstuff(mtmp, practical);
1593 picked |= mpickstuff(mtmp, magical);
1595 picked |= mpickstuff(mtmp, boulder_class);
1597 picked |= mpickstuff(mtmp, gem_class);
1599 picked |= mpickstuff(mtmp, (char *) 0);
1605 newsym(mtmp->mx, mtmp->my);
1611 if (hides_under(ptr) || ptr->mlet == S_EEL) {
1612 /* Always set--or reset--mundetected if it's already hidden
1613 (just in case the object it was hiding under went away);
1614 usually set mundetected unless monster can't move. */
1615 if (mtmp->mundetected
1616 || (mtmp->mcanmove && !mtmp->msleeping && rn2(5)))
1617 (void) hideunder(mtmp);
1618 newsym(mtmp->mx, mtmp->my);
1621 after_shk_move(mtmp);
1631 levl[x][y].typ = (Is_special(&u.uz) || *in_rooms(x, y, 0)) ? ROOM : CORR;
1632 levl[x][y].flags = 0;
1640 return (boolean) (IS_DOOR(levl[x][y].typ)
1641 && (levl[x][y].doormask & (D_LOCKED | D_CLOSED)));
1648 int levtyp = levl[x][y].typ;
1650 /* use underlying terrain in front of closed drawbridge */
1651 if (levtyp == DRAWBRIDGE_UP)
1652 levtyp = db_under_typ(levl[x][y].drawbridgemask);
1654 return (boolean) (ACCESSIBLE(levtyp) && !closed_door(x, y));
1657 /* decide where the monster thinks you are standing */
1660 register struct monst *mtmp;
1662 boolean notseen, gotu;
1663 register int disp, mx = mtmp->mux, my = mtmp->muy;
1664 long umoney = money_cnt(invent);
1667 * do cheapest and/or most likely tests first
1670 /* pet knows your smell; grabber still has hold of you */
1671 if (mtmp->mtame || mtmp == u.ustuck)
1674 /* monsters which know where you are don't suddenly forget,
1675 if you haven't moved away */
1676 if (mx == u.ux && my == u.uy)
1679 notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data)));
1680 /* add cases as required. eg. Displacement ... */
1681 if (notseen || Underwater) {
1682 /* Xorns can smell quantities of valuable metal
1683 like that in solid gold coins, treat as seen */
1684 if ((mtmp->data == &mons[PM_XORN]) && umoney && !Underwater)
1688 } else if (Displaced) {
1689 disp = couldsee(mx, my) ? 2 : 1;
1695 /* without something like the following, invisibility and displacement
1697 gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE;
1700 register int try_cnt = 0;
1703 if (++try_cnt > 200)
1704 goto found_you; /* punt */
1705 mx = u.ux - disp + rn2(2 * disp + 1);
1706 my = u.uy - disp + rn2(2 * disp + 1);
1707 } while (!isok(mx, my)
1708 || (disp != 2 && mx == mtmp->mx && my == mtmp->my)
1709 || ((mx != u.ux || my != u.uy) && !passes_walls(mtmp->data)
1710 && !(accessible(mx, my)
1711 || (closed_door(mx, my)
1712 && (can_ooze(mtmp) || can_fog(mtmp)))))
1713 || !couldsee(mx, my));
1725 * mon-to-mon displacement is a deliberate "get out of my way" act,
1726 * not an accidental bump, so we don't consider mstun or mconf in
1729 * We do consider many other things about the target and its
1733 undesirable_disp(mtmp, x, y)
1734 struct monst *mtmp; /* barging creature */
1735 xchar x, y; /* spot 'mtmp' is considering moving to */
1737 boolean is_pet = (mtmp && mtmp->mtame && !mtmp->isminion);
1738 struct trap *trap = t_at(x, y);
1741 /* Pets avoid a trap if you've seen it usually. */
1742 if (trap && trap->tseen && rn2(40))
1744 /* Pets avoid cursed locations */
1745 if (cursed_object_at(x, y))
1748 /* Monsters avoid a trap if they've seen that type before */
1749 } else if (trap && rn2(40)
1750 && (mtmp->mtrapseen & (1 << (trap->ttyp - 1))) != 0) {
1754 /* oversimplification: creatures that bargethrough can't swap places
1755 when target monster is in rock or closed door or water (in particular,
1756 avoid moving to spots where mondied() won't leave a corpse; doesn't
1757 matter whether barger is capable of moving to such a target spot if
1758 it were unoccupied) */
1759 if (!accessible(x, y)
1760 /* mondied() allows is_pool() as an exception to !accessible(),
1761 but we'll only do that if 'mtmp' is already at a water location
1762 so that we don't swap a water critter onto land */
1763 && !(is_pool(x, y) && is_pool(mtmp->mx, mtmp->my)))
1770 * Inventory prevents passage under door.
1771 * Used by can_ooze() and can_fog().
1774 stuff_prevents_passage(mtmp)
1777 struct obj *chain, *obj;
1779 if (mtmp == &youmonst) {
1782 chain = mtmp->minvent;
1784 for (obj = chain; obj; obj = obj->nobj) {
1785 int typ = obj->otyp;
1787 if (typ == COIN_CLASS && obj->quan > 100L)
1789 if (obj->oclass != GEM_CLASS && !(typ >= ARROW && typ <= BOOMERANG)
1790 && !(typ >= DAGGER && typ <= CRYSKNIFE) && typ != SLING
1791 && !is_cloak(obj) && typ != FEDORA && !is_gloves(obj)
1792 && typ != LEATHER_JACKET && typ != CREDIT_CARD && !is_shirt(obj)
1793 && !(typ == CORPSE && verysmall(&mons[obj->corpsenm]))
1794 && typ != FORTUNE_COOKIE && typ != CANDY_BAR && typ != PANCAKE
1795 && typ != LEMBAS_WAFER && typ != LUMP_OF_ROYAL_JELLY
1796 && obj->oclass != AMULET_CLASS && obj->oclass != RING_CLASS
1797 && obj->oclass != VENOM_CLASS && typ != SACK
1798 && typ != BAG_OF_HOLDING && typ != BAG_OF_TRICKS
1799 && !Is_candle(obj) && typ != OILSKIN_SACK && typ != LEASH
1800 && typ != STETHOSCOPE && typ != BLINDFOLD && typ != TOWEL
1801 && typ != TIN_WHISTLE && typ != MAGIC_WHISTLE
1802 && typ != MAGIC_MARKER && typ != TIN_OPENER && typ != SKELETON_KEY
1803 && typ != LOCK_PICK)
1805 if (Is_container(obj) && obj->cobj)
1815 if (!amorphous(mtmp->data) || stuff_prevents_passage(mtmp))
1820 /* monster can change form into a fog if necessary */
1825 if (!(mvitals[PM_FOG_CLOUD].mvflags & G_GENOD) && is_vampshifter(mtmp)
1826 && !Protection_from_shape_changers && !stuff_prevents_passage(mtmp))
1832 vamp_shift(mon, ptr, domsg)
1834 struct permonst *ptr;
1838 char oldmtype[BUFSZ];
1840 /* remember current monster type before shapechange */
1841 Strcpy(oldmtype, domsg ? noname_monnam(mon, ARTICLE_THE) : "");
1843 if (mon->data == ptr) {
1844 /* already right shape */
1847 } else if (is_vampshifter(mon)) {
1848 reslt = newcham(mon, ptr, FALSE, FALSE);
1851 if (reslt && domsg) {
1853 pline("You %s %s where %s was.",
1854 !canseemon(mon) ? "now detect" : "observe",
1855 noname_monnam(mon, ARTICLE_A), oldmtype);
1857 pline("
\82 \82È
\82½
\82Í%s
\82ª
\82¢
\82½
\8fê
\8f\8a\82É%s
\82ð%s
\81D",
1858 oldmtype, noname_monnam(mon, ARTICLE_A),
1859 !canseemon(mon) ? "
\8a´
\92m
\82µ
\82½" : "
\8c©
\82Â
\82¯
\82½");
1861 /* this message is given when it turns into a fog cloud
1862 in order to move under a closed door */
1863 display_nhwindow(WIN_MESSAGE, FALSE);