1 /* NetHack 3.6 mondata.c $NHDT-Date: 1508479720 2017/10/20 06:08:40 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.63 $ */
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. */
6 /* JNetHack Copyright */
7 /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */
8 /* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2016 */
9 /* JNetHack may be freely redistributed. See license for details. */
13 * These routines provide basic data for any type of monster.
16 /* set up an individual monster's base type (initial creation, shapechange) */
18 set_mon_data(mon, ptr, flag)
23 int new_speed, old_speed = mon->data ? mon->data->mmove : 0;
26 mon->mnum = (short) monsndx(ptr);
28 return; /* "don't care" */
31 mon->mintrinsics |= (ptr->mresists & 0x00FF);
33 mon->mintrinsics = (ptr->mresists & 0x00FF);
35 if (mon->movement) { /* same adjustment as poly'd hero undergoes */
36 new_speed = ptr->mmove;
37 /* prorate unused movement if new form is slower so that
38 it doesn't get extra moves leftover from previous form;
39 if new form is faster, leave unused movement as is */
40 if (new_speed < old_speed)
41 mon->movement = new_speed * mon->movement / old_speed;
46 /* does monster-type have any attack for a specific type of damage? */
48 attacktype_fordmg(ptr, atyp, dtyp)
54 for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
55 if (a->aatyp == atyp && (dtyp == AD_ANY || a->adtyp == dtyp))
57 return (struct attack *) 0;
60 /* does monster-type have a particular type of attack */
66 return attacktype_fordmg(ptr, atyp, AD_ANY) ? TRUE : FALSE;
69 /* returns True if monster doesn't attack, False if it does */
75 struct attack *mattk = ptr->mattk;
77 for (i = 0; i < NATTK; i++) {
78 /* AT_BOOM "passive attack" (gas spore's explosion upon death)
79 isn't an attack as far as our callers are concerned */
80 if (mattk[i].aatyp == AT_BOOM)
89 /* does monster-type transform into something else when petrified? */
94 /* non-stone golems turn into stone golems unless latter is genocided */
95 return (boolean) (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM]
96 && !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD));
100 /* returns True if monster is drain-life resistant */
105 struct permonst *ptr = mon->data;
108 if (is_undead(ptr) || is_demon(ptr) || is_were(ptr)
109 /* is_were() doesn't handle hero in human form */
110 || (mon == &youmonst && u.ulycn >= LOW_PM)
111 || ptr == &mons[PM_DEATH] || is_vampshifter(mon))
113 wep = (mon == &youmonst) ? uwep : MON_WEP(mon);
114 return (boolean) (wep && wep->oartifact && defends(AD_DRLI, wep));
117 /* True if monster is magic-missile (actually, general magic) resistant */
122 struct permonst *ptr = mon->data;
123 boolean is_you = (mon == &youmonst);
127 /* as of 3.2.0: gray dragons, Angels, Oracle, Yeenoghu */
128 if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON]
129 || dmgtype(ptr, AD_RBRE)) /* Chromatic Dragon */
131 /* check for magic resistance granted by wielded weapon */
132 o = is_you ? uwep : MON_WEP(mon);
133 if (o && o->oartifact && defends(AD_MAGM, o))
135 /* check for magic resistance granted by worn or carried items */
136 o = is_you ? invent : mon->minvent;
137 slotmask = W_ARMOR | W_ACCESSORY;
138 if (!is_you /* assumes monsters don't wield non-weapons */
139 || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
141 if (is_you && u.twoweap)
142 slotmask |= W_SWAPWEP;
143 for (; o; o = o->nobj)
144 if (((o->owornmask & slotmask) != 0L
145 && objects[o->otyp].oc_oprop == ANTIMAGIC)
146 || (o->oartifact && defends_when_carried(AD_MAGM, o)))
151 /* True iff monster is resistant to light-induced blindness */
156 struct permonst *ptr = mon->data;
157 boolean is_you = (mon == &youmonst);
161 if (is_you ? (Blind || Unaware)
162 : (mon->mblinded || !mon->mcansee || !haseyes(ptr)
163 /* BUG: temporary sleep sets mfrozen, but since
164 paralysis does too, we can't check it */
167 /* yellow light, Archon; !dust vortex, !cobra, !raven */
168 if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL)
169 || dmgtype_fromattack(ptr, AD_BLND, AT_GAZE))
171 o = is_you ? uwep : MON_WEP(mon);
172 if (o && o->oartifact && defends(AD_BLND, o))
174 o = is_you ? invent : mon->minvent;
175 slotmask = W_ARMOR | W_ACCESSORY;
176 if (!is_you /* assumes monsters don't wield non-weapons */
177 || (uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))))
179 if (is_you && u.twoweap)
180 slotmask |= W_SWAPWEP;
181 for (; o; o = o->nobj)
182 if (((o->owornmask & slotmask) != 0L
183 && objects[o->otyp].oc_oprop == BLINDED)
184 || (o->oartifact && defends_when_carried(AD_BLND, o)))
189 /* True iff monster can be blinded by the given attack;
190 note: may return True when mdef is blind (e.g. new cream-pie attack) */
192 can_blnd(magr, mdef, aatyp, obj)
193 struct monst *magr; /* NULL == no specific aggressor */
196 struct obj *obj; /* aatyp == AT_WEAP, AT_SPIT */
198 boolean is_you = (mdef == &youmonst);
199 boolean check_visor = FALSE;
203 /* no eyes protect against all attacks for now */
204 if (!haseyes(mdef->data))
212 case AT_BREA: /* assumed to be lightning */
213 /* light-based attacks may be cancelled or resisted */
214 if (magr && magr->mcan)
216 return !resists_blnd(mdef);
221 /* an object is used (thrown/spit/other) */
222 if (obj && (obj->otyp == CREAM_PIE)) {
223 if (is_you && Blindfolded)
225 } else if (obj && (obj->otyp == BLINDING_VENOM)) {
226 /* all ublindf, including LENSES, protect, cream-pies too */
227 if (is_you && (ublindf || u.ucreamed))
230 } else if (obj && (obj->otyp == POT_BLINDNESS)) {
231 return TRUE; /* no defense */
233 return FALSE; /* other objects cannot cause blindness yet */
234 if ((magr == &youmonst) && u.uswallow)
235 return FALSE; /* can't affect eyes while inside monster */
239 if (is_you && (Blindfolded || Unaware || u.ucreamed))
241 if (!is_you && mdef->msleeping)
246 /* e.g. raven: all ublindf, including LENSES, protect */
247 if (is_you && ublindf)
249 if ((magr == &youmonst) && u.uswallow)
250 return FALSE; /* can't affect eyes while inside monster */
256 /* some physical, blind-inducing attacks can be cancelled */
257 if (magr && magr->mcan)
265 /* check if wearing a visor (only checked if visor might help) */
267 o = (mdef == &youmonst) ? invent : mdef->minvent;
268 for (; o; o = o->nobj)
270 if ((o->owornmask & W_ARMH)
271 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
272 && !strcmp(s, "visored helmet"))
274 if ((o->owornmask & W_ARMH)
275 && (s = OBJ_DESCR(objects[o->otyp])) != (char *) 0
276 && !strcmp(s, "
\96Ê
\96j
\95t
\82«
\82Ì
\8a\95"))
284 /* returns True if monster can attack at range */
287 struct permonst *ptr;
289 register int i, atyp;
290 long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE);
292 /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP)
293 * || attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE)
294 * || attacktype(ptr, AT_MAGC));
295 * but that's too slow -dlc
297 for (i = 0; i < NATTK; i++) {
298 atyp = ptr->mattk[i].aatyp;
301 /* assert(atyp < 32); */
302 if ((atk_mask & (1L << atyp)) != 0L)
308 /* True if specific monster is especially affected by silver weapons */
310 mon_hates_silver(mon)
313 return (boolean) (is_vampshifter(mon) || hates_silver(mon->data));
316 /* True if monster-type is especially affected by silver weapons */
319 register struct permonst *ptr;
321 return (boolean) (is_were(ptr) || ptr->mlet == S_VAMPIRE || is_demon(ptr)
322 || ptr == &mons[PM_SHADE]
323 || (ptr->mlet == S_IMP && ptr != &mons[PM_TENGU]));
326 /* True iff the type of monster pass through iron bars */
329 struct permonst *mptr;
331 return (boolean) (passes_walls(mptr) || amorphous(mptr) || unsolid(mptr)
332 || is_whirly(mptr) || verysmall(mptr)
333 || dmgtype(mptr, AD_CORR) || dmgtype(mptr, AD_RUST)
334 || (slithy(mptr) && !bigmonst(mptr)));
337 /* returns True if monster can blow (whistle, etc) */
342 if ((is_silent(mtmp->data) || mtmp->data->msound == MS_BUZZ)
343 && (breathless(mtmp->data) || verysmall(mtmp->data)
344 || !has_head(mtmp->data) || mtmp->data->mlet == S_EEL))
346 if ((mtmp == &youmonst) && Strangled)
351 /* for casting spells and reading scrolls while blind */
356 if ((mtmp == &youmonst && Strangled)
357 || is_silent(mtmp->data) || !has_head(mtmp->data)
358 || mtmp->data->msound == MS_BUZZ || mtmp->data->msound == MS_BURBLE)
363 /* True if mon is vulnerable to strangulation */
365 can_be_strangled(mon)
369 boolean nonbreathing, nobrainer;
371 /* For amulet of strangulation support: here we're considering
372 strangulation to be loss of blood flow to the brain due to
373 constriction of the arteries in the neck, so all headless
374 creatures are immune (no neck) as are mindless creatures
375 who don't need to breathe (brain, if any, doesn't care).
376 Mindless creatures who do need to breath are vulnerable, as
377 are non-breathing creatures which have higher brain function. */
378 if (!has_head(mon->data))
380 if (mon == &youmonst) {
381 /* hero can't be mindless but poly'ing into mindless form can
382 confer strangulation protection */
383 nobrainer = mindless(youmonst.data);
384 nonbreathing = Breathless;
386 nobrainer = mindless(mon->data);
387 /* monsters don't wear amulets of magical breathing,
388 so second part doesn't achieve anything useful... */
389 nonbreathing = (breathless(mon->data)
390 || ((mamul = which_armor(mon, W_AMUL)) != 0
391 && (mamul->otyp == AMULET_OF_MAGICAL_BREATHING)));
393 return (boolean) (!nobrainer || !nonbreathing);
396 /* returns True if monster can track well */
399 register struct permonst *ptr;
401 if (uwep && uwep->oartifact == ART_EXCALIBUR)
404 return (boolean) haseyes(ptr);
407 /* creature will slide out of armor */
410 register struct permonst *ptr;
412 return (boolean) (is_whirly(ptr) || ptr->msize <= MZ_SMALL
413 || noncorporeal(ptr));
416 /* creature will break out of armor */
419 register struct permonst *ptr;
424 return (boolean) (bigmonst(ptr)
425 || (ptr->msize > MZ_SMALL && !humanoid(ptr))
426 /* special cases of humanoids that cannot wear suits */
427 || ptr == &mons[PM_MARILITH]
428 || ptr == &mons[PM_WINGED_GARGOYLE]);
431 /* creature sticks other creatures it hits */
434 register struct permonst *ptr;
436 return (boolean) (dmgtype(ptr, AD_STCK) || dmgtype(ptr, AD_WRAP)
437 || attacktype(ptr, AT_HUGS));
440 /* some monster-types can't vomit */
443 struct permonst *ptr;
445 /* rats and mice are incapable of vomiting;
446 which other creatures have the same limitation? */
447 if (ptr->mlet == S_RODENT && ptr != &mons[PM_ROCK_MOLE]
448 && ptr != &mons[PM_WOODCHUCK])
453 /* number of horns this type of monster has on its head */
456 struct permonst *ptr;
458 switch (monsndx(ptr)) {
459 case PM_HORNED_DEVIL: /* ? "more than one" */
464 case PM_WHITE_UNICORN:
465 case PM_GRAY_UNICORN:
466 case PM_BLACK_UNICORN:
475 /* does monster-type deal out a particular type of damage from a particular
478 dmgtype_fromattack(ptr, dtyp, atyp)
479 struct permonst *ptr;
484 for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
485 if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp))
487 return (struct attack *) 0;
490 /* does monster-type deal out a particular type of damage from any attack */
493 struct permonst *ptr;
496 return dmgtype_fromattack(ptr, dtyp, AT_ANY) ? TRUE : FALSE;
499 /* returns the maximum damage a defender can do to the attacker via
502 max_passive_dmg(mdef, magr)
503 register struct monst *mdef, *magr;
505 int i, dmg = 0, multi2 = 0;
508 /* each attack by magr can result in passive damage */
509 for (i = 0; i < NATTK; i++)
510 switch (magr->data->mattk[i].aatyp) {
527 for (i = 0; i < NATTK; i++)
528 if (mdef->data->mattk[i].aatyp == AT_NONE
529 || mdef->data->mattk[i].aatyp == AT_BOOM) {
530 adtyp = mdef->data->mattk[i].adtyp;
531 if ((adtyp == AD_ACID && !resists_acid(magr))
532 || (adtyp == AD_COLD && !resists_cold(magr))
533 || (adtyp == AD_FIRE && !resists_fire(magr))
534 || (adtyp == AD_ELEC && !resists_elec(magr))
535 || adtyp == AD_PHYS) {
536 dmg = mdef->data->mattk[i].damn;
538 dmg = mdef->data->mlevel + 1;
539 dmg *= mdef->data->mattk[i].damd;
548 /* determine whether two monster types are from the same species */
551 struct permonst *pm1, *pm2;
553 char let1 = pm1->mlet, let2 = pm2->mlet;
556 return TRUE; /* exact match */
557 /* player races have their own predicates */
559 return is_human(pm2);
563 return is_dwarf(pm2);
565 return is_gnome(pm2);
568 /* other creatures are less precise */
570 return is_giant(pm2); /* open to quibbling here */
572 return is_golem(pm2); /* even moreso... */
573 if (is_mind_flayer(pm1))
574 return is_mind_flayer(pm2);
575 if (let1 == S_KOBOLD || pm1 == &mons[PM_KOBOLD_ZOMBIE]
576 || pm1 == &mons[PM_KOBOLD_MUMMY])
577 return (let2 == S_KOBOLD || pm2 == &mons[PM_KOBOLD_ZOMBIE]
578 || pm2 == &mons[PM_KOBOLD_MUMMY]);
580 return (let2 == S_OGRE);
582 return (let2 == S_NYMPH);
583 if (let1 == S_CENTAUR)
584 return (let2 == S_CENTAUR);
586 return is_unicorn(pm2);
587 if (let1 == S_DRAGON)
588 return (let2 == S_DRAGON);
590 return (let2 == S_NAGA);
591 /* other critters get steadily messier */
593 return is_rider(pm2); /* debatable */
595 return is_minion(pm2); /* [needs work?] */
596 /* tengu don't match imps (first test handled case of both being tengu) */
597 if (pm1 == &mons[PM_TENGU] || pm2 == &mons[PM_TENGU])
600 return (let2 == S_IMP);
601 /* and minor demons (imps) don't match major demons */
602 else if (let2 == S_IMP)
605 return is_demon(pm2);
606 if (is_undead(pm1)) {
607 if (let1 == S_ZOMBIE)
608 return (let2 == S_ZOMBIE);
610 return (let2 == S_MUMMY);
611 if (let1 == S_VAMPIRE)
612 return (let2 == S_VAMPIRE);
614 return (let2 == S_LICH);
615 if (let1 == S_WRAITH)
616 return (let2 == S_WRAITH);
618 return (let2 == S_GHOST);
619 } else if (is_undead(pm2))
622 /* check for monsters which grow into more mature forms */
624 int m1 = monsndx(pm1), m2 = monsndx(pm2), prv, nxt;
626 /* we know m1 != m2 (very first check above); test all smaller
627 forms of m1 against m2, then all larger ones; don't need to
628 make the corresponding tests for variants of m2 against m1 */
629 for (prv = m1, nxt = big_to_little(m1); nxt != prv;
630 prv = nxt, nxt = big_to_little(nxt))
633 for (prv = m1, nxt = little_to_big(m1); nxt != prv;
634 prv = nxt, nxt = little_to_big(nxt))
638 /* not caught by little/big handling */
639 if (pm1 == &mons[PM_GARGOYLE] || pm1 == &mons[PM_WINGED_GARGOYLE])
640 return (pm2 == &mons[PM_GARGOYLE]
641 || pm2 == &mons[PM_WINGED_GARGOYLE]);
642 if (pm1 == &mons[PM_KILLER_BEE] || pm1 == &mons[PM_QUEEN_BEE])
643 return (pm2 == &mons[PM_KILLER_BEE] || pm2 == &mons[PM_QUEEN_BEE]);
645 if (is_longworm(pm1))
646 return is_longworm(pm2); /* handles tail */
647 /* [currently there's no reason to bother matching up
648 assorted bugs and blobs with their closest variants] */
653 /* return an index into the mons array */
656 struct permonst *ptr;
660 i = (int) (ptr - &mons[0]);
661 if (i < LOW_PM || i >= NUMMONS) {
662 panic("monsndx - could not index monster (%s)",
663 fmt_ptr((genericptr_t) ptr));
664 return NON_PM; /* will not get here */
669 /* for handling alternate spellings */
675 /* figure out what type of monster a user-supplied string is specifying */
680 /* Be careful. We must check the entire string in case it was
681 * something such as "ettin zombie corpse". The calling routine
682 * doesn't know about the "corpse" until the monster name has
683 * already been taken off the front, so we have to be able to
684 * read the name with extraneous stuff such as "corpse" stuck on
686 * This causes a problem for names which prefix other names such
687 * as "ettin" on "ettin zombie". In this case we want the _longest_
689 * This also permits plurals created by adding suffixes such as 's'
690 * or 'es'. Other plurals must still be handled explicitly.
693 register int mntmp = NON_PM;
694 register char *s, *str, *term;
698 str = strcpy(buf, in_str);
700 if (!strncmp(str, "a ", 2))
702 else if (!strncmp(str, "an ", 3))
704 else if (!strncmp(str, "the ", 4))
710 if ((s = strstri(str, "vortices")) != 0)
712 /* be careful with "ies"; "priest", "zombies" */
713 else if (slen > 3 && !strcmpi(term - 3, "ies")
714 && (slen < 7 || strcmpi(term - 7, "zombies")))
715 Strcpy(term - 3, "y");
716 /* luckily no monster names end in fe or ve with ves plurals */
717 else if (slen > 3 && !strcmpi(term - 3, "ves"))
718 Strcpy(term - 3, "f");
720 slen = strlen(str); /* length possibly needs recomputing */
723 static const struct alt_spl names[] = {
724 /* Alternate spellings */
725 { "grey dragon", PM_GRAY_DRAGON },
726 { "baby grey dragon", PM_BABY_GRAY_DRAGON },
727 { "grey unicorn", PM_GRAY_UNICORN },
728 { "grey ooze", PM_GRAY_OOZE },
729 { "gray-elf", PM_GREY_ELF },
730 { "mindflayer", PM_MIND_FLAYER },
731 { "master mindflayer", PM_MASTER_MIND_FLAYER },
732 /* More alternates; priest and priestess are separate monster
733 types but that isn't the case for {aligned,high} priests */
734 { "aligned priestess", PM_ALIGNED_PRIEST },
735 { "high priestess", PM_HIGH_PRIEST },
736 /* Inappropriate singularization by -ves check above */
737 { "master of thief", PM_MASTER_OF_THIEVES },
738 /* Potential misspellings where we want to avoid falling back
739 to the rank title prefix (input has been singularized) */
740 { "master thief", PM_MASTER_OF_THIEVES },
741 { "master of assassin", PM_MASTER_ASSASSIN },
743 { "invisible stalker", PM_STALKER },
744 { "high-elf", PM_ELVENKING }, /* PM_HIGH_ELF is obsolete */
745 { "halfling", PM_HOBBIT }, /* potential guess for polyself */
746 /* Hyphenated names */
747 { "ki rin", PM_KI_RIN },
748 { "uruk hai", PM_URUK_HAI },
749 { "orc captain", PM_ORC_CAPTAIN },
750 { "woodland elf", PM_WOODLAND_ELF },
751 { "green elf", PM_GREEN_ELF },
752 { "grey elf", PM_GREY_ELF },
753 { "gray elf", PM_GREY_ELF },
754 { "elf lord", PM_ELF_LORD },
755 { "olog hai", PM_OLOG_HAI },
756 { "arch lich", PM_ARCH_LICH },
757 /* Some irregular plurals */
758 { "incubi", PM_INCUBUS },
759 { "succubi", PM_SUCCUBUS },
760 { "violet fungi", PM_VIOLET_FUNGUS },
761 { "homunculi", PM_HOMUNCULUS },
762 { "baluchitheria", PM_BALUCHITHERIUM },
763 { "lurkers above", PM_LURKER_ABOVE },
764 { "cavemen", PM_CAVEMAN },
765 { "cavewomen", PM_CAVEWOMAN },
766 { "djinn", PM_DJINNI },
767 { "mumakil", PM_MUMAK },
768 { "erinyes", PM_ERINYS },
772 register const struct alt_spl *namep;
774 for (namep = names; namep->name; namep++)
775 if (!strncmpi(str, namep->name, (int) strlen(namep->name)))
776 return namep->pm_val;
779 for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
780 register int m_i_len = strlen(mons[i].mname);
782 if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
783 if (m_i_len == slen) {
784 return i; /* exact match */
785 } else if (slen > m_i_len
787 && (str[m_i_len] == ' '
788 || !strcmpi(&str[m_i_len], "s")
789 || !strncmpi(&str[m_i_len], "s ", 2)
790 || !strcmpi(&str[m_i_len], "'")
791 || !strncmpi(&str[m_i_len], "' ", 2)
792 || !strcmpi(&str[m_i_len], "'s")
793 || !strncmpi(&str[m_i_len], "'s ", 3)
794 || !strcmpi(&str[m_i_len], "es")
795 || !strncmpi(&str[m_i_len], "es ", 3))) {
797 && !strncmp(&str[m_i_len], "
\82Ì", 2)) {
805 mntmp = title_to_mon(str, (int *) 0, (int *) 0);
809 /* monster class from user input; used for genocide and controlled polymorph;
810 returns 0 rather than MAXMCLASSES if no match is found */
812 name_to_monclass(in_str, mndx_p)
816 /* Single letters are matched against def_monsyms[].sym; words
817 or phrases are first matched against def_monsyms[].explain
818 to check class description; if not found there, then against
819 mons[].mname to test individual monster types. Input can be a
820 substring of the full description or mname, but to be accepted,
821 such partial matches must start at beginning of a word. Some
822 class descriptions include "foo or bar" and "foo or other foo"
823 so we don't want to accept "or", "other", "or other" there. */
824 static NEARDATA const char *const falsematch[] = {
825 /* multiple-letter input which matches any of these gets rejected */
826 "an", "the", "or", "other", "or other", 0
828 /* positive pm_val => specific monster; negative => class */
829 static NEARDATA const struct alt_spl truematch[] = {
830 /* "long worm" won't match "worm" class but would accidentally match
831 "long worm tail" class before the comparison with monster types */
832 { "long worm", PM_LONG_WORM },
833 /* matches wrong--or at least suboptimal--class */
834 { "demon", -S_DEMON }, /* hits "imp or minor demon" */
835 /* matches specific monster (overly restrictive) */
836 { "devil", -S_DEMON }, /* always "horned devil" */
837 /* some plausible guesses which need help */
838 { "bug", -S_XAN }, /* would match bugbear... */
839 { "fish", -S_EEL }, /* wouldn't match anything */
847 *mndx_p = NON_PM; /* haven't [yet] matched a specific type */
849 if (!in_str || !in_str[0]) {
852 } else if (!in_str[1]) {
853 /* single character */
854 i = def_char_to_monclass(*in_str);
855 if (i == S_MIMIC_DEF) { /* ']' -> 'm' */
857 } else if (i == S_WORM_TAIL) { /* '~' -> 'w' */
860 *mndx_p = PM_LONG_WORM;
861 } else if (i == MAXMCLASSES) /* maybe 'I' */
862 i = (*in_str == DEF_INVISIBLE) ? S_invisible : 0;
865 /* multiple characters */
866 in_str = makesingular(in_str);
867 /* check for special cases */
868 for (i = 0; falsematch[i]; i++)
869 if (!strcmpi(in_str, falsematch[i]))
871 for (i = 0; truematch[i].name; i++)
872 if (!strcmpi(in_str, truematch[i].name)) {
873 i = truematch[i].pm_val;
875 return -i; /* class */
877 *mndx_p = i; /* monster */
880 /* check monster class descriptions */
881 for (i = 1; i < MAXMCLASSES; i++) {
882 x = def_monsyms[i].explain;
883 if ((p = strstri(x, in_str)) != 0 && (p == x || *(p - 1) == ' '))
886 /* check individual species names */
887 i = name_to_mon(in_str);
897 /* returns 3 values (0=male, 1=female, 2=none) */
900 register struct monst *mtmp;
902 if (is_neuter(mtmp->data))
907 /* Like gender(), but lower animals and such are still "it".
908 This is the one we want to use when printing messages. */
911 register struct monst *mtmp;
913 if (is_neuter(mtmp->data) || !canspotmon(mtmp))
915 return (humanoid(mtmp->data) || (mtmp->data->geno & G_UNIQ)
916 || type_is_pname(mtmp->data)) ? (int) mtmp->female : 2;
919 /* used for nearby monsters when you go to another level */
924 if (mtmp == u.usteed)
927 /* Wizard with Amulet won't bother trying to follow across levels */
928 if (mtmp->iswiz && mon_has_amulet(mtmp))
930 /* some monsters will follow even while intending to flee from you */
931 if (mtmp->mtame || mtmp->iswiz || is_fshk(mtmp))
933 /* stalking types follow, but won't when fleeing unless you hold
935 return (boolean) ((mtmp->data->mflags2 & M2_STALK)
936 && (!mtmp->mflee || u.uhave.amulet));
939 static const short grownups[][2] = {
940 { PM_CHICKATRICE, PM_COCKATRICE },
941 { PM_LITTLE_DOG, PM_DOG },
942 { PM_DOG, PM_LARGE_DOG },
943 { PM_HELL_HOUND_PUP, PM_HELL_HOUND },
944 { PM_WINTER_WOLF_CUB, PM_WINTER_WOLF },
945 { PM_KITTEN, PM_HOUSECAT },
946 { PM_HOUSECAT, PM_LARGE_CAT },
947 { PM_PONY, PM_HORSE },
948 { PM_HORSE, PM_WARHORSE },
949 { PM_KOBOLD, PM_LARGE_KOBOLD },
950 { PM_LARGE_KOBOLD, PM_KOBOLD_LORD },
951 { PM_GNOME, PM_GNOME_LORD },
952 { PM_GNOME_LORD, PM_GNOME_KING },
953 { PM_DWARF, PM_DWARF_LORD },
954 { PM_DWARF_LORD, PM_DWARF_KING },
955 { PM_MIND_FLAYER, PM_MASTER_MIND_FLAYER },
956 { PM_ORC, PM_ORC_CAPTAIN },
957 { PM_HILL_ORC, PM_ORC_CAPTAIN },
958 { PM_MORDOR_ORC, PM_ORC_CAPTAIN },
959 { PM_URUK_HAI, PM_ORC_CAPTAIN },
960 { PM_SEWER_RAT, PM_GIANT_RAT },
961 { PM_CAVE_SPIDER, PM_GIANT_SPIDER },
962 { PM_OGRE, PM_OGRE_LORD },
963 { PM_OGRE_LORD, PM_OGRE_KING },
964 { PM_ELF, PM_ELF_LORD },
965 { PM_WOODLAND_ELF, PM_ELF_LORD },
966 { PM_GREEN_ELF, PM_ELF_LORD },
967 { PM_GREY_ELF, PM_ELF_LORD },
968 { PM_ELF_LORD, PM_ELVENKING },
969 { PM_LICH, PM_DEMILICH },
970 { PM_DEMILICH, PM_MASTER_LICH },
971 { PM_MASTER_LICH, PM_ARCH_LICH },
972 { PM_VAMPIRE, PM_VAMPIRE_LORD },
973 { PM_BAT, PM_GIANT_BAT },
974 { PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON },
975 { PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON },
977 {PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
979 { PM_BABY_RED_DRAGON, PM_RED_DRAGON },
980 { PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON },
981 { PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON },
982 { PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON },
983 { PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON },
984 { PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON },
985 { PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON },
986 { PM_RED_NAGA_HATCHLING, PM_RED_NAGA },
987 { PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA },
988 { PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA },
989 { PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA },
990 { PM_SMALL_MIMIC, PM_LARGE_MIMIC },
991 { PM_LARGE_MIMIC, PM_GIANT_MIMIC },
992 { PM_BABY_LONG_WORM, PM_LONG_WORM },
993 { PM_BABY_PURPLE_WORM, PM_PURPLE_WORM },
994 { PM_BABY_CROCODILE, PM_CROCODILE },
995 { PM_SOLDIER, PM_SERGEANT },
996 { PM_SERGEANT, PM_LIEUTENANT },
997 { PM_LIEUTENANT, PM_CAPTAIN },
998 { PM_WATCHMAN, PM_WATCH_CAPTAIN },
999 { PM_ALIGNED_PRIEST, PM_HIGH_PRIEST },
1000 { PM_STUDENT, PM_ARCHEOLOGIST },
1001 { PM_ATTENDANT, PM_HEALER },
1002 { PM_PAGE, PM_KNIGHT },
1003 { PM_ACOLYTE, PM_PRIEST },
1004 { PM_APPRENTICE, PM_WIZARD },
1005 { PM_MANES, PM_LEMURE },
1006 { PM_KEYSTONE_KOP, PM_KOP_SERGEANT },
1007 { PM_KOP_SERGEANT, PM_KOP_LIEUTENANT },
1008 { PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN },
1013 little_to_big(montype)
1018 for (i = 0; grownups[i][0] >= LOW_PM; i++)
1019 if (montype == grownups[i][0]) {
1020 montype = grownups[i][1];
1027 big_to_little(montype)
1032 for (i = 0; grownups[i][0] >= LOW_PM; i++)
1033 if (montype == grownups[i][1]) {
1034 montype = grownups[i][0];
1040 /* determine whether two permonst indices are part of the same progression;
1041 existence of progressions with more than one step makes it a bit tricky */
1043 big_little_match(montyp1, montyp2)
1044 int montyp1, montyp2;
1048 /* simplest case: both are same pm */
1049 if (montyp1 == montyp2)
1051 /* assume it isn't possible to grow from one class letter to another */
1052 if (mons[montyp1].mlet != mons[montyp2].mlet)
1054 /* check whether montyp1 can grow up into montyp2 */
1055 for (l = montyp1; (b = little_to_big(l)) != l; l = b)
1058 /* check whether montyp2 can grow up into montyp1 */
1059 for (l = montyp2; (b = little_to_big(l)) != l; l = b)
1062 /* neither grows up to become the other; no match */
1067 * Return the permonst ptr for the race of the monster.
1068 * Returns correct pointer for non-polymorphed and polymorphed
1069 * player. It does not return a pointer to player role character.
1071 const struct permonst *
1075 if (mtmp == &youmonst && !Upolyd)
1076 return &mons[urace.malenum];
1082 static const char *levitate[4] = { "float", "Float", "wobble", "Wobble" };
1084 static const char *levitate[4] = { "
\95\82\82", "
\95\82\82", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1086 static const char *flys[4] = { "fly", "Fly", "flutter", "Flutter" };
1088 static const char *flys[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82¨
\82Ì
\82Ì
\82", "
\82¨
\82Ì
\82Ì
\82" };
1090 static const char *flyl[4] = { "fly", "Fly", "stagger", "Stagger" };
1092 static const char *flyl[4] = { "
\94ò
\82Ô", "
\94ò
\82Ô", "
\82æ
\82ë
\82ß
\82", "
\82æ
\82ë
\82ß
\82" };
1094 static const char *slither[4] = { "slither", "Slither", "falter", "Falter" };
1096 static const char *slither[4] = { "
\8a\8a\82é", "
\8a\8a\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1098 static const char *ooze[4] = { "ooze", "Ooze", "tremble", "Tremble" };
1100 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é" };
1102 static const char *immobile[4] = { "wiggle", "Wiggle", "pulsate", "Pulsate" };
1104 static const char *immobile[4] = { "
\93®
\82", "
\93®
\82", "
\90k
\82¦
\82é", "
\90k
\82¦
\82é" };
1106 static const char *crawl[4] = { "crawl", "Crawl", "falter", "Falter" };
1108 static const char *crawl[4] = { "
\82Í
\82¢
\82¸
\82é", "
\82Í
\82¢
\82¸
\82é", "
\82½
\82¶
\82ë
\82®", "
\82½
\82¶
\82ë
\82®" };
1111 locomotion(ptr, def)
1112 const struct permonst *ptr;
1115 int capitalize = (*def == highc(*def));
1117 return (is_floater(ptr) ? levitate[capitalize]
1118 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1119 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1120 : slithy(ptr) ? slither[capitalize]
1121 : amorphous(ptr) ? ooze[capitalize]
1122 : !ptr->mmove ? immobile[capitalize]
1123 : nolimbs(ptr) ? crawl[capitalize]
1128 *
\81u
\82æ
\82ë
\82ß
\82
\81v
\82ð
\89ö
\95¨
\82Ì
\8eí
\97Þ
\82É
\82æ
\82Á
\82Ä
\95Ï
\82¦
\82é
\81B
1129 *
\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
1130 *
\95Ï
\89»
\82µ
\82Ä
\82¢
\82Ä
\82à
\82»
\82Ì
\82Ü
\82Ü
\82É
\82·
\82é
\81B
1131 *
\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
1135 const struct permonst *ptr;
1138 int capitalize = 2 + (*def == highc(*def));
1140 return (is_floater(ptr) ? levitate[capitalize]
1141 : (is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize]
1142 : (is_flyer(ptr) && ptr->msize > MZ_SMALL) ? flyl[capitalize]
1143 : slithy(ptr) ? slither[capitalize]
1144 : amorphous(ptr) ? ooze[capitalize]
1145 : !ptr->mmove ? immobile[capitalize]
1146 : nolimbs(ptr) ? crawl[capitalize]
1150 static const char *levitate2 = "
\95\82\82«
\8fo
\82½";
1151 static const char *fly2 = "
\94ò
\82Ñ
\8fo
\82½";
1152 static const char *slither2 = "
\8a\8a\82è
\8fo
\82½";
1153 static const char *ooze2 = "
\82É
\82¶
\82Ý
\8fo
\82½";
1154 static const char *crawl2 = "
\82Í
\82¢
\82¸
\82è
\8fo
\82½";
1157 jumpedthrough(ptr, def)
1158 const struct permonst *ptr;
1162 is_floater(ptr) ? levitate2 :
1163 is_flyer(ptr) ? fly2 :
1164 slithy(ptr) ? slither2 :
1165 amorphous(ptr) ? ooze2 :
1166 nolimbs(ptr) ? crawl2 :
1172 /* return phrase describing the effect of fire attack on a type of monster */
1174 on_fire(mptr, mattk)
1175 struct permonst *mptr;
1176 struct attack *mattk;
1180 switch (monsndx(mptr)) {
1181 case PM_FLAMING_SPHERE:
1182 case PM_FIRE_VORTEX:
1183 case PM_FIRE_ELEMENTAL:
1186 what = "already on fire";
1188 what = "
\82·
\82Å
\82É
\89\8a\82É
\82Â
\82Â
\82Ü
\82ê
\82Ä
\82¢
\82é";
1190 case PM_WATER_ELEMENTAL:
1192 case PM_STEAM_VORTEX:
1196 what = "
\95¦
\93«
\82µ
\82½";
1199 case PM_GLASS_GOLEM:
1203 what = "
\97n
\82¯
\82½";
1205 case PM_STONE_GOLEM:
1208 case PM_AIR_ELEMENTAL:
1209 case PM_EARTH_ELEMENTAL:
1210 case PM_DUST_VORTEX:
1211 case PM_ENERGY_VORTEX:
1213 what = "heating up";
1215 what = "
\94M
\82
\82È
\82Á
\82½";
1219 what = (mattk->aatyp == AT_HUGS) ? "being roasted" : "on fire";
1221 what = (mattk->aatyp == AT_HUGS) ? "
\8aÛ
\8fÄ
\82¯
\82É
\82È
\82Á
\82½" : "
\89Î
\82¾
\82é
\82Ü
\82É
\82È
\82Á
\82½";
1229 * True if monster is presumed to have a sense of smell.
1230 * False if monster definitely does not have a sense of smell.
1232 * Do not base this on presence of a head or nose, since many
1233 * creatures sense smells other ways (feelers, forked-tongues, etc.)
1234 * We're assuming all insects can smell at a distance too.
1238 struct permonst *mdat;
1241 || mdat->mlet == S_EYE /* spheres */
1242 || mdat->mlet == S_JELLY || mdat->mlet == S_PUDDING
1243 || mdat->mlet == S_BLOB || mdat->mlet == S_VORTEX
1244 || mdat->mlet == S_ELEMENTAL
1245 || mdat->mlet == S_FUNGUS /* mushrooms and fungi */
1246 || mdat->mlet == S_LIGHT)