Source:NetHack 3.3.0/mondata.c

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