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
761 && (str[m_i_len] == ' '
762 || !strcmpi(&str[m_i_len], "s")
763 || !strncmpi(&str[m_i_len], "s ", 2)
764 || !strcmpi(&str[m_i_len], "'")
765 || !strncmpi(&str[m_i_len], "' ", 2)
766 || !strcmpi(&str[m_i_len], "'s")
767 || !strncmpi(&str[m_i_len], "'s ", 3)
768 || !strcmpi(&str[m_i_len], "es")
769 || !strncmpi(&str[m_i_len], "es ", 3))) {
771 && !strncmp(&str[m_i_len], "
\82Ì", 2)) {
779 mntmp = title_to_mon(str, (int *) 0, (int *) 0);
783 /* monster class from user input; used for genocide and controlled polymorph;
784 returns 0 rather than MAXMCLASSES if no match is found */
786 name_to_monclass(in_str, mndx_p)
790 /* Single letters are matched against def_monsyms[].sym; words
791 or phrases are first matched against def_monsyms[].explain
792 to check class description; if not found there, then against
793 mons[].mname to test individual monster types. Input can be a
794 substring of the full description or mname, but to be accepted,
795 such partial matches must start at beginning of a word. Some
796 class descriptions include "foo or bar" and "foo or other foo"
797 so we don't want to accept "or", "other", "or other" there. */
798 static NEARDATA const char *const falsematch[] = {
799 /* multiple-letter input which matches any of these gets rejected */
800 "an", "the", "or", "other", "or other", 0
802 /* positive pm_val => specific monster; negative => class */
803 static NEARDATA const struct alt_spl truematch[] = {
804 /* "long worm" won't match "worm" class but would accidentally match
805 "long worm tail" class before the comparison with monster types */
806 { "long worm", PM_LONG_WORM },
807 /* matches wrong--or at least suboptimal--class */
808 { "demon", -S_DEMON }, /* hits "imp or minor demon" */
809 /* matches specific monster (overly restrictive) */
810 { "devil", -S_DEMON }, /* always "horned devil" */
811 /* some plausible guesses which need help */
812 { "bug", -S_XAN }, /* would match bugbear... */
813 { "fish", -S_EEL }, /* wouldn't match anything */
821 *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
823 if (!in_str || !in_str[0]) {
826 } else if (!in_str[1]) {
827 /* single character */
828 i = def_char_to_monclass(*in_str);
829 if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
831 } else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
834 *mndx_p = PM_LONG_WORM;
835 } else if (i == MAXMCLASSES) /* maybe 'I' */
836 i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
839 /* multiple characters */
840 in_str = makesingular(in_str);
841 /* check for special cases */
842 for (i = 0; falsematch[i]; i++)
843 if (!strcmpi(in_str, falsematch[i]))
845 for (i = 0; truematch[i].name; i++)
846 if (!strcmpi(in_str, truematch[i].name)) {
847 i = truematch[i].pm_val;
849 return -i; /* class */
851 *mndx_p = i; /* monster */
854 /* check monster class descriptions */
855 for (i = 1; i < MAXMCLASSES; i++) {
856 x = def_monsyms[i].explain;
857 if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
860 /* check individual species names; not as thorough as mon_to_name()
861 but our caller can call that directly if desired */
862 for (i = LOW_PM; i < NUMMONS; i++) {
864 if ((p = strstri(x, in_str)) != 0
865 && (p == x || *(p - 1) == ' ')) {
875 /* returns 3 values (0=male, 1=female, 2=none) */
878 register struct monst *mtmp;
880 if (is_neuter(mtmp->data))
885 /* Like gender(), but lower animals and such are still "it".
886 This is the one we want to use when printing messages. */
889 register struct monst *mtmp;
891 if (is_neuter(mtmp->data) || !canspotmon(mtmp))
893 return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
894 || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
897 /* used for nearby monsters when you go to another level */
902 if (mtmp == u.usteed)
905 /* Wizard with Amulet won't bother trying to follow across levels */
906 if (mtmp->iswiz && mon_has_amulet(mtmp))
908 /* some monsters will follow even while intending to flee from you */
909 if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp))
911 /* stalking types follow, but won't when fleeing unless you hold
913 return (boolean) ((mtmp->data->mflags2 & M2_STALK)
914 && (!mtmp->mflee || u.uhave.amulet));
917 static const short grownups[][2] = {
918 { PM_CHICKATRICE, PM_COCKATRICE },
919 { PM_LITTLE_DOG, PM_DOG },
920 { PM_DOG, PM_LARGE_DOG },
921 { PM_HELL_HOUND_PUP, PM_HELL_HOUND },
922 { PM_WINTER_WOLF_CUB, PM_WINTER_WOLF },
923 { PM_KITTEN, PM_HOUSECAT },
924 { PM_HOUSECAT, PM_LARGE_CAT },
925 { PM_PONY, PM_HORSE },
926 { PM_HORSE, PM_WARHORSE },
927 { PM_KOBOLD, PM_LARGE_KOBOLD },
928 { PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
929 { PM_GNOME, PM_GNOME_LORD },
930 { PM_GNOME_LORD, PM_GNOME_KING },
931 { PM_DWARF, PM_DWARF_LORD },
932 { PM_DWARF_LORD, PM_DWARF_KING },
933 { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
934 { PM_ORC, PM_ORC_CAPTAIN },
935 { PM_HILL_ORC, PM_ORC_CAPTAIN },
936 { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
937 { PM_URUK_HAI, PM_ORC_CAPTAIN },
938 { PM_SEWER_RAT, PM_GIANT_RAT },
939 { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
940 { PM_OGRE, PM_OGRE_LORD },
941 { PM_OGRE_LORD, PM_OGRE_KING },
942 { PM_ELF, PM_ELF_LORD },
943 { PM_WOODLAND_ELF, PM_ELF_LORD },
944 { PM_GREEN_ELF, PM_ELF_LORD },
945 { PM_GREY_ELF, PM_ELF_LORD },
946 { PM_ELF_LORD, PM_ELVENKING },
947 { PM_LICH, PM_DEMILICH },
948 { PM_DEMILICH, PM_MASTER_LICH },
949 { PM_MASTER_LICH, PM_ARCH_LICH },
950 { PM_VAMPIRE, PM_VAMPIRE_LORD },
951 { PM_BAT, PM_GIANT_BAT },
952 { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
953 { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
955 {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
957 { PM_BABY_RED_DRAGON, PM_RED_DRAGON },
958 { PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON },
959 { PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON },
960 { PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON },
961 { PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON },
962 { PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON },
963 { PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON },
964 { PM_RED_NAGA_HATCHLING, PM_RED_NAGA },
965 { PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA },
966 { PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA },
967 { PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA },
968 { PM_SMALL_MIMIC, PM_LARGE_MIMIC },
969 { PM_LARGE_MIMIC, PM_GIANT_MIMIC },
970 { PM_BABY_LONG_WORM, PM_LONG_WORM },
971 { PM_BABY_PURPLE_WORM, PM_PURPLE_WORM },
972 { PM_BABY_CROCODILE, PM_CROCODILE },
973 { PM_SOLDIER, PM_SERGEANT },
974 { PM_SERGEANT, PM_LIEUTENANT },
975 { PM_LIEUTENANT, PM_CAPTAIN },
976 { PM_WATCHMAN, PM_WATCH_CAPTAIN },
977 { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
978 { PM_STUDENT, PM_ARCHEOLOGIST },
979 { PM_ATTENDANT, PM_HEALER },
980 { PM_PAGE, PM_KNIGHT },
981 { PM_ACOLYTE, PM_PRIEST },
982 { PM_APPRENTICE, PM_WIZARD },
983 { PM_MANES, PM_LEMURE },
984 { PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
985 { PM_KOP_SERGEANT, PM_KOP_LIEUTENANT },
986 { PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN },
991 little_to_big(montype)
996 for (i = 0; grownups[i][0] >= LOW_PM; i++)
997 if (montype == grownups[i][0]) {
998 montype = grownups[i][1];
1005 big_to_little(montype)
1010 for (i = 0; grownups[i][0] >= LOW_PM; i++)
1011 if (montype == grownups[i][1]) {
1012 montype = grownups[i][0];
1019 * Return the permonst ptr for the race of the monster.
1020 * Returns correct pointer for non-polymorphed and polymorphed
1021 * player. It does not return a pointer to player role character.
1023 const struct permonst *
1027 if (mtmp == &youmonst && !Upolyd)
1028 return &mons[urace.malenum];
1034 static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" };
1036 static const char *levitate[4] = { "
\95\82\82", "
\95\82\82", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1038 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
1040 static const char *flys[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82¨
\82Ì
\82Ì
\82", "
\82¨
\82Ì
\82Ì
\82" };
1042 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
1044 static const char *flyl[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1046 static const char *slither[4] = { "slither", "Slither", "falter", "Falter" };
1048 static const char *slither[4] = { "
\8a\8a\82é", "
\8a\8a\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1050 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
1052 static const char *ooze[4] = { "
\82É
\82¶
\82Ý
\8fo
\82é", "
\82É
\82¶
\82Ý
\8fo
\82é", "
\90g
\90k
\82¢
\82·
\82é", "
\90g
\90k
\82¢
\82·
\82é" };
1054 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
1056 static const char *immobile[4] = { "
\93®
\82", "
\93®
\82", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1058 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
1060 static const char *crawl[4] = { "
\82Í
\82¢
\82¸
\82é", "
\82Í
\82¢
\82¸
\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1063 locomotion(ptr, def)
1064 const struct permonst *ptr;
1067 int capitalize = (*def == highc(*def));
1069 return (is_floater(ptr) ? levitate[capitalize]
1070 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1071 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1072 : slithy(ptr) ? slither[capitalize]
1073 : amorphous(ptr) ? ooze[capitalize]
1074 : !ptr->mmove ? immobile[capitalize]
1075 : nolimbs(ptr) ? crawl[capitalize]
1080 *
\81u
\82æ
\82ë
\82ß
\82
\81v
\82ð
\89ö
\95¨
\82Ì
\8eí
\97Þ
\82É
\82æ
\82Á
\82Ä
\95Ï
\82¦
\82é
\81B
1081 *
\8e©
\95ª
\82É
\91Î
\82µ
\82Ä
\8eg
\82¤
\8fê
\8d\87\82É
\82Í
\8aù
\82É
\81u
\82
\82ç
\82
\82ç
\82·
\82é
\81v
\82ª
\8eg
\82í
\82ê
\82Ä
\82¢
\82é
\82Ì
\82Å
\81A
1082 *
\95Ï
\89»
\82µ
\82Ä
\82¢
\82Ä
\82à
\82»
\82Ì
\82Ü
\82Ü
\82É
\82·
\82é
\81B
1083 *
\91\8a\8eè
\82É
\91Î
\82µ
\82Ä
\8eg
\82¤
\8fê
\8d\87\82Í
\81u
\82
\82ç
\82
\82ç
\82·
\82é
\81v
\82Í
\95s
\8e©
\91R
\82È
\82Ì
\82Å
\82±
\82ê
\82ð
\8eg
\82¤
\81B
1087 const struct permonst *ptr;
1090 int capitalize = 2 + (*def == highc(*def));
1092 return (is_floater(ptr) ? levitate[capitalize]
1093 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1094 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1095 : slithy(ptr) ? slither[capitalize]
1096 : amorphous(ptr) ? ooze[capitalize]
1097 : !ptr->mmove ? immobile[capitalize]
1098 : nolimbs(ptr) ? crawl[capitalize]
1102 static const char *levitate2 = "
\95\82\82«
\8fo
\82½";
1103 static const char *fly2 = "
\94ò
\82Ñ
\8fo
\82½";
1104 static const char *slither2 = "
\8a\8a\82è
\8fo
\82½";
1105 static const char *ooze2 = "
\82É
\82¶
\82Ý
\8fo
\82½";
1106 static const char *crawl2 = "
\82Í
\82¢
\82¸
\82è
\8fo
\82½";
1109 jumpedthrough(ptr, def)
1110 const struct permonst *ptr;
1114 is_floater(ptr) ? levitate2 :
1115 is_flyer(ptr) ? fly2 :
1116 slithy(ptr) ? slither2 :
1117 amorphous(ptr) ? ooze2 :
1118 nolimbs(ptr) ? crawl2 :
1124 /* return phrase describing the effect of fire attack on a type of monster */
1126 on_fire(mptr, mattk)
1127 struct permonst *mptr;
1128 struct attack *mattk;
1132 switch (monsndx(mptr)) {
1133 case PM_FLAMING_SPHERE:
1134 case PM_FIRE_VORTEX:
1135 case PM_FIRE_ELEMENTAL:
1138 what = "already on fire";
1140 what = "
\82·
\82Å
\82É
\89\8a\82É
\82Â
\82Â
\82Ü
\82ê
\82Ä
\82¢
\82é";
1142 case PM_WATER_ELEMENTAL:
1144 case PM_STEAM_VORTEX:
1148 what = "
\95¦
\93«
\82µ
\82½";
1151 case PM_GLASS_GOLEM:
1155 what = "
\97n
\82¯
\82½";
1157 case PM_STONE_GOLEM:
1160 case PM_AIR_ELEMENTAL:
1161 case PM_EARTH_ELEMENTAL:
1162 case PM_DUST_VORTEX:
1163 case PM_ENERGY_VORTEX:
1165 what = "heating up";
1167 what = "
\94M
\82
\82È
\82Á
\82½";
1171 what = (mattk->aatyp == AT_HUGS) ? "being roasted" : "on fire";
1173 what = (mattk->aatyp == AT_HUGS) ? "
\8aÛ
\8fÄ
\82¯
\82É
\82È
\82Á
\82½" : "
\89Î
\82¾
\82é
\82Ü
\82É
\82È
\82Á
\82½";
1181 * True if monster is presumed to have a sense of smell.
1182 * False if monster definitely does not have a sense of smell.
1184 * Do not base this on presence of a head or nose, since many
1185 * creatures sense smells other ways (feelers, forked-tongues, etc.)
1186 * We're assuming all insects can smell at a distance too.
1190 struct permonst *mdat;
1193 || mdat->mlet == S_EYE /* spheres */
1194 || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING
1195 || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX
1196 || mdat->mlet == S_ELEMENTAL
1197 || mdat->mlet == S_FUNGUS /* mushrooms and fungi */
1198 || mdat->mlet == S_LIGHT)