Source:NetHack 3.4.0/mondata.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to mondata.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.0/mondata.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

1.    /*	SCCS Id: @(#)mondata.c	3.4	2001/12/05	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    #include "eshk.h"
7.    #include "epri.h"
8.    
9.    /* fake attack and damage types */
10.   #define AT_ANY (-1)
11.   #define AD_ANY (-1)
12.   
13.   /*	These routines provide basic data for any type of monster. */
14.   
15.   #ifdef OVLB
16.   
17.   void
18.   set_mon_data(mon, ptr, flag)
19.   struct monst *mon;
20.   struct permonst *ptr;
21.   int flag;
22.   {
23.       mon->data = ptr;
24.       if (flag == -1) return;		/* "don't care" */
25.   
26.       if (flag == 1)
27.   	mon->mintrinsics |= (ptr->mresists & 0x00FF);
28.       else
29.   	mon->mintrinsics = (ptr->mresists & 0x00FF);
30.       return;
31.   }
32.   
33.   #endif /* OVLB */
34.   #ifdef OVL0
35.   
36.   struct attack *
37.   attacktype_fordmg(ptr, atyp, dtyp)
38.   struct permonst *ptr;
39.   int atyp, dtyp;
40.   {
41.       struct attack *a;
42.   
43.       for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
44.   	if (a->aatyp == atyp && (dtyp == AD_ANY || a->adtyp == dtyp))
45.   	    return a;
46.   
47.       return (struct attack *)0;
48.   }
49.   
50.   boolean
51.   attacktype(ptr, atyp)
52.   struct permonst *ptr;
53.   int atyp;
54.   {
55.       return attacktype_fordmg(ptr, atyp, AD_ANY) ? TRUE : FALSE;
56.   }
57.   
58.   #endif /* OVL0 */
59.   #ifdef OVLB
60.   
61.   boolean
62.   poly_when_stoned(ptr)
63.       struct permonst *ptr;
64.   {
65.       return((boolean)(is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] &&
66.   	    !(mvitals[PM_STONE_GOLEM].mvflags & G_GENOD)));
67.   	    /* allow G_EXTINCT */
68.   }
69.   
70.   boolean
71.   resists_drli(mon)	/* returns TRUE if monster is drain-life resistant */
72.   struct monst *mon;
73.   {
74.   	struct permonst *ptr = mon->data;
75.   	struct obj *wep = ((mon == &youmonst) ? uwep : MON_WEP(mon));
76.   
77.   	return (boolean)(is_undead(ptr) || is_demon(ptr) || is_were(ptr) ||
78.   			 ptr == &mons[PM_DEATH] ||
79.   			 (wep && wep->oartifact && defends(AD_DRLI, wep)));
80.   }
81.   
82.   boolean
83.   resists_magm(mon)	/* TRUE if monster is magic-missile resistant */
84.   struct monst *mon;
85.   {
86.   	struct permonst *ptr = mon->data;
87.   	struct obj *o;
88.   
89.   	/* as of 3.2.0:  gray dragons, Angels, Oracle, Yeenoghu */
90.   	if (dmgtype(ptr, AD_MAGM) || ptr == &mons[PM_BABY_GRAY_DRAGON] ||
91.   		dmgtype(ptr, AD_RBRE))	/* Chromatic Dragon */
92.   	    return TRUE;
93.   	/* check for magic resistance granted by wielded weapon */
94.   	o = (mon == &youmonst) ? uwep : MON_WEP(mon);
95.   	if (o && o->oartifact && defends(AD_MAGM, o))
96.   	    return TRUE;
97.   	/* check for magic resistance granted by worn or carried items */
98.   	o = (mon == &youmonst) ? invent : mon->minvent;
99.   	for ( ; o; o = o->nobj)
100.  	    if ((o->owornmask && objects[o->otyp].oc_oprop == ANTIMAGIC) ||
101.  		    (o->oartifact && protects(AD_MAGM, o)))
102.  		return TRUE;
103.  	return FALSE;
104.  }
105.  
106.  /* TRUE iff monster is resistant to light-induced blindness */
107.  boolean
108.  resists_blnd(mon)
109.  struct monst *mon;
110.  {
111.  	struct permonst *ptr = mon->data;
112.  	boolean is_you = (mon == &youmonst);
113.  	struct obj *o;
114.  
115.  	if (is_you ? (Blind || u.usleep) :
116.  		(mon->mblinded || !mon->mcansee || !haseyes(ptr) ||
117.  		    /* BUG: temporary sleep sets mfrozen, but since
118.  			    paralysis does too, we can't check it */
119.  		    mon->msleeping))
120.  	    return TRUE;
121.  	/* yellow light, Archon; !dust vortex, !cobra, !raven */
122.  	if (dmgtype_fromattack(ptr, AD_BLND, AT_EXPL) ||
123.  		dmgtype_fromattack(ptr, AD_BLND, AT_GAZE))
124.  	    return TRUE;
125.  	o = is_you ? uwep : MON_WEP(mon);
126.  	if (o && o->oartifact && defends(AD_BLND, o))
127.  	    return TRUE;
128.  	o = is_you ? invent : mon->minvent;
129.  	for ( ; o; o = o->nobj)
130.  	    if ((o->owornmask && objects[o->otyp].oc_oprop == BLINDED) ||
131.  		    (o->oartifact && protects(AD_BLND, o)))
132.  		return TRUE;
133.  	return FALSE;
134.  }
135.  
136.  /* TRUE iff monster can be blinded by the given attack */
137.  /* Note: may return TRUE when mdef is blind (e.g. new cream-pie attack) */
138.  boolean
139.  can_blnd(magr, mdef, aatyp, obj)
140.  struct monst *magr;		/* NULL == no specific aggressor */
141.  struct monst *mdef;
142.  uchar aatyp;
143.  struct obj *obj;		/* aatyp == AT_WEAP, AT_SPIT */
144.  {
145.  	boolean is_you = (mdef == &youmonst);
146.  	boolean check_visor = FALSE;
147.  	struct obj *o;
148.  	const char *s;
149.  
150.  	/* no eyes protect against all attacks for now */
151.  	if (!haseyes(mdef->data))
152.  	    return FALSE;
153.  
154.  	switch(aatyp) {
155.  	case AT_EXPL: case AT_BOOM: case AT_GAZE: case AT_MAGC:
156.  	case AT_BREA: /* assumed to be lightning */
157.  	    /* light-based attacks may be cancelled or resisted */
158.  	    if (magr && magr->mcan)
159.  		return FALSE;
160.  	    return !resists_blnd(mdef);
161.  
162.  	case AT_WEAP: case AT_SPIT: case AT_NONE:
163.  	    /* an object is used (thrown/spit/other) */
164.  	    if (obj && (obj->otyp == CREAM_PIE)) {
165.  		if (is_you && Blindfolded)
166.  		    return FALSE;
167.  	    } else if (obj && (obj->otyp == BLINDING_VENOM)) {
168.  		/* all ublindf, including LENSES, protect, cream-pies too */
169.  		if (is_you && (ublindf || u.ucreamed))
170.  		    return FALSE;
171.  		check_visor = TRUE;
172.  	    } else if (obj && (obj->otyp == POT_BLINDNESS)) {
173.  		return TRUE;	/* no defense */
174.  	    } else
175.  		return FALSE;	/* other objects cannot cause blindness yet */
176.  	    if ((magr == &youmonst) && u.uswallow)
177.  		return FALSE;	/* can't affect eyes while inside monster */
178.  	    break;
179.  
180.  	case AT_ENGL:
181.  	    if (is_you && (Blindfolded || u.usleep || u.ucreamed))
182.  		return FALSE;
183.  	    if (!is_you && mdef->msleeping)
184.  		return FALSE;
185.  	    break;
186.  
187.  	case AT_CLAW:
188.  	    /* e.g. raven: all ublindf, including LENSES, protect */
189.  	    if (is_you && ublindf)
190.  		return FALSE;
191.  	    if ((magr == &youmonst) && u.uswallow)
192.  		return FALSE;	/* can't affect eyes while inside monster */
193.  	    check_visor = TRUE;
194.  	    break;
195.  
196.  	case AT_TUCH: case AT_STNG:
197.  	    /* some physical, blind-inducing attacks can be cancelled */
198.  	    if (magr && magr->mcan)
199.  		return FALSE;
200.  	    break;
201.  
202.  	default:
203.  	    break;
204.  	}
205.  
206.  	/* check if wearing a visor (only checked if visor might help) */
207.  	if (check_visor) {
208.  	    o = (mdef == &youmonst) ? invent : mdef->minvent;
209.  	    for ( ; o; o = o->nobj)
210.  		if ((o->owornmask & W_ARMH) &&
211.  		    (s = OBJ_DESCR(objects[o->otyp])) != (char *)0 &&
212.  		    !strcmp(s, "visored helmet"))
213.  		    return FALSE;
214.  	}
215.  
216.  	return TRUE;
217.  }
218.  
219.  #endif /* OVLB */
220.  #ifdef OVL0
221.  
222.  boolean
223.  ranged_attk(ptr)	/* returns TRUE if monster can attack at range */
224.  struct permonst *ptr;
225.  {
226.  	register int i, atyp;
227.  	long atk_mask = (1L << AT_BREA) | (1L << AT_SPIT) | (1L << AT_GAZE);
228.  
229.  	/* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) ||
230.  		attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) ||
231.  		attacktype(ptr, AT_MAGC));
232.  	   but that's too slow -dlc
233.  	 */
234.  	for (i = 0; i < NATTK; i++) {
235.  	    atyp = ptr->mattk[i].aatyp;
236.  	    if (atyp >= AT_WEAP) return TRUE;
237.  	 /* assert(atyp < 32); */
238.  	    if ((atk_mask & (1L << atyp)) != 0L) return TRUE;
239.  	}
240.  
241.  	return FALSE;
242.  }
243.  
244.  boolean
245.  hates_silver(ptr)
246.  register struct permonst *ptr;
247.  /* returns TRUE if monster is especially affected by silver weapons */
248.  {
249.  	return((boolean)(is_were(ptr) || ptr->mlet==S_VAMPIRE || is_demon(ptr) ||
250.  		ptr == &mons[PM_SHADE] ||
251.  		(ptr->mlet==S_IMP && ptr != &mons[PM_TENGU])));
252.  }
253.  
254.  #endif /* OVL0 */
255.  #ifdef OVL1
256.  
257.  boolean
258.  can_track(ptr)		/* returns TRUE if monster can track well */
259.  	register struct permonst *ptr;
260.  {
261.  	if (uwep && uwep->oartifact == ART_EXCALIBUR)
262.  		return TRUE;
263.  	else
264.  		return((boolean)haseyes(ptr));
265.  }
266.  
267.  #endif /* OVL1 */
268.  #ifdef OVLB
269.  
270.  boolean
271.  sliparm(ptr)	/* creature will slide out of armor */
272.  	register struct permonst *ptr;
273.  {
274.  	return((boolean)(is_whirly(ptr) || ptr->msize <= MZ_SMALL ||
275.  			 noncorporeal(ptr)));
276.  }
277.  
278.  boolean
279.  breakarm(ptr)	/* creature will break out of armor */
280.  	register struct permonst *ptr;
281.  {
282.  	return ((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr)) ||
283.  		/* special cases of humanoids that cannot wear body armor */
284.  		ptr == &mons[PM_MARILITH] || ptr == &mons[PM_WINGED_GARGOYLE])
285.  	      && !sliparm(ptr));
286.  }
287.  #endif /* OVLB */
288.  #ifdef OVL1
289.  
290.  boolean
291.  sticks(ptr)	/* creature sticks other creatures it hits */
292.  	register struct permonst *ptr;
293.  {
294.  	return((boolean)(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) ||
295.  		attacktype(ptr,AT_HUGS)));
296.  }
297.  
298.  struct attack *
299.  dmgtype_fromattack(ptr, dtyp, atyp)
300.  struct permonst *ptr;
301.  int dtyp, atyp;
302.  {
303.      struct attack *a;
304.  
305.      for (a = &ptr->mattk[0]; a < &ptr->mattk[NATTK]; a++)
306.  	if (a->adtyp == dtyp && (atyp == AT_ANY || a->aatyp == atyp))
307.  	    return a;
308.  
309.      return (struct attack *)0;
310.  }
311.  
312.  boolean
313.  dmgtype(ptr, dtyp)
314.  struct permonst *ptr;
315.  int dtyp;
316.  {
317.      return dmgtype_fromattack(ptr, dtyp, AT_ANY) ? TRUE : FALSE;
318.  }
319.  
320.  /* returns the maximum damage a defender can do to the attacker via
321.   * a passive defense */
322.  int
323.  max_passive_dmg(mdef, magr)
324.      register struct monst *mdef, *magr;
325.  {
326.      int	i, dmg = 0;
327.      uchar adtyp;
328.  
329.      for(i = 0; i < NATTK; i++)
330.  	if(mdef->data->mattk[i].aatyp == AT_NONE ||
331.  		mdef->data->mattk[i].aatyp == AT_BOOM) {
332.  	    adtyp = mdef->data->mattk[i].adtyp;
333.  	    if ((adtyp == AD_ACID && !resists_acid(magr)) ||
334.  		    (adtyp == AD_COLD && !resists_cold(magr)) ||
335.  		    (adtyp == AD_FIRE && !resists_fire(magr)) ||
336.  		    (adtyp == AD_ELEC && !resists_elec(magr)) ||
337.  		    adtyp == AD_PHYS) {
338.  		dmg = mdef->data->mattk[i].damn;
339.  		if(!dmg) dmg = mdef->data->mlevel+1;
340.  		dmg *= mdef->data->mattk[i].damd;
341.  	    } else dmg = 0;
342.  
343.  	    return dmg;
344.  	}
345.      return 0;
346.  }
347.  
348.  #endif /* OVL1 */
349.  #ifdef OVL0
350.  
351.  int
352.  monsndx(ptr)		/* return an index into the mons array */
353.  	struct	permonst	*ptr;
354.  {
355.  	register int	i;
356.  
357.  	i = (int)(ptr - &mons[0]);
358.  	if (i < LOW_PM || i >= NUMMONS) {
359.  		/* ought to switch this to use `fmt_ptr' */
360.  	    panic("monsndx - could not index monster (%lx)",
361.  		  (unsigned long)ptr);
362.  	    return FALSE;		/* will not get here */
363.  	}
364.  
365.  	return(i);
366.  }
367.  
368.  #endif /* OVL0 */
369.  #ifdef OVL1
370.  
371.  
372.  int
373.  name_to_mon(in_str)
374.  const char *in_str;
375.  {
376.  	/* Be careful.  We must check the entire string in case it was
377.  	 * something such as "ettin zombie corpse".  The calling routine
378.  	 * doesn't know about the "corpse" until the monster name has
379.  	 * already been taken off the front, so we have to be able to
380.  	 * read the name with extraneous stuff such as "corpse" stuck on
381.  	 * the end.
382.  	 * This causes a problem for names which prefix other names such
383.  	 * as "ettin" on "ettin zombie".  In this case we want the _longest_
384.  	 * name which exists.
385.  	 * This also permits plurals created by adding suffixes such as 's'
386.  	 * or 'es'.  Other plurals must still be handled explicitly.
387.  	 */
388.  	register int i;
389.  	register int mntmp = NON_PM;
390.  	register char *s, *str, *term;
391.  	char buf[BUFSZ];
392.  	int len, slen;
393.  
394.  	str = strcpy(buf, in_str);
395.  
396.  	if (!strncmp(str, "a ", 2)) str += 2;
397.  	else if (!strncmp(str, "an ", 3)) str += 3;
398.  
399.  	slen = strlen(str);
400.  	term = str + slen;
401.  
402.  	if ((s = strstri(str, "vortices")) != 0)
403.  	    Strcpy(s+4, "ex");
404.  	/* be careful with "ies"; "priest", "zombies" */
405.  	else if (slen > 3 && !strcmpi(term-3, "ies") &&
406.  		    (slen < 7 || strcmpi(term-7, "zombies")))
407.  	    Strcpy(term-3, "y");
408.  	/* luckily no monster names end in fe or ve with ves plurals */
409.  	else if (slen > 3 && !strcmpi(term-3, "ves"))
410.  	    Strcpy(term-3, "f");
411.  
412.  	slen = strlen(str); /* length possibly needs recomputing */
413.  
414.      {
415.  	static const struct alt_spl { const char* name; short pm_val; }
416.  	    names[] = {
417.  	    /* Alternate spellings */
418.  		{ "grey dragon",	PM_GRAY_DRAGON },
419.  		{ "baby grey dragon",	PM_BABY_GRAY_DRAGON },
420.  		{ "grey unicorn",	PM_GRAY_UNICORN },
421.  		{ "grey ooze",		PM_GRAY_OOZE },
422.  		{ "gray-elf",		PM_GREY_ELF },
423.  	    /* Hyphenated names */
424.  		{ "ki rin",		PM_KI_RIN },
425.  		{ "uruk hai",		PM_URUK_HAI },
426.  		{ "orc captain",	PM_ORC_CAPTAIN },
427.  		{ "woodland elf",	PM_WOODLAND_ELF },
428.  		{ "green elf",		PM_GREEN_ELF },
429.  		{ "grey elf",		PM_GREY_ELF },
430.  		{ "gray elf",		PM_GREY_ELF },
431.  		{ "elf lord",		PM_ELF_LORD },
432.  #if 0	/* OBSOLETE */
433.  		{ "high elf",		PM_HIGH_ELF },
434.  #endif
435.  		{ "olog hai",		PM_OLOG_HAI },
436.  		{ "arch lich",		PM_ARCH_LICH },
437.  	    /* Some irregular plurals */
438.  		{ "incubi",		PM_INCUBUS },
439.  		{ "succubi",		PM_SUCCUBUS },
440.  		{ "violet fungi",	PM_VIOLET_FUNGUS },
441.  		{ "homunculi",		PM_HOMUNCULUS },
442.  		{ "baluchitheria",	PM_BALUCHITHERIUM },
443.  		{ "lurkers above",	PM_LURKER_ABOVE },
444.  		{ "cavemen",		PM_CAVEMAN },
445.  		{ "cavewomen",		PM_CAVEWOMAN },
446.  		{ "djinn",		PM_DJINNI },
447.  		{ "mumakil",		PM_MUMAK },
448.  		{ "erinyes",		PM_ERINYS },
449.  	    /* falsely caught by -ves check above */
450.  		{ "master of thief",	PM_MASTER_OF_THIEVES },
451.  	    /* end of list */
452.  		{ 0, 0 }
453.  	};
454.  	register const struct alt_spl *namep;
455.  
456.  	for (namep = names; namep->name; namep++)
457.  	    if (!strncmpi(str, namep->name, (int)strlen(namep->name)))
458.  		return namep->pm_val;
459.      }
460.  
461.  	for (len = 0, i = LOW_PM; i < NUMMONS; i++) {
462.  	    register int m_i_len = strlen(mons[i].mname);
463.  	    if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
464.  		if (m_i_len == slen) return i;	/* exact match */
465.  		else if (slen > m_i_len &&
466.  			(str[m_i_len] == ' ' ||
467.  			 !strcmpi(&str[m_i_len], "s") ||
468.  			 !strncmpi(&str[m_i_len], "s ", 2) ||
469.  			 !strcmpi(&str[m_i_len], "es") ||
470.  			 !strncmpi(&str[m_i_len], "es ", 3))) {
471.  		    mntmp = i;
472.  		    len = m_i_len;
473.  		}
474.  	    }
475.  	}
476.  	if (mntmp == NON_PM) mntmp = title_to_mon(str, (int *)0, (int *)0);
477.  	return mntmp;
478.  }
479.  
480.  #endif /* OVL1 */
481.  #ifdef OVL2
482.  
483.  /* returns 3 values (0=male, 1=female, 2=none) */
484.  int
485.  gender(mtmp)
486.  register struct monst *mtmp;
487.  {
488.  	if (is_neuter(mtmp->data)) return 2;
489.  	return mtmp->female;
490.  }
491.  
492.  /* Like gender(), but lower animals and such are still "it". */
493.  /* This is the one we want to use when printing messages. */
494.  int
495.  pronoun_gender(mtmp)
496.  register struct monst *mtmp;
497.  {
498.  	if (!canspotmon(mtmp) || !humanoid(mtmp->data))
499.  		return 2;
500.  	return mtmp->female;
501.  }
502.  
503.  #endif /* OVL2 */
504.  #ifdef OVLB
505.  
506.  boolean
507.  levl_follower(mtmp)
508.  register struct monst *mtmp;
509.  {
510.  	return((boolean)(mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp)
511.  		|| (mtmp->iswiz && !mon_has_amulet(mtmp))));
512.  }
513.  
514.  static const short grownups[][2] = {
515.  	{PM_CHICKATRICE, PM_COCKATRICE},
516.  	{PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG},
517.  	{PM_HELL_HOUND_PUP, PM_HELL_HOUND},
518.  	{PM_WINTER_WOLF_CUB, PM_WINTER_WOLF},
519.  	{PM_KITTEN, PM_HOUSECAT}, {PM_HOUSECAT, PM_LARGE_CAT},
520.  	{PM_PONY, PM_HORSE}, {PM_HORSE, PM_WARHORSE},
521.  	{PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD},
522.  	{PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING},
523.  	{PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING},
524.  	{PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
525.  	{PM_ELF, PM_ELF_LORD}, {PM_WOODLAND_ELF, PM_ELF_LORD},
526.  	{PM_GREEN_ELF, PM_ELF_LORD}, {PM_GREY_ELF, PM_ELF_LORD},
527.  	{PM_ELF_LORD, PM_ELVENKING},
528.  	{PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH},
529.  	{PM_MASTER_LICH, PM_ARCH_LICH},
530.  	{PM_VAMPIRE, PM_VAMPIRE_LORD}, {PM_BAT, PM_GIANT_BAT},
531.  	{PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON},
532.  	{PM_BABY_SILVER_DRAGON, PM_SILVER_DRAGON},
533.  #if 0	/* DEFERRED */
534.  	{PM_BABY_SHIMMERING_DRAGON, PM_SHIMMERING_DRAGON},
535.  #endif
536.  	{PM_BABY_RED_DRAGON, PM_RED_DRAGON},
537.  	{PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON},
538.  	{PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON},
539.  	{PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON},
540.  	{PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON},
541.  	{PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON},
542.  	{PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON},
543.  	{PM_RED_NAGA_HATCHLING, PM_RED_NAGA},
544.  	{PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA},
545.  	{PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA},
546.  	{PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA},
547.  	{PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC},
548.  	{PM_BABY_LONG_WORM, PM_LONG_WORM},
549.  	{PM_BABY_PURPLE_WORM, PM_PURPLE_WORM},
550.  	{PM_BABY_CROCODILE, PM_CROCODILE},
551.  	{PM_SOLDIER, PM_SERGEANT},
552.  	{PM_SERGEANT, PM_LIEUTENANT},
553.  	{PM_LIEUTENANT, PM_CAPTAIN},
554.  	{PM_WATCHMAN, PM_WATCH_CAPTAIN},
555.  	{PM_ALIGNED_PRIEST, PM_HIGH_PRIEST},
556.  	{PM_STUDENT, PM_ARCHEOLOGIST},
557.  	{PM_ATTENDANT, PM_HEALER},
558.  	{PM_PAGE, PM_KNIGHT},
559.  	{PM_ACOLYTE, PM_PRIEST},
560.  	{PM_APPRENTICE, PM_WIZARD},
561.  	{PM_MANES,PM_LEMURE},
562.  #ifdef KOPS
563.  	{PM_KEYSTONE_KOP, PM_KOP_SERGEANT},
564.  	{PM_KOP_SERGEANT, PM_KOP_LIEUTENANT},
565.  	{PM_KOP_LIEUTENANT, PM_KOP_KAPTAIN},
566.  #endif
567.  	{NON_PM,NON_PM}
568.  };
569.  
570.  int
571.  little_to_big(montype)
572.  int montype;
573.  {
574.  #ifndef AIXPS2_BUG
575.  	register int i;
576.  
577.  	for (i = 0; grownups[i][0] >= LOW_PM; i++)
578.  		if(montype == grownups[i][0]) return grownups[i][1];
579.  	return montype;
580.  #else
581.  /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop,
582.   * and causes segmentation faults at runtime.  (The problem does not
583.   * occur if -O is not used.)
584.   * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990
585.   */
586.  	int i;
587.  	int monvalue;
588.  
589.  	monvalue = montype;
590.  	for (i = 0; grownups[i][0] >= LOW_PM; i++)
591.  		if(montype == grownups[i][0]) monvalue = grownups[i][1];
592.  
593.  	return monvalue;
594.  #endif
595.  }
596.  
597.  int
598.  big_to_little(montype)
599.  int montype;
600.  {
601.  	register int i;
602.  
603.  	for (i = 0; grownups[i][0] >= LOW_PM; i++)
604.  		if(montype == grownups[i][1]) return grownups[i][0];
605.  	return montype;
606.  }
607.  
608.  static const char *levitate[4]	= { "float", "Float", "wobble", "Wobble" };
609.  static const char *flys[4]	= { "fly", "Fly", "flutter", "Flutter" };
610.  static const char *flyl[4]	= { "fly", "Fly", "stagger", "Stagger" };
611.  static const char *slither[4]	= { "slither", "Slither", "falter", "Falter" };
612.  static const char *ooze[4]	= { "ooze", "Ooze", "tremble", "Tremble" };
613.  static const char *immobile[4]	= { "wiggle", "Wiggle", "pulsate", "Pulsate" };
614.  static const char *crawl[4]	= { "crawl", "Crawl", "falter", "Falter" };
615.  
616.  const char *
617.  locomotion(ptr, def)
618.  const struct permonst *ptr;
619.  const char *def;
620.  {
621.  	int capitalize = (*def == highc(*def));
622.  
623.  	return (
624.  		is_floater(ptr) ? levitate[capitalize] :
625.  		(is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize] :
626.  		(is_flyer(ptr) && ptr->msize > MZ_SMALL)  ? flyl[capitalize] :
627.  		slithy(ptr)     ? slither[capitalize] :
628.  		amorphous(ptr)  ? ooze[capitalize] :
629.  		!ptr->mmove	? immobile[capitalize] :
630.  		nolimbs(ptr)    ? crawl[capitalize] :
631.  		def
632.  	       );
633.  
634.  }
635.  
636.  const char *
637.  stagger(ptr, def)
638.  const struct permonst *ptr;
639.  const char *def;
640.  {
641.  	int capitalize = 2 + (*def == highc(*def));
642.  
643.  	return (
644.  		is_floater(ptr) ? levitate[capitalize] :
645.  		(is_flyer(ptr) && ptr->msize <= MZ_SMALL) ? flys[capitalize] :
646.  		(is_flyer(ptr) && ptr->msize > MZ_SMALL)  ? flyl[capitalize] :
647.  		slithy(ptr)     ? slither[capitalize] :
648.  		amorphous(ptr)  ? ooze[capitalize] :
649.  		!ptr->mmove	? immobile[capitalize] :
650.  		nolimbs(ptr)    ? crawl[capitalize] :
651.  		def
652.  	       );
653.  
654.  }
655.  
656.  #endif /* OVLB */
657.  
658.  /*mondata.c*/