Source:NetHack 3.2.0/mondata.c
(Redirected from NetHack 3.2.0/mondata.c)
Jump to navigation
Jump to search
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
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.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<<AT_BREA) | (1<<AT_SPIT) | (1<<AT_GAZE); 101. 102. /* was: (attacktype(ptr, AT_BREA) || attacktype(ptr, AT_WEAP) || 103. attacktype(ptr, AT_SPIT) || attacktype(ptr, AT_GAZE) || 104. attacktype(ptr, AT_MAGC)); 105. but that's too slow -dlc 106. */ 107. for(i = 0; i < NATTK; i++) { 108. if((j=ptr->mattk[i].aatyp) >= AT_WEAP || (atk_mask & (1<<j))) 109. return TRUE; 110. } 111. 112. return(FALSE); 113. } 114. 115. boolean 116. hates_silver(ptr) 117. register struct permonst *ptr; 118. /* returns TRUE if monster is especially affected by silver weapons */ 119. { 120. return((boolean)(is_were(ptr) || ptr->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*/