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)
256 if ((o->owornmask & W_ARMH)
257 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
258 && !strcmp(s, "visored helmet"))
260 if ((o->owornmask & W_ARMH)
261 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
262 && !strcmp(s, "
\96Ê
\96j
\95t
\82«
\82Ì
\8a\95"))
270 /* returns True if monster can attack at range */
273 struct permonst *ptr;
275 register int i, atyp;
276 long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE);
278 /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP)
279 * || attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE)
280 * || attacktype(ptr, AT_MAGC));
281 * but that's too slow -dlc
283 for (i = 0; i < NATTK; i++) {
284 atyp = ptr->mattk[i].aatyp;
287 /* assert(atyp < 32); */
288 if ((atk_mask & (1L << atyp)) != 0L)
294 /* True if specific monster is especially affected by silver weapons */
296 mon_hates_silver(mon)
299 return (boolean) (is_vampshifter(mon) || hates_silver(mon->data));
302 /* True if monster-type is especially affected by silver weapons */
305 register struct permonst *ptr;
307 return (boolean) (is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr)
308 || ptr == &mons[PM_SHADE]
309 || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
312 /* True iff the type of monster pass through iron bars */
315 struct permonst *mptr;
317 return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr)
318 || is_whirly(mptr) || verysmall(mptr)
319 || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST)
320 || (slithy(mptr) && !bigmonst(mptr)));
323 /* returns True if monster can blow (whistle, etc) */
326 register struct monst *mtmp;
328 if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ)
329 && (breathless(mtmp->data) || verysmall(mtmp->data)
330 || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL))
332 if ((mtmp == &youmonst) && Strangled)
337 /* True if mon is vulnerable to strangulation */
339 can_be_strangled(mon)
343 boolean nonbreathing, nobrainer;
345 /* For amulet of strangulation support: here we're considering
346 strangulation to be loss of blood flow to the brain due to
347 constriction of the arteries in the neck, so all headless
348 creatures are immune (no neck) as are mindless creatures
349 who don't need to breathe (brain, if any, doesn't care).
350 Mindless creatures who do need to breath are vulnerable, as
351 are non-breathing creatures which have higher brain function. */
352 if (!has_head(mon->data))
354 if (mon == &youmonst) {
355 /* hero can't be mindless but poly'ing into mindless form can
356 confer strangulation protection */
357 nobrainer = mindless(youmonst.data);
358 nonbreathing = Breathless;
360 nobrainer = mindless(mon->data);
361 /* monsters don't wear amulets of magical breathing,
362 so second part doesn't achieve anything useful... */
363 nonbreathing = (breathless(mon->data)
364 || ((mamul = which_armor(mon, W_AMUL)) != 0
365 && (mamul->otyp == AMULET_OF_MAGICAL_BREATHING)));
367 return (boolean) (!nobrainer || !nonbreathing);
370 /* returns True if monster can track well */
373 register struct permonst *ptr;
375 if (uwep && uwep->oartifact == ART_EXCALIBUR)
378 return (boolean) haseyes(ptr);
381 /* creature will slide out of armor */
384 register struct permonst *ptr;
386 return (boolean) (is_whirly(ptr) || ptr->msize <= MZ_SMALL
387 || noncorporeal(ptr));
390 /* creature will break out of armor */
393 register struct permonst *ptr;
398 return (boolean) (bigmonst(ptr)
399 || (ptr->msize > MZ_SMALL && !humanoid(ptr))
400 /* special cases of humanoids that cannot wear suits */
401 || ptr == &mons[PM_MARILITH]
402 || ptr == &mons[PM_WINGED_GARGOYLE]);
405 /* creature sticks other creatures it hits */
408 register struct permonst *ptr;
410 return (boolean) (dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP)
411 || attacktype(ptr, AT_HUGS));
414 /* some monster-types can't vomit */
417 struct permonst *ptr;
419 /* rats and mice are incapable of vomiting;
420 which other creatures have the same limitation? */
421 if (ptr->mlet == S_RODENT && ptr != &mons[PM_ROCK_MOLE]
422 && ptr != &mons[PM_WOODCHUCK])
427 /* number of horns this type of monster has on its head */
430 struct permonst *ptr;
432 switch (monsndx(ptr)) {
433 case PM_HORNED_DEVIL: /* ? "more than one" */
438 case PM_WHITE_UNICORN:
439 case PM_GRAY_UNICORN:
440 case PM_BLACK_UNICORN:
449 /* does monster-type deal out a particular type of damage from a particular
452 dmgtype_fromattack(ptr, dtyp, atyp)
453 struct permonst *ptr;
458 for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
459 if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp))
461 return (struct attack *) 0;
464 /* does monster-type deal out a particular type of damage from any attack */
467 struct permonst *ptr;
470 return dmgtype_fromattack(ptr, dtyp, AT_ANY) ? TRUE : FALSE;
473 /* returns the maximum damage a defender can do to the attacker via
476 max_passive_dmg(mdef, magr)
477 register struct monst *mdef, *magr;
479 int i, dmg = 0, multi2 = 0;
482 /* each attack by magr can result in passive damage */
483 for (i = 0; i < NATTK; i++)
484 switch (magr->data->mattk[i].aatyp) {
501 for (i = 0; i < NATTK; i++)
502 if (mdef->data->mattk[i].aatyp == AT_NONE
503 || mdef->data->mattk[i].aatyp == AT_BOOM) {
504 adtyp = mdef->data->mattk[i].adtyp;
505 if ((adtyp == AD_ACID && !resists_acid(magr))
506 || (adtyp == AD_COLD && !resists_cold(magr))
507 || (adtyp == AD_FIRE && !resists_fire(magr))
508 || (adtyp == AD_ELEC && !resists_elec(magr))
509 || adtyp == AD_PHYS) {
510 dmg = mdef->data->mattk[i].damn;
512 dmg = mdef->data->mlevel + 1;
513 dmg *= mdef->data->mattk[i].damd;
522 /* determine whether two monster types are from the same species */
525 struct permonst *pm1, *pm2;
527 char let1 = pm1->mlet, let2 = pm2->mlet;
530 return TRUE; /* exact match */
531 /* player races have their own predicates */
533 return is_human(pm2);
537 return is_dwarf(pm2);
539 return is_gnome(pm2);
542 /* other creatures are less precise */
544 return is_giant(pm2); /* open to quibbling here */
546 return is_golem(pm2); /* even moreso... */
547 if (is_mind_flayer(pm1))
548 return is_mind_flayer(pm2);
549 if (let1 == S_KOBOLD || pm1 == &mons[PM_KOBOLD_ZOMBIE]
550 || pm1 == &mons[PM_KOBOLD_MUMMY])
551 return (let2 == S_KOBOLD || pm2 == &mons[PM_KOBOLD_ZOMBIE]
552 || pm2 == &mons[PM_KOBOLD_MUMMY]);
554 return (let2 == S_OGRE);
556 return (let2 == S_NYMPH);
557 if (let1 == S_CENTAUR)
558 return (let2 == S_CENTAUR);
560 return is_unicorn(pm2);
561 if (let1 == S_DRAGON)
562 return (let2 == S_DRAGON);
564 return (let2 == S_NAGA);
565 /* other critters get steadily messier */
567 return is_rider(pm2); /* debatable */
569 return is_minion(pm2); /* [needs work?] */
570 /* tengu don't match imps (first test handled case of both being tengu) */
571 if (pm1 == &mons[PM_TENGU] || pm2 == &mons[PM_TENGU])
574 return (let2 == S_IMP);
575 /* and minor demons (imps) don't match major demons */
576 else if (let2 == S_IMP)
579 return is_demon(pm2);
580 if (is_undead(pm1)) {
581 if (let1 == S_ZOMBIE)
582 return (let2 == S_ZOMBIE);
584 return (let2 == S_MUMMY);
585 if (let1 == S_VAMPIRE)
586 return (let2 == S_VAMPIRE);
588 return (let2 == S_LICH);
589 if (let1 == S_WRAITH)
590 return (let2 == S_WRAITH);
592 return (let2 == S_GHOST);
593 } else if (is_undead(pm2))
596 /* check for monsters which grow into more mature forms */
598 int m1 = monsndx(pm1), m2 = monsndx(pm2), prv, nxt;
600 /* we know m1 != m2 (very first check above); test all smaller
601 forms of m1 against m2, then all larger ones; don't need to
602 make the corresponding tests for variants of m2 against m1 */
603 for (prv = m1, nxt = big_to_little(m1); nxt != prv;
604 prv = nxt, nxt = big_to_little(nxt))
607 for (prv = m1, nxt = little_to_big(m1); nxt != prv;
608 prv = nxt, nxt = little_to_big(nxt))
612 /* not caught by little/big handling */
613 if (pm1 == &mons[PM_GARGOYLE] || pm1 == &mons[PM_WINGED_GARGOYLE])
614 return (pm2 == &mons[PM_GARGOYLE]
615 || pm2 == &mons[PM_WINGED_GARGOYLE]);
616 if (pm1 == &mons[PM_KILLER_BEE] || pm1 == &mons[PM_QUEEN_BEE])
617 return (pm2 == &mons[PM_KILLER_BEE] || pm2 == &mons[PM_QUEEN_BEE]);
619 if (is_longworm(pm1))
620 return is_longworm(pm2); /* handles tail */
621 /* [currently there's no reason to bother matching up
622 assorted bugs and blobs with their closest variants] */
627 /* return an index into the mons array */
630 struct permonst *ptr;
634 i = (int) (ptr - &mons[0]);
635 if (i < LOW_PM || i >= NUMMONS) {
636 panic("monsndx - could not index monster (%s)",
637 fmt_ptr((genericptr_t) ptr));
638 return NON_PM; /* will not get here */
643 /* for handling alternate spellings */
649 /* figure out what type of monster a user-supplied string is specifying */
654 /* Be careful. We must check the entire string in case it was
655 * something such as "ettin zombie corpse". The calling routine
656 * doesn't know about the "corpse" until the monster name has
657 * already been taken off the front, so we have to be able to
658 * read the name with extraneous stuff such as "corpse" stuck on
660 * This causes a problem for names which prefix other names such
661 * as "ettin" on "ettin zombie". In this case we want the _longest_
663 * This also permits plurals created by adding suffixes such as 's'
664 * or 'es'. Other plurals must still be handled explicitly.
667 register int mntmp = NON_PM;
668 register char *s, *str, *term;
672 str = strcpy(buf, in_str);
674 if (!strncmp(str, "a ", 2))
676 else if (!strncmp(str, "an ", 3))
678 else if (!strncmp(str, "the ", 4))
684 if ((s = strstri(str, "vortices")) != 0)
686 /* be careful with "ies"; "priest", "zombies" */
687 else if (slen > 3 && !strcmpi(term - 3, "ies")
688 && (slen < 7 || strcmpi(term - 7, "zombies")))
689 Strcpy(term - 3, "y");
690 /* luckily no monster names end in fe or ve with ves plurals */
691 else if (slen > 3 && !strcmpi(term - 3, "ves"))
692 Strcpy(term - 3, "f");
694 slen = strlen(str); /* length possibly needs recomputing */
697 static const struct alt_spl names[] = {
698 /* Alternate spellings */
699 { "grey dragon", PM_GRAY_DRAGON },
700 { "baby grey dragon", PM_BABY_GRAY_DRAGON },
701 { "grey unicorn", PM_GRAY_UNICORN },
702 { "grey ooze", PM_GRAY_OOZE },
703 { "gray-elf", PM_GREY_ELF },
704 { "mindflayer", PM_MIND_FLAYER },
705 { "master mindflayer", PM_MASTER_MIND_FLAYER },
706 /* More alternates; priest and priestess are separate monster
707 types but that isn't the case for {aligned,high} priests */
708 { "aligned priestess", PM_ALIGNED_PRIEST },
709 { "high priestess", PM_HIGH_PRIEST },
710 /* Inappropriate singularization by -ves check above */
711 { "master of thief", PM_MASTER_OF_THIEVES },
712 /* Potential misspellings where we want to avoid falling back
713 to the rank title prefix (input has been singularized) */
714 { "master thief", PM_MASTER_OF_THIEVES },
715 { "master of assassin", PM_MASTER_ASSASSIN },
717 { "invisible stalker", PM_STALKER },
718 { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
719 { "halfling", PM_HOBBIT }, /* potential guess for polyself */
720 /* Hyphenated names */
721 { "ki rin", PM_KI_RIN },
722 { "uruk hai", PM_URUK_HAI },
723 { "orc captain", PM_ORC_CAPTAIN },
724 { "woodland elf", PM_WOODLAND_ELF },
725 { "green elf", PM_GREEN_ELF },
726 { "grey elf", PM_GREY_ELF },
727 { "gray elf", PM_GREY_ELF },
728 { "elf lord", PM_ELF_LORD },
729 { "olog hai", PM_OLOG_HAI },
730 { "arch lich", PM_ARCH_LICH },
731 /* Some irregular plurals */
732 { "incubi", PM_INCUBUS },
733 { "succubi", PM_SUCCUBUS },
734 { "violet fungi", PM_VIOLET_FUNGUS },
735 { "homunculi", PM_HOMUNCULUS },
736 { "baluchitheria", PM_BALUCHITHERIUM },
737 { "lurkers above", PM_LURKER_ABOVE },
738 { "cavemen", PM_CAVEMAN },
739 { "cavewomen", PM_CAVEWOMAN },
740 { "djinn", PM_DJINNI },
741 { "mumakil", PM_MUMAK },
742 { "erinyes", PM_ERINYS },
746 register const struct alt_spl *namep;
748 for (namep = names; namep->name; namep++)
749 if (!strncmpi(str, namep->name, (int) strlen(namep->name)))
750 return namep->pm_val;
753 for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
754 register int m_i_len = strlen(mons[i].mname);
756 if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
757 if (m_i_len == slen) {
758 return i; /* exact match */
759 } else if (slen > m_i_len
760 && (str[m_i_len] == ' '
761 || !strcmpi(&str[m_i_len], "s")
762 || !strncmpi(&str[m_i_len], "s ", 2)
763 || !strcmpi(&str[m_i_len], "'")
764 || !strncmpi(&str[m_i_len], "' ", 2)
765 || !strcmpi(&str[m_i_len], "'s")
766 || !strncmpi(&str[m_i_len], "'s ", 3)
767 || !strcmpi(&str[m_i_len], "es")
768 || !strncmpi(&str[m_i_len], "es ", 3))) {
775 mntmp = title_to_mon(str, (int *) 0, (int *) 0);
779 /* monster class from user input; used for genocide and controlled polymorph;
780 returns 0 rather than MAXMCLASSES if no match is found */
782 name_to_monclass(in_str, mndx_p)
786 /* Single letters are matched against def_monsyms[].sym; words
787 or phrases are first matched against def_monsyms[].explain
788 to check class description; if not found there, then against
789 mons[].mname to test individual monster types. Input can be a
790 substring of the full description or mname, but to be accepted,
791 such partial matches must start at beginning of a word. Some
792 class descriptions include "foo or bar" and "foo or other foo"
793 so we don't want to accept "or", "other", "or other" there. */
794 static NEARDATA const char *const falsematch[] = {
795 /* multiple-letter input which matches any of these gets rejected */
796 "an", "the", "or", "other", "or other", 0
798 /* positive pm_val => specific monster; negative => class */
799 static NEARDATA const struct alt_spl truematch[] = {
800 /* "long worm" won't match "worm" class but would accidentally match
801 "long worm tail" class before the comparison with monster types */
802 { "long worm", PM_LONG_WORM },
803 /* matches wrong--or at least suboptimal--class */
804 { "demon", -S_DEMON }, /* hits "imp or minor demon" */
805 /* matches specific monster (overly restrictive) */
806 { "devil", -S_DEMON }, /* always "horned devil" */
807 /* some plausible guesses which need help */
808 { "bug", -S_XAN }, /* would match bugbear... */
809 { "fish", -S_EEL }, /* wouldn't match anything */
817 *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
819 if (!in_str || !in_str[0]) {
822 } else if (!in_str[1]) {
823 /* single character */
824 i = def_char_to_monclass(*in_str);
825 if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
827 } else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
830 *mndx_p = PM_LONG_WORM;
831 } else if (i == MAXMCLASSES) /* maybe 'I' */
832 i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
835 /* multiple characters */
836 in_str = makesingular(in_str);
837 /* check for special cases */
838 for (i = 0; falsematch[i]; i++)
839 if (!strcmpi(in_str, falsematch[i]))
841 for (i = 0; truematch[i].name; i++)
842 if (!strcmpi(in_str, truematch[i].name)) {
843 i = truematch[i].pm_val;
845 return -i; /* class */
847 *mndx_p = i; /* monster */
850 /* check monster class descriptions */
851 for (i = 1; i < MAXMCLASSES; i++) {
852 x = def_monsyms[i].explain;
853 if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
856 /* check individual species names; not as thorough as mon_to_name()
857 but our caller can call that directly if desired */
858 for (i = LOW_PM; i < NUMMONS; i++) {
860 if ((p = strstri(x, in_str)) != 0
861 && (p == x || *(p - 1) == ' ')) {
871 /* returns 3 values (0=male, 1=female, 2=none) */
874 register struct monst *mtmp;
876 if (is_neuter(mtmp->data))
881 /* Like gender(), but lower animals and such are still "it".
882 This is the one we want to use when printing messages. */
885 register struct monst *mtmp;
887 if (is_neuter(mtmp->data) || !canspotmon(mtmp))
889 return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
890 || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
893 /* used for nearby monsters when you go to another level */
898 if (mtmp == u.usteed)
901 /* Wizard with Amulet won't bother trying to follow across levels */
902 if (mtmp->iswiz && mon_has_amulet(mtmp))
904 /* some monsters will follow even while intending to flee from you */
905 if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp))
907 /* stalking types follow, but won't when fleeing unless you hold
909 return (boolean) ((mtmp->data->mflags2 & M2_STALK)
910 && (!mtmp->mflee || u.uhave.amulet));
913 static const short grownups[][2] = {
914 { PM_CHICKATRICE, PM_COCKATRICE },
915 { PM_LITTLE_DOG, PM_DOG },
916 { PM_DOG, PM_LARGE_DOG },
917 { PM_HELL_HOUND_PUP, PM_HELL_HOUND },
918 { PM_WINTER_WOLF_CUB, PM_WINTER_WOLF },
919 { PM_KITTEN, PM_HOUSECAT },
920 { PM_HOUSECAT, PM_LARGE_CAT },
921 { PM_PONY, PM_HORSE },
922 { PM_HORSE, PM_WARHORSE },
923 { PM_KOBOLD, PM_LARGE_KOBOLD },
924 { PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
925 { PM_GNOME, PM_GNOME_LORD },
926 { PM_GNOME_LORD, PM_GNOME_KING },
927 { PM_DWARF, PM_DWARF_LORD },
928 { PM_DWARF_LORD, PM_DWARF_KING },
929 { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
930 { PM_ORC, PM_ORC_CAPTAIN },
931 { PM_HILL_ORC, PM_ORC_CAPTAIN },
932 { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
933 { PM_URUK_HAI, PM_ORC_CAPTAIN },
934 { PM_SEWER_RAT, PM_GIANT_RAT },
935 { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
936 { PM_OGRE, PM_OGRE_LORD },
937 { PM_OGRE_LORD, PM_OGRE_KING },
938 { PM_ELF, PM_ELF_LORD },
939 { PM_WOODLAND_ELF, PM_ELF_LORD },
940 { PM_GREEN_ELF, PM_ELF_LORD },
941 { PM_GREY_ELF, PM_ELF_LORD },
942 { PM_ELF_LORD, PM_ELVENKING },
943 { PM_LICH, PM_DEMILICH },
944 { PM_DEMILICH, PM_MASTER_LICH },
945 { PM_MASTER_LICH, PM_ARCH_LICH },
946 { PM_VAMPIRE, PM_VAMPIRE_LORD },
947 { PM_BAT, PM_GIANT_BAT },
948 { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
949 { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
951 {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
953 { PM_BABY_RED_DRAGON, PM_RED_DRAGON },
954 { PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON },
955 { PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON },
956 { PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON },
957 { PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON },
958 { PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON },
959 { PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON },
960 { PM_RED_NAGA_HATCHLING, PM_RED_NAGA },
961 { PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA },
962 { PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA },
963 { PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA },
964 { PM_SMALL_MIMIC, PM_LARGE_MIMIC },
965 { PM_LARGE_MIMIC, PM_GIANT_MIMIC },
966 { PM_BABY_LONG_WORM, PM_LONG_WORM },
967 { PM_BABY_PURPLE_WORM, PM_PURPLE_WORM },
968 { PM_BABY_CROCODILE, PM_CROCODILE },
969 { PM_SOLDIER, PM_SERGEANT },
970 { PM_SERGEANT, PM_LIEUTENANT },
971 { PM_LIEUTENANT, PM_CAPTAIN },
972 { PM_WATCHMAN, PM_WATCH_CAPTAIN },
973 { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
974 { PM_STUDENT, PM_ARCHEOLOGIST },
975 { PM_ATTENDANT, PM_HEALER },
976 { PM_PAGE, PM_KNIGHT },
977 { PM_ACOLYTE, PM_PRIEST },
978 { PM_APPRENTICE, PM_WIZARD },
979 { PM_MANES, PM_LEMURE },
980 { PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
981 { PM_KOP_SERGEANT, PM_KOP_LIEUTENANT },
982 { PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN },
987 little_to_big(montype)
992 for (i = 0; grownups[i][0] >= LOW_PM; i++)
993 if (montype == grownups[i][0]) {
994 montype = grownups[i][1];
1001 big_to_little(montype)
1006 for (i = 0; grownups[i][0] >= LOW_PM; i++)
1007 if (montype == grownups[i][1]) {
1008 montype = grownups[i][0];
1015 * Return the permonst ptr for the race of the monster.
1016 * Returns correct pointer for non-polymorphed and polymorphed
1017 * player. It does not return a pointer to player role character.
1019 const struct permonst *
1023 if (mtmp == &youmonst && !Upolyd)
1024 return &mons[urace.malenum];
1030 static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" };
1032 static const char *levitate[4] = { "
\95\82\82", "
\95\82\82", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1034 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
1036 static const char *flys[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82Í
\82½
\82ß
\82", "
\82Í
\82½
\82ß
\82" };
1038 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
1040 static const char *flyl[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1042 static const char *slither[4] = { "slither", "Slither", "falter", "Falter" };
1044 static const char *slither[4] = { "
\8a\8a\82é", "
\8a\8a\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1046 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
1048 static const char *ooze[4] = { "
\82É
\82¶
\82Ý
\8fo
\82é", "
\82É
\82¶
\82Ý
\8fo
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1050 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
1052 static const char *immobile[4] = { "
\90k
\82¦
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1054 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
1056 static const char *crawl[4] = { "
\82Í
\82¢
\82¸
\82é", "
\82Í
\82¢
\82¸
\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1059 locomotion(ptr, def)
1060 const struct permonst *ptr;
1063 int capitalize = (*def == highc(*def));
1065 return (is_floater(ptr) ? levitate[capitalize]
1066 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1067 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1068 : slithy(ptr) ? slither[capitalize]
1069 : amorphous(ptr) ? ooze[capitalize]
1070 : !ptr->mmove ? immobile[capitalize]
1071 : nolimbs(ptr) ? crawl[capitalize]
1077 const struct permonst *ptr;
1080 int capitalize = 2 + (*def == highc(*def));
1082 return (is_floater(ptr) ? levitate[capitalize]
1083 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1084 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1085 : slithy(ptr) ? slither[capitalize]
1086 : amorphous(ptr) ? ooze[capitalize]
1087 : !ptr->mmove ? immobile[capitalize]
1088 : nolimbs(ptr) ? crawl[capitalize]
1092 static const char *levitate2 = "
\95\82\82«
\8fo
\82½";
1093 static const char *fly2 = "
\94ò
\82Ñ
\8fo
\82½";
1094 static const char *slither2 = "
\8a\8a\82è
\8fo
\82½";
1095 static const char *ooze2 = "
\82É
\82¶
\82Ý
\8fo
\82½";
1096 static const char *crawl2 = "
\82Í
\82¢
\82¸
\82è
\8fo
\82½";
1099 jumpedthrough(ptr, def)
1100 const struct permonst *ptr;
1104 is_floater(ptr) ? levitate2 :
1105 is_flyer(ptr) ? fly2 :
1106 slithy(ptr) ? slither2 :
1107 amorphous(ptr) ? ooze2 :
1108 nolimbs(ptr) ? crawl2 :
1114 /* return phrase describing the effect of fire attack on a type of monster */
1116 on_fire(mptr, mattk)
1117 struct permonst *mptr;
1118 struct attack *mattk;
1122 switch (monsndx(mptr)) {
1123 case PM_FLAMING_SPHERE:
1124 case PM_FIRE_VORTEX:
1125 case PM_FIRE_ELEMENTAL:
1128 what = "already on fire";
1130 what = "
\82·
\82Å
\82É
\89\8a\82É
\82Â
\82Â
\82Ü
\82ê
\82Ä
\82¢
\82é";
1132 case PM_WATER_ELEMENTAL:
1134 case PM_STEAM_VORTEX:
1138 what = "
\95¦
\93«
\82µ
\82½";
1141 case PM_GLASS_GOLEM:
1145 what = "
\97n
\82¯
\82½";
1147 case PM_STONE_GOLEM:
1150 case PM_AIR_ELEMENTAL:
1151 case PM_EARTH_ELEMENTAL:
1152 case PM_DUST_VORTEX:
1153 case PM_ENERGY_VORTEX:
1155 what = "heating up";
1157 what = "
\94M
\82
\82È
\82Á
\82½";
1161 what = (mattk->aatyp == AT_HUGS) ? "being roasted" : "on fire";
1163 what = (mattk->aatyp == AT_HUGS) ? "
\8aÛ
\8fÄ
\82¯
\82É
\82È
\82Á
\82½" : "
\89Î
\82¾
\82é
\82Ü
\82É
\82È
\82Á
\82½";
1171 * True if monster is presumed to have a sense of smell.
1172 * False if monster definitely does not have a sense of smell.
1174 * Do not base this on presence of a head or nose, since many
1175 * creatures sense smells other ways (feelers, forked-tongues, etc.)
1176 * We're assuming all insects can smell at a distance too.
1180 struct permonst *mdat;
1183 || mdat->mlet == S_EYE /* spheres */
1184 || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING
1185 || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX
1186 || mdat->mlet == S_ELEMENTAL
1187 || mdat->mlet == S_FUNGUS /* mushrooms and fungi */
1188 || mdat->mlet == S_LIGHT)