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