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