Source:NetHack 3.2.0/mondata.c

Below is the full text to mondata.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	95/07/29	*/ 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.   #endif /* OVLB */ 93.  #ifdef OVL0 94.   95.   boolean 96.  ranged_attk(ptr)	/* returns TRUE if monster can attack at range */ 97.  	register struct permonst *ptr; 98.  {  99.   	register int	i, j;  100. register int atk_mask = (1<mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<mlet==S_VAMPIRE || is_demon(ptr) || 121. 		ptr == &mons[PM_SHADE] || 122. 		(ptr->mlet==S_IMP && ptr != &mons[PM_TENGU]))); 123. }  124.   125.  #endif /* OVL0 */ 126. #ifdef OVL1 127.  128.  boolean 129. can_track(ptr)		/* returns TRUE if monster can track well */ 130. 	register struct permonst *ptr; 131. {  132.  	if (uwep && uwep->oartifact == ART_EXCALIBUR) 133. 		return TRUE; 134. 	else 135. 		return((boolean)haseyes(ptr)); 136. }  137.   138.  #endif /* OVL1 */ 139. #ifdef OVLB 140.  141.  boolean 142. sliparm(ptr)	/* creature will slide out of armor */ 143. 	register struct permonst *ptr; 144. {  145.  	return((boolean)(is_whirly(ptr) || ptr->msize <= MZ_SMALL || 146. 			 noncorporeal(ptr))); 147. }  148.   149.  boolean 150. breakarm(ptr)	/* creature will break out of armor */ 151. 	register struct permonst *ptr; 152. {  153.  	return((boolean)((bigmonst(ptr) || (ptr->msize > MZ_SMALL && !humanoid(ptr))  154.  	                || ptr == &mons[PM_MARILITH]) && !sliparm(ptr))); 155. 	/* Marilith is about the only case of a monster which is otherwise 156. 	 * humanoid but cannot wear armor (too many arms). Centaurs would 157. 	 * be another except that they are already accounted for by  158. * bigmonst. 159. 	 */  160.  }  161.  #endif /* OVLB */ 162. #ifdef OVL1 163.  164.  boolean 165. sticks(ptr)	/* creature sticks other creatures it hits */ 166. 	register struct permonst *ptr; 167. {  168.  	return((boolean)(dmgtype(ptr,AD_STCK) || dmgtype(ptr,AD_WRAP) || 169. 		attacktype(ptr,AT_HUGS))); 170. }  171.   172.  boolean 173. dmgtype(ptr, dtyp) 174. 	register struct	permonst	*ptr; 175. 	register int dtyp; 176. {  177.  	int	i; 178.  179.  	for(i = 0; i < NATTK; i++) 180. 	    if(ptr->mattk[i].adtyp == dtyp) return TRUE; 181.  182.  	return FALSE; 183. }  184.   185.  /* returns the maximum damage a defender can do to the attacker via 186.  * a passive defense */ 187. int 188. max_passive_dmg(mdef, magr) 189.     register struct monst *mdef, *magr; 190. {  191.      int	i, dmg = 0; 192.     uchar adtyp; 193.  194.      for(i = 0; i < NATTK; i++) 195. 	if(mdef->data->mattk[i].aatyp == AT_NONE) { 196. 	    adtyp = mdef->data->mattk[i].adtyp; 197. 	    if ((adtyp == AD_ACID && !resists_acid(magr)) ||  198.  		    (adtyp == AD_COLD && !resists_cold(magr)) ||  199.  		    (adtyp == AD_FIRE && !resists_fire(magr)) ||  200.  		    (adtyp == AD_ELEC && !resists_elec(magr))) { 201. 		dmg = mdef->data->mattk[i].damn; 202. 		if(!dmg) dmg = mdef->data->mlevel+1; 203. 		dmg *= mdef->data->mattk[i].damd; 204. 	    } else dmg = 0; 205.  206.  	    return dmg; 207. 	}  208.      return 0; 209. }  210.   211.  #endif /* OVL1 */ 212. #ifdef OVL0 213.  214.  int 215. monsndx(ptr)		/* return an index into the mons array */ 216. 	struct	permonst	*ptr; 217. {  218.  	register int	i; 219.  220.  	if (ptr == &playermon) return PM_PLAYERMON; 221.  222.  	i = (int)(ptr - &mons[0]); 223. 	if (i < LOW_PM || i >= NUMMONS) { 224. 		/* ought to switch this to use `fmt_ptr' */ 225. 	    panic("monsndx - could not index monster (%lx)",  226.  		  (unsigned long)ptr); 227. 	    return FALSE;		/* will not get here */ 228. 	}  229.   230.  	return(i); 231. }  232.   233.  #endif /* OVL0 */ 234. #ifdef OVL1 235.  236.   237.  int 238. name_to_mon(in_str) 239. const char *in_str; 240. {  241.  	/* Be careful. We must check the entire string in case it was 242. 	 * something such as "ettin zombie corpse". The calling routine 243. 	 * doesn't know about the "corpse" until the monster name has 244. 	 * already been taken off the front, so we have to be able to  245. * read the name with extraneous stuff such as "corpse" stuck on 246. * the end. 247. 	 * This causes a problem for names which prefix other names such 248. 	 * as "ettin" on "ettin zombie". In this case we want the _longest_ 249. 	 * name which exists. 250. 	 * This also permits plurals created by adding suffixes such as 's'  251. * or 'es'. Other plurals must still be handled explicitly. 252. 	 */  253.  	register int i;  254. register int mntmp = NON_PM; 255. 	register char *s, *str; 256. 	char buf[BUFSZ]; 257. 	int len, slen; 258.  259.  	str = strcpy(buf, in_str); 260. 	if (!strncmp(str, "a ", 2)) str += 2; 261. 	else if (!strncmp(str, "an ", 3)) str += 3; 262.  263.  	if ((s = strstri(str, "vortices")) != 0) 264. 	    Strcpy(s+4, "ex"); 265. 	/* be careful with "ies"; "priest", "zombies" */ 266. 	else if ((s = strstri(str, "jellies")) != 0 ||  267.  		 (s = strstri(str, "mummies")) != 0) 268. 	    Strcpy(s+4, "y"); 269. 	/* luckily no monster names end in fe or ve with ves plurals */ 270. 	else if ((s = strstri(str, "ves")) != 0) 271. 	    Strcpy(s, "f"); 272.  273.      {  274.  	static const struct alt_spl { const char* name; short pm_val; } 275. 	    names[] = { 276. 	    /* Alternate spellings */ 277. 		{ "grey dragon",	PM_GRAY_DRAGON }, 278. 		{ "baby grey dragon",	PM_BABY_GRAY_DRAGON }, 279. 		{ "grey unicorn",	PM_GRAY_UNICORN }, 280. 		{ "grey ooze",		PM_GRAY_OOZE }, 281. 		{ "gray-elf",		PM_GREY_ELF }, 282. 	    /* Hyphenated names */ 283. 		{ "ki rin",		PM_KI_RIN }, 284. 		{ "uruk hai",		PM_URUK_HAI }, 285. 		{ "orc captain",	PM_ORC_CAPTAIN }, 286. 		{ "woodland elf",	PM_WOODLAND_ELF }, 287. 		{ "green elf",		PM_GREEN_ELF }, 288. 		{ "grey elf",		PM_GREY_ELF }, 289. 		{ "gray elf",		PM_GREY_ELF }, 290. 		{ "elf lord",		PM_ELF_LORD }, 291. 		{ "high elf",		PM_HIGH_ELF }, 292. 		{ "olog hai",		PM_OLOG_HAI }, 293. 	    /* Some irregular plurals */ 294. 		{ "incubi",		PM_INCUBUS }, 295. 		{ "succubi",		PM_SUCCUBUS }, 296. 		{ "violet fungi",	PM_VIOLET_FUNGUS }, 297. 		{ "homunculi",		PM_HOMUNCULUS }, 298. 		{ "baluchitheria",	PM_BALUCHITHERIUM }, 299. 		{ "lurkers above",	PM_LURKER_ABOVE }, 300. 		{ "cavemen",		PM_CAVEMAN }, 301. 		{ "cavewomen",		PM_CAVEWOMAN }, 302. 		{ "zruties",		PM_ZRUTY }, 303. 		{ "djinn",		PM_DJINNI }, 304. 		{ "mumakil",		PM_MUMAK }, 305. 		{ "erinyes",		PM_ERINYS }, 306. 	    /* end of list */ 307. 		{ 0, 0 }  308.  	};  309.  	register const struct alt_spl *namep; 310.  311.  	for (namep = names; namep->name; namep++) 312. 	    if (!strncmpi(str, namep->name, (int)strlen(namep->name))) 313. 		return namep->pm_val; 314.     }  315.   316.  	slen = strlen(str); 317. 	for (len = 0, i = LOW_PM; i < NUMMONS; i++) { 318. 	    register int m_i_len = strlen(mons[i].mname); 319. 	    if (m_i_len > len && !strncmpi(mons[i].mname, str, m_i_len)) { 320. 		if (m_i_len == slen) return i;	/* exact match */ 321. 		else if (slen > m_i_len &&  322.  			(str[m_i_len] == ' ' || 323. 			 !strcmpi(&str[m_i_len], "s") || 324. 			 !strncmpi(&str[m_i_len], "s ", 2) || 325. 			 !strcmpi(&str[m_i_len], "es") || 326. 			 !strncmpi(&str[m_i_len], "es ", 3))) { 327. 		    mntmp = i;  328. len = m_i_len; 329. 		}  330.  	    }  331.  	}  332.  	if (mntmp == NON_PM) mntmp = title_to_mon(str, (int *)0, (int *)0); 333. 	return mntmp; 334. }  335.   336.  #endif /* OVL1 */ 337. #ifdef OVLB 338.  339.  boolean 340. webmaker(ptr)   /* creature can spin a web */ 341. 	register struct permonst *ptr; 342. {  343.  	return((boolean)(ptr->mlet == S_SPIDER && ptr != &mons[PM_SCORPION])); 344. }  345.   346.  #endif /* OVLB */ 347. #ifdef OVL2 348.  349.  /* returns 3 values (0=male, 1=female, 2=none) */ 350. int 351. gender(mtmp) 352. register struct monst *mtmp; 353. {  354.  	if (is_neuter(mtmp->data)) return 2; 355. 	return mtmp->female; 356. }  357.   358.  /* Like gender, but lower animals and such are still "it". */ 359.  /* This is the one we want to use when printing messages. */ 360.  int 361. pronoun_gender(mtmp) 362. register struct monst *mtmp; 363. {  364.  	if (!canspotmon(mtmp) || !humanoid(mtmp->data)) 365. 		return 2; 366. 	return mtmp->female; 367. }  368.   369.  #endif /* OVL2 */ 370. #ifdef OVLB 371.  372.  boolean 373. levl_follower(mtmp) 374. register struct monst *mtmp; 375. {  376.  	return((boolean)(mtmp->mtame || (mtmp->data->mflags2 & M2_STALK) || is_fshk(mtmp) 377. 		|| (mtmp->iswiz && !mon_has_amulet(mtmp)))); 378. }  379.   380.  struct permonst * 381. player_mon 382. {  383.  	switch (u.role) { 384. 		case 'A': return &mons[PM_ARCHEOLOGIST]; 385. 		case 'B': return &mons[PM_BARBARIAN]; 386. 		case 'C': if (flags.female) return &mons[PM_CAVEWOMAN]; 387. 			else return &mons[PM_CAVEMAN]; 388. 		case 'E': return &mons[PM_ELF]; 389. 		case 'H': return &mons[PM_HEALER]; 390. 		case 'K': return &mons[PM_KNIGHT]; 391. 		case 'P': if (flags.female) return &mons[PM_PRIESTESS]; 392. 			else return &mons[PM_PRIEST]; 393. 		case 'R': return &mons[PM_ROGUE]; 394. 		case 'S': return &mons[PM_SAMURAI]; 395. #ifdef TOURIST 396. 		case 'T': return &mons[PM_TOURIST]; 397. #endif 398. 		case 'V': return &mons[PM_VALKYRIE]; 399. 		case 'W': return &mons[PM_WIZARD]; 400. 		default: impossible("what are you?"); 401. 			return &mons[PM_HUMAN]; 402. 	}  403.  }  404.   405.  static const short grownups[][2] = { 406. 	{PM_LITTLE_DOG, PM_DOG}, {PM_DOG, PM_LARGE_DOG}, 407. 	{PM_HELL_HOUND_PUP, PM_HELL_HOUND}, 408. 	{PM_KITTEN, PM_HOUSECAT}, {PM_HOUSECAT, PM_LARGE_CAT}, 409. 	{PM_KOBOLD, PM_LARGE_KOBOLD}, {PM_LARGE_KOBOLD, PM_KOBOLD_LORD}, 410. 	{PM_GNOME, PM_GNOME_LORD}, {PM_GNOME_LORD, PM_GNOME_KING}, 411. 	{PM_DWARF, PM_DWARF_LORD}, {PM_DWARF_LORD, PM_DWARF_KING}, 412. 	{PM_OGRE, PM_OGRE_LORD}, {PM_OGRE_LORD, PM_OGRE_KING}, 413. 	{PM_LICH, PM_DEMILICH}, {PM_DEMILICH, PM_MASTER_LICH}, 414. 	{PM_VAMPIRE, PM_VAMPIRE_LORD}, {PM_BAT, PM_GIANT_BAT}, 415. 	{PM_BABY_GRAY_DRAGON, PM_GRAY_DRAGON}, 416. 	{PM_BABY_RED_DRAGON, PM_RED_DRAGON}, 417. 	{PM_BABY_WHITE_DRAGON, PM_WHITE_DRAGON}, 418. 	{PM_BABY_ORANGE_DRAGON, PM_ORANGE_DRAGON}, 419. 	{PM_BABY_BLACK_DRAGON, PM_BLACK_DRAGON}, 420. 	{PM_BABY_BLUE_DRAGON, PM_BLUE_DRAGON}, 421. 	{PM_BABY_GREEN_DRAGON, PM_GREEN_DRAGON}, 422. 	{PM_BABY_YELLOW_DRAGON, PM_YELLOW_DRAGON}, 423. 	{PM_RED_NAGA_HATCHLING, PM_RED_NAGA}, 424. 	{PM_BLACK_NAGA_HATCHLING, PM_BLACK_NAGA}, 425. 	{PM_GOLDEN_NAGA_HATCHLING, PM_GOLDEN_NAGA}, 426. 	{PM_GUARDIAN_NAGA_HATCHLING, PM_GUARDIAN_NAGA}, 427. 	{PM_BABY_LONG_WORM, PM_LONG_WORM}, 428. 	{PM_BABY_PURPLE_WORM, PM_PURPLE_WORM}, 429. 	{PM_BABY_CROCODILE, PM_CROCODILE}, 430. 	{PM_SOLDIER, PM_SERGEANT}, 431. 	{PM_SERGEANT, PM_LIEUTENANT}, 432. 	{PM_LIEUTENANT, PM_CAPTAIN}, 433. 	{PM_WATCHMAN, PM_WATCH_CAPTAIN}, 434. 	{PM_SMALL_MIMIC, PM_LARGE_MIMIC}, {PM_LARGE_MIMIC, PM_GIANT_MIMIC}, 435. 	{NON_PM,NON_PM} 436. };  437.   438.  int 439. little_to_big(montype) 440. int montype; 441. {  442.  #ifndef AIXPS2_BUG 443. 	register int i;  444. 445. 	for (i = 0; grownups[i][0] >= LOW_PM; i++) 446. 		if(montype == grownups[i][0]) return grownups[i][1]; 447. 	return montype; 448. #else 449. /* AIX PS/2 C-compiler 1.1.1 optimizer does not like the above for loop, 450.  * and causes segmentation faults at runtime. (The problem does not 451.   * occur if -O is not used.) 452.  * lehtonen@cs.Helsinki.FI (Tapio Lehtonen) 28031990 453.  */  454.  	int i;  455. int monvalue; 456.  457.  	monvalue = montype; 458. 	for (i = 0; grownups[i][0] >= LOW_PM; i++) 459. 		if(montype == grownups[i][0]) monvalue = grownups[i][1]; 460.  461.  	return monvalue; 462. #endif 463. }  464.   465.  int 466. big_to_little(montype) 467. int montype; 468. {  469.  	register int i;  470. 471. 	for (i = 0; grownups[i][0] >= LOW_PM; i++) 472. 		if(montype == grownups[i][1]) return grownups[i][0]; 473. 	return montype; 474. }  475.   476.  static const char *levitate[2]	= { "float", "Float" }; 477. static const char *fly[2]	= { "fly", "Fly" }; 478. static const char *slither[2]	= { "slither", "Slither" }; 479. static const char *ooze[2]	= { "ooze", "Ooze" }; 480. static const char *crawl[2]	= { "crawl", "Crawl" }; 481.  482.  const char * 483. locomotion(ptr, def) 484. const struct permonst *ptr; 485. const char *def; 486. {  487.  	int capitalize = (*def == highc(*def)); 488.  489.  	return (  490.  		is_floater(ptr) ? levitate[capitalize] :  491.  		is_flyer(ptr)   ? fly[capitalize] :  492.  		slithy(ptr)     ? slither[capitalize] :  493.  		amorphous(ptr)  ? ooze[capitalize] :  494.  		nolimbs(ptr)    ? crawl[capitalize] :  495.  		def  496.  	       ); 497.  498.  }  499.   500.  #endif /* OVLB */ 501.  502.  /*mondata.c*/