1 /* NetHack 3.6 mondata.c $NHDT-Date: 1446604115 2015/11/04 02:28:35 $ $NHDT-Branch: master $:$NHDT-Revision: 1.58 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
5 /* JNetHack Copyright */
6 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
7 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
8 /* JNetHack may be freely redistributed. See license for details. */
12 /* These routines provide basic data for any type of monster. */
14 /* set up an individual monster's base type (initial creation, shapechange) */
16 set_mon_data(mon, ptr, flag)
23 return; /* "don't care" */
26 mon->mintrinsics |= (ptr->mresists & 0x00FF);
28 mon->mintrinsics = (ptr->mresists & 0x00FF);
32 /* does monster-type have any attack for a specific type of damage? */
34 attacktype_fordmg(ptr, atyp, dtyp)
40 for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
41 if (a->aatyp == atyp && (dtyp == AD_ANY || a->adtyp == dtyp))
43 return (struct attack *) 0;
46 /* does monster-type have a particular type of attack */
52 return attacktype_fordmg(ptr, atyp, AD_ANY) ? TRUE : FALSE;
55 /* returns True if monster doesn't attack, False if it does */
61 struct attack *mattk = ptr->mattk;
63 for (i = 0; i < NATTK; i++) {
64 /* AT_BOOM "passive attack" (gas spore's explosion upon death)
65 isn't an attack as far as our callers are concerned */
66 if (mattk[i].aatyp == AT_BOOM)
75 /* does monster-type transform into something else when petrified? */
80 /* non-stone golems turn into stone golems unless latter is genocided */
81 return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM]
82 && !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD));
86 /* returns True if monster is drain-life resistant */
91 struct permonst *ptr = mon->data;
94 if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
95 /* is_were() doesn't handle hero in human form */
96 || (mon == &youmonst && u.ulycn >= LOW_PM)
97 || ptr == &mons[PM_DEATH] || is_vampshifter(mon))
99 wep = (mon == &youmonst) ? uwep : MON_WEP(mon);
100 return (boolean) (wep && wep->oartifact && defends(AD_DRLI, wep));
103 /* True if monster is magic-missile (actually, general magic) resistant */
108 struct permonst *ptr = mon->data;
109 boolean is_you = (mon == &youmonst);
113 /* as of 3.2.0: gray dragons, Angels, Oracle, Yeenoghu */
114 if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON]
115 || dmgtype(ptr, AD_RBRE)) /* Chromatic Dragon */
117 /* check for magic resistance granted by wielded weapon */
118 o = is_you ? uwep : MON_WEP(mon);
119 if (o && o->oartifact && defends(AD_MAGM, o))
121 /* check for magic resistance granted by worn or carried items */
122 o = is_you ? invent : mon->minvent;
123 slotmask = W_ARMOR | W_ACCESSORY;
124 if (!is_you /* assumes monsters don't wield non-weapons */
125 || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
127 if (is_you && u.twoweap)
128 slotmask |= W_SWAPWEP;
129 for (; o; o = o->nobj)
130 if (((o->owornmask & slotmask) != 0L
131 && objects[o->otyp].oc_oprop == ANTIMAGIC)
132 || (o->oartifact && defends_when_carried(AD_MAGM, o)))
137 /* True iff monster is resistant to light-induced blindness */
142 struct permonst *ptr = mon->data;
143 boolean is_you = (mon == &youmonst);
147 if (is_you ? (Blind || Unaware)
148 : (mon->mblinded || !mon->mcansee || !haseyes(ptr)
149 /* BUG: temporary sleep sets mfrozen, but since
150 paralysis does too, we can't check it */
153 /* yellow light, Archon; !dust vortex, !cobra, !raven */
154 if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL)
155 || dmgtype_fromattack(ptr, AD_BLND, AT_GAZE))
157 o = is_you ? uwep : MON_WEP(mon);
158 if (o && o->oartifact && defends(AD_BLND, o))
160 o = is_you ? invent : mon->minvent;
161 slotmask = W_ARMOR | W_ACCESSORY;
162 if (!is_you /* assumes monsters don't wield non-weapons */
163 || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
165 if (is_you && u.twoweap)
166 slotmask |= W_SWAPWEP;
167 for (; o; o = o->nobj)
168 if (((o->owornmask & slotmask) != 0L
169 && objects[o->otyp].oc_oprop == BLINDED)
170 || (o->oartifact && defends_when_carried(AD_BLND, o)))
175 /* True iff monster can be blinded by the given attack;
176 note: may return True when mdef is blind (e.g. new cream-pie attack) */
178 can_blnd(magr, mdef, aatyp, obj)
179 struct monst *magr; /* NULL == no specific aggressor */
182 struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */
184 boolean is_you = (mdef == &youmonst);
185 boolean check_visor = FALSE;
189 /* no eyes protect against all attacks for now */
190 if (!haseyes(mdef->data))
198 case AT_BREA: /* assumed to be lightning */
199 /* light-based attacks may be cancelled or resisted */
200 if (magr && magr->mcan)
202 return !resists_blnd(mdef);
207 /* an object is used (thrown/spit/other) */
208 if (obj && (obj->otyp == CREAM_PIE)) {
209 if (is_you && Blindfolded)
211 } else if (obj && (obj->otyp == BLINDING_VENOM)) {
212 /* all ublindf, including LENSES, protect, cream-pies too */
213 if (is_you && (ublindf || u.ucreamed))
216 } else if (obj && (obj->otyp == POT_BLINDNESS)) {
217 return TRUE; /* no defense */
219 return FALSE; /* other objects cannot cause blindness yet */
220 if ((magr == &youmonst) && u.uswallow)
221 return FALSE; /* can't affect eyes while inside monster */
225 if (is_you && (Blindfolded || Unaware || u.ucreamed))
227 if (!is_you && mdef->msleeping)
232 /* e.g. raven: all ublindf, including LENSES, protect */
233 if (is_you && ublindf)
235 if ((magr == &youmonst) && u.uswallow)
236 return FALSE; /* can't affect eyes while inside monster */
242 /* some physical, blind-inducing attacks can be cancelled */
243 if (magr && magr->mcan)
251 /* check if wearing a visor (only checked if visor might help) */
253 o = (mdef == &youmonst) ? invent : mdef->minvent;
254 for (; o; o = o->nobj)
255 if ((o->owornmask & W_ARMH)
256 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
257 && !strcmp(s, "visored helmet"))
264 /* returns True if monster can attack at range */
267 struct permonst *ptr;
269 register int i, atyp;
270 long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE);
272 /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP)
273 * || attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE)
274 * || attacktype(ptr, AT_MAGC));
275 * but that's too slow -dlc
277 for (i = 0; i < NATTK; i++) {
278 atyp = ptr->mattk[i].aatyp;
281 /* assert(atyp < 32); */
282 if ((atk_mask & (1L << atyp)) != 0L)
288 /* True if specific monster is especially affected by silver weapons */
290 mon_hates_silver(mon)
293 return (boolean) (is_vampshifter(mon) || hates_silver(mon->data));
296 /* True if monster-type is especially affected by silver weapons */
299 register struct permonst *ptr;
301 return (boolean) (is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr)
302 || ptr == &mons[PM_SHADE]
303 || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
306 /* True iff the type of monster pass through iron bars */
309 struct permonst *mptr;
311 return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr)
312 || is_whirly(mptr) || verysmall(mptr)
313 || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST)
314 || (slithy(mptr) && !bigmonst(mptr)));
317 /* returns True if monster can blow (whistle, etc) */
320 register struct monst *mtmp;
322 if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ)
323 && (breathless(mtmp->data) || verysmall(mtmp->data)
324 || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL))
326 if ((mtmp == &youmonst) && Strangled)
331 /* True if mon is vulnerable to strangulation */
333 can_be_strangled(mon)
337 boolean nonbreathing, nobrainer;
339 /* For amulet of strangulation support: here we're considering
340 strangulation to be loss of blood flow to the brain due to
341 constriction of the arteries in the neck, so all headless
342 creatures are immune (no neck) as are mindless creatures
343 who don't need to breathe (brain, if any, doesn't care).
344 Mindless creatures who do need to breath are vulnerable, as
345 are non-breathing creatures which have higher brain function. */
346 if (!has_head(mon->data))
348 if (mon == &youmonst) {
349 /* hero can't be mindless but poly'ing into mindless form can
350 confer strangulation protection */
351 nobrainer = mindless(youmonst.data);
352 nonbreathing = Breathless;
354 nobrainer = mindless(mon->data);
355 /* monsters don't wear amulets of magical breathing,
356 so second part doesn't achieve anything useful... */
357 nonbreathing = (breathless(mon->data)
358 || ((mamul = which_armor(mon, W_AMUL)) != 0
359 && (mamul->otyp == AMULET_OF_MAGICAL_BREATHING)));
361 return (boolean) (!nobrainer || !nonbreathing);
364 /* returns True if monster can track well */
367 register struct permonst *ptr;
369 if (uwep && uwep->oartifact == ART_EXCALIBUR)
372 return (boolean) haseyes(ptr);
375 /* creature will slide out of armor */
378 register struct permonst *ptr;
380 return (boolean) (is_whirly(ptr) || ptr->msize <= MZ_SMALL
381 || noncorporeal(ptr));
384 /* creature will break out of armor */
387 register struct permonst *ptr;
392 return (boolean) (bigmonst(ptr)
393 || (ptr->msize > MZ_SMALL && !humanoid(ptr))
394 /* special cases of humanoids that cannot wear suits */
395 || ptr == &mons[PM_MARILITH]
396 || ptr == &mons[PM_WINGED_GARGOYLE]);
399 /* creature sticks other creatures it hits */
402 register struct permonst *ptr;
404 return (boolean) (dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP)
405 || attacktype(ptr, AT_HUGS));
408 /* some monster-types can't vomit */
411 struct permonst *ptr;
413 /* rats and mice are incapable of vomiting;
414 which other creatures have the same limitation? */
415 if (ptr->mlet == S_RODENT && ptr != &mons[PM_ROCK_MOLE]
416 && ptr != &mons[PM_WOODCHUCK])
421 /* number of horns this type of monster has on its head */
424 struct permonst *ptr;
426 switch (monsndx(ptr)) {
427 case PM_HORNED_DEVIL: /* ? "more than one" */
432 case PM_WHITE_UNICORN:
433 case PM_GRAY_UNICORN:
434 case PM_BLACK_UNICORN:
443 /* does monster-type deal out a particular type of damage from a particular
446 dmgtype_fromattack(ptr, dtyp, atyp)
447 struct permonst *ptr;
452 for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
453 if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp))
455 return (struct attack *) 0;
458 /* does monster-type deal out a particular type of damage from any attack */
461 struct permonst *ptr;
464 return dmgtype_fromattack(ptr, dtyp, AT_ANY) ? TRUE : FALSE;
467 /* returns the maximum damage a defender can do to the attacker via
470 max_passive_dmg(mdef, magr)
471 register struct monst *mdef, *magr;
473 int i, dmg = 0, multi2 = 0;
476 /* each attack by magr can result in passive damage */
477 for (i = 0; i < NATTK; i++)
478 switch (magr->data->mattk[i].aatyp) {
495 for (i = 0; i < NATTK; i++)
496 if (mdef->data->mattk[i].aatyp == AT_NONE
497 || mdef->data->mattk[i].aatyp == AT_BOOM) {
498 adtyp = mdef->data->mattk[i].adtyp;
499 if ((adtyp == AD_ACID && !resists_acid(magr))
500 || (adtyp == AD_COLD && !resists_cold(magr))
501 || (adtyp == AD_FIRE && !resists_fire(magr))
502 || (adtyp == AD_ELEC && !resists_elec(magr))
503 || adtyp == AD_PHYS) {
504 dmg = mdef->data->mattk[i].damn;
506 dmg = mdef->data->mlevel + 1;
507 dmg *= mdef->data->mattk[i].damd;
516 /* determine whether two monster types are from the same species */
519 struct permonst *pm1, *pm2;
521 char let1 = pm1->mlet, let2 = pm2->mlet;
524 return TRUE; /* exact match */
525 /* player races have their own predicates */
527 return is_human(pm2);
531 return is_dwarf(pm2);
533 return is_gnome(pm2);
536 /* other creatures are less precise */
538 return is_giant(pm2); /* open to quibbling here */
540 return is_golem(pm2); /* even moreso... */
541 if (is_mind_flayer(pm1))
542 return is_mind_flayer(pm2);
543 if (let1 == S_KOBOLD || pm1 == &mons[PM_KOBOLD_ZOMBIE]
544 || pm1 == &mons[PM_KOBOLD_MUMMY])
545 return (let2 == S_KOBOLD || pm2 == &mons[PM_KOBOLD_ZOMBIE]
546 || pm2 == &mons[PM_KOBOLD_MUMMY]);
548 return (let2 == S_OGRE);
550 return (let2 == S_NYMPH);
551 if (let1 == S_CENTAUR)
552 return (let2 == S_CENTAUR);
554 return is_unicorn(pm2);
555 if (let1 == S_DRAGON)
556 return (let2 == S_DRAGON);
558 return (let2 == S_NAGA);
559 /* other critters get steadily messier */
561 return is_rider(pm2); /* debatable */
563 return is_minion(pm2); /* [needs work?] */
564 /* tengu don't match imps (first test handled case of both being tengu) */
565 if (pm1 == &mons[PM_TENGU] || pm2 == &mons[PM_TENGU])
568 return (let2 == S_IMP);
569 /* and minor demons (imps) don't match major demons */
570 else if (let2 == S_IMP)
573 return is_demon(pm2);
574 if (is_undead(pm1)) {
575 if (let1 == S_ZOMBIE)
576 return (let2 == S_ZOMBIE);
578 return (let2 == S_MUMMY);
579 if (let1 == S_VAMPIRE)
580 return (let2 == S_VAMPIRE);
582 return (let2 == S_LICH);
583 if (let1 == S_WRAITH)
584 return (let2 == S_WRAITH);
586 return (let2 == S_GHOST);
587 } else if (is_undead(pm2))
590 /* check for monsters which grow into more mature forms */
592 int m1 = monsndx(pm1), m2 = monsndx(pm2), prv, nxt;
594 /* we know m1 != m2 (very first check above); test all smaller
595 forms of m1 against m2, then all larger ones; don't need to
596 make the corresponding tests for variants of m2 against m1 */
597 for (prv = m1, nxt = big_to_little(m1); nxt != prv;
598 prv = nxt, nxt = big_to_little(nxt))
601 for (prv = m1, nxt = little_to_big(m1); nxt != prv;
602 prv = nxt, nxt = little_to_big(nxt))
606 /* not caught by little/big handling */
607 if (pm1 == &mons[PM_GARGOYLE] || pm1 == &mons[PM_WINGED_GARGOYLE])
608 return (pm2 == &mons[PM_GARGOYLE]
609 || pm2 == &mons[PM_WINGED_GARGOYLE]);
610 if (pm1 == &mons[PM_KILLER_BEE] || pm1 == &mons[PM_QUEEN_BEE])
611 return (pm2 == &mons[PM_KILLER_BEE] || pm2 == &mons[PM_QUEEN_BEE]);
613 if (is_longworm(pm1))
614 return is_longworm(pm2); /* handles tail */
615 /* [currently there's no reason to bother matching up
616 assorted bugs and blobs with their closest variants] */
621 /* return an index into the mons array */
624 struct permonst *ptr;
628 i = (int) (ptr - &mons[0]);
629 if (i < LOW_PM || i >= NUMMONS) {
630 panic("monsndx - could not index monster (%s)",
631 fmt_ptr((genericptr_t) ptr));
632 return NON_PM; /* will not get here */
637 /* for handling alternate spellings */
643 /* figure out what type of monster a user-supplied string is specifying */
648 /* Be careful. We must check the entire string in case it was
649 * something such as "ettin zombie corpse". The calling routine
650 * doesn't know about the "corpse" until the monster name has
651 * already been taken off the front, so we have to be able to
652 * read the name with extraneous stuff such as "corpse" stuck on
654 * This causes a problem for names which prefix other names such
655 * as "ettin" on "ettin zombie". In this case we want the _longest_
657 * This also permits plurals created by adding suffixes such as 's'
658 * or 'es'. Other plurals must still be handled explicitly.
661 register int mntmp = NON_PM;
662 register char *s, *str, *term;
666 str = strcpy(buf, in_str);
668 if (!strncmp(str, "a ", 2))
670 else if (!strncmp(str, "an ", 3))
672 else if (!strncmp(str, "the ", 4))
678 if ((s = strstri(str, "vortices")) != 0)
680 /* be careful with "ies"; "priest", "zombies" */
681 else if (slen > 3 && !strcmpi(term - 3, "ies")
682 && (slen < 7 || strcmpi(term - 7, "zombies")))
683 Strcpy(term - 3, "y");
684 /* luckily no monster names end in fe or ve with ves plurals */
685 else if (slen > 3 && !strcmpi(term - 3, "ves"))
686 Strcpy(term - 3, "f");
688 slen = strlen(str); /* length possibly needs recomputing */
691 static const struct alt_spl names[] = {
692 /* Alternate spellings */
693 { "grey dragon", PM_GRAY_DRAGON },
694 { "baby grey dragon", PM_BABY_GRAY_DRAGON },
695 { "grey unicorn", PM_GRAY_UNICORN },
696 { "grey ooze", PM_GRAY_OOZE },
697 { "gray-elf", PM_GREY_ELF },
698 { "mindflayer", PM_MIND_FLAYER },
699 { "master mindflayer", PM_MASTER_MIND_FLAYER },
700 /* More alternates; priest and priestess are separate monster
701 types but that isn't the case for {aligned,high} priests */
702 { "aligned priestess", PM_ALIGNED_PRIEST },
703 { "high priestess", PM_HIGH_PRIEST },
704 /* Inappropriate singularization by -ves check above */
705 { "master of thief", PM_MASTER_OF_THIEVES },
706 /* Potential misspellings where we want to avoid falling back
707 to the rank title prefix (input has been singularized) */
708 { "master thief", PM_MASTER_OF_THIEVES },
709 { "master of assassin", PM_MASTER_ASSASSIN },
711 { "invisible stalker", PM_STALKER },
712 { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
713 { "halfling", PM_HOBBIT }, /* potential guess for polyself */
714 /* Hyphenated names */
715 { "ki rin", PM_KI_RIN },
716 { "uruk hai", PM_URUK_HAI },
717 { "orc captain", PM_ORC_CAPTAIN },
718 { "woodland elf", PM_WOODLAND_ELF },
719 { "green elf", PM_GREEN_ELF },
720 { "grey elf", PM_GREY_ELF },
721 { "gray elf", PM_GREY_ELF },
722 { "elf lord", PM_ELF_LORD },
723 { "olog hai", PM_OLOG_HAI },
724 { "arch lich", PM_ARCH_LICH },
725 /* Some irregular plurals */
726 { "incubi", PM_INCUBUS },
727 { "succubi", PM_SUCCUBUS },
728 { "violet fungi", PM_VIOLET_FUNGUS },
729 { "homunculi", PM_HOMUNCULUS },
730 { "baluchitheria", PM_BALUCHITHERIUM },
731 { "lurkers above", PM_LURKER_ABOVE },
732 { "cavemen", PM_CAVEMAN },
733 { "cavewomen", PM_CAVEWOMAN },
734 { "djinn", PM_DJINNI },
735 { "mumakil", PM_MUMAK },
736 { "erinyes", PM_ERINYS },
740 register const struct alt_spl *namep;
742 for (namep = names; namep->name; namep++)
743 if (!strncmpi(str, namep->name, (int) strlen(namep->name)))
744 return namep->pm_val;
747 for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
748 register int m_i_len = strlen(mons[i].mname);
750 if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
751 if (m_i_len == slen) {
752 return i; /* exact match */
753 } else if (slen > m_i_len
754 && (str[m_i_len] == ' '
755 || !strcmpi(&str[m_i_len], "s")
756 || !strncmpi(&str[m_i_len], "s ", 2)
757 || !strcmpi(&str[m_i_len], "'")
758 || !strncmpi(&str[m_i_len], "' ", 2)
759 || !strcmpi(&str[m_i_len], "'s")
760 || !strncmpi(&str[m_i_len], "'s ", 3)
761 || !strcmpi(&str[m_i_len], "es")
762 || !strncmpi(&str[m_i_len], "es ", 3))) {
769 mntmp = title_to_mon(str, (int *) 0, (int *) 0);
773 /* monster class from user input; used for genocide and controlled polymorph;
774 returns 0 rather than MAXMCLASSES if no match is found */
776 name_to_monclass(in_str, mndx_p)
780 /* Single letters are matched against def_monsyms[].sym; words
781 or phrases are first matched against def_monsyms[].explain
782 to check class description; if not found there, then against
783 mons[].mname to test individual monster types. Input can be a
784 substring of the full description or mname, but to be accepted,
785 such partial matches must start at beginning of a word. Some
786 class descriptions include "foo or bar" and "foo or other foo"
787 so we don't want to accept "or", "other", "or other" there. */
788 static NEARDATA const char *const falsematch[] = {
789 /* multiple-letter input which matches any of these gets rejected */
790 "an", "the", "or", "other", "or other", 0
792 /* positive pm_val => specific monster; negative => class */
793 static NEARDATA const struct alt_spl truematch[] = {
794 /* "long worm" won't match "worm" class but would accidentally match
795 "long worm tail" class before the comparison with monster types */
796 { "long worm", PM_LONG_WORM },
797 /* matches wrong--or at least suboptimal--class */
798 { "demon", -S_DEMON }, /* hits "imp or minor demon" */
799 /* matches specific monster (overly restrictive) */
800 { "devil", -S_DEMON }, /* always "horned devil" */
801 /* some plausible guesses which need help */
802 { "bug", -S_XAN }, /* would match bugbear... */
803 { "fish", -S_EEL }, /* wouldn't match anything */
811 *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
813 if (!in_str || !in_str[0]) {
816 } else if (!in_str[1]) {
817 /* single character */
818 i = def_char_to_monclass(*in_str);
819 if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
821 } else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
824 *mndx_p = PM_LONG_WORM;
825 } else if (i == MAXMCLASSES) /* maybe 'I' */
826 i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
829 /* multiple characters */
830 in_str = makesingular(in_str);
831 /* check for special cases */
832 for (i = 0; falsematch[i]; i++)
833 if (!strcmpi(in_str, falsematch[i]))
835 for (i = 0; truematch[i].name; i++)
836 if (!strcmpi(in_str, truematch[i].name)) {
837 i = truematch[i].pm_val;
839 return -i; /* class */
841 *mndx_p = i; /* monster */
844 /* check monster class descriptions */
845 for (i = 1; i < MAXMCLASSES; i++) {
846 x = def_monsyms[i].explain;
847 if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
850 /* check individual species names; not as thorough as mon_to_name()
851 but our caller can call that directly if desired */
852 for (i = LOW_PM; i < NUMMONS; i++) {
854 if ((p = strstri(x, in_str)) != 0
855 && (p == x || *(p - 1) == ' ')) {
865 /* returns 3 values (0=male, 1=female, 2=none) */
868 register struct monst *mtmp;
870 if (is_neuter(mtmp->data))
875 /* Like gender(), but lower animals and such are still "it".
876 This is the one we want to use when printing messages. */
879 register struct monst *mtmp;
881 if (is_neuter(mtmp->data) || !canspotmon(mtmp))
883 return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
884 || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
887 /* used for nearby monsters when you go to another level */
892 if (mtmp == u.usteed)
895 /* Wizard with Amulet won't bother trying to follow across levels */
896 if (mtmp->iswiz && mon_has_amulet(mtmp))
898 /* some monsters will follow even while intending to flee from you */
899 if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp))
901 /* stalking types follow, but won't when fleeing unless you hold
903 return (boolean) ((mtmp->data->mflags2 & M2_STALK)
904 && (!mtmp->mflee || u.uhave.amulet));
907 static const short grownups[][2] = {
908 { PM_CHICKATRICE, PM_COCKATRICE },
909 { PM_LITTLE_DOG, PM_DOG },
910 { PM_DOG, PM_LARGE_DOG },
911 { PM_HELL_HOUND_PUP, PM_HELL_HOUND },
912 { PM_WINTER_WOLF_CUB, PM_WINTER_WOLF },
913 { PM_KITTEN, PM_HOUSECAT },
914 { PM_HOUSECAT, PM_LARGE_CAT },
915 { PM_PONY, PM_HORSE },
916 { PM_HORSE, PM_WARHORSE },
917 { PM_KOBOLD, PM_LARGE_KOBOLD },
918 { PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
919 { PM_GNOME, PM_GNOME_LORD },
920 { PM_GNOME_LORD, PM_GNOME_KING },
921 { PM_DWARF, PM_DWARF_LORD },
922 { PM_DWARF_LORD, PM_DWARF_KING },
923 { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
924 { PM_ORC, PM_ORC_CAPTAIN },
925 { PM_HILL_ORC, PM_ORC_CAPTAIN },
926 { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
927 { PM_URUK_HAI, PM_ORC_CAPTAIN },
928 { PM_SEWER_RAT, PM_GIANT_RAT },
929 { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
930 { PM_OGRE, PM_OGRE_LORD },
931 { PM_OGRE_LORD, PM_OGRE_KING },
932 { PM_ELF, PM_ELF_LORD },
933 { PM_WOODLAND_ELF, PM_ELF_LORD },
934 { PM_GREEN_ELF, PM_ELF_LORD },
935 { PM_GREY_ELF, PM_ELF_LORD },
936 { PM_ELF_LORD, PM_ELVENKING },
937 { PM_LICH, PM_DEMILICH },
938 { PM_DEMILICH, PM_MASTER_LICH },
939 { PM_MASTER_LICH, PM_ARCH_LICH },
940 { PM_VAMPIRE, PM_VAMPIRE_LORD },
941 { PM_BAT, PM_GIANT_BAT },
942 { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
943 { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
945 {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
947 { PM_BABY_RED_DRAGON, PM_RED_DRAGON },
948 { PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON },
949 { PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON },
950 { PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON },
951 { PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON },
952 { PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON },
953 { PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON },
954 { PM_RED_NAGA_HATCHLING, PM_RED_NAGA },
955 { PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA },
956 { PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA },
957 { PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA },
958 { PM_SMALL_MIMIC, PM_LARGE_MIMIC },
959 { PM_LARGE_MIMIC, PM_GIANT_MIMIC },
960 { PM_BABY_LONG_WORM, PM_LONG_WORM },
961 { PM_BABY_PURPLE_WORM, PM_PURPLE_WORM },
962 { PM_BABY_CROCODILE, PM_CROCODILE },
963 { PM_SOLDIER, PM_SERGEANT },
964 { PM_SERGEANT, PM_LIEUTENANT },
965 { PM_LIEUTENANT, PM_CAPTAIN },
966 { PM_WATCHMAN, PM_WATCH_CAPTAIN },
967 { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
968 { PM_STUDENT, PM_ARCHEOLOGIST },
969 { PM_ATTENDANT, PM_HEALER },
970 { PM_PAGE, PM_KNIGHT },
971 { PM_ACOLYTE, PM_PRIEST },
972 { PM_APPRENTICE, PM_WIZARD },
973 { PM_MANES, PM_LEMURE },
974 { PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
975 { PM_KOP_SERGEANT, PM_KOP_LIEUTENANT },
976 { PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN },
981 little_to_big(montype)
986 for (i = 0; grownups[i][0] >= LOW_PM; i++)
987 if (montype == grownups[i][0]) {
988 montype = grownups[i][1];
995 big_to_little(montype)
1000 for (i = 0; grownups[i][0] >= LOW_PM; i++)
1001 if (montype == grownups[i][1]) {
1002 montype = grownups[i][0];
1009 * Return the permonst ptr for the race of the monster.
1010 * Returns correct pointer for non-polymorphed and polymorphed
1011 * player. It does not return a pointer to player role character.
1013 const struct permonst *
1017 if (mtmp == &youmonst && !Upolyd)
1018 return &mons[urace.malenum];
1024 static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" };
1026 static const char *levitate[4] = { "
\95\82\82", "
\95\82\82", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1028 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
1030 static const char *flys[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82Í
\82½
\82ß
\82", "
\82Í
\82½
\82ß
\82" };
1032 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
1034 static const char *flyl[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1036 static const char *slither[4] = { "slither", "Slither", "falter", "Falter" };
1038 static const char *slither[4] = { "
\8a\8a\82é", "
\8a\8a\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1040 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
1042 static const char *ooze[4] = { "
\82É
\82¶
\82Ý
\8fo
\82é", "
\82É
\82¶
\82Ý
\8fo
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1044 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
1046 static const char *immobile[4] = { "
\90k
\82¦
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1048 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
1050 static const char *crawl[4] = { "
\82Í
\82¢
\82¸
\82é", "
\82Í
\82¢
\82¸
\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1053 locomotion(ptr, def)
1054 const struct permonst *ptr;
1057 int capitalize = (*def == highc(*def));
1059 return (is_floater(ptr) ? levitate[capitalize]
1060 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1061 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1062 : slithy(ptr) ? slither[capitalize]
1063 : amorphous(ptr) ? ooze[capitalize]
1064 : !ptr->mmove ? immobile[capitalize]
1065 : nolimbs(ptr) ? crawl[capitalize]
1071 const struct permonst *ptr;
1074 int capitalize = 2 + (*def == highc(*def));
1076 return (is_floater(ptr) ? levitate[capitalize]
1077 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1078 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1079 : slithy(ptr) ? slither[capitalize]
1080 : amorphous(ptr) ? ooze[capitalize]
1081 : !ptr->mmove ? immobile[capitalize]
1082 : nolimbs(ptr) ? crawl[capitalize]
1086 static const char *levitate2 = "
\95\82\82«
\8fo
\82½";
1087 static const char *fly2 = "
\94ò
\82Ñ
\8fo
\82½";
1088 static const char *slither2 = "
\8a\8a\82è
\8fo
\82½";
1089 static const char *ooze2 = "
\82É
\82¶
\82Ý
\8fo
\82½";
1090 static const char *crawl2 = "
\82Í
\82¢
\82¸
\82è
\8fo
\82½";
1093 jumpedthrough(ptr, def)
1094 const struct permonst *ptr;
1098 is_floater(ptr) ? levitate2 :
1099 is_flyer(ptr) ? fly2 :
1100 slithy(ptr) ? slither2 :
1101 amorphous(ptr) ? ooze2 :
1102 nolimbs(ptr) ? crawl2 :
1108 /* return phrase describing the effect of fire attack on a type of monster */
1110 on_fire(mptr, mattk)
1111 struct permonst *mptr;
1112 struct attack *mattk;
1116 switch (monsndx(mptr)) {
1117 case PM_FLAMING_SPHERE:
1118 case PM_FIRE_VORTEX:
1119 case PM_FIRE_ELEMENTAL:
1122 what = "already on fire";
1124 what = "
\82·
\82Å
\82É
\89\8a\82É
\82Â
\82Â
\82Ü
\82ê
\82Ä
\82¢
\82é";
1126 case PM_WATER_ELEMENTAL:
1128 case PM_STEAM_VORTEX:
1132 what = "
\95¦
\93«
\82µ
\82½";
1135 case PM_GLASS_GOLEM:
1139 what = "
\97n
\82¯
\82½";
1141 case PM_STONE_GOLEM:
1144 case PM_AIR_ELEMENTAL:
1145 case PM_EARTH_ELEMENTAL:
1146 case PM_DUST_VORTEX:
1147 case PM_ENERGY_VORTEX:
1149 what = "heating up";
1151 what = "
\94M
\82
\82È
\82Á
\82½";
1155 what = (mattk->aatyp == AT_HUGS) ? "being roasted" : "on fire";
1157 what = (mattk->aatyp == AT_HUGS) ? "
\8aÛ
\8fÄ
\82¯
\82É
\82È
\82Á
\82½" : "
\89Î
\82¾
\82é
\82Ü
\82É
\82È
\82Á
\82½";
1165 * True if monster is presumed to have a sense of smell.
1166 * False if monster definitely does not have a sense of smell.
1168 * Do not base this on presence of a head or nose, since many
1169 * creatures sense smells other ways (feelers, forked-tongues, etc.)
1170 * We're assuming all insects can smell at a distance too.
1174 struct permonst *mdat;
1177 || mdat->mlet == S_EYE /* spheres */
1178 || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING
1179 || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX
1180 || mdat->mlet == S_ELEMENTAL
1181 || mdat->mlet == S_FUNGUS /* mushrooms and fungi */
1182 || mdat->mlet == S_LIGHT)