OSDN Git Service

update year to 2020
[jnethack/source.git] / src / mondata.c
1 /* NetHack 3.6  mondata.c       $NHDT-Date: 1550525093 2019/02/18 21:24:53 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /*-Copyright (c) Robert Patrick Rankin, 2011. */
4 /* NetHack may be freely redistributed.  See license for details. */
5
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000  */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2020            */
9 /* JNetHack may be freely redistributed.  See license for details. */
10
11 #include "hack.h"
12 /*
13  *      These routines provide basic data for any type of monster.
14  */
15
16 /* set up an individual monster's base type (initial creation, shapechange) */
17 void
18 set_mon_data(mon, ptr)
19 struct monst *mon;
20 struct permonst *ptr;
21 {
22     int new_speed, old_speed = mon->data ? mon->data->mmove : 0;
23
24     mon->data = ptr;
25     mon->mnum = (short) monsndx(ptr);
26
27     if (mon->movement) { /* used to adjust poly'd hero as well as monsters */
28         new_speed = ptr->mmove;
29         /* prorate unused movement if new form is slower so that
30            it doesn't get extra moves leftover from previous form;
31            if new form is faster, leave unused movement as is */
32         if (new_speed < old_speed) {
33             /*
34              * Some static analysis warns that this might divide by 0
35                mon->movement = new_speed * mon->movement / old_speed;
36              * so add a redundant test to suppress that.
37              */
38             mon->movement *= new_speed;
39             if (old_speed > 0) /* old > new and new >= 0, so always True */
40                 mon->movement /= old_speed;
41         }
42     }
43     return;
44 }
45
46 /* does monster-type have any attack for a specific type of damage? */
47 struct attack *
48 attacktype_fordmg(ptr, atyp, dtyp)
49 struct permonst *ptr;
50 int atyp, dtyp;
51 {
52     struct attack *a;
53
54     for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
55         if (a->aatyp == atyp && (dtyp == AD_ANY || a->adtyp == dtyp))
56             return a;
57     return (struct attack *) 0;
58 }
59
60 /* does monster-type have a particular type of attack */
61 boolean
62 attacktype(ptr, atyp)
63 struct permonst *ptr;
64 int atyp;
65 {
66     return attacktype_fordmg(ptr, atyp, AD_ANY) ? TRUE : FALSE;
67 }
68
69 /* returns True if monster doesn't attack, False if it does */
70 boolean
71 noattacks(ptr)
72 struct permonst *ptr;
73 {
74     int i;
75     struct attack *mattk = ptr->mattk;
76
77     for (i = 0; i < NATTK; i++) {
78         /* AT_BOOM "passive attack" (gas spore's explosion upon death)
79            isn't an attack as far as our callers are concerned */
80         if (mattk[i].aatyp == AT_BOOM)
81             continue;
82
83         if (mattk[i].aatyp)
84             return FALSE;
85     }
86     return TRUE;
87 }
88
89 /* does monster-type transform into something else when petrified? */
90 boolean
91 poly_when_stoned(ptr)
92 struct permonst *ptr;
93 {
94     /* non-stone golems turn into stone golems unless latter is genocided */
95     return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM]
96                       && !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD));
97     /* allow G_EXTINCT */
98 }
99
100 /* returns True if monster is drain-life resistant */
101 boolean
102 resists_drli(mon)
103 struct monst *mon;
104 {
105     struct permonst *ptr = mon->data;
106     struct obj *wep;
107
108     if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
109         /* is_were() doesn't handle hero in human form */
110         || (mon == &youmonst && u.ulycn >= LOW_PM)
111         || ptr == &mons[PM_DEATH] || is_vampshifter(mon))
112         return TRUE;
113     wep = (mon == &youmonst) ? uwep : MON_WEP(mon);
114     return (boolean) (wep && wep->oartifact && defends(AD_DRLI, wep));
115 }
116
117 /* True if monster is magic-missile (actually, general magic) resistant */
118 boolean
119 resists_magm(mon)
120 struct monst *mon;
121 {
122     struct permonst *ptr = mon->data;
123     boolean is_you = (mon == &youmonst);
124     long slotmask;
125     struct obj *o;
126
127     /* as of 3.2.0:  gray dragons, Angels, Oracle, Yeenoghu */
128     if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON]
129         || dmgtype(ptr, AD_RBRE)) /* Chromatic Dragon */
130         return TRUE;
131     /* check for magic resistance granted by wielded weapon */
132     o = is_you ? uwep : MON_WEP(mon);
133     if (o && o->oartifact && defends(AD_MAGM, o))
134         return TRUE;
135     /* check for magic resistance granted by worn or carried items */
136     o = is_you ? invent : mon->minvent;
137     slotmask = W_ARMOR | W_ACCESSORY;
138     if (!is_you /* assumes monsters don't wield non-weapons */
139         || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
140         slotmask |= W_WEP;
141     if (is_you && u.twoweap)
142         slotmask |= W_SWAPWEP;
143     for (; o; o = o->nobj)
144         if (((o->owornmask & slotmask) != 0L
145              && objects[o->otyp].oc_oprop == ANTIMAGIC)
146             || (o->oartifact && defends_when_carried(AD_MAGM, o)))
147             return TRUE;
148     return FALSE;
149 }
150
151 /* True iff monster is resistant to light-induced blindness */
152 boolean
153 resists_blnd(mon)
154 struct monst *mon;
155 {
156     struct permonst *ptr = mon->data;
157     boolean is_you = (mon == &youmonst);
158     long slotmask;
159     struct obj *o;
160
161     if (is_you ? (Blind || Unaware)
162                : (mon->mblinded || !mon->mcansee || !haseyes(ptr)
163                   /* BUG: temporary sleep sets mfrozen, but since
164                           paralysis does too, we can't check it */
165                   || mon->msleeping))
166         return TRUE;
167     /* yellow light, Archon; !dust vortex, !cobra, !raven */
168     if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL)
169         || dmgtype_fromattack(ptr, AD_BLND, AT_GAZE))
170         return TRUE;
171     o = is_you ? uwep : MON_WEP(mon);
172     if (o && o->oartifact && defends(AD_BLND, o))
173         return TRUE;
174     o = is_you ? invent : mon->minvent;
175     slotmask = W_ARMOR | W_ACCESSORY;
176     if (!is_you /* assumes monsters don't wield non-weapons */
177         || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
178         slotmask |= W_WEP;
179     if (is_you && u.twoweap)
180         slotmask |= W_SWAPWEP;
181     for (; o; o = o->nobj)
182         if (((o->owornmask & slotmask) != 0L
183              && objects[o->otyp].oc_oprop == BLINDED)
184             || (o->oartifact && defends_when_carried(AD_BLND, o)))
185             return TRUE;
186     return FALSE;
187 }
188
189 /* True iff monster can be blinded by the given attack;
190    note: may return True when mdef is blind (e.g. new cream-pie attack) */
191 boolean
192 can_blnd(magr, mdef, aatyp, obj)
193 struct monst *magr; /* NULL == no specific aggressor */
194 struct monst *mdef;
195 uchar aatyp;
196 struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */
197 {
198     boolean is_you = (mdef == &youmonst);
199     boolean check_visor = FALSE;
200     struct obj *o;
201     const char *s;
202
203     /* no eyes protect against all attacks for now */
204     if (!haseyes(mdef->data))
205         return FALSE;
206
207     switch (aatyp) {
208     case AT_EXPL:
209     case AT_BOOM:
210     case AT_GAZE:
211     case AT_MAGC:
212     case AT_BREA: /* assumed to be lightning */
213         /* light-based attacks may be cancelled or resisted */
214         if (magr && magr->mcan)
215             return FALSE;
216         return !resists_blnd(mdef);
217
218     case AT_WEAP:
219     case AT_SPIT:
220     case AT_NONE:
221         /* an object is used (thrown/spit/other) */
222         if (obj && (obj->otyp == CREAM_PIE)) {
223             if (is_you && Blindfolded)
224                 return FALSE;
225         } else if (obj && (obj->otyp == BLINDING_VENOM)) {
226             /* all ublindf, including LENSES, protect, cream-pies too */
227             if (is_you && (ublindf || u.ucreamed))
228                 return FALSE;
229             check_visor = TRUE;
230         } else if (obj && (obj->otyp == POT_BLINDNESS)) {
231             return TRUE; /* no defense */
232         } else
233             return FALSE; /* other objects cannot cause blindness yet */
234         if ((magr == &youmonst) && u.uswallow)
235             return FALSE; /* can't affect eyes while inside monster */
236         break;
237
238     case AT_ENGL:
239         if (is_you && (Blindfolded || Unaware || u.ucreamed))
240             return FALSE;
241         if (!is_you && mdef->msleeping)
242             return FALSE;
243         break;
244
245     case AT_CLAW:
246         /* e.g. raven: all ublindf, including LENSES, protect */
247         if (is_you && ublindf)
248             return FALSE;
249         if ((magr == &youmonst) && u.uswallow)
250             return FALSE; /* can't affect eyes while inside monster */
251         check_visor = TRUE;
252         break;
253
254     case AT_TUCH:
255     case AT_STNG:
256         /* some physical, blind-inducing attacks can be cancelled */
257         if (magr && magr->mcan)
258             return FALSE;
259         break;
260
261     default:
262         break;
263     }
264
265     /* check if wearing a visor (only checked if visor might help) */
266     if (check_visor) {
267         o = (mdef == &youmonst) ? invent : mdef->minvent;
268         for (; o; o = o->nobj)
269 #if 0 /*JP:T*/
270             if ((o->owornmask & W_ARMH)
271                 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
272                 && !strcmp(s, "visored helmet"))
273 #else
274             if ((o->owornmask & W_ARMH)
275                 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
276                 && !strcmp(s, "\96Ê\96j\95t\82«\82Ì\8a\95"))
277 #endif
278                 return FALSE;
279     }
280
281     return TRUE;
282 }
283
284 /* returns True if monster can attack at range */
285 boolean
286 ranged_attk(ptr)
287 struct permonst *ptr;
288 {
289     register int i, atyp;
290     long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE);
291
292     /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP)
293      *       || attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE)
294      *       || attacktype(ptr, AT_MAGC));
295      * but that's too slow -dlc
296      */
297     for (i = 0; i < NATTK; i++) {
298         atyp = ptr->mattk[i].aatyp;
299         if (atyp >= AT_WEAP)
300             return TRUE;
301         /* assert(atyp < 32); */
302         if ((atk_mask & (1L << atyp)) != 0L)
303             return TRUE;
304     }
305     return FALSE;
306 }
307
308 /* True if specific monster is especially affected by silver weapons */
309 boolean
310 mon_hates_silver(mon)
311 struct monst *mon;
312 {
313     return (boolean) (is_vampshifter(mon) || hates_silver(mon->data));
314 }
315
316 /* True if monster-type is especially affected by silver weapons */
317 boolean
318 hates_silver(ptr)
319 register struct permonst *ptr;
320 {
321     return (boolean) (is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr)
322                       || ptr == &mons[PM_SHADE]
323                       || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
324 }
325
326 /* True if specific monster is especially affected by light-emitting weapons */
327 boolean
328 mon_hates_light(mon)
329 struct monst *mon;
330 {
331     return (boolean) (hates_light(mon->data));
332 }
333
334 /* True iff the type of monster pass through iron bars */
335 boolean
336 passes_bars(mptr)
337 struct permonst *mptr;
338 {
339     return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr)
340                       || is_whirly(mptr) || verysmall(mptr)
341                       || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST)
342                       || (slithy(mptr) && !bigmonst(mptr)));
343 }
344
345 /* returns True if monster can blow (whistle, etc) */
346 boolean
347 can_blow(mtmp)
348 struct monst *mtmp;
349 {
350     if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ)
351         && (breathless(mtmp->data) || verysmall(mtmp->data)
352             || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL))
353         return FALSE;
354     if ((mtmp == &youmonst) && Strangled)
355         return FALSE;
356     return TRUE;
357 }
358
359 /* for casting spells and reading scrolls while blind */
360 boolean
361 can_chant(mtmp)
362 struct monst *mtmp;
363 {
364     if ((mtmp == &youmonst && Strangled)
365         || is_silent(mtmp->data) || !has_head(mtmp->data)
366         || mtmp->data->msound == MS_BUZZ || mtmp->data->msound == MS_BURBLE)
367         return FALSE;
368     return TRUE;
369 }
370
371 /* True if mon is vulnerable to strangulation */
372 boolean
373 can_be_strangled(mon)
374 struct monst *mon;
375 {
376     struct obj *mamul;
377     boolean nonbreathing, nobrainer;
378
379     /* For amulet of strangulation support:  here we're considering
380        strangulation to be loss of blood flow to the brain due to
381        constriction of the arteries in the neck, so all headless
382        creatures are immune (no neck) as are mindless creatures
383        who don't need to breathe (brain, if any, doesn't care).
384        Mindless creatures who do need to breath are vulnerable, as
385        are non-breathing creatures which have higher brain function. */
386     if (!has_head(mon->data))
387         return FALSE;
388     if (mon == &youmonst) {
389         /* hero can't be mindless but poly'ing into mindless form can
390            confer strangulation protection */
391         nobrainer = mindless(youmonst.data);
392         nonbreathing = Breathless;
393     } else {
394         nobrainer = mindless(mon->data);
395         /* monsters don't wear amulets of magical breathing,
396            so second part doesn't achieve anything useful... */
397         nonbreathing = (breathless(mon->data)
398                         || ((mamul = which_armor(mon, W_AMUL)) != 0
399                             && (mamul->otyp == AMULET_OF_MAGICAL_BREATHING)));
400     }
401     return (boolean) (!nobrainer || !nonbreathing);
402 }
403
404 /* returns True if monster can track well */
405 boolean
406 can_track(ptr)
407 register struct permonst *ptr;
408 {
409     if (uwep && uwep->oartifact == ART_EXCALIBUR)
410         return TRUE;
411     else
412         return (boolean) haseyes(ptr);
413 }
414
415 /* creature will slide out of armor */
416 boolean
417 sliparm(ptr)
418 register struct permonst *ptr;
419 {
420     return (boolean) (is_whirly(ptr) || ptr->msize <= MZ_SMALL
421                       || noncorporeal(ptr));
422 }
423
424 /* creature will break out of armor */
425 boolean
426 breakarm(ptr)
427 register struct permonst *ptr;
428 {
429     if (sliparm(ptr))
430         return FALSE;
431
432     return (boolean) (bigmonst(ptr)
433                       || (ptr->msize > MZ_SMALL && !humanoid(ptr))
434                       /* special cases of humanoids that cannot wear suits */
435                       || ptr == &mons[PM_MARILITH]
436                       || ptr == &mons[PM_WINGED_GARGOYLE]);
437 }
438
439 /* creature sticks other creatures it hits */
440 boolean
441 sticks(ptr)
442 register struct permonst *ptr;
443 {
444     return (boolean) (dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP)
445                       || attacktype(ptr, AT_HUGS));
446 }
447
448 /* some monster-types can't vomit */
449 boolean
450 cantvomit(ptr)
451 struct permonst *ptr;
452 {
453     /* rats and mice are incapable of vomiting;
454        which other creatures have the same limitation? */
455     if (ptr->mlet == S_RODENT && ptr != &mons[PM_ROCK_MOLE]
456         && ptr != &mons[PM_WOODCHUCK])
457         return TRUE;
458     return FALSE;
459 }
460
461 /* number of horns this type of monster has on its head */
462 int
463 num_horns(ptr)
464 struct permonst *ptr;
465 {
466     switch (monsndx(ptr)) {
467     case PM_HORNED_DEVIL: /* ? "more than one" */
468     case PM_MINOTAUR:
469     case PM_ASMODEUS:
470     case PM_BALROG:
471         return 2;
472     case PM_WHITE_UNICORN:
473     case PM_GRAY_UNICORN:
474     case PM_BLACK_UNICORN:
475     case PM_KI_RIN:
476         return 1;
477     default:
478         break;
479     }
480     return 0;
481 }
482
483 /* does monster-type deal out a particular type of damage from a particular
484    type of attack? */
485 struct attack *
486 dmgtype_fromattack(ptr, dtyp, atyp)
487 struct permonst *ptr;
488 int dtyp, atyp;
489 {
490     struct attack *a;
491
492     for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
493         if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp))
494             return a;
495     return (struct attack *) 0;
496 }
497
498 /* does monster-type deal out a particular type of damage from any attack */
499 boolean
500 dmgtype(ptr, dtyp)
501 struct permonst *ptr;
502 int dtyp;
503 {
504     return dmgtype_fromattack(ptr, dtyp, AT_ANY) ? TRUE : FALSE;
505 }
506
507 /* returns the maximum damage a defender can do to the attacker via
508    a passive defense */
509 int
510 max_passive_dmg(mdef, magr)
511 register struct monst *mdef, *magr;
512 {
513     int i, dmg = 0, multi2 = 0;
514     uchar adtyp;
515
516     /* each attack by magr can result in passive damage */
517     for (i = 0; i < NATTK; i++)
518         switch (magr->data->mattk[i].aatyp) {
519         case AT_CLAW:
520         case AT_BITE:
521         case AT_KICK:
522         case AT_BUTT:
523         case AT_TUCH:
524         case AT_STNG:
525         case AT_HUGS:
526         case AT_ENGL:
527         case AT_TENT:
528         case AT_WEAP:
529             multi2++;
530             break;
531         default:
532             break;
533         }
534
535     for (i = 0; i < NATTK; i++)
536         if (mdef->data->mattk[i].aatyp == AT_NONE
537             || mdef->data->mattk[i].aatyp == AT_BOOM) {
538             adtyp = mdef->data->mattk[i].adtyp;
539             if ((adtyp == AD_ACID && !resists_acid(magr))
540                 || (adtyp == AD_COLD && !resists_cold(magr))
541                 || (adtyp == AD_FIRE && !resists_fire(magr))
542                 || (adtyp == AD_ELEC && !resists_elec(magr))
543                 || adtyp == AD_PHYS) {
544                 dmg = mdef->data->mattk[i].damn;
545                 if (!dmg)
546                     dmg = mdef->data->mlevel + 1;
547                 dmg *= mdef->data->mattk[i].damd;
548             } else
549                 dmg = 0;
550
551             return dmg * multi2;
552         }
553     return 0;
554 }
555
556 /* determine whether two monster types are from the same species */
557 boolean
558 same_race(pm1, pm2)
559 struct permonst *pm1, *pm2;
560 {
561     char let1 = pm1->mlet, let2 = pm2->mlet;
562
563     if (pm1 == pm2)
564         return TRUE; /* exact match */
565     /* player races have their own predicates */
566     if (is_human(pm1))
567         return is_human(pm2);
568     if (is_elf(pm1))
569         return is_elf(pm2);
570     if (is_dwarf(pm1))
571         return is_dwarf(pm2);
572     if (is_gnome(pm1))
573         return is_gnome(pm2);
574     if (is_orc(pm1))
575         return is_orc(pm2);
576     /* other creatures are less precise */
577     if (is_giant(pm1))
578         return is_giant(pm2); /* open to quibbling here */
579     if (is_golem(pm1))
580         return is_golem(pm2); /* even moreso... */
581     if (is_mind_flayer(pm1))
582         return is_mind_flayer(pm2);
583     if (let1 == S_KOBOLD || pm1 == &mons[PM_KOBOLD_ZOMBIE]
584         || pm1 == &mons[PM_KOBOLD_MUMMY])
585         return (let2 == S_KOBOLD || pm2 == &mons[PM_KOBOLD_ZOMBIE]
586                 || pm2 == &mons[PM_KOBOLD_MUMMY]);
587     if (let1 == S_OGRE)
588         return (let2 == S_OGRE);
589     if (let1 == S_NYMPH)
590         return (let2 == S_NYMPH);
591     if (let1 == S_CENTAUR)
592         return (let2 == S_CENTAUR);
593     if (is_unicorn(pm1))
594         return is_unicorn(pm2);
595     if (let1 == S_DRAGON)
596         return (let2 == S_DRAGON);
597     if (let1 == S_NAGA)
598         return (let2 == S_NAGA);
599     /* other critters get steadily messier */
600     if (is_rider(pm1))
601         return is_rider(pm2); /* debatable */
602     if (is_minion(pm1))
603         return is_minion(pm2); /* [needs work?] */
604     /* tengu don't match imps (first test handled case of both being tengu) */
605     if (pm1 == &mons[PM_TENGU] || pm2 == &mons[PM_TENGU])
606         return FALSE;
607     if (let1 == S_IMP)
608         return (let2 == S_IMP);
609     /* and minor demons (imps) don't match major demons */
610     else if (let2 == S_IMP)
611         return FALSE;
612     if (is_demon(pm1))
613         return is_demon(pm2);
614     if (is_undead(pm1)) {
615         if (let1 == S_ZOMBIE)
616             return (let2 == S_ZOMBIE);
617         if (let1 == S_MUMMY)
618             return (let2 == S_MUMMY);
619         if (let1 == S_VAMPIRE)
620             return (let2 == S_VAMPIRE);
621         if (let1 == S_LICH)
622             return (let2 == S_LICH);
623         if (let1 == S_WRAITH)
624             return (let2 == S_WRAITH);
625         if (let1 == S_GHOST)
626             return (let2 == S_GHOST);
627     } else if (is_undead(pm2))
628         return FALSE;
629
630     /* check for monsters which grow into more mature forms */
631     if (let1 == let2) {
632         int m1 = monsndx(pm1), m2 = monsndx(pm2), prv, nxt;
633
634         /* we know m1 != m2 (very first check above); test all smaller
635            forms of m1 against m2, then all larger ones; don't need to
636            make the corresponding tests for variants of m2 against m1 */
637         for (prv = m1, nxt = big_to_little(m1); nxt != prv;
638              prv = nxt, nxt = big_to_little(nxt))
639             if (nxt == m2)
640                 return TRUE;
641         for (prv = m1, nxt = little_to_big(m1); nxt != prv;
642              prv = nxt, nxt = little_to_big(nxt))
643             if (nxt == m2)
644                 return TRUE;
645     }
646     /* not caught by little/big handling */
647     if (pm1 == &mons[PM_GARGOYLE] || pm1 == &mons[PM_WINGED_GARGOYLE])
648         return (pm2 == &mons[PM_GARGOYLE]
649                 || pm2 == &mons[PM_WINGED_GARGOYLE]);
650     if (pm1 == &mons[PM_KILLER_BEE] || pm1 == &mons[PM_QUEEN_BEE])
651         return (pm2 == &mons[PM_KILLER_BEE] || pm2 == &mons[PM_QUEEN_BEE]);
652
653     if (is_longworm(pm1))
654         return is_longworm(pm2); /* handles tail */
655     /* [currently there's no reason to bother matching up
656         assorted bugs and blobs with their closest variants] */
657     /* didn't match */
658     return FALSE;
659 }
660
661 /* return an index into the mons array */
662 int
663 monsndx(ptr)
664 struct permonst *ptr;
665 {
666     register int i;
667
668     i = (int) (ptr - &mons[0]);
669     if (i < LOW_PM || i >= NUMMONS) {
670         panic("monsndx - could not index monster (%s)",
671               fmt_ptr((genericptr_t) ptr));
672         return NON_PM; /* will not get here */
673     }
674     return i;
675 }
676
677 /* for handling alternate spellings */
678 struct alt_spl {
679     const char *name;
680     short pm_val;
681 };
682
683 /* figure out what type of monster a user-supplied string is specifying */
684 int
685 name_to_mon(in_str)
686 const char *in_str;
687 {
688     /* Be careful.  We must check the entire string in case it was
689      * something such as "ettin zombie corpse".  The calling routine
690      * doesn't know about the "corpse" until the monster name has
691      * already been taken off the front, so we have to be able to
692      * read the name with extraneous stuff such as "corpse" stuck on
693      * the end.
694      * This causes a problem for names which prefix other names such
695      * as "ettin" on "ettin zombie".  In this case we want the _longest_
696      * name which exists.
697      * This also permits plurals created by adding suffixes such as 's'
698      * or 'es'.  Other plurals must still be handled explicitly.
699      */
700     register int i;
701     register int mntmp = NON_PM;
702     register char *s, *str, *term;
703     char buf[BUFSZ];
704     int len, slen;
705
706     str = strcpy(buf, in_str);
707
708     if (!strncmp(str, "a ", 2))
709         str += 2;
710     else if (!strncmp(str, "an ", 3))
711         str += 3;
712     else if (!strncmp(str, "the ", 4))
713         str += 4;
714
715     slen = strlen(str);
716     term = str + slen;
717
718     if ((s = strstri(str, "vortices")) != 0)
719         Strcpy(s + 4, "ex");
720     /* be careful with "ies"; "priest", "zombies" */
721     else if (slen > 3 && !strcmpi(term - 3, "ies")
722              && (slen < 7 || strcmpi(term - 7, "zombies")))
723         Strcpy(term - 3, "y");
724     /* luckily no monster names end in fe or ve with ves plurals */
725     else if (slen > 3 && !strcmpi(term - 3, "ves"))
726         Strcpy(term - 3, "f");
727
728     slen = strlen(str); /* length possibly needs recomputing */
729
730     {
731         static const struct alt_spl names[] = {
732             /* Alternate spellings */
733             { "grey dragon", PM_GRAY_DRAGON },
734             { "baby grey dragon", PM_BABY_GRAY_DRAGON },
735             { "grey unicorn", PM_GRAY_UNICORN },
736             { "grey ooze", PM_GRAY_OOZE },
737             { "gray-elf", PM_GREY_ELF },
738             { "mindflayer", PM_MIND_FLAYER },
739             { "master mindflayer", PM_MASTER_MIND_FLAYER },
740             /* More alternates; priest and priestess are separate monster
741                types but that isn't the case for {aligned,high} priests */
742             { "aligned priestess", PM_ALIGNED_PRIEST },
743             { "high priestess", PM_HIGH_PRIEST },
744             /* Inappropriate singularization by -ves check above */
745             { "master of thief", PM_MASTER_OF_THIEVES },
746             /* Potential misspellings where we want to avoid falling back
747                to the rank title prefix (input has been singularized) */
748             { "master thief", PM_MASTER_OF_THIEVES },
749             { "master of assassin", PM_MASTER_ASSASSIN },
750             /* Outdated names */
751             { "invisible stalker", PM_STALKER },
752             { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
753             /* other misspellings or incorrect words */
754             { "wood-elf", PM_WOODLAND_ELF },
755             { "wood elf", PM_WOODLAND_ELF },
756             { "woodland nymph", PM_WOOD_NYMPH },
757             { "halfling", PM_HOBBIT },    /* potential guess for polyself */
758             { "genie", PM_DJINNI }, /* potential guess for ^G/#wizgenesis */
759             /* Hyphenated names -- it would be nice to handle these via
760                fuzzymatch() but it isn't able to ignore trailing stuff */
761             { "ki rin", PM_KI_RIN },
762             { "uruk hai", PM_URUK_HAI },
763             { "orc captain", PM_ORC_CAPTAIN },
764             { "woodland elf", PM_WOODLAND_ELF },
765             { "green elf", PM_GREEN_ELF },
766             { "grey elf", PM_GREY_ELF },
767             { "gray elf", PM_GREY_ELF },
768             { "elf lord", PM_ELF_LORD },
769             { "olog hai", PM_OLOG_HAI },
770             { "arch lich", PM_ARCH_LICH },
771             /* Some irregular plurals */
772             { "incubi", PM_INCUBUS },
773             { "succubi", PM_SUCCUBUS },
774             { "violet fungi", PM_VIOLET_FUNGUS },
775             { "homunculi", PM_HOMUNCULUS },
776             { "baluchitheria", PM_BALUCHITHERIUM },
777             { "lurkers above", PM_LURKER_ABOVE },
778             { "cavemen", PM_CAVEMAN },
779             { "cavewomen", PM_CAVEWOMAN },
780             { "watchmen", PM_WATCHMAN },
781             { "djinn", PM_DJINNI },
782             { "mumakil", PM_MUMAK },
783             { "erinyes", PM_ERINYS },
784             /* end of list */
785             { 0, NON_PM }
786         };
787         register const struct alt_spl *namep;
788
789         for (namep = names; namep->name; namep++)
790             if (!strncmpi(str, namep->name, (int) strlen(namep->name)))
791                 return namep->pm_val;
792     }
793
794     for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
795         register int m_i_len = (int) strlen(mons[i].mname);
796
797         if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
798             if (m_i_len == slen) {
799                 mntmp = i;
800                 break; /* exact match */
801             } else if (slen > m_i_len
802 #if 0 /*JP*/
803                        && (str[m_i_len] == ' '
804                            || !strcmpi(&str[m_i_len], "s")
805                            || !strncmpi(&str[m_i_len], "s ", 2)
806                            || !strcmpi(&str[m_i_len], "'")
807                            || !strncmpi(&str[m_i_len], "' ", 2)
808                            || !strcmpi(&str[m_i_len], "'s")
809                            || !strncmpi(&str[m_i_len], "'s ", 3)
810                            || !strcmpi(&str[m_i_len], "es")
811                            || !strncmpi(&str[m_i_len], "es ", 3))) {
812 #else
813                        && !strncmp(&str[m_i_len], "\82Ì", 2)) {
814 #endif
815                 mntmp = i;
816                 len = m_i_len;
817             }
818         }
819     }
820     if (mntmp == NON_PM)
821         mntmp = title_to_mon(str, (int *) 0, (int *) 0);
822     return mntmp;
823 }
824
825 /* monster class from user input; used for genocide and controlled polymorph;
826    returns 0 rather than MAXMCLASSES if no match is found */
827 int
828 name_to_monclass(in_str, mndx_p)
829 const char *in_str;
830 int *mndx_p;
831 {
832     /* Single letters are matched against def_monsyms[].sym; words
833        or phrases are first matched against def_monsyms[].explain
834        to check class description; if not found there, then against
835        mons[].mname to test individual monster types.  Input can be a
836        substring of the full description or mname, but to be accepted,
837        such partial matches must start at beginning of a word.  Some
838        class descriptions include "foo or bar" and "foo or other foo"
839        so we don't want to accept "or", "other", "or other" there. */
840     static NEARDATA const char *const falsematch[] = {
841         /* multiple-letter input which matches any of these gets rejected */
842         "an", "the", "or", "other", "or other", 0
843     };
844     /* positive pm_val => specific monster; negative => class */
845     static NEARDATA const struct alt_spl truematch[] = {
846         /* "long worm" won't match "worm" class but would accidentally match
847            "long worm tail" class before the comparison with monster types */
848         { "long worm", PM_LONG_WORM },
849         /* matches wrong--or at least suboptimal--class */
850         { "demon", -S_DEMON }, /* hits "imp or minor demon" */
851         /* matches specific monster (overly restrictive) */
852         { "devil", -S_DEMON }, /* always "horned devil" */
853         /* some plausible guesses which need help */
854         { "bug", -S_XAN },  /* would match bugbear... */
855         { "fish", -S_EEL }, /* wouldn't match anything */
856         /* end of list */
857         { 0, NON_PM }
858     };
859     const char *p, *x;
860     int i, len;
861
862     if (mndx_p)
863         *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
864
865     if (!in_str || !in_str[0]) {
866         /* empty input */
867         return 0;
868     } else if (!in_str[1]) {
869         /* single character */
870         i = def_char_to_monclass(*in_str);
871         if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
872             i = S_MIMIC;
873         } else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
874             i = S_WORM;
875             if (mndx_p)
876                 *mndx_p = PM_LONG_WORM;
877         } else if (i == MAXMCLASSES) /* maybe 'I' */
878             i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
879         return i;
880     } else {
881         /* multiple characters */
882         if (!strcmpi(in_str, "long")) /* not enough to match "long worm" */
883             return 0; /* avoid false whole-word match with "long worm tail" */
884         in_str = makesingular(in_str);
885         /* check for special cases */
886         for (i = 0; falsematch[i]; i++)
887             if (!strcmpi(in_str, falsematch[i]))
888                 return 0;
889         for (i = 0; truematch[i].name; i++)
890             if (!strcmpi(in_str, truematch[i].name)) {
891                 i = truematch[i].pm_val;
892                 if (i < 0)
893                     return -i; /* class */
894                 if (mndx_p)
895                     *mndx_p = i; /* monster */
896                 return mons[i].mlet;
897             }
898         /* check monster class descriptions */
899         len = (int) strlen(in_str);
900         for (i = 1; i < MAXMCLASSES; i++) {
901             x = def_monsyms[i].explain;
902             if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' ')
903                 && ((int) strlen(p) >= len
904                     && (p[len] == '\0' || p[len] == ' ')))
905                 return i;
906         }
907         /* check individual species names */
908         i = name_to_mon(in_str);
909         if (i != NON_PM) {
910             if (mndx_p)
911                 *mndx_p = i;
912             return mons[i].mlet;
913         }
914     }
915     return 0;
916 }
917
918 /* returns 3 values (0=male, 1=female, 2=none) */
919 int
920 gender(mtmp)
921 register struct monst *mtmp;
922 {
923     if (is_neuter(mtmp->data))
924         return 2;
925     return mtmp->female;
926 }
927
928 /* Like gender(), but lower animals and such are still "it".
929    This is the one we want to use when printing messages. */
930 int
931 pronoun_gender(mtmp, override_vis)
932 register struct monst *mtmp;
933 boolean override_vis; /* if True then 'no it' unless neuter */
934 {
935     if (!override_vis && !canspotmon(mtmp))
936         return 2;
937     if (is_neuter(mtmp->data))
938         return 2;
939     return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
940             || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
941 }
942
943 /* used for nearby monsters when you go to another level */
944 boolean
945 levl_follower(mtmp)
946 struct monst *mtmp;
947 {
948     if (mtmp == u.usteed)
949         return TRUE;
950
951     /* Wizard with Amulet won't bother trying to follow across levels */
952     if (mtmp->iswiz && mon_has_amulet(mtmp))
953         return FALSE;
954     /* some monsters will follow even while intending to flee from you */
955     if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp))
956         return TRUE;
957     /* stalking types follow, but won't when fleeing unless you hold
958        the Amulet */
959     return (boolean) ((mtmp->data->mflags2 & M2_STALK)
960                       && (!mtmp->mflee || u.uhave.amulet));
961 }
962
963 static const short grownups[][2] = {
964     { PM_CHICKATRICE, PM_COCKATRICE },
965     { PM_LITTLE_DOG, PM_DOG },
966     { PM_DOG, PM_LARGE_DOG },
967     { PM_HELL_HOUND_PUP, PM_HELL_HOUND },
968     { PM_WINTER_WOLF_CUB, PM_WINTER_WOLF },
969     { PM_KITTEN, PM_HOUSECAT },
970     { PM_HOUSECAT, PM_LARGE_CAT },
971     { PM_PONY, PM_HORSE },
972     { PM_HORSE, PM_WARHORSE },
973     { PM_KOBOLD, PM_LARGE_KOBOLD },
974     { PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
975     { PM_GNOME, PM_GNOME_LORD },
976     { PM_GNOME_LORD, PM_GNOME_KING },
977     { PM_DWARF, PM_DWARF_LORD },
978     { PM_DWARF_LORD, PM_DWARF_KING },
979     { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
980     { PM_ORC, PM_ORC_CAPTAIN },
981     { PM_HILL_ORC, PM_ORC_CAPTAIN },
982     { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
983     { PM_URUK_HAI, PM_ORC_CAPTAIN },
984     { PM_SEWER_RAT, PM_GIANT_RAT },
985     { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
986     { PM_OGRE, PM_OGRE_LORD },
987     { PM_OGRE_LORD, PM_OGRE_KING },
988     { PM_ELF, PM_ELF_LORD },
989     { PM_WOODLAND_ELF, PM_ELF_LORD },
990     { PM_GREEN_ELF, PM_ELF_LORD },
991     { PM_GREY_ELF, PM_ELF_LORD },
992     { PM_ELF_LORD, PM_ELVENKING },
993     { PM_LICH, PM_DEMILICH },
994     { PM_DEMILICH, PM_MASTER_LICH },
995     { PM_MASTER_LICH, PM_ARCH_LICH },
996     { PM_VAMPIRE, PM_VAMPIRE_LORD },
997     { PM_BAT, PM_GIANT_BAT },
998     { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
999     { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
1000 #if 0 /* DEFERRED */
1001     {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
1002 #endif
1003     { PM_BABY_RED_DRAGON, PM_RED_DRAGON },
1004     { PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON },
1005     { PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON },
1006     { PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON },
1007     { PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON },
1008     { PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON },
1009     { PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON },
1010     { PM_RED_NAGA_HATCHLING, PM_RED_NAGA },
1011     { PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA },
1012     { PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA },
1013     { PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA },
1014     { PM_SMALL_MIMIC, PM_LARGE_MIMIC },
1015     { PM_LARGE_MIMIC, PM_GIANT_MIMIC },
1016     { PM_BABY_LONG_WORM, PM_LONG_WORM },
1017     { PM_BABY_PURPLE_WORM, PM_PURPLE_WORM },
1018     { PM_BABY_CROCODILE, PM_CROCODILE },
1019     { PM_SOLDIER, PM_SERGEANT },
1020     { PM_SERGEANT, PM_LIEUTENANT },
1021     { PM_LIEUTENANT, PM_CAPTAIN },
1022     { PM_WATCHMAN, PM_WATCH_CAPTAIN },
1023     { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
1024     { PM_STUDENT, PM_ARCHEOLOGIST },
1025     { PM_ATTENDANT, PM_HEALER },
1026     { PM_PAGE, PM_KNIGHT },
1027     { PM_ACOLYTE, PM_PRIEST },
1028     { PM_APPRENTICE, PM_WIZARD },
1029     { PM_MANES, PM_LEMURE },
1030     { PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
1031     { PM_KOP_SERGEANT, PM_KOP_LIEUTENANT },
1032     { PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN },
1033     { NON_PM, NON_PM }
1034 };
1035
1036 int
1037 little_to_big(montype)
1038 int montype;
1039 {
1040     register int i;
1041
1042     for (i = 0; grownups[i][0] >= LOW_PM; i++)
1043         if (montype == grownups[i][0]) {
1044             montype = grownups[i][1];
1045             break;
1046         }
1047     return montype;
1048 }
1049
1050 int
1051 big_to_little(montype)
1052 int montype;
1053 {
1054     register int i;
1055
1056     for (i = 0; grownups[i][0] >= LOW_PM; i++)
1057         if (montype == grownups[i][1]) {
1058             montype = grownups[i][0];
1059             break;
1060         }
1061     return montype;
1062 }
1063
1064 /* determine whether two permonst indices are part of the same progression;
1065    existence of progressions with more than one step makes it a bit tricky */
1066 boolean
1067 big_little_match(montyp1, montyp2)
1068 int montyp1, montyp2;
1069 {
1070     int l, b;
1071
1072     /* simplest case: both are same pm */
1073     if (montyp1 == montyp2)
1074         return TRUE;
1075     /* assume it isn't possible to grow from one class letter to another */
1076     if (mons[montyp1].mlet != mons[montyp2].mlet)
1077         return FALSE;
1078     /* check whether montyp1 can grow up into montyp2 */
1079     for (l = montyp1; (b = little_to_big(l)) != l; l = b)
1080         if (b == montyp2)
1081             return TRUE;
1082     /* check whether montyp2 can grow up into montyp1 */
1083     for (l = montyp2; (b = little_to_big(l)) != l; l = b)
1084         if (b == montyp1)
1085             return TRUE;
1086     /* neither grows up to become the other; no match */
1087     return FALSE;
1088 }
1089
1090 /*
1091  * Return the permonst ptr for the race of the monster.
1092  * Returns correct pointer for non-polymorphed and polymorphed
1093  * player.  It does not return a pointer to player role character.
1094  */
1095 const struct permonst *
1096 raceptr(mtmp)
1097 struct monst *mtmp;
1098 {
1099     if (mtmp == &youmonst && !Upolyd)
1100         return &mons[urace.malenum];
1101     else
1102         return mtmp->data;
1103 }
1104
1105 /*JP
1106 static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" };
1107 */
1108 static const char *levitate[4] = { "\95\82\82­", "\95\82\82­", "\82æ\82ë\82ß\82­", "\82æ\82ë\82ß\82­" };
1109 /*JP
1110 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
1111 */
1112 static const char *flys[4] = { "\94ò\82Ô", "\94ò\82Ô", "\82¨\82Ì\82Ì\82­", "\82¨\82Ì\82Ì\82­" };
1113 /*JP
1114 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
1115 */
1116 static const char *flyl[4] = { "\94ò\82Ô", "\94ò\82Ô", "\82æ\82ë\82ß\82­", "\82æ\82ë\82ß\82­" };
1117 /*JP
1118 static const char *slither[4] = { "slither", "Slither", "falter", "Falter" };
1119 */
1120 static const char *slither[4] = { "\8a\8a\82é", "\8a\8a\82é", "\82½\82\82ë\82®", "\82½\82\82ë\82®" };
1121 /*JP
1122 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
1123 */
1124 static const char *ooze[4] = { "\82É\82\82Ý\8fo\82é", "\82É\82\82Ý\8fo\82é", "\90g\90k\82¢\82·\82é", "\90g\90k\82¢\82·\82é" };
1125 /*JP
1126 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
1127 */
1128 static const char *immobile[4] = { "\93®\82­", "\93®\82­", "\90k\82¦\82é", "\90k\82¦\82é" };
1129 /*JP
1130 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
1131 */
1132 static const char *crawl[4] = { "\82Í\82¢\82¸\82é", "\82Í\82¢\82¸\82é", "\82½\82\82ë\82®", "\82½\82\82ë\82®" };
1133
1134 const char *
1135 locomotion(ptr, def)
1136 const struct permonst *ptr;
1137 const char *def;
1138 {
1139     int capitalize = (*def == highc(*def));
1140
1141     return (is_floater(ptr) ? levitate[capitalize]
1142             : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1143               : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1144                 : slithy(ptr) ? slither[capitalize]
1145                   : amorphous(ptr) ? ooze[capitalize]
1146                     : !ptr->mmove ? immobile[capitalize]
1147                       : nolimbs(ptr) ? crawl[capitalize]
1148                         : def);
1149 }
1150
1151 /*JP:
1152  * \81u\82æ\82ë\82ß\82­\81v\82ð\89ö\95¨\82Ì\8eí\97Þ\82É\82æ\82Á\82Ä\95Ï\82¦\82é\81B
1153  * \8e©\95ª\82É\91Î\82µ\82Ä\8eg\82¤\8fê\8d\87\82É\82Í\8aù\82É\81u\82­\82ç\82­\82ç\82·\82é\81v\82ª\8eg\82í\82ê\82Ä\82¢\82é\82Ì\82Å\81A
1154  * \95Ï\89»\82µ\82Ä\82¢\82Ä\82à\82»\82Ì\82Ü\82Ü\82É\82·\82é\81B
1155  * \91\8a\8eè\82É\91Î\82µ\82Ä\8eg\82¤\8fê\8d\87\82Í\81u\82­\82ç\82­\82ç\82·\82é\81v\82Í\95s\8e©\91R\82È\82Ì\82Å\82±\82ê\82ð\8eg\82¤\81B
1156  */
1157 const char *
1158 stagger(ptr, def)
1159 const struct permonst *ptr;
1160 const char *def;
1161 {
1162     int capitalize = 2 + (*def == highc(*def));
1163
1164     return (is_floater(ptr) ? levitate[capitalize]
1165             : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1166               : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1167                 : slithy(ptr) ? slither[capitalize]
1168                   : amorphous(ptr) ? ooze[capitalize]
1169                     : !ptr->mmove ? immobile[capitalize]
1170                       : nolimbs(ptr) ? crawl[capitalize]
1171                         : def);
1172 }
1173 #if 1 /*JP*/
1174 static const char *levitate2 = "\95\82\82«\8fo\82½";
1175 static const char *fly2 = "\94ò\82Ñ\8fo\82½";
1176 static const char *slither2 = "\8a\8a\82è\8fo\82½";
1177 static const char *ooze2 = "\82É\82\82Ý\8fo\82½";
1178 static const char *crawl2 = "\82Í\82¢\82¸\82è\8fo\82½";
1179
1180 const char *
1181 jumpedthrough(ptr, def)
1182 const struct permonst *ptr;
1183 const char *def;
1184 {
1185         return (
1186             is_floater(ptr) ? levitate2 :
1187             is_flyer(ptr)   ? fly2 :
1188             slithy(ptr)     ? slither2 :
1189             amorphous(ptr)  ? ooze2 :
1190             nolimbs(ptr)    ? crawl2 :
1191             def
1192             );
1193 }
1194 #endif
1195
1196 /* return phrase describing the effect of fire attack on a type of monster */
1197 const char *
1198 on_fire(mptr, mattk)
1199 struct permonst *mptr;
1200 struct attack *mattk;
1201 {
1202     const char *what;
1203
1204     switch (monsndx(mptr)) {
1205     case PM_FLAMING_SPHERE:
1206     case PM_FIRE_VORTEX:
1207     case PM_FIRE_ELEMENTAL:
1208     case PM_SALAMANDER:
1209 /*JP
1210         what = "already on fire";
1211 */
1212         what = "\82·\82Å\82É\89\8a\82É\82Â\82Â\82Ü\82ê\82Ä\82¢\82é";
1213         break;
1214     case PM_WATER_ELEMENTAL:
1215     case PM_FOG_CLOUD:
1216     case PM_STEAM_VORTEX:
1217 /*JP
1218         what = "boiling";
1219 */
1220         what = "\95¦\93«\82µ\82½";
1221         break;
1222     case PM_ICE_VORTEX:
1223     case PM_GLASS_GOLEM:
1224 /*JP
1225         what = "melting";
1226 */
1227         what = "\97n\82¯\82½";
1228         break;
1229     case PM_STONE_GOLEM:
1230     case PM_CLAY_GOLEM:
1231     case PM_GOLD_GOLEM:
1232     case PM_AIR_ELEMENTAL:
1233     case PM_EARTH_ELEMENTAL:
1234     case PM_DUST_VORTEX:
1235     case PM_ENERGY_VORTEX:
1236 /*JP
1237         what = "heating up";
1238 */
1239         what = "\94M\82­\82È\82Á\82½";
1240         break;
1241     default:
1242 /*JP
1243         what = (mattk->aatyp == AT_HUGS) ? "being roasted" : "on fire";
1244 */
1245         what = (mattk->aatyp == AT_HUGS) ? "\8aÛ\8fÄ\82¯\82É\82È\82Á\82½" : "\89Î\82¾\82é\82Ü\82É\82È\82Á\82½";
1246         break;
1247     }
1248     return what;
1249 }
1250
1251 /*
1252  * Returns:
1253  *      True if monster is presumed to have a sense of smell.
1254  *      False if monster definitely does not have a sense of smell.
1255  *
1256  * Do not base this on presence of a head or nose, since many
1257  * creatures sense smells other ways (feelers, forked-tongues, etc.)
1258  * We're assuming all insects can smell at a distance too.
1259  */
1260 boolean
1261 olfaction(mdat)
1262 struct permonst *mdat;
1263 {
1264     if (is_golem(mdat)
1265         || mdat->mlet == S_EYE /* spheres  */
1266         || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING
1267         || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX
1268         || mdat->mlet == S_ELEMENTAL
1269         || mdat->mlet == S_FUNGUS /* mushrooms and fungi */
1270         || mdat->mlet == S_LIGHT)
1271         return FALSE;
1272     return TRUE;
1273 }
1274
1275 /*mondata.c*/