1 /* SCCS Id: @(#)monmove.c 3.3 2000/07/24 */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
4
5 #include "hack.h"
6 #include "mfndpos.h"
7 #include "artifact.h"
8
9 extern boolean notonhead;
10
11 #ifdef OVL0
12
13 STATIC_DCL int FDECL(disturb,(struct monst *));
14 STATIC_DCL void FDECL(distfleeck,(struct monst *,int *,int *,int *));
15 STATIC_DCL int FDECL(m_arrival, (struct monst *));
16 STATIC_DCL void FDECL(watch_on_duty,(struct monst *));
17
18 #endif /* OVL0 */
19 #ifdef OVLB
20
21 boolean /* TRUE : mtmp died */
mb_trapped(mtmp)22 mb_trapped(mtmp)
23 register struct monst *mtmp;
24 {
25 if (flags.verbose) {
26 if (cansee(mtmp->mx, mtmp->my))
27 pline("KABOOM!! You see a door explode.");
28 else if (flags.soundok)
29 You_hear("a distant explosion.");
30 }
31 wake_nearto(mtmp->mx, mtmp->my, 7*7);
32 mtmp->mstun = 1;
33 mtmp->mhp -= rnd(15);
34 if(mtmp->mhp <= 0) {
35 mondied(mtmp);
36 if (mtmp->mhp > 0) /* lifesaved */
37 return(FALSE);
38 else
39 return(TRUE);
40 }
41 return(FALSE);
42 }
43
44 #endif /* OVLB */
45 #ifdef OVL0
46
47 STATIC_OVL void
watch_on_duty(mtmp)48 watch_on_duty(mtmp)
49 register struct monst *mtmp;
50 {
51 register s_level *slev = Is_special(&u.uz);
52 int x, y;
53
54 if(slev && slev->flags.town && mtmp->mpeaceful &&
55 mtmp->mcansee && m_canseeu(mtmp) && !rn2(3)) {
56
57 if(picking_lock(&x, &y) && IS_DOOR(levl[x][y].typ) &&
58 (levl[x][y].doormask & D_LOCKED)) {
59
60 if(couldsee(mtmp->mx, mtmp->my)) {
61
62 pline("%s yells:", Amonnam(mtmp));
63 if(levl[x][y].looted & D_WARNED) {
64 verbalize("Halt, thief! You're under arrest!");
65 (void) angry_guards(!(flags.soundok));
66 } else {
67 verbalize("Hey, stop picking that lock!");
68 levl[x][y].looted |= D_WARNED;
69 }
70 stop_occupation();
71 }
72 }
73 }
74 }
75
76 #endif /* OVL0 */
77 #ifdef OVL1
78
79 int
dochugw(mtmp)80 dochugw(mtmp)
81 register struct monst *mtmp;
82 {
83 register int x = mtmp->mx, y = mtmp->my;
84 boolean already_saw_mon = !occupation ? 0 : canspotmon(mtmp);
85 int rd = dochug(mtmp);
86 #if 0
87 /* part of the original warning code which was replaced in 3.3.1 */
88 int dd;
89
90 if(Warning && !rd && !mtmp->mpeaceful &&
91 (dd = distu(mtmp->mx,mtmp->my)) < distu(x,y) &&
92 dd < 100 && !canseemon(mtmp)) {
93 /* Note: this assumes we only want to warn against the monster to
94 * which the weapon does extra damage, as there is no "monster
95 * which the weapon warns against" field.
96 */
97 if (spec_ability(uwep, SPFX_WARN) && spec_dbon(uwep, mtmp, 1))
98 warnlevel = 100;
99 else if ((int) (mtmp->m_lev / 4) > warnlevel)
100 warnlevel = (mtmp->m_lev / 4);
101 }
102 #endif /* 0 */
103
104 /* a similar check is in monster_nearby() in hack.c */
105 /* check whether hero notices monster and stops current activity */
106 if (occupation && !rd && !Confusion &&
107 (!mtmp->mpeaceful || Hallucination) &&
108 /* it's close enough to be a threat */
109 distu(mtmp->mx,mtmp->my) <= (BOLT_LIM+1)*(BOLT_LIM+1) &&
110 /* and either couldn't see it before, or it was too far away */
111 (!already_saw_mon || !couldsee(x,y) ||
112 distu(x,y) > (BOLT_LIM+1)*(BOLT_LIM+1)) &&
113 /* can see it now, or sense it and would normally see it */
114 (canseemon(mtmp) ||
115 (sensemon(mtmp) && couldsee(mtmp->mx,mtmp->my))) &&
116 !noattacks(mtmp->data) && !onscary(u.ux, u.uy, mtmp))
117 stop_occupation();
118
119 return(rd);
120 }
121
122 #endif /* OVL1 */
123 #ifdef OVL2
124
125 boolean
onscary(x,y,mtmp)126 onscary(x, y, mtmp)
127 int x, y;
128 struct monst *mtmp;
129 {
130 if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
131 mtmp->mpeaceful || mtmp->data->mlet == S_HUMAN ||
132 is_lminion(mtmp->data) || is_rider(mtmp->data) ||
133 mtmp->data == &mons[PM_MINOTAUR])
134 return(FALSE);
135
136 return (boolean)(sobj_at(SCR_SCARE_MONSTER, x, y)
137 #ifdef ELBERETH
138 || sengr_at("Elbereth", x, y)
139 #endif
140 || (mtmp->data->mlet == S_VAMPIRE
141 && IS_ALTAR(levl[x][y].typ)));
142 }
143
144 #endif /* OVL2 */
145 #ifdef OVL0
146
147 /* regenerate lost hit points */
148 void
mon_regen(mon,digest_meal)149 mon_regen(mon, digest_meal)
150 struct monst *mon;
151 boolean digest_meal;
152 {
153 if (mon->mhp < mon->mhpmax &&
154 (moves % 20 == 0 || regenerates(mon->data))) mon->mhp++;
155 if (mon->mspec_used) mon->mspec_used--;
156 if (digest_meal) {
157 if (mon->meating) mon->meating--;
158 }
159 }
160
161 /*
162 * Possibly awaken the given monster. Return a 1 if the monster has been
163 * jolted awake.
164 */
165 STATIC_OVL int
disturb(mtmp)166 disturb(mtmp)
167 register struct monst *mtmp;
168 {
169 /*
170 * + Ettins are hard to surprise.
171 * + Nymphs, jabberwocks, and leprechauns do not easily wake up.
172 *
173 * Wake up if:
174 * in direct LOS AND
175 * within 10 squares AND
176 * not stealthy or (mon is an ettin and 9/10) AND
177 * (mon is not a nymph, jabberwock, or leprechaun) or 1/50 AND
178 * Aggravate or mon is (dog or human) or
179 * (1/7 and mon is not mimicing furniture or object)
180 */
181 if(couldsee(mtmp->mx,mtmp->my) &&
182 distu(mtmp->mx,mtmp->my) <= 100 &&
183 (!Stealth || (mtmp->data == &mons[PM_ETTIN] && rn2(10))) &&
184 (!(mtmp->data->mlet == S_NYMPH
185 || mtmp->data == &mons[PM_JABBERWOCK]
186 #if 0 /* DEFERRED */
187 || mtmp->data == &mons[PM_VORPAL_JABBERWOCK]
188 #endif
189 || mtmp->data->mlet == S_LEPRECHAUN) || !rn2(50)) &&
190 (Aggravate_monster
191 || (mtmp->data->mlet == S_DOG ||
192 mtmp->data->mlet == S_HUMAN)
193 || (!rn2(7) && mtmp->m_ap_type != M_AP_FURNITURE &&
194 mtmp->m_ap_type != M_AP_OBJECT) )) {
195 mtmp->msleeping = 0;
196 return(1);
197 }
198 return(0);
199 }
200
201 STATIC_OVL void
distfleeck(mtmp,inrange,nearby,scared)202 distfleeck(mtmp,inrange,nearby,scared)
203 register struct monst *mtmp;
204 int *inrange, *nearby, *scared;
205 {
206 int seescaryx, seescaryy;
207
208 *inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
209 (BOLT_LIM * BOLT_LIM));
210 *nearby = *inrange && monnear(mtmp, mtmp->mux, mtmp->muy);
211
212 /* Note: if your image is displaced, the monster sees the Elbereth
213 * at your displaced position, thus never attacking your displaced
214 * position, but possibly attacking you by accident. If you are
215 * invisible, it sees the Elbereth at your real position, thus never
216 * running into you by accident but possibly attacking the spot
217 * where it guesses you are.
218 */
219 if (!mtmp->mcansee || (Invis && !perceives(mtmp->data))) {
220 seescaryx = mtmp->mux;
221 seescaryy = mtmp->muy;
222 } else {
223 seescaryx = u.ux;
224 seescaryy = u.uy;
225 }
226 *scared = (*nearby && (onscary(seescaryx, seescaryy, mtmp) ||
227 (!mtmp->mpeaceful &&
228 in_your_sanctuary(mtmp, 0, 0))));
229
230 if(*scared && !mtmp->mflee) {
231 if (!sticks(youmonst.data))
232 unstuck(mtmp); /* monster lets go when fleeing */
233 mtmp->mflee = 1;
234 #ifdef STUPID
235 if (rn2(7))
236 mtmp->mfleetim = rnd(10);
237 else
238 mtmp->mfleetim = rnd(100);
239 #else
240 mtmp->mfleetim = rnd(rn2(7) ? 10 : 100);
241 #endif
242 }
243
244 }
245
246 /* perform a special one-time action for a monster; returns -1 if nothing
247 special happened, 0 if monster uses up its turn, 1 if monster is killed */
248 STATIC_OVL int
m_arrival(mon)249 m_arrival(mon)
250 struct monst *mon;
251 {
252 mon->mstrategy &= ~STRAT_ARRIVE; /* always reset */
253
254 return -1;
255 }
256
257 /* returns 1 if monster died moving, 0 otherwise */
258 /* The whole dochugw/m_move/distfleeck/mfndpos section is serious spaghetti
259 * code. --KAA
260 */
261 int
dochug(mtmp)262 dochug(mtmp)
263 register struct monst *mtmp;
264 {
265 register struct permonst *mdat;
266 register int tmp=0;
267 int inrange, nearby, scared;
268
269 /* Pre-movement adjustments */
270
271 mdat = mtmp->data;
272
273 if (mtmp->mstrategy & STRAT_ARRIVE) {
274 int res = m_arrival(mtmp);
275 if (res >= 0) return res;
276 }
277
278 /* check for waitmask status change */
279 if ((mtmp->mstrategy & STRAT_WAITFORU) &&
280 (m_canseeu(mtmp) || mtmp->mhp < mtmp->mhpmax))
281 mtmp->mstrategy &= ~STRAT_WAITFORU;
282
283 /* update quest status flags */
284 quest_stat_check(mtmp);
285
286 if (!mtmp->mcanmove || (mtmp->mstrategy & STRAT_WAITMASK)) {
287 if (Hallucination) newsym(mtmp->mx,mtmp->my);
288 if (mtmp->mcanmove && (mtmp->mstrategy & STRAT_CLOSE) &&
289 !mtmp->msleeping && monnear(mtmp, u.ux, u.uy))
290 quest_talk(mtmp); /* give the leaders a chance to speak */
291 return(0); /* other frozen monsters can't do anything */
292 }
293
294 /* there is a chance we will wake it */
295 if (mtmp->msleeping && !disturb(mtmp)) {
296 if (Hallucination) newsym(mtmp->mx,mtmp->my);
297 return(0);
298 }
299
300 /* not frozen or sleeping: wipe out texts written in the dust */
301 wipe_engr_at(mtmp->mx, mtmp->my, 1);
302
303 /* confused monsters get unconfused with small probability */
304 if (mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
305
306 /* stunned monsters get un-stunned with larger probability */
307 if (mtmp->mstun && !rn2(10)) mtmp->mstun = 0;
308
309 /* some monsters teleport */
310 if (mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz &&
311 !level.flags.noteleport) {
312 rloc(mtmp);
313 return(0);
314 }
315 if (mdat->msound == MS_SHRIEK && !um_dist(mtmp->mx, mtmp->my, 1))
316 m_respond(mtmp);
317 if (mdat == &mons[PM_MEDUSA] && cansee(mtmp->mx, mtmp->my))
318 m_respond(mtmp);
319 if (mtmp->mhp <= 0) return(1); /* m_respond gaze can kill medusa */
320
321 /* fleeing monsters might regain courage */
322 if (mtmp->mflee && !mtmp->mfleetim
323 && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0;
324
325 set_apparxy(mtmp);
326 /* Must be done after you move and before the monster does. The
327 * set_apparxy() call in m_move() doesn't suffice since the variables
328 * inrange, etc. all depend on stuff set by set_apparxy().
329 */
330
331 /* Monsters that want to acquire things */
332 /* may teleport, so do it before inrange is set */
333 if(is_covetous(mdat)) (void) tactics(mtmp);
334
335 /* check distance and scariness of attacks */
336 distfleeck(mtmp,&inrange,&nearby,&scared);
337
338 if(find_defensive(mtmp)) {
339 if (use_defensive(mtmp) != 0)
340 return 1;
341 } else if(find_misc(mtmp)) {
342 if (use_misc(mtmp) != 0)
343 return 1;
344 }
345
346 /* Demonic Blackmail! */
347 if(nearby && mdat->msound == MS_BRIBE &&
348 mtmp->mpeaceful && !mtmp->mtame && !u.uswallow) {
349 if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
350 pline("%s whispers at thin air.",
351 cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
352
353 if (is_demon(youmonst.data)) {
354 /* "Good hunting, brother" */
355 if (!tele_restrict(mtmp)) rloc(mtmp);
356 } else {
357 mtmp->minvis = mtmp->perminvis = 0;
358 /* Why? For the same reason in real demon talk */
359 pline("%s gets angry!", Amonnam(mtmp));
360 mtmp->mpeaceful = 0;
361 /* since no way is an image going to pay it off */
362 }
363 } else if(demon_talk(mtmp)) return(1); /* you paid it off */
364 }
365
366 /* the watch will look around and see if you are up to no good :-) */
367 if (mdat == &mons[PM_WATCHMAN] || mdat == &mons[PM_WATCH_CAPTAIN])
368 watch_on_duty(mtmp);
369
370 else if (is_mind_flayer(mdat) && !rn2(20)) {
371 struct monst *m2, *nmon = (struct monst *)0;
372
373 if (canseemon(mtmp))
374 pline("%s concentrates.", Monnam(mtmp));
375 if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM) {
376 You("sense a faint wave of psychic energy.");
377 goto toofar;
378 }
379 pline("A wave of psychic energy pours over you!");
380 if (mtmp->mpeaceful &&
381 (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))
382 pline("It feels quite soothing.");
383 else {
384 register boolean m_sen = sensemon(mtmp);
385
386 if (m_sen || (Blind_telepat && rn2(2)) || !rn2(10)) {
387 int dmg;
388 pline("It locks on to your %s!",
389 m_sen ? "telepathy" :
390 Blind_telepat ? "latent telepathy" : "mind");
391 dmg = rnd(15);
392 if (Half_spell_damage) dmg = (dmg+1) / 2;
393 losehp(dmg, "psychic blast", KILLED_BY_AN);
394 }
395 }
396 for(m2=fmon; m2; m2 = nmon) {
397 nmon = m2->nmon;
398 if (DEADMONSTER(m2)) continue;
399 if (m2->mpeaceful == mtmp->mpeaceful) continue;
400 if (mindless(m2->data)) continue;
401 if (m2 == mtmp) continue;
402 if ((telepathic(m2->data) &&
403 (rn2(2) || m2->mblinded)) || !rn2(10)) {
404 if (cansee(m2->mx, m2->my))
405 pline("It locks on to %s.", mon_nam(m2));
406 m2->mhp -= rnd(15);
407 if (m2->mhp <= 0)
408 monkilled(m2, "", AD_DRIN);
409 }
410 }
411 }
412 toofar:
413 /* If monster is nearby you, and has to wield a weapon, do so. This
414 * costs the monster a move, of course.
415 */
416 if((!mtmp->mpeaceful || Conflict) && inrange &&
417 dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <= 8
418 && attacktype(mdat, AT_WEAP)) {
419 struct obj *mw_tmp;
420
421 /* The scared check is necessary. Otherwise a monster that is
422 * one square near the player but fleeing into a wall would keep
423 * switching between pick-axe and weapon.
424 */
425 mw_tmp = MON_WEP(mtmp);
426 if (!(scared && mw_tmp && is_pick(mw_tmp)) &&
427 mtmp->weapon_check == NEED_WEAPON) {
428 mtmp->weapon_check = NEED_HTH_WEAPON;
429 if (mon_wield_item(mtmp) != 0) return(0);
430 }
431 }
432
433 /* Now the actual movement phase */
434
435 if(!nearby || mtmp->mflee || scared ||
436 mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
437 (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
438 (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) ||
439 (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
440
441 tmp = m_move(mtmp, 0);
442 distfleeck(mtmp,&inrange,&nearby,&scared); /* recalc */
443
444 switch (tmp) {
445 case 0: /* no movement, but it can still attack you */
446 case 3: /* absolutely no movement */
447 /* for pets, case 0 and 3 are equivalent */
448 /* During hallucination, monster appearance should
449 * still change - even if it doesn't move.
450 */
451 if(Hallucination) newsym(mtmp->mx,mtmp->my);
452 break;
453 case 1: /* monster moved */
454 /* Maybe it stepped on a trap and fell asleep... */
455 if (mtmp->msleeping || !mtmp->mcanmove) return(0);
456 if(!nearby &&
457 (ranged_attk(mdat) || find_offensive(mtmp)))
458 break;
459 else if(u.uswallow && mtmp == u.ustuck) {
460 /* a monster that's digesting you can move at the
461 * same time -dlc
462 */
463 return(mattacku(mtmp));
464 } else
465 return(0);
466 /*NOTREACHED*/
467 break;
468 case 2: /* monster died */
469 return(1);
470 }
471 }
472
473 /* Now, attack the player if possible - one attack set per monst */
474
475 if (!mtmp->mpeaceful ||
476 (Conflict && !resist(mtmp, RING_CLASS, 0, 0))) {
477 if(inrange && !noattacks(mdat) && u.uhp > 0 && !scared && tmp != 3)
478 if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */
479
480 if(mtmp->wormno) wormhitu(mtmp);
481 }
482 /* special speeches for quest monsters */
483 if (!mtmp->msleeping && mtmp->mcanmove && nearby)
484 quest_talk(mtmp);
485 /* extra emotional attack for vile monsters */
486 if (inrange && mtmp->data->msound == MS_CUSS && !mtmp->mpeaceful &&
487 couldsee(mtmp->mx, mtmp->my) && !mtmp->minvis && !rn2(5))
488 cuss(mtmp);
489
490 return(tmp == 2);
491 }
492
493 static NEARDATA const char practical[] = { WEAPON_CLASS, ARMOR_CLASS, GEM_CLASS, FOOD_CLASS, 0 };
494 static NEARDATA const char magical[] = {
495 AMULET_CLASS, POTION_CLASS, SCROLL_CLASS, WAND_CLASS, RING_CLASS,
496 SPBOOK_CLASS, 0 };
497 static NEARDATA const char indigestion[] = { BALL_CLASS, ROCK_CLASS, 0 };
498 static NEARDATA const char boulder_class[] = { ROCK_CLASS, 0 };
499 static NEARDATA const char gem_class[] = { GEM_CLASS, 0 };
500
501 boolean
itsstuck(mtmp)502 itsstuck(mtmp)
503 register struct monst *mtmp;
504 {
505 if (sticks(youmonst.data) && mtmp==u.ustuck && !u.uswallow) {
506 pline("%s cannot escape from you!", Monnam(mtmp));
507 return(TRUE);
508 }
509 return(FALSE);
510 }
511
512 /* Return values:
513 * 0: did not move, but can still attack and do other stuff.
514 * 1: moved, possibly can attack.
515 * 2: monster died.
516 * 3: did not move, and can't do anything else either.
517 */
518 int
m_move(mtmp,after)519 m_move(mtmp, after)
520 register struct monst *mtmp;
521 register int after;
522 {
523 register int appr;
524 xchar gx,gy,nix,niy,chcnt;
525 int chi; /* could be schar except for stupid Sun-2 compiler */
526 boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0;
527 boolean likerock=0, can_tunnel=0;
528 boolean can_open=0, can_unlock=0, doorbuster=0;
529 boolean uses_items=0;
530 struct permonst *ptr;
531 struct monst *mtoo;
532 schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
533 long info[9];
534 long flag;
535 int omx = mtmp->mx, omy = mtmp->my;
536 struct obj *mw_tmp;
537
538 if(mtmp->mtrapped) {
539 int i = mintrap(mtmp);
540 if(i >= 2) { newsym(mtmp->mx,mtmp->my); return(2); }/* it died */
541 if(i == 1) return(0); /* still in trap, so didn't move */
542 }
543 ptr = mtmp->data; /* mintrap() can change mtmp->data -dlc */
544
545 if (mtmp->meating) {
546 mtmp->meating--;
547 return 3; /* still eating */
548 }
549 if (hides_under(ptr) && OBJ_AT(mtmp->mx, mtmp->my) && rn2(10))
550 return 0; /* do not leave hiding place */
551
552 set_apparxy(mtmp);
553 /* where does mtmp think you are? */
554 /* Not necessary if m_move called from this file, but necessary in
555 * other calls of m_move (ex. leprechauns dodging)
556 */
557 can_tunnel = tunnels(ptr) &&
558 #ifdef REINCARNATION
559 !Is_rogue_level(&u.uz) &&
560 #endif
561 (!needspick(ptr) || m_carrying(mtmp, PICK_AXE) ||
562 (m_carrying(mtmp, DWARVISH_MATTOCK) && !which_armor(mtmp, W_ARMS)));
563 can_open = !(nohands(ptr) || verysmall(ptr));
564 can_unlock = ((can_open && m_carrying(mtmp, SKELETON_KEY)) ||
565 mtmp->iswiz || is_rider(ptr));
566 doorbuster = is_giant(ptr);
567 if(mtmp->wormno) goto not_special;
568 /* my dog gets special treatment */
569 if(mtmp->mtame) {
570 mmoved = dog_move(mtmp, after);
571 goto postmov;
572 }
573
574 /* likewise for shopkeeper */
575 if(mtmp->isshk) {
576 mmoved = shk_move(mtmp);
577 if(mmoved == -2) return(2);
578 if(mmoved >= 0) goto postmov;
579 mmoved = 0; /* follow player outside shop */
580 }
581
582 /* and for the guard */
583 if(mtmp->isgd) {
584 mmoved = gd_move(mtmp);
585 if(mmoved == -2) return(2);
586 if(mmoved >= 0) goto postmov;
587 mmoved = 0;
588 }
589
590 /* and the acquisitive monsters get special treatment */
591 if(is_covetous(ptr)) {
592 xchar tx = STRAT_GOALX(mtmp->mstrategy),
593 ty = STRAT_GOALY(mtmp->mstrategy);
594 struct monst *intruder = m_at(tx, ty);
595 /*
596 * if there's a monster on the object or in possesion of it,
597 * attack it.
598 */
599 if((dist2(mtmp->mx, mtmp->my, tx, ty) < 2) &&
600 intruder && (intruder != mtmp)) {
601
602 notonhead = (intruder->mx != tx || intruder->my != ty);
603 if(mattackm(mtmp, intruder) == 2) return(2);
604 mmoved = 1;
605 } else mmoved = 0;
606 goto postmov;
607 }
608
609 /* and for the priest */
610 if(mtmp->ispriest) {
611 mmoved = pri_move(mtmp);
612 if(mmoved == -2) return(2);
613 if(mmoved >= 0) goto postmov;
614 mmoved = 0;
615 }
616
617 #ifdef MAIL
618 if(ptr == &mons[PM_MAIL_DAEMON]) {
619 if(flags.soundok && canseemon(mtmp))
620 verbalize("I'm late!");
621 mongone(mtmp);
622 return(2);
623 }
624 #endif
625
626 /* teleport if that lies in our nature */
627 if(ptr == &mons[PM_TENGU] && !rn2(5) && !mtmp->mcan &&
628 !tele_restrict(mtmp)) {
629 if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
630 rloc(mtmp);
631 else
632 mnexto(mtmp);
633 mmoved = 1;
634 goto postmov;
635 }
636 not_special:
637 if(u.uswallow && !mtmp->mflee && u.ustuck != mtmp) return(1);
638 omx = mtmp->mx;
639 omy = mtmp->my;
640 gx = mtmp->mux;
641 gy = mtmp->muy;
642 appr = mtmp->mflee ? -1 : 1;
643 if (mtmp->mconf || (u.uswallow && mtmp == u.ustuck))
644 appr = 0;
645 else {
646 boolean should_see = (couldsee(omx, omy) &&
647 (levl[gx][gy].lit ||
648 !levl[omx][omy].lit) &&
649 (dist2(omx, omy, gx, gy) <= 36));
650
651 if (!mtmp->mcansee ||
652 (should_see && Invis && !perceives(ptr) && rn2(11)) ||
653 (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == STRANGE_OBJECT) || u.uundetected ||
654 (youmonst.m_ap_type == M_AP_OBJECT && youmonst.mappearance == GOLD_PIECE && !likes_gold(ptr)) ||
655 (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */
656 ((monsndx(ptr) == PM_STALKER || ptr->mlet == S_BAT ||
657 ptr->mlet == S_LIGHT) && !rn2(3)))
658 appr = 0;
659
660 if(monsndx(ptr) == PM_LEPRECHAUN && (appr == 1) &&
661 (mtmp->mgold > u.ugold))
662 appr = -1;
663
664 if (!should_see && can_track(ptr)) {
665 register coord *cp;
666
667 cp = gettrack(omx,omy);
668 if (cp) {
669 gx = cp->x;
670 gy = cp->y;
671 }
672 }
673 }
674
675 if ((!mtmp->mpeaceful || !rn2(10))
676 #ifdef REINCARNATION
677 && (!Is_rogue_level(&u.uz))
678 #endif
679 ) {
680 boolean in_line = lined_up(mtmp) &&
681 (distmin(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
682 (throws_rocks(youmonst.data) ? 20 : ACURRSTR/2+1)
683 );
684
685 if (appr != 1 || !in_line) {
686 /* Monsters in combat won't pick stuff up, avoiding the
687 * situation where you toss arrows at it and it has nothing
688 * better to do than pick the arrows up.
689 */
690 register int pctload = (curr_mon_load(mtmp) * 100) /
691 max_mon_load(mtmp);
692
693 /* look for gold or jewels nearby */
694 likegold = (likes_gold(ptr) && pctload < 95);
695 likegems = (likes_gems(ptr) && pctload < 85);
696 uses_items = (!mindless(ptr) && !is_animal(ptr)
697 && pctload < 75);
698 likeobjs = (likes_objs(ptr) && pctload < 75);
699 likemagic = (likes_magic(ptr) && pctload < 85);
700 likerock = (throws_rocks(ptr) && pctload < 50 && !In_sokoban(&u.uz));
701 conceals = hides_under(ptr);
702 }
703 }
704
705 #define SQSRCHRADIUS 5
706
707 { register int minr = SQSRCHRADIUS; /* not too far away */
708 register struct obj *otmp;
709 register int xx, yy;
710 int oomx, oomy, lmx, lmy;
711
712 /* cut down the search radius if it thinks character is closer. */
713 if(distmin(mtmp->mux, mtmp->muy, omx, omy) < SQSRCHRADIUS &&
714 !mtmp->mpeaceful) minr--;
715 /* guards shouldn't get too distracted */
716 if(!mtmp->mpeaceful && is_mercenary(ptr)) minr = 1;
717
718 if((likegold || likegems || likeobjs || likemagic || likerock || conceals)
719 && (!*in_rooms(omx, omy, SHOPBASE) || (!rn2(25) && !mtmp->isshk))) {
720 look_for_obj:
721 oomx = min(COLNO-1, omx+minr);
722 oomy = min(ROWNO-1, omy+minr);
723 lmx = max(1, omx-minr);
724 lmy = max(0, omy-minr);
725 for(otmp = fobj; otmp; otmp = otmp->nobj) {
726 /* monsters may pick rocks up, but won't go out of their way
727 to grab them; this might hamper sling wielders, but it cuts
728 down on move overhead by filtering out most common item */
729 if (otmp->otyp == ROCK) continue;
730 xx = otmp->ox;
731 yy = otmp->oy;
732 /* Nymphs take everything. Most other creatures should not
733 * pick up corpses except as a special case like in
734 * searches_for_item(). We need to do this check in
735 * mpickstuff() as well.
736 */
737 if(xx >= lmx && xx <= oomx && yy >= lmy && yy <= oomy) {
738 /* don't get stuck circling around an object that's underneath
739 an immobile or hidden monster; paralysis victims excluded */
740 if ((mtoo = m_at(xx,yy)) != 0 &&
741 (mtoo->msleeping || mtoo->mundetected ||
742 (mtoo->mappearance && !mtoo->iswiz) ||
743 !mtoo->data->mmove)) continue;
744
745 if(((likegold && otmp->oclass == GOLD_CLASS) ||
746 (likeobjs && index(practical, otmp->oclass) &&
747 (otmp->otyp != CORPSE || (ptr->mlet == S_NYMPH
748 && !is_rider(&mons[otmp->corpsenm])))) ||
749 (likemagic && index(magical, otmp->oclass)) ||
750 (uses_items && searches_for_item(mtmp, otmp)) ||
751 (likerock && otmp->otyp == BOULDER) ||
752 (likegems && otmp->oclass == GEM_CLASS &&
753 objects[otmp->otyp].oc_material != MINERAL) ||
754 (conceals && !cansee(otmp->ox,otmp->oy)) ||
755 (ptr == &mons[PM_GELATINOUS_CUBE] &&
756 !index(indigestion, otmp->oclass) &&
757 !(otmp->otyp == CORPSE &&
758 touch_petrifies(&mons[otmp->corpsenm])))
759 ) && touch_artifact(otmp,mtmp)) {
760 if(can_carry(mtmp,otmp) &&
761 (throws_rocks(ptr) ||
762 !sobj_at(BOULDER,xx,yy)) &&
763 (!is_unicorn(ptr) ||
764 objects[otmp->otyp].oc_material == GEMSTONE) &&
765 /* Don't get stuck circling an Elbereth */
766 !(onscary(xx, yy, mtmp))) {
767 minr = distmin(omx,omy,xx,yy);
768 oomx = min(COLNO-1, omx+minr);
769 oomy = min(ROWNO-1, omy+minr);
770 lmx = max(1, omx-minr);
771 lmy = max(0, omy-minr);
772 gx = otmp->ox;
773 gy = otmp->oy;
774 if (gx == omx && gy == omy) {
775 mmoved = 3; /* actually unnecessary */
776 goto postmov;
777 }
778 }
779 }
780 }
781 }
782 } else if(likegold) {
783 /* don't try to pick up anything else, but use the same loop */
784 uses_items = 0;
785 likegems = likeobjs = likemagic = likerock = conceals = 0;
786 goto look_for_obj;
787 }
788
789 if(minr < SQSRCHRADIUS && appr == -1) {
790 if(distmin(omx,omy,mtmp->mux,mtmp->muy) <= 3) {
791 gx = mtmp->mux;
792 gy = mtmp->muy;
793 } else
794 appr = 1;
795 }
796 }
797
798 if (can_tunnel && needspick(ptr) &&
799 (mw_tmp = MON_WEP(mtmp)) != 0 && !is_pick(mw_tmp) &&
800 mw_tmp->cursed && mtmp->weapon_check == NO_WEAPON_WANTED)
801 can_tunnel = FALSE;
802
803 nix = omx;
804 niy = omy;
805 flag = 0L;
806 if (mtmp->mpeaceful && (!Conflict || resist(mtmp, RING_CLASS, 0, 0)))
807 flag |= (ALLOW_SANCT | ALLOW_SSM);
808 else flag |= ALLOW_U;
809 if (is_minion(ptr) || is_rider(ptr)) flag |= ALLOW_SANCT;
810 if (is_unicorn(ptr)) flag |= NOTONL;
811 if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK);
812 if (can_tunnel) flag |= ALLOW_DIG;
813 if (is_human(ptr) || ptr == &mons[PM_MINOTAUR]) flag |= ALLOW_SSM;
814 if (is_undead(ptr) && ptr->mlet != S_GHOST) flag |= NOGARLIC;
815 if (throws_rocks(ptr)) flag |= ALLOW_ROCK;
816 if (can_open) flag |= OPENDOOR;
817 if (can_unlock) flag |= UNLOCKDOOR;
818 if (doorbuster) flag |= BUSTDOOR;
819 {
820 register int i, j, nx, ny, nearer;
821 int jcnt, cnt;
822 int ndist, nidist;
823 register coord *mtrk;
824 coord poss[9];
825
826 cnt = mfndpos(mtmp, poss, info, flag);
827 chcnt = 0;
828 jcnt = min(MTSZ, cnt-1);
829 chi = -1;
830 nidist = dist2(nix,niy,gx,gy);
831 /* allow monsters be shortsighted on some levels for balance */
832 if(!mtmp->mpeaceful && level.flags.shortsighted &&
833 nidist > (couldsee(nix,niy) ? 144 : 36) && appr == 1) appr = 0;
834
835 for(i=0; i < cnt; i++) {
836 nx = poss[i].x;
837 ny = poss[i].y;
838
839 if (appr != 0) {
840 mtrk = &mtmp->mtrack[0];
841 for(j=0; j < jcnt; mtrk++, j++)
842 if(nx == mtrk->x && ny == mtrk->y)
843 if(rn2(4*(cnt-j)))
844 goto nxti;
845 }
846
847 nearer = ((ndist = dist2(nx,ny,gx,gy)) < nidist);
848
849 if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
850 (!appr && !rn2(++chcnt)) || !mmoved) {
851 nix = nx;
852 niy = ny;
853 nidist = ndist;
854 chi = i;
855 mmoved = 1;
856 }
857 nxti: ;
858 }
859 }
860
861 if(mmoved) {
862 register int j;
863
864 if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
865 return(3);
866
867 if(IS_ROCK(levl[nix][niy].typ) && may_dig(nix,niy) &&
868 mmoved==1 && can_tunnel && needspick(ptr) &&
869 (!(mw_tmp = MON_WEP(mtmp)) || !is_pick(mw_tmp))) {
870 mtmp->weapon_check = NEED_PICK_AXE;
871 if (mon_wield_item(mtmp))
872 return(3);
873 }
874 /* If ALLOW_U is set, either it's trying to attack you, or it
875 * thinks it is. In either case, attack this spot in preference to
876 * all others.
877 */
878 /* Actually, this whole section of code doesn't work as you'd expect.
879 * Most attacks are handled in dochug(). It calls distfleeck(), which
880 * among other things sets nearby if the monster is near you--and if
881 * nearby is set, we never call m_move unless it is a special case
882 * (confused, stun, etc.) The effect is that this ALLOW_U (and
883 * mfndpos) has no effect for normal attacks, though it lets a confused
884 * monster attack you by accident.
885 */
886 if(info[chi] & ALLOW_U) {
887 nix = mtmp->mux;
888 niy = mtmp->muy;
889 }
890 if (nix == u.ux && niy == u.uy) {
891 mtmp->mux = u.ux;
892 mtmp->muy = u.uy;
893 return(0);
894 }
895 /* The monster may attack another based on 1 of 2 conditions:
896 * 1 - It may be confused.
897 * 2 - It may mistake the monster for your (displaced) image.
898 * Pets get taken care of above and shouldn't reach this code.
899 * Conflict gets handled even farther away (movemon()).
900 */
901 if((info[chi] & ALLOW_M) ||
902 (nix == mtmp->mux && niy == mtmp->muy)) {
903 struct monst *mtmp2;
904 int mstatus;
905 mtmp2 = m_at(nix,niy);
906
907 notonhead = mtmp2 && (nix != mtmp2->mx || niy != mtmp2->my);
908 /* note: mstatus returns 0 if mtmp2 is nonexistent */
909 mstatus = mattackm(mtmp, mtmp2);
910
911 if (mstatus & MM_AGR_DIED) /* aggressor died */
912 return 2;
913
914 if ((mstatus & MM_HIT) && !(mstatus & MM_DEF_DIED) &&
915 rn2(4) && mtmp2->movement >= NORMAL_SPEED) {
916 mtmp2->movement -= NORMAL_SPEED;
917 notonhead = 0;
918 mstatus = mattackm(mtmp2, mtmp); /* return attack */
919 if (mstatus & MM_DEF_DIED)
920 return 2;
921 }
922 return 3;
923 }
924
925 if (!m_in_out_region(mtmp,nix,niy))
926 return 3;
927 remove_monster(omx, omy);
928 place_monster(mtmp, nix, niy);
929 for(j = MTSZ-1; j > 0; j--)
930 mtmp->mtrack[j] = mtmp->mtrack[j-1];
931 mtmp->mtrack[0].x = omx;
932 mtmp->mtrack[0].y = omy;
933 /* Place a segment at the old position. */
934 if (mtmp->wormno) worm_move(mtmp);
935 } else {
936 if(is_unicorn(ptr) && rn2(2) && !tele_restrict(mtmp)) {
937 rloc(mtmp);
938 return(1);
939 }
940 if(mtmp->wormno) worm_nomove(mtmp);
941 }
942 postmov:
943 if(mmoved == 1 || mmoved == 3) {
944 boolean canseeit = cansee(mtmp->mx, mtmp->my);
945
946 if(mmoved == 1) {
947 newsym(omx,omy); /* update the old position */
948 if (mintrap(mtmp) >= 2) {
949 if(mtmp->mx) newsym(mtmp->mx,mtmp->my);
950 return(2); /* it died */
951 }
952 ptr = mtmp->data;
953
954 /* open a door, or crash through it, if you can */
955 if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
956 && !passes_walls(ptr) /* doesn't need to open doors */
957 && !can_tunnel /* taken care of below */
958 ) {
959 struct rm *here = &levl[mtmp->mx][mtmp->my];
960 boolean btrapped = (here->doormask & D_TRAPPED);
961
962 if(here->doormask & (D_LOCKED|D_CLOSED) && amorphous(ptr)) {
963 if (flags.verbose && canseemon(mtmp))
964 pline("%s %ss under the door.", Monnam(mtmp),
965 (ptr == &mons[PM_FOG_CLOUD] ||
966 ptr == &mons[PM_YELLOW_LIGHT])
967 ? "flow" : "ooze");
968 } else if(here->doormask & D_LOCKED && can_unlock) {
969 if(btrapped) {
970 here->doormask = D_NODOOR;
971 newsym(mtmp->mx, mtmp->my);
972 unblock_point(mtmp->mx,mtmp->my); /* vision */
973 if(mb_trapped(mtmp)) return(2);
974 } else {
975 if (flags.verbose) {
976 if (canseeit)
977 You("see a door unlock and open.");
978 else if (flags.soundok)
979 You_hear("a door unlock and open.");
980 }
981 here->doormask = D_ISOPEN;
982 /* newsym(mtmp->mx, mtmp->my); */
983 unblock_point(mtmp->mx,mtmp->my); /* vision */
984 }
985 } else if (here->doormask == D_CLOSED && can_open) {
986 if(btrapped) {
987 here->doormask = D_NODOOR;
988 newsym(mtmp->mx, mtmp->my);
989 unblock_point(mtmp->mx,mtmp->my); /* vision */
990 if(mb_trapped(mtmp)) return(2);
991 } else {
992 if (flags.verbose) {
993 if (canseeit)
994 You("see a door open.");
995 else if (flags.soundok)
996 You_hear("a door open.");
997 }
998 here->doormask = D_ISOPEN;
999 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
1000 unblock_point(mtmp->mx,mtmp->my); /* vision */
1001 }
1002 } else if (here->doormask & (D_LOCKED|D_CLOSED)) {
1003 /* mfndpos guarantees this must be a doorbuster */
1004 if(btrapped) {
1005 here->doormask = D_NODOOR;
1006 newsym(mtmp->mx, mtmp->my);
1007 unblock_point(mtmp->mx,mtmp->my); /* vision */
1008 if(mb_trapped(mtmp)) return(2);
1009 } else {
1010 if (flags.verbose) {
1011 if (canseeit)
1012 You("see a door crash open.");
1013 else if (flags.soundok)
1014 You_hear("a door crash open.");
1015 }
1016 if (here->doormask & D_LOCKED && !rn2(2))
1017 here->doormask = D_NODOOR;
1018 else here->doormask = D_BROKEN;
1019 /* newsym(mtmp->mx, mtmp->my); */ /* done below */
1020 unblock_point(mtmp->mx,mtmp->my); /* vision */
1021 }
1022 /* if it's a shop door, schedule repair */
1023 if (*in_rooms(mtmp->mx, mtmp->my, SHOPBASE))
1024 add_damage(mtmp->mx, mtmp->my, 0L);
1025 }
1026 }
1027
1028 /* possibly dig */
1029 if (can_tunnel && mdig_tunnel(mtmp))
1030 return(2); /* mon died (position already updated) */
1031
1032 /* set also in domove(), hack.c */
1033 if (u.uswallow && mtmp == u.ustuck &&
1034 (mtmp->mx != omx || mtmp->my != omy)) {
1035 /* If the monster moved, then update */
1036 u.ux0 = u.ux;
1037 u.uy0 = u.uy;
1038 u.ux = mtmp->mx;
1039 u.uy = mtmp->my;
1040 swallowed(0);
1041 } else
1042 newsym(mtmp->mx,mtmp->my);
1043 }
1044 if(OBJ_AT(mtmp->mx, mtmp->my) && mtmp->mcanmove) {
1045 /* Maybe a rock mole just ate some metal object */
1046 if (metallivorous(ptr)) {
1047 if (meatgold(mtmp) == 2) return 2; /* it died */
1048 }
1049
1050 if(g_at(mtmp->mx,mtmp->my) && likegold) mpickgold(mtmp);
1051
1052 /* Maybe a cube ate just about anything */
1053 if (ptr == &mons[PM_GELATINOUS_CUBE]) {
1054 if (meatobj(mtmp) == 2) return 2; /* it died */
1055 }
1056
1057 if(!*in_rooms(mtmp->mx, mtmp->my, SHOPBASE) || !rn2(25)) {
1058 boolean picked = FALSE;
1059
1060 if(likeobjs) picked |= mpickstuff(mtmp, practical);
1061 if(likemagic) picked |= mpickstuff(mtmp, magical);
1062 if(likerock) picked |= mpickstuff(mtmp, boulder_class);
1063 if(likegems) picked |= mpickstuff(mtmp, gem_class);
1064 if(uses_items) picked |= mpickstuff(mtmp, (char *)0);
1065 if(picked) mmoved = 3;
1066 }
1067
1068 if(mtmp->minvis) {
1069 newsym(mtmp->mx, mtmp->my);
1070 if (mtmp->wormno) see_wsegs(mtmp);
1071 }
1072 }
1073
1074 if(hides_under(ptr) || ptr->mlet == S_EEL) {
1075 /* Always set--or reset--mundetected if it's already hidden
1076 (just in case the object it was hiding under went away);
1077 usually set mundetected unless monster can't move. */
1078 if (mtmp->mundetected ||
1079 (mtmp->mcanmove && !mtmp->msleeping && rn2(5)))
1080 mtmp->mundetected = (ptr->mlet != S_EEL) ?
1081 OBJ_AT(mtmp->mx, mtmp->my) :
1082 (is_pool(mtmp->mx, mtmp->my) && !Is_waterlevel(&u.uz));
1083 newsym(mtmp->mx, mtmp->my);
1084 }
1085 }
1086 return(mmoved);
1087 }
1088
1089 #endif /* OVL0 */
1090 #ifdef OVL2
1091
1092 boolean
closed_door(x,y)1093 closed_door(x, y)
1094 register int x, y;
1095 {
1096 return((boolean)(IS_DOOR(levl[x][y].typ) &&
1097 (levl[x][y].doormask & (D_LOCKED | D_CLOSED))));
1098 }
1099
1100 boolean
accessible(x,y)1101 accessible(x, y)
1102 register int x, y;
1103 {
1104 return((boolean)(ACCESSIBLE(levl[x][y].typ) && !closed_door(x, y)));
1105 }
1106
1107 #endif /* OVL2 */
1108 #ifdef OVL0
1109
1110 /* decide where the monster thinks you are standing */
1111 void
set_apparxy(mtmp)1112 set_apparxy(mtmp)
1113 register struct monst *mtmp;
1114 {
1115 boolean notseen, gotu;
1116 register int disp, mx = mtmp->mux, my = mtmp->muy;
1117
1118 /*
1119 * do cheapest and/or most likely tests first
1120 */
1121
1122 /* pet knows your smell; grabber still has hold of you */
1123 if (mtmp->mtame || mtmp == u.ustuck) goto found_you;
1124
1125 /* monsters which know where you are don't suddenly forget,
1126 if you haven't moved away */
1127 if (mx == u.ux && my == u.uy) goto found_you;
1128
1129 notseen = (!mtmp->mcansee || (Invis && !perceives(mtmp->data)));
1130 /* add cases as required. eg. Displacement ... */
1131 disp = ((notseen || Underwater) ? 1 :
1132 Displaced ? (couldsee(mx, my) ? 2 : 1) : 0);
1133 if (!disp) goto found_you;
1134
1135 /* without something like the following, invis. and displ.
1136 are too powerful */
1137 gotu = notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE;
1138
1139 #if 0 /* this never worked as intended & isn't needed anyway */
1140 /* If invis but not displaced, staying around gets you 'discovered' */
1141 gotu |= (!Displaced && u.dx == 0 && u.dy == 0);
1142 #endif
1143
1144 if (!gotu) {
1145 register int try_cnt = 0;
1146 do {
1147 if (++try_cnt > 200) goto found_you; /* punt */
1148 mx = u.ux - disp + rn2(2*disp+1);
1149 my = u.uy - disp + rn2(2*disp+1);
1150 } while (!isok(mx,my)
1151 || (disp != 2 && mx == mtmp->mx && my == mtmp->my)
1152 || ((mx != u.ux || my != u.uy) &&
1153 !passes_walls(mtmp->data) &&
1154 (!ACCESSIBLE(levl[mx][my].typ) ||
1155 (closed_door(mx, my) && !can_ooze(mtmp)))));
1156 } else {
1157 found_you:
1158 mx = u.ux;
1159 my = u.uy;
1160 }
1161
1162 mtmp->mux = mx;
1163 mtmp->muy = my;
1164 }
1165
1166 boolean
can_ooze(mtmp)1167 can_ooze(mtmp)
1168 struct monst *mtmp;
1169 {
1170 struct obj *chain, *obj;
1171
1172 if (!amorphous(mtmp->data)) return FALSE;
1173 if (mtmp == &youmonst) {
1174 if (u.ugold > 100L) return FALSE;
1175 chain = invent;
1176 } else {
1177 if (mtmp->mgold > 100L) return FALSE;
1178 chain = mtmp->minvent;
1179 }
1180 for (obj = chain; obj; obj = obj->nobj) {
1181 int typ = obj->otyp;
1182
1183 if (obj->oclass != GEM_CLASS &&
1184 !(typ >= ARROW && typ <= BOOMERANG) &&
1185 !(typ >= DAGGER && typ <= CRYSKNIFE) &&
1186 typ != SLING &&
1187 !is_cloak(obj) && typ != FEDORA &&
1188 !is_gloves(obj) && typ != LEATHER_JACKET &&
1189 #ifdef TOURIST
1190 typ != CREDIT_CARD && !is_shirt(obj) &&
1191 #endif
1192 !(typ == CORPSE && verysmall(&mons[obj->corpsenm])) &&
1193 typ != FORTUNE_COOKIE && typ != CANDY_BAR &&
1194 typ != PANCAKE && typ != LEMBAS_WAFER &&
1195 typ != LUMP_OF_ROYAL_JELLY &&
1196 obj->oclass != AMULET_CLASS &&
1197 obj->oclass != RING_CLASS &&
1198 #ifdef WIZARD
1199 obj->oclass != VENOM_CLASS &&
1200 #endif
1201 typ != SACK && typ != BAG_OF_HOLDING &&
1202 typ != BAG_OF_TRICKS && !Is_candle(obj) &&
1203 typ != OILSKIN_SACK && typ != LEASH &&
1204 typ != STETHOSCOPE && typ != BLINDFOLD && typ != TOWEL &&
1205 typ != TIN_WHISTLE && typ != MAGIC_WHISTLE &&
1206 typ != MAGIC_MARKER && typ != TIN_OPENER &&
1207 typ != SKELETON_KEY && typ != LOCK_PICK
1208 ) return FALSE;
1209 if (Is_container(obj) && obj->cobj) return FALSE;
1210
1211 }
1212 return TRUE;
1213 }
1214
1215 #endif /* OVL0 */
1216
1217 /*monmove.c*/
1218