Source:NetHack 3.1.0/mondata.c

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

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<mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<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*/