Source:NetHack 3.1.0/mondata.c

From NetHackWiki
(Redirected from NetHack 3.1.0/mondata.c)
Jump to navigation Jump to search

Below is the full text to mondata.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1	92/11/24	*/
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.    /*	These routines provide basic data for any type of monster. */
10.   
11.   #ifdef OVL0
12.   
13.   boolean
14.   attacktype(ptr, atyp)
15.   	register struct	permonst	*ptr;
16.   	register int atyp;
17.   {
18.   	int	i;
19.   
20.   	for(i = 0; i < NATTK; i++)
21.   	    if(ptr->mattk[i].aatyp == atyp) return(TRUE);
22.   
23.   	return(FALSE);
24.   }
25.   
26.   #endif /* OVL0 */
27.   #ifdef OVLB
28.   
29.   boolean
30.   poly_when_stoned(ptr)
31.       struct permonst *ptr;
32.   {
33.       return (is_golem(ptr) && ptr != &mons[PM_STONE_GOLEM] &&
34.   	    !(mons[PM_STONE_GOLEM].geno & G_GENOD));	/* allow G_EXTINCT */
35.   }
36.   
37.   boolean
38.   resists_drli(ptr)	/* returns TRUE if monster is drain-life resistant */
39.   
40.   	register struct permonst *ptr;
41.   {
42.   	return(is_undead(ptr) || is_demon(ptr) || is_were(ptr));
43.   }
44.   
45.   #endif /* OVLB */
46.   #ifdef OVL0
47.   
48.   boolean
49.   ranged_attk(ptr)	/* returns TRUE if monster can attack at range */
50.   	register struct permonst *ptr;
51.   {
52.   	register int	i, j;
53.   	register int atk_mask = (1<<AT_BREA) | (1<<AT_SPIT) | (1<<AT_GAZE);
54.   
55.   	/* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) ||
56.   		attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) ||
57.   		attacktype(ptr, AT_MAGC));
58.   	   but that's too slow -dlc
59.   	 */
60.   	for(i = 0; i < NATTK; i++) {
61.   	    if((j=ptr->mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<<j)))
62.   		return TRUE;
63.   	}
64.   
65.   	return(FALSE);
66.   }
67.   
68.   boolean
69.   hates_silver(ptr)
70.   register struct permonst *ptr;
71.   /* returns TRUE if monster is especially affected by silver weapons */
72.   {
73.   	return (is_were(ptr) || ptr->mlet==S_VAMPIRE || is_demon(ptr) ||
74.   		ptr == &mons[PM_SHADE] ||
75.   		(ptr->mlet==S_IMP && ptr != &mons[PM_TENGU]));
76.   }
77.   
78.   #endif /* OVL0 */
79.   #ifdef OVL1
80.   
81.   boolean
82.   can_track(ptr)		/* returns TRUE if monster can track well */
83.   	register struct permonst *ptr;
84.   {
85.   	if (uwep && uwep->oartifact == ART_EXCALIBUR)
86.   		return TRUE;
87.   	else
88.   		return(haseyes(ptr));
89.   }
90.   
91.   #endif /* OVL1 */
92.   #ifdef OVLB
93.   
94.   #if defined(POLYSELF) || defined(MUSE)
95.   boolean
96.   sliparm(ptr)	/* creature will slide out of armor */
97.   	register struct permonst *ptr;
98.   {
99.   	return is_whirly(ptr) || ptr->msize <= MZ_SMALL ||
100.  		ptr == &mons[PM_GHOST];
101.  }
102.  
103.  boolean
104.  breakarm(ptr)	/* creature will break out of armor */
105.  	register struct permonst *ptr;
106.  {
107.  	return((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr))
108.  	                || ptr == &mons[PM_MARILITH]) && !sliparm(ptr));
109.  	/* Marilith is about the only case of a monster which is otherwise
110.  	 * humanoid but cannot wear armor (too many arms).  Centaurs would
111.  	 * be another except that they are already accounted for by
112.  	 * bigmonst.
113.  	 */
114.  }
115.  #endif
116.  #endif /* OVLB */
117.  #ifdef OVL1
118.  
119.  boolean
120.  sticks(ptr)	/* creature sticks other creatures it hits */
121.  	register struct permonst *ptr;
122.  {
123.  	return(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) ||
124.  		attacktype(ptr,AT_HUGS));
125.  }
126.  
127.  boolean
128.  dmgtype(ptr, dtyp)
129.  	register struct	permonst	*ptr;
130.  	register int dtyp;
131.  {
132.  	int	i;
133.  
134.  	for(i = 0; i < NATTK; i++)
135.  	    if(ptr->mattk[i].adtyp == dtyp) return TRUE;
136.  
137.  	return FALSE;
138.  }
139.  
140.  /* returns the maximum damage a defender can do to the attacker via
141.   * a passive defense */
142.  int
143.  max_passive_dmg(mdef, magr)
144.      register struct monst *mdef, *magr;
145.  {
146.      int	i, dmg = 0;
147.      uchar adtyp;
148.  
149.      for(i = 0; i < NATTK; i++)
150.  	if(mdef->data->mattk[i].aatyp == AT_NONE) {
151.  	    adtyp = mdef->data->mattk[i].adtyp;
152.  	    if((adtyp == AD_ACID && !resists_acid(magr->data)) ||
153.  		    (adtyp == AD_COLD && !resists_cold(magr->data)) ||
154.  		    (adtyp == AD_FIRE && !resists_fire(magr->data)) ||
155.  		    (adtyp == AD_ELEC && !resists_elec(magr->data))) {
156.  		dmg = mdef->data->mattk[i].damn;
157.  		if(!dmg) dmg = mdef->data->mlevel+1;
158.  		dmg *= mdef->data->mattk[i].damd;
159.  	    } else dmg = 0;
160.  
161.  	    return dmg;
162.  	}
163.      return 0;
164.  }
165.  
166.  #endif /* OVL1 */
167.  #ifdef OVL0
168.  
169.  int
170.  monsndx(ptr)		/* return an index into the mons array */
171.  	struct	permonst	*ptr;
172.  {
173.  	register int	i;
174.  
175.  	if(ptr == &playermon) return(-1);
176.  
177.  	i = (int)(ptr - &mons[0]);
178.  	if(i < 0 || i >= NUMMONS) {    
179.  	    panic("monsndx - could not index monster (%lx)", (long)ptr);
180.  	    return FALSE;		/* will not get here */
181.  	}
182.  
183.  	return(i);
184.  }
185.  
186.  #endif /* OVL0 */
187.  #ifdef OVL1
188.  
189.  
190.  int
191.  name_to_mon(str)
192.  char *str;
193.  {
194.  	/* Be careful.  We must check the entire string in case it was
195.  	 * something such as "ettin zombie corpse".  The calling routine
196.  	 * doesn't know about the "corpse" until the monster name has
197.  	 * already been taken off the front, so we have to be able to
198.  	 * read the name with extraneous stuff such as "corpse" stuck on
199.  	 * the end.
200.  	 * This causes a problem for names which prefix other names such
201.  	 * as "ettin" on "ettin zombie".  In this case we want the _longest_
202.  	 * name which exists.
203.  	 * This also permits plurals created by adding suffixes such as 's'
204.  	 * or 'es'.  Other plurals must still be handled explicitly.
205.  	 */
206.  	register int i;
207.  	register int mntmp = -1;
208.  	register char *s;
209.  	char buf[BUFSZ];
210.  	int len, slen;
211.  
212.  	Strcpy(buf, str);
213.  	str = buf;
214.  	if (!strncmp(str, "a ", 2)) str += 2;
215.  	else if (!strncmp(str, "an ", 3)) str += 3;
216.  
217.  	/* Some irregular plurals */
218.  	if (!strncmpi(str, "incubi", 6)) return PM_INCUBUS;
219.  	if (!strncmpi(str, "succubi", 7)) return PM_SUCCUBUS;
220.  	if (!strncmpi(str, "violet fungi", 12)) return PM_VIOLET_FUNGUS;
221.  	if (!strncmpi(str, "homunculi", 9)) return PM_HOMUNCULUS;
222.  	if (!strncmpi(str, "baluchitheria", 13)) return PM_BALUCHITHERIUM;
223.  	if (!strncmpi(str, "lurkers above", 13)) return PM_LURKER_ABOVE;
224.  	if (!strncmpi(str, "cavemen", 7)) return PM_CAVEMAN;
225.  	if (!strncmpi(str, "cavewomen", 9)) return PM_CAVEWOMAN;
226.  	if (!strncmpi(str, "zruties", 7)) return PM_ZRUTY;
227.  	if (!strncmpi(str, "djinn", 5)) return PM_DJINNI;
228.  	if (!strncmpi(str, "mumakil", 7)) return PM_MUMAK;
229.  	if ((s = strstri(str, "vortices")) != 0)
230.  	    Strcpy(s+4, "ex");
231.  	/* be careful with "ies"; "priest", "zombies" */
232.  	else if ((s = strstri(str, "jellies")) != 0 ||
233.  		 (s = strstri(str, "mummies")) != 0)
234.  	    Strcpy(s+4, "y");
235.  	/* luckily no monster names end in fe or ve with ves plurals */
236.  	else if ((s = strstri(str, "ves")) != 0)
237.  	    Strcpy(s, "f");
238.  
239.  	slen = strlen(str);
240.  	for (len = 0, i = 0; i < NUMMONS; i++) {
241.  	    register int m_i_len = strlen(mons[i].mname);
242.  	    if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) {
243.  		if (m_i_len == slen) return i;	/* exact match */
244.  		else if (slen > m_i_len &&
245.  			(str[m_i_len] == ' ' ||
246.  			 !strcmpi(&str[m_i_len], "s") ||
247.  			 !strncmpi(&str[m_i_len], "s ", 2) ||
248.  			 !strcmpi(&str[m_i_len], "es") ||
249.  			 !strncmpi(&str[m_i_len], "es ", 3))) {
250.  		    mntmp = i;
251.  		    len = m_i_len;
252.  		}
253.  	    }
254.  	}
255.  	if (mntmp == -1) mntmp = title_to_mon(str, (int *)0, (int *)0);
256.  	return mntmp;
257.  }
258.  
259.  #endif /* OVL1 */
260.  #ifdef OVLB
261.  
262.  #ifdef POLYSELF
263.  boolean
264.  webmaker(ptr)   /* creature can spin a web */
265.  	register struct permonst *ptr;
266.  {
267.  	return (ptr->mlet == S_SPIDER && ptr != &mons[PM_SCORPION]);
268.  }
269.  #endif
270.  
271.  #endif /* OVLB */
272.  #ifdef OVL2
273.  
274.  /* returns 3 values (0=male, 1=female, 2=none) */
275.  int
276.  gender(mtmp)
277.  	register struct monst *mtmp;
278.  {
279.  	if (is_neuter(mtmp->data)) return 2;
280.  	return mtmp->female;
281.  }
282.  
283.  #endif /* OVL2 */
284.  #ifdef OVLB
285.  
286.  boolean
287.  levl_follower(mtmp)
288.  register struct monst *mtmp;
289.  {
290.  	return (mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp)
291.  		|| (mtmp->iswiz && !mon_has_amulet(mtmp)));
292.  }
293.  
294.  struct permonst *
295.  player_mon()
296.  {
297.  	switch (pl_character[0]) {
298.  		case 'A': return &mons[PM_ARCHEOLOGIST];
299.  		case 'B': return &mons[PM_BARBARIAN];
300.  		case 'C': if (flags.female) return &mons[PM_CAVEWOMAN];
301.  			else return &mons[PM_CAVEMAN];
302.  		case 'E': return &mons[PM_ELF];
303.  		case 'H': return &mons[PM_HEALER];
304.  		case 'K': return &mons[PM_KNIGHT];
305.  		case 'P': if (flags.female) return &mons[PM_PRIESTESS];
306.  			else return &mons[PM_PRIEST];
307.  		case 'R': return &mons[PM_ROGUE];
308.  		case 'S': return &mons[PM_SAMURAI];
309.  #ifdef TOURIST
310.  		case 'T': return &mons[PM_TOURIST];
311.  #endif
312.  		case 'V': return &mons[PM_VALKYRIE];
313.  		case 'W': return &mons[PM_WIZARD];
314.  		default: impossible("what are you?");
315.  			return &mons[PM_HUMAN];
316.  	}
317.  }
318.  
319.  const int grownups[][2] = { {PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG},
320.  	{PM_HELL_HOUND_PUP, PM_HELL_HOUND}, {PM_KITTEN, PM_HOUSECAT},
321.  	{PM_HOUSECAT, PM_LARGE_CAT}, {PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON},
322.  	{PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD},
323.  	{PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING},
324.  	{PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING},
325.  	{PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC},
326.  	{PM_BAT, PM_GIANT_BAT},
327.  	{PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH},
328.  	{PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING},
329.  	{PM_VAMPIRE, PM_VAMPIRE_LORD},
330.  	{PM_BABY_RED_DRAGON, PM_RED_DRAGON},
331.  	{PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON},
332.  	{PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON},
333.  	{PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON},
334.  	{PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON},
335.  	{PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON},
336.  	{PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON},
337.  	{PM_RED_NAGA_HATCHLING, PM_RED_NAGA},
338.  	{PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA},
339.  	{PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA},
340.  	{PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA},
341.  	{PM_BABY_PURPLE_WORM, PM_PURPLE_WORM},
342.  	{PM_BABY_LONG_WORM, PM_LONG_WORM},
343.  #ifdef ARMY
344.  	{PM_SOLDIER, PM_SERGEANT},
345.  	{PM_SERGEANT, PM_LIEUTENANT},
346.  	{PM_LIEUTENANT, PM_CAPTAIN},
347.  #endif
348.  	{PM_WATCHMAN, PM_WATCH_CAPTAIN},
349.  	{PM_BABY_CROCODILE, PM_CROCODILE},
350.  	{-1,-1}
351.  };
352.  
353.  int
354.  little_to_big(montype)
355.  int montype;
356.  {
357.  #ifndef AIXPS2_BUG
358.  	register int i;
359.  	
360.  	for(i=0; grownups[i][0] >= 0; i++)
361.  		if(montype == grownups[i][0]) return grownups[i][1];
362.  	return montype;
363.  #else
364.  /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop,
365.   * and causes segmentation faults at runtime.  (The problem does not
366.   * occur if -O is not used.)
367.   * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990
368.   */
369.  	int i;
370.  	int monvalue;
371.  
372.  	monvalue = montype;
373.  	for(i=0; grownups[i][0] >= 0; i++)
374.  		if(montype == grownups[i][0]) monvalue = grownups[i][1];
375.  	
376.  	return monvalue;
377.  #endif
378.  }
379.  
380.  int
381.  big_to_little(montype)
382.  int montype;
383.  {
384.  	register int i;
385.  	
386.  	for(i=0; grownups[i][0] >= 0; i++)
387.  		if(montype == grownups[i][1]) return grownups[i][0];
388.  	return montype;
389.  }
390.  
391.  
392.  const char *
393.  locomotion(ptr, def)
394.  const struct permonst *ptr;
395.  const char *def;
396.  {
397.  	return (
398.  		is_floater(ptr) ? (const char *)"float" :
399.  		is_flyer(ptr)   ? (const char *)"fly" :
400.  		slithy(ptr)     ? (const char *)"slither" :
401.  		amorphous(ptr)  ? (const char *)"ooze" :
402.  		nolimbs(ptr)    ? (const char *)"crawl" :
403.  		def
404.  	       );
405.  
406.  }
407.  
408.  #endif /* OVLB */
409.  
410.  /*mondata.c*/