About: Source:NetHack 3.3.0/mon.c   Sponge Permalink

An Entity of Type : owl:Thing, within Data Space : 134.155.108.49:8890 associated with source dataset(s)

Below is the full text to mon.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/mon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code

AttributesValues
rdfs:label
  • Source:NetHack 3.3.0/mon.c
rdfs:comment
  • Below is the full text to mon.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/mon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/pro...iPageUsesTemplate
abstract
  • Below is the full text to mon.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/mon.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)mon.c 3.3 1999/12/03 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* If you're using precompiled headers, you don't want this either */ 6. #ifdef MICROPORT_BUG 7. #define MKROOM_H 8. #endif 9. 10. #include "hack.h" 11. #include "mfndpos.h" 12. #include "edog.h" 13. #include 14. 15. STATIC_DCL boolean FDECL(corpse_chance,(struct monst *)); 16. STATIC_DCL boolean FDECL(restrap,(struct monst *)); 17. STATIC_DCL long FDECL(mm_aggression, (struct monst *,struct monst *)); 18. #ifdef OVL2 19. STATIC_DCL int NDECL(pick_animal); 20. STATIC_DCL int FDECL(select_newcham_form, (struct monst *)); 21. STATIC_DCL void FDECL(kill_eggs, (struct obj *)); 22. #endif 23. 24. #ifdef OVL1 25. #define warnDelay 10 26. long lastwarntime; 27. int lastwarnlev; 28. 29. const char *warnings[] = { 30. "white", "pink", "red", "ruby", "purple", "black" 31. }; 32. 33. STATIC_DCL void NDECL(warn_effects); 34. 35. #endif /* OVL1 */ 36. 37. 38. #ifndef OVLB 39. STATIC_VAR short cham_to_pm[]; 40. #else 41. STATIC_DCL struct obj *FDECL(make_corpse,(struct monst *)); 42. STATIC_DCL void FDECL(m_detach, (struct monst *, struct permonst *)); 43. STATIC_DCL void FDECL(lifesaved_monster, (struct monst *)); 44. 45. /* convert the monster index of an undead to its living counterpart */ 46. int 47. undead_to_corpse(mndx) 48. int mndx; 49. { 50. switch (mndx) { 51. case PM_KOBOLD_ZOMBIE: 52. case PM_KOBOLD_MUMMY: mndx = PM_KOBOLD; break; 53. case PM_DWARF_ZOMBIE: 54. case PM_DWARF_MUMMY: mndx = PM_DWARF; break; 55. case PM_GNOME_ZOMBIE: 56. case PM_GNOME_MUMMY: mndx = PM_GNOME; break; 57. case PM_ORC_ZOMBIE: 58. case PM_ORC_MUMMY: mndx = PM_ORC; break; 59. case PM_ELF_ZOMBIE: 60. case PM_ELF_MUMMY: mndx = PM_ELF; break; 61. case PM_VAMPIRE: 62. case PM_VAMPIRE_LORD: 63. #if 0 /* DEFERRED */ 64. case PM_VAMPIRE_MAGE: 65. #endif 66. case PM_HUMAN_ZOMBIE: 67. case PM_HUMAN_MUMMY: mndx = PM_HUMAN; break; 68. case PM_GIANT_ZOMBIE: 69. case PM_GIANT_MUMMY: mndx = PM_GIANT; break; 70. case PM_ETTIN_ZOMBIE: 71. case PM_ETTIN_MUMMY: mndx = PM_ETTIN; break; 72. default: break; 73. } 74. return mndx; 75. } 76. 77. /* convert monster index to chameleon index */ 78. int 79. pm_to_cham(mndx) 80. int mndx; 81. { 82. int mcham; 83. 84. switch (mndx) { 85. case PM_CHAMELEON: mcham = CHAM_CHAMELEON; break; 86. case PM_DOPPELGANGER: mcham = CHAM_DOPPELGANGER; break; 87. case PM_SANDESTIN: mcham = CHAM_SANDESTIN; break; 88. default: mcham = CHAM_ORDINARY; break; 89. } 90. return mcham; 91. } 92. 93. /* convert chameleon index to monster index */ 94. STATIC_VAR short cham_to_pm[] = { 95. NON_PM, /* placeholder for CHAM_ORDINARY */ 96. PM_CHAMELEON, 97. PM_DOPPELGANGER, 98. PM_SANDESTIN, 99. }; 100. 101. /* return TRUE if the monster tends to revive */ 102. #define REVIVER(num) ((is_rider(&mons[num])) \ 103. || (mons[num].mlet == S_TROLL)) 104. 105. 106. /* Creates a monster corpse, a "special" corpse, or nothing if it doesn't 107. * leave corpses. Monsters which leave "special" corpses should have 108. * G_NOCORPSE set in order to prevent wishing for one, finding tins of one, 109. * etc.... 110. */ 111. STATIC_OVL struct obj * 112. make_corpse(mtmp) 113. register struct monst *mtmp; 114. { 115. register struct permonst *mdat = mtmp->data; 116. int num; 117. struct obj *obj = (struct obj *)0; 118. int x = mtmp->mx, y = mtmp->my; 119. int mndx = monsndx(mdat); 120. 121. switch(mndx) { 122. case PM_GRAY_DRAGON: 123. case PM_SILVER_DRAGON: 124. #if 0 /* DEFERRED */ 125. case PM_SHIMMERING_DRAGON: 126. #endif 127. case PM_RED_DRAGON: 128. case PM_ORANGE_DRAGON: 129. case PM_WHITE_DRAGON: 130. case PM_BLACK_DRAGON: 131. case PM_BLUE_DRAGON: 132. case PM_GREEN_DRAGON: 133. case PM_YELLOW_DRAGON: 134. /* Make dragon scales. This assumes that the order of the */ 135. /* dragons is the same as the order of the scales. */ 136. if (!rn2(mtmp->mrevived ? 20 : 3)) { 137. obj = mksobj_at(GRAY_DRAGON_SCALES + 138. monsndx(mdat)-PM_GRAY_DRAGON, x, y, FALSE); 139. obj->spe = 0; 140. obj->cursed = obj->blessed = FALSE; 141. } 142. goto default_1; 143. 144. case PM_WHITE_UNICORN: 145. case PM_GRAY_UNICORN: 146. case PM_BLACK_UNICORN: 147. (void) mksobj_at(UNICORN_HORN, x, y, TRUE); 148. goto default_1; 149. case PM_LONG_WORM: 150. (void) mksobj_at(WORM_TOOTH, x, y, TRUE); 151. goto default_1; 152. case PM_VAMPIRE: 153. case PM_VAMPIRE_LORD: 154. /* include mtmp in the mkcorpstat() call */ 155. num = undead_to_corpse(mndx); 156. obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE); 157. obj->age -= 100; /* this is an *OLD* corpse */ 158. break; 159. case PM_KOBOLD_MUMMY: 160. case PM_DWARF_MUMMY: 161. case PM_GNOME_MUMMY: 162. case PM_ORC_MUMMY: 163. case PM_ELF_MUMMY: 164. case PM_HUMAN_MUMMY: 165. case PM_GIANT_MUMMY: 166. case PM_ETTIN_MUMMY: 167. case PM_KOBOLD_ZOMBIE: 168. case PM_DWARF_ZOMBIE: 169. case PM_GNOME_ZOMBIE: 170. case PM_ORC_ZOMBIE: 171. case PM_ELF_ZOMBIE: 172. case PM_HUMAN_ZOMBIE: 173. case PM_GIANT_ZOMBIE: 174. case PM_ETTIN_ZOMBIE: 175. num = undead_to_corpse(mndx); 176. obj = mkcorpstat(CORPSE, mtmp, &mons[num], x, y, TRUE); 177. obj->age -= 100; /* this is an *OLD* corpse */ 178. break; 179. case PM_IRON_GOLEM: 180. num = d(2,6); 181. while (num--) 182. obj = mksobj_at(IRON_CHAIN, x, y, TRUE); 183. mtmp->mnamelth = 0; 184. break; 185. case PM_GLASS_GOLEM: 186. num = d(2,4); /* very low chance of creating all glass gems */ 187. while (num--) 188. obj = mksobj_at((LAST_GEM + rnd(9)), x, y, TRUE); 189. mtmp->mnamelth = 0; 190. break; 191. case PM_CLAY_GOLEM: 192. obj = mksobj_at(ROCK, x, y, FALSE); 193. obj->quan = (long)(rn2(20) + 50); 194. obj->owt = weight(obj); 195. mtmp->mnamelth = 0; 196. break; 197. case PM_STONE_GOLEM: 198. obj = mkcorpstat(STATUE, (struct monst *)0, 199. mdat, x, y, FALSE); 200. break; 201. case PM_WOOD_GOLEM: 202. num = d(2,4); 203. while(num--) { 204. obj = mksobj_at(QUARTERSTAFF, x, y, TRUE); 205. if (obj && obj->oartifact) { /* don't allow this */ 206. artifact_exists(obj, ONAME(obj), FALSE); 207. Strcpy(ONAME(obj), ""); obj->onamelth = 0; 208. } 209. } 210. mtmp->mnamelth = 0; 211. break; 212. case PM_LEATHER_GOLEM: 213. num = d(2,4); 214. while(num--) 215. obj = mksobj_at(LEATHER_ARMOR, x, y, TRUE); 216. mtmp->mnamelth = 0; 217. break; 218. case PM_GOLD_GOLEM: 219. /* Good luck gives more coins */ 220. obj = mkgold((long)(200 - rnl(101)), x, y); 221. mtmp->mnamelth = 0; 222. break; 223. case PM_PAPER_GOLEM: 224. num = d(2,3); 225. while (num--) 226. obj = mksobj_at(SCR_BLANK_PAPER, x, y, TRUE); 227. mtmp->mnamelth = 0; 228. break; 229. default_1: 230. default: 231. if (mvitals[mndx].mvflags & G_NOCORPSE) 232. return (struct obj *)0; 233. else { 234. /* preserve the unique traits of some creatures */ 235. if (mndx == PM_SHOPKEEPER /* a shopkeeper */ 236. || mtmp->mtame /* a pet */ 237. || (mdat->geno & G_UNIQ) /* unique mon */ 238. || REVIVER(mndx)) /* reviving mon */ 239. obj = mkcorpstat(CORPSE, mtmp, mdat, 240. x, y, TRUE); 241. else 242. /* general corpse of appropriate type */ 243. obj = mkcorpstat(CORPSE, (struct monst *)0, 244. mdat, x, y, TRUE); 245. } 246. break; 247. } 248. /* All special cases should precede the G_NOCORPSE check */ 249. 250. if (mtmp->mnamelth) 251. obj = oname(obj, NAME(mtmp)); 252. 253. #ifdef INVISIBLE_OBJECTS 254. /* Invisible monster ==> invisible corpse */ 255. obj->oinvis = mtmp->minvis; 256. #endif 257. 258. stackobj(obj); 259. newsym(x, y); 260. return obj; 261. } 262. 263. #endif /* OVLB */ 264. #ifdef OVL1 265. 266. STATIC_OVL void 267. warn_effects() 268. { 269. if (warnlevel == 100) { 270. if(!Blind && uwep && 271. (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) { 272. Your("%s %s!", aobjnam(uwep, "glow"), 273. hcolor(light_blue)); 274. lastwarnlev = warnlevel; 275. lastwarntime = moves; 276. } 277. warnlevel = 0; 278. return; 279. } 280. 281. if (warnlevel >= SIZE(warnings)) 282. warnlevel = SIZE(warnings)-1; 283. if (!Blind && 284. (warnlevel > lastwarnlev || moves > lastwarntime + warnDelay)) { 285. const char *which, *what, *how; 286. long rings = (EWarning & (LEFT_RING|RIGHT_RING)); 287. 288. if (rings) { 289. what = Hallucination ? "mood ring" : "ring"; 290. how = "glows"; /* singular verb */ 291. if (rings == LEFT_RING) { 292. which = "left "; 293. } else if (rings == RIGHT_RING) { 294. which = "right "; 295. } else { /* both */ 296. which = ""; 297. what = (const char *) makeplural(what); 298. how = "glow"; /* plural verb */ 299. } 300. Your("%s%s %s %s!", which, what, how, hcolor(warnings[warnlevel])); 301. } else { 302. if (Hallucination) 303. Your("spider-sense is tingling..."); 304. else 305. You_feel("apprehensive as you sense a %s flash.", 306. warnings[warnlevel]); 307. } 308. 309. lastwarntime = moves; 310. lastwarnlev = warnlevel; 311. } 312. } 313. 314. /* check mtmp and water for compatibility, 0 (survived), 1 (drowned) */ 315. int 316. minwater(mtmp) 317. register struct monst *mtmp; 318. { 319. boolean inpool, infountain; 320. 321. inpool = is_pool(mtmp->mx,mtmp->my) && 322. !is_flyer(mtmp->data) && !is_floater(mtmp->data); 323. infountain = IS_FOUNTAIN(levl[mtmp->mx][mtmp->my].typ); 324. 325. #ifdef STEED 326. /* Flying and levitation keeps our steed out of the water */ 327. /* (but not water-walking or swimming) */ 328. if (mtmp == u.usteed && (Flying || Levitation)) 329. return (0); 330. #endif 331. 332. /* Gremlin multiplying won't go on forever since the hit points 333. * keep going down, and when it gets to 1 hit point the clone 334. * function will fail. 335. */ 336. if (mtmp->data == &mons[PM_GREMLIN] && (inpool || infountain) && rn2(3)) { 337. if (split_mon(mtmp, (struct monst *)0)) 338. dryup(mtmp->mx, mtmp->my); 339. if (inpool) water_damage(mtmp->minvent, FALSE, FALSE); 340. return (0); 341. } 342. if (inpool) { 343. /* Most monsters drown in pools. flooreffects() will take care of 344. * water damage to dead monsters' inventory, but survivors need to 345. * be handled here. Swimmers are able to protect their stuff... 346. */ 347. if (!is_clinger(mtmp->data) 348. && !is_swimmer(mtmp->data) && !amphibious(mtmp->data)) { 349. if (cansee(mtmp->mx,mtmp->my)) 350. pline("%s drowns.", Monnam(mtmp)); 351. mondead(mtmp); 352. if (mtmp->mhp > 0) { 353. rloc(mtmp); 354. water_damage(mtmp->minvent, FALSE, FALSE); 355. return 0; 356. } 357. return (1); 358. } 359. } else { 360. /* but eels have a difficult time outside */ 361. if (mtmp->data->mlet == S_EEL && !Is_waterlevel(&u.uz)) { 362. if(mtmp->mhp > 1) mtmp->mhp--; 363. mtmp->mflee = 1; 364. mtmp->mfleetim += 2; 365. } 366. } 367. return (0); 368. } 369. 370. 371. void 372. mcalcmove(mon) 373. struct monst *mon; 374. { 375. int mmove = mon->data->mmove; 376. 377. /* Note: MSLOW's `+ 1' prevents slowed speed 1 getting reduced to 0; 378. * MFAST's `+ 2' prevents hasted speed 1 from becoming a no-op; 379. * both adjustments have negligible effect on higher speeds. 380. */ 381. if (mon->mspeed == MSLOW) 382. mmove = (2 * mmove + 1) / 3; 383. else if (mon->mspeed == MFAST) 384. mmove = (4 * mmove + 2) / 3; 385. 386. #ifdef STEED 387. if (mon == u.usteed) { 388. if (u.ugallop && flags.mv) { 389. /* average movement is 1.50 times normal */ 390. mmove = ((rn2(2) ? 4 : 5) * mmove) / 3; 391. } 392. } 393. #endif 394. 395. mon->movement += mmove; 396. } 397. 398. void 399. mcalcdistress() 400. { 401. struct monst *mtmp; 402. 403. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 404. if (mtmp->mblinded && !--mtmp->mblinded) 405. mtmp->mcansee = 1; 406. if (mtmp->mfrozen && !--mtmp->mfrozen) 407. mtmp->mcanmove = 1; 408. if (mtmp->mfleetim && !--mtmp->mfleetim) 409. mtmp->mflee = 0; 410. } 411. } 412. 413. int 414. movemon() 415. { 416. register struct monst *mtmp, *nmtmp; 417. register boolean somebody_can_move = FALSE; 418. 419. warnlevel = 0; 420. 421. /* 422. Some of you may remember the former assertion here that 423. because of deaths and other actions, a simple one-pass 424. algorithm wasn't possible for movemon. Deaths are no longer 425. removed to the separate list fdmon; they are simply left in 426. the chain with hit points <= 0, to be cleaned up at the end 427. of the pass. 428. 429. The only other actions which cause monsters to be removed from 430. the chain are level migrations and losedogs(). I believe losedogs() 431. is a cleanup routine not associated with monster movements, and 432. monsters can only affect level migrations on themselves, not others 433. (hence the fetching of nmon before moving the monster). Currently, 434. monsters can jump into traps, read cursed scrolls of teleportation, 435. and drink cursed potions of raise level to change levels. These are 436. all reflexive at this point. Should one monster be able to level 437. teleport another, this scheme would have problems. 438. */ 439. 440. for(mtmp = fmon; mtmp; mtmp = nmtmp) { 441. nmtmp = mtmp->nmon; 442. /* Find a monster that we have not treated yet. */ 443. if(mtmp->movement < NORMAL_SPEED || mtmp->mhp <= 0) 444. continue; 445. 446. mtmp->movement -= NORMAL_SPEED; 447. if (mtmp->movement >= NORMAL_SPEED) 448. somebody_can_move = TRUE; 449. 450. if (minwater(mtmp)) continue; 451. 452. if (is_hider(mtmp->data)) { 453. /* unwatched mimics and piercers may hide again [MRS] */ 454. if(restrap(mtmp)) continue; 455. if(mtmp->m_ap_type == M_AP_FURNITURE || 456. mtmp->m_ap_type == M_AP_OBJECT) 457. continue; 458. if(mtmp->mundetected) continue; 459. } 460. 461. /* continue if the monster died fighting */ 462. if (Conflict && !mtmp->iswiz && mtmp->mcansee) { 463. /* Note: 464. * Conflict does not take effect in the first round. 465. * Therefore, A monster when stepping into the area will 466. * get to swing at you. 467. * 468. * The call to fightm() must be _last_. The monster might 469. * have died if it returns 1. 470. */ 471. if (couldsee(mtmp->mx,mtmp->my) && 472. (distu(mtmp->mx,mtmp->my) <= BOLT_LIM*BOLT_LIM) && 473. fightm(mtmp)) 474. continue; /* mon might have died */ 475. } 476. if(dochugw(mtmp)) /* otherwise just move the monster */ 477. continue; 478. } 479. if(warnlevel > 0) 480. warn_effects(); 481. 482. if (any_light_source()) 483. vision_full_recalc = 1; /* in case a mon moved with a light source */ 484. dmonsfree(); /* remove all dead monsters */ 485. 486. /* a monster may have levteleported player -dlc */ 487. if (u.utotype) { 488. deferred_goto(); 489. /* changed levels, so these monsters are dormant */ 490. somebody_can_move = FALSE; 491. } 492. 493. return somebody_can_move; 494. } 495. 496. #endif /* OVL1 */ 497. #ifdef OVLB 498. 499. #define mstoning(obj) (ofood(obj) && \ 500. (touch_petrifies(&mons[(obj)->corpsenm]) || \ 501. (obj)->corpsenm == PM_MEDUSA)) 502. 503. /* 504. * Maybe eat a metallic object (not just gold). 505. * Return value: 0 => nothing happened, 1 => monster ate something, 506. * 2 => monster died (it must have grown into a genocided form, but 507. * that can't happen at present because nothing which eats objects 508. * has young and old forms). 509. */ 510. int 511. meatgold(mtmp) 512. register struct monst *mtmp; 513. { 514. register struct obj *otmp; 515. struct permonst *ptr; 516. int poly, grow, heal, mstone; 517. 518. /* If a pet, eating is handled separately, in dog.c */ 519. if (mtmp->mtame) return 0; 520. 521. /* Eats topmost metal object if it is there */ 522. for (otmp = level.objects[mtmp->mx][mtmp->my]; 523. otmp; otmp = otmp->nexthere) 524. if (is_metallic(otmp) && !obj_resists(otmp, 5, 95) && 525. touch_artifact(otmp,mtmp)) { 526. if (mtmp->data == &mons[PM_RUST_MONSTER] && otmp->oerodeproof) { 527. if (canseemon(mtmp) && flags.verbose) { 528. pline("%s eats %s!", 529. Monnam(mtmp), 530. distant_name(otmp,doname)); 531. } 532. /* The object's rustproofing is gone now */ 533. otmp->oerodeproof = 0; 534. mtmp->mstun = 1; 535. if (canseemon(mtmp) && flags.verbose) { 536. pline("%s spits %s out in disgust!", 537. Monnam(mtmp), distant_name(otmp,doname)); 538. } 539. /* KMH -- Don't eat undigestable/choking objects */ 540. } else if (otmp->otyp != AMULET_OF_STRANGULATION && 541. otmp->otyp != RIN_SLOW_DIGESTION) { 542. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 543. pline("%s eats %s!", Monnam(mtmp), 544. distant_name(otmp,doname)); 545. else if (flags.soundok && flags.verbose) 546. You_hear("a crunching sound."); 547. mtmp->meating = otmp->owt/2 + 1; 548. /* Heal up to the object's weight in hp */ 549. if (mtmp->mhp < mtmp->mhpmax) { 550. mtmp->mhp += objects[otmp->otyp].oc_weight; 551. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 552. } 553. if(otmp == uball) { 554. unpunish(); 555. delobj(otmp); 556. } else if (otmp == uchain) { 557. unpunish(); /* frees uchain */ 558. } else { 559. poly = polyfodder(otmp); 560. grow = mlevelgain(otmp); 561. heal = mhealup(otmp); 562. mstone = mstoning(otmp); 563. delobj(otmp); 564. ptr = mtmp->data; 565. if (poly) { 566. if (newcham(mtmp, (struct permonst *)0)) 567. ptr = mtmp->data; 568. } else if (grow) { 569. ptr = grow_up(mtmp, (struct monst *)0); 570. } else if (mstone) { 571. if (poly_when_stoned(ptr)) { 572. mon_to_stone(mtmp); 573. ptr = mtmp->data; 574. } else if (!resists_ston(mtmp)) { 575. if (canseemon(mtmp)) 576. pline("%s turns to stone!", Monnam(mtmp)); 577. monstone(mtmp); 578. ptr = (struct permonst *)0; 579. } 580. } else if (heal) { 581. mtmp->mhp = mtmp->mhpmax; 582. } 583. if (!ptr) return 2; /* it died */ 584. } 585. /* Left behind a pile? */ 586. if(rnd(25) < 3) (void) mksobj_at(ROCK, mtmp->mx, mtmp->my, TRUE); 587. newsym(mtmp->mx, mtmp->my); 588. return 1; 589. } 590. } 591. return 0; 592. } 593. 594. int 595. meatobj(mtmp) /* for gelatinous cubes */ 596. register struct monst *mtmp; 597. { 598. register struct obj *otmp, *otmp2; 599. struct permonst *ptr; 600. int poly, grow, heal, count = 0, ecount = 0; 601. char buf[BUFSZ]; 602. 603. /* If a pet, eating is handled separately, in dog.c */ 604. if (mtmp->mtame) return 0; 605. 606. /* Eats organic objects, including cloth and wood, if there */ 607. /* Engulfs others, except huge rocks and metal attached to player */ 608. for (otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { 609. otmp2 = otmp->nexthere; 610. if (is_organic(otmp) && !obj_resists(otmp, 5, 95) && 611. touch_artifact(otmp,mtmp)) { 612. if (otmp->otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && 613. !resists_ston(mtmp)) 614. continue; 615. if (otmp->otyp == AMULET_OF_STRANGULATION || 616. otmp->otyp == RIN_SLOW_DIGESTION) 617. continue; 618. ++count; 619. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 620. pline("%s eats %s!", Monnam(mtmp), 621. distant_name(otmp, doname)); 622. else if (flags.soundok && flags.verbose) 623. You_hear("a slurping sound."); 624. /* Heal up to the object's weight in hp */ 625. if (mtmp->mhp < mtmp->mhpmax) { 626. mtmp->mhp += objects[otmp->otyp].oc_weight; 627. if (mtmp->mhp > mtmp->mhpmax) mtmp->mhp = mtmp->mhpmax; 628. } 629. if (Has_contents(otmp)) { 630. register struct obj *otmp3; 631. /* contents of eaten containers become engulfed; this 632. is arbitrary, but otherwise g.cubes are too powerful */ 633. while ((otmp3 = otmp->cobj) != 0) { 634. obj_extract_self(otmp3); 635. if (otmp->otyp == ICE_BOX && otmp3->otyp == CORPSE) { 636. otmp3->age = monstermoves - otmp3->age; 637. start_corpse_timeout(otmp3); 638. } 639. mpickobj(mtmp, otmp3); 640. } 641. } 642. poly = polyfodder(otmp); 643. grow = mlevelgain(otmp); 644. heal = mhealup(otmp); 645. delobj(otmp); /* munch */ 646. ptr = mtmp->data; 647. if (poly) { 648. if (newcham(mtmp, (struct permonst *)0)) ptr = mtmp->data; 649. } else if (grow) { 650. ptr = grow_up(mtmp, (struct monst *)0); 651. } else if (heal) { 652. mtmp->mhp = mtmp->mhpmax; 653. } 654. /* in case it polymorphed or died */ 655. if (ptr != &mons[PM_GELATINOUS_CUBE]) 656. return !ptr ? 2 : 1; 657. } else if (otmp->oclass != ROCK_CLASS && 658. otmp != uball && otmp != uchain) { 659. ++ecount; 660. if (cansee(mtmp->mx, mtmp->my) && flags.verbose) { 661. if (ecount == 1) { 662. Sprintf(buf, "%s engulfs %s.", Monnam(mtmp), 663. distant_name(otmp,doname)); 664. } else if (ecount == 2) 665. pline("%s engulfs several objects.", Monnam(mtmp)); 666. } 667. obj_extract_self(otmp); 668. mpickobj(mtmp, otmp); /* slurp */ 669. } 670. /* Engulf & devour is instant, so don't set meating */ 671. if (mtmp->minvis) newsym(mtmp->mx, mtmp->my); 672. } 673. if (ecount == 1) pline(buf); 674. return (count > 0) ? 1 : 0; 675. } 676. 677. void 678. mpickgold(mtmp) 679. register struct monst *mtmp; 680. { 681. register struct obj *gold; 682. 683. if ((gold = g_at(mtmp->mx, mtmp->my)) != 0) { 684. mtmp->mgold += gold->quan; 685. delobj(gold); 686. if (cansee(mtmp->mx, mtmp->my) ) { 687. if (flags.verbose && !mtmp->isgd) 688. pline("%s picks up some gold.", Monnam(mtmp)); 689. newsym(mtmp->mx, mtmp->my); 690. } 691. } 692. } 693. #endif /* OVLB */ 694. #ifdef OVL2 695. 696. boolean 697. mpickstuff(mtmp, str) 698. register struct monst *mtmp; 699. register const char *str; 700. { 701. register struct obj *otmp, *otmp2; 702. 703. /* prevent shopkeepers from leaving the door of their shop */ 704. if(mtmp->isshk && inhishop(mtmp)) return FALSE; 705. 706. for(otmp = level.objects[mtmp->mx][mtmp->my]; otmp; otmp = otmp2) { 707. otmp2 = otmp->nexthere; 708. /* Nymphs take everything. Most monsters don't pick up corpses. */ 709. if (!str ? searches_for_item(mtmp,otmp) : 710. !!(index(str, otmp->oclass))) { 711. if (otmp->otyp == CORPSE && ( 712. is_rider(&mons[otmp->corpsenm]) || 713. (touch_petrifies(&mons[otmp->corpsenm]) 714. && !(mtmp->misc_worn_check & W_ARMG)) || 715. (mtmp->data->mlet != S_NYMPH 716. && !touch_petrifies(&mons[otmp->corpsenm]) 717. && otmp->corpsenm != PM_LIZARD 718. && !acidic(&mons[otmp->corpsenm])) 719. )) 720. continue; 721. if (!touch_artifact(otmp,mtmp)) continue; 722. if (!can_carry(mtmp,otmp)) continue; 723. #ifdef INVISIBLE_OBJECTS 724. if (otmp->oinvis && !perceives(mtmp->data)) continue; 725. #endif 726. if (cansee(mtmp->mx,mtmp->my) && flags.verbose) 727. pline("%s picks up %s.", Monnam(mtmp), 728. (distu(mtmp->my, mtmp->my) <= 5) ? 729. doname(otmp) : distant_name(otmp, doname)); 730. obj_extract_self(otmp); 731. mpickobj(mtmp, otmp); 732. m_dowear(mtmp, FALSE); 733. newsym(mtmp->mx, mtmp->my); 734. if (otmp->otyp == BOULDER) 735. unblock_point(otmp->ox,otmp->oy); /* vision */ 736. return TRUE; /* pick only one object */ 737. } 738. } 739. return FALSE; 740. } 741. 742. #endif /* OVL2 */ 743. #ifdef OVL0 744. 745. int 746. curr_mon_load(mtmp) 747. register struct monst *mtmp; 748. { 749. register int curload = 0; 750. register struct obj *obj; 751. 752. for(obj = mtmp->minvent; obj; obj = obj->nobj) { 753. if(obj->otyp != BOULDER || !throws_rocks(mtmp->data)) 754. curload += obj->owt; 755. } 756. 757. return curload; 758. } 759. 760. int 761. max_mon_load(mtmp) 762. register struct monst *mtmp; 763. { 764. register long maxload; 765. 766. /* Base monster carrying capacity is equal to human maximum 767. * carrying capacity, or half human maximum if not strong. 768. * (for a polymorphed player, the value used would be the 769. * non-polymorphed carrying capacity instead of max/half max). 770. * This is then modified by the ratio between the monster weights 771. * and human weights. Corpseless monsters are given a capacity 772. * proportional to their size instead of weight. 773. */ 774. if (!mtmp->data->cwt) 775. maxload = (MAX_CARR_CAP * (long)mtmp->data->msize) / MZ_HUMAN; 776. else if (!strongmonst(mtmp->data) 777. || (strongmonst(mtmp->data) && (mtmp->data->cwt > WT_HUMAN))) 778. maxload = (MAX_CARR_CAP * (long)mtmp->data->cwt) / WT_HUMAN; 779. else maxload = MAX_CARR_CAP; /*strong monsters w/cwt <= WT_HUMAN*/ 780. 781. if (!strongmonst(mtmp->data)) maxload /= 2; 782. 783. if (maxload < 1) maxload = 1; 784. 785. return (int) maxload; 786. } 787. 788. /* for restricting monsters' object-pickup */ 789. boolean 790. can_carry(mtmp,otmp) 791. struct monst *mtmp; 792. struct obj *otmp; 793. { 794. int otyp = otmp->otyp, newload = otmp->owt; 795. struct permonst *mdat = mtmp->data; 796. 797. if (otyp == CORPSE && touch_petrifies(&mons[otmp->corpsenm]) && 798. !(mtmp->misc_worn_check & W_ARMG) && !resists_ston(mtmp)) 799. return FALSE; 800. if (objects[otyp].oc_material == SILVER && hates_silver(mdat) && 801. (otyp != BELL_OF_OPENING || !is_covetous(mdat))) 802. return FALSE; 803. 804. #ifdef STEED 805. /* Steeds don't pick up stuff (to avoid shop abuse) */ 806. if (mtmp == u.usteed) return (FALSE); 807. #endif 808. if (mtmp->isshk) return(TRUE); /* no limit */ 809. if (mtmp->mpeaceful && !mtmp->mtame) return(FALSE); 810. /* otherwise players might find themselves obligated to violate 811. * their alignment if the monster takes something they need 812. */ 813. 814. /* special--boulder throwers carry unlimited amounts of boulders */ 815. if (throws_rocks(mdat) && otyp == BOULDER) 816. return(TRUE); 817. 818. /* nymphs deal in stolen merchandise, but not boulders or statues */ 819. if (mdat->mlet == S_NYMPH) 820. return (boolean)(otmp->oclass != ROCK_CLASS); 821. 822. if (curr_mon_load(mtmp) + newload > max_mon_load(mtmp)) return FALSE; 823. 824. return(TRUE); 825. } 826. 827. /* return number of acceptable neighbour positions */ 828. int 829. mfndpos(mon, poss, info, flag) 830. register struct monst *mon; 831. coord *poss; /* coord poss[9] */ 832. long *info; /* long info[9] */ 833. long flag; 834. { 835. struct permonst *mdat = mon->data; 836. register xchar x,y,nx,ny; 837. register int cnt = 0; 838. register uchar ntyp; 839. uchar nowtyp; 840. boolean wantpool,poolok,lavaok,nodiag; 841. int maxx, maxy; 842. 843. x = mon->mx; 844. y = mon->my; 845. nowtyp = levl[x][y].typ; 846. 847. nodiag = (mdat == &mons[PM_GRID_BUG]); 848. wantpool = mdat->mlet == S_EEL; 849. poolok = is_flyer(mdat) || is_clinger(mdat) || 850. (is_swimmer(mdat) && !wantpool); 851. lavaok = is_flyer(mdat) || is_clinger(mdat) || likes_lava(mdat); 852. 853. nexttry: /* eels prefer the water, but if there is no water nearby, 854. they will crawl over land */ 855. if(mon->mconf) { 856. flag |= ALLOW_ALL; 857. flag &= ~NOTONL; 858. } 859. if(!mon->mcansee) 860. flag |= ALLOW_SSM; 861. maxx = min(x+1,COLNO-1); 862. maxy = min(y+1,ROWNO-1); 863. for(nx = max(1,x-1); nx <= maxx; nx++) 864. for(ny = max(0,y-1); ny <= maxy; ny++) { 865. if(nx == x && ny == y) continue; 866. if(IS_ROCK(ntyp = levl[nx][ny].typ) && 867. !((flag & ALLOW_WALL) && may_passwall(nx,ny)) && 868. !((flag & ALLOW_DIG) && may_dig(nx,ny))) continue; 869. /* KMH -- Added iron bars */ 870. if (ntyp == IRONBARS && 871. !((flag & ALLOW_WALL) && may_passwall(nx,ny))) continue; 872. if(IS_DOOR(ntyp) && !amorphous(mdat) && 873. ((levl[nx][ny].doormask & D_CLOSED && !(flag & OPENDOOR)) || 874. (levl[nx][ny].doormask & D_LOCKED && !(flag & UNLOCKDOOR)) 875. ) && !(flag & (ALLOW_WALL|ALLOW_DIG|BUSTDOOR))) continue; 876. if(nx != x && ny != y && (nodiag || 877. #ifdef REINCARNATION 878. ((IS_DOOR(nowtyp) && 879. ((levl[x][y].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz))) || 880. (IS_DOOR(ntyp) && 881. ((levl[nx][ny].doormask & ~D_BROKEN) || Is_rogue_level(&u.uz)))) 882. #else 883. ((IS_DOOR(nowtyp) && (levl[x][y].doormask & ~D_BROKEN)) || 884. (IS_DOOR(ntyp) && (levl[nx][ny].doormask & ~D_BROKEN))) 885. #endif 886. )) 887. continue; 888. if((is_pool(nx,ny) == wantpool || poolok) && 889. (lavaok || !is_lava(nx,ny))) { 890. int dispx, dispy; 891. boolean monseeu = (mon->mcansee && (!Invis || perceives(mdat))); 892. boolean checkobj = OBJ_AT(nx,ny); 893. 894. /* Displacement also displaces the Elbereth/scare monster, 895. * as long as you are visible. 896. */ 897. if(Displaced && monseeu && (mon->mux==nx) && (mon->muy==ny)) { 898. dispx = u.ux; 899. dispy = u.uy; 900. } else { 901. dispx = nx; 902. dispy = ny; 903. } 904. 905. info[cnt] = 0; 906. if ((checkobj || Displaced) && onscary(dispx, dispy, mon)) { 907. if(!(flag & ALLOW_SSM)) continue; 908. info[cnt] |= ALLOW_SSM; 909. } 910. if((nx == u.ux && ny == u.uy) || 911. (nx == mon->mux && ny == mon->muy)) { 912. if (nx == u.ux && ny == u.uy) { 913. /* If it's right next to you, it found you, 914. * displaced or no. We must set mux and muy 915. * right now, so when we return we can tell 916. * that the ALLOW_U means to attack _you_ and 917. * not the image. 918. */ 919. mon->mux = u.ux; 920. mon->muy = u.uy; 921. } 922. if(!(flag & ALLOW_U)) continue; 923. info[cnt] |= ALLOW_U; 924. } else { 925. if(MON_AT(nx, ny)) { 926. struct monst *mtmp2 = m_at(nx, ny); 927. long mmflag = flag | mm_aggression(mon, mtmp2); 928. 929. if (!(mmflag & ALLOW_M)) continue; 930. info[cnt] |= ALLOW_M; 931. if (mtmp2->mtame) { 932. if (!(mmflag & ALLOW_TM)) continue; 933. info[cnt] |= ALLOW_TM; 934. } 935. } 936. /* Note: ALLOW_SANCT only prevents movement, not */ 937. /* attack, into a temple. */ 938. if(level.flags.has_temple && 939. *in_rooms(nx, ny, TEMPLE) && 940. !*in_rooms(x, y, TEMPLE) && 941. in_your_sanctuary((struct monst *)0, nx, ny)) { 942. if(!(flag & ALLOW_SANCT)) continue; 943. info[cnt] |= ALLOW_SANCT; 944. } 945. } 946. if(checkobj && sobj_at(CLOVE_OF_GARLIC, nx, ny)) { 947. if(flag & NOGARLIC) continue; 948. info[cnt] |= NOGARLIC; 949. } 950. if(checkobj && sobj_at(BOULDER, nx, ny)) { 951. if(!(flag & ALLOW_ROCK)) continue; 952. info[cnt] |= ALLOW_ROCK; 953. } 954. if (monseeu && onlineu(nx,ny)) { 955. if(flag & NOTONL) continue; 956. info[cnt] |= NOTONL; 957. } 958. if (nx != x && ny != y && bad_rock(mdat, x, ny) 959. && bad_rock(mdat, nx, y) 960. && (bigmonst(mdat) || (curr_mon_load(mon) > 600))) 961. continue; 962. /* The monster avoids a particular type of trap if it's familiar 963. * with the trap type. Pets get ALLOW_TRAPS and checking is 964. * done in dogmove.c. In either case, "harmless" traps are 965. * neither avoided nor marked in info[]. 966. */ 967. { register struct trap *ttmp = t_at(nx, ny); 968. if(ttmp) { 969. if(ttmp->ttyp >= TRAPNUM || ttmp->ttyp == 0) { 970. impossible("A monster looked at a very strange trap of type %d.", ttmp->ttyp); 971. continue; 972. } 973. if ((ttmp->ttyp != RUST_TRAP 974. || mdat == &mons[PM_IRON_GOLEM]) 975. && ttmp->ttyp != STATUE_TRAP 976. && ((ttmp->ttyp != PIT 977. && ttmp->ttyp != SPIKED_PIT 978. && ttmp->ttyp != TRAPDOOR 979. && ttmp->ttyp != HOLE) 980. || (!is_flyer(mdat) 981. && !is_floater(mdat) 982. && !is_clinger(mdat)) 983. || In_sokoban(&u.uz)) 984. && (ttmp->ttyp != SLP_GAS_TRAP || 985. !resists_sleep(mon)) 986. && (ttmp->ttyp != BEAR_TRAP || 987. (mdat->msize > MZ_SMALL && 988. !amorphous(mdat) && !is_flyer(mdat))) 989. && (ttmp->ttyp != FIRE_TRAP || 990. !resists_fire(mon)) 991. && (ttmp->ttyp != SQKY_BOARD || !is_flyer(mdat)) 992. && (ttmp->ttyp != WEB || (!amorphous(mdat) && 993. mdat->mlet != S_SPIDER)) 994. ) { 995. if (!(flag & ALLOW_TRAPS)) { 996. if (mon->mtrapseen & (1L << (ttmp->ttyp - 1))) 997. continue; 998. } 999. info[cnt] |= ALLOW_TRAPS; 1000. } 1001. } 1002. } 1003. poss[cnt].x = nx; 1004. poss[cnt].y = ny; 1005. cnt++; 1006. } 1007. } 1008. if(!cnt && wantpool && !is_pool(x,y)) { 1009. wantpool = FALSE; 1010. goto nexttry; 1011. } 1012. return(cnt); 1013. } 1014. 1015. #endif /* OVL0 */ 1016. #ifdef OVL1 1017. 1018. /* Monster against monster special attacks; for the specified monster 1019. combinations, this allows one monster to attack another adjacent one 1020. in the absence of Conflict. There is no provision for targetting 1021. other monsters; just hand to hand fighting when they happen to be 1022. next to each other. */ 1023. STATIC_OVL long 1024. mm_aggression(magr, mdef) 1025. struct monst *magr, /* monster that is currently deciding where to move */ 1026. *mdef; /* another monster which is next to it */ 1027. { 1028. /* supposedly purple worms are attracted to shrieking because they 1029. like to eat shriekers, so attack the latter when feasible */ 1030. if (magr->data == &mons[PM_PURPLE_WORM] && 1031. mdef->data == &mons[PM_SHRIEKER]) 1032. return ALLOW_M|ALLOW_TM; 1033. /* Various other combinations such as dog vs cat, cat vs rat, and 1034. elf vs orc have been suggested. For the time being we don't 1035. support those. */ 1036. return 0L; 1037. } 1038. 1039. boolean 1040. monnear(mon, x, y) 1041. register struct monst *mon; 1042. register int x,y; 1043. /* Is the square close enough for the monster to move or attack into? */ 1044. { 1045. register int distance = dist2(mon->mx, mon->my, x, y); 1046. if (distance==2 && mon->data==&mons[PM_GRID_BUG]) return 0; 1047. return((boolean)(distance < 3)); 1048. } 1049. 1050. /* really free dead monsters */ 1051. void 1052. dmonsfree() 1053. { 1054. struct monst **mtmp; 1055. 1056. for (mtmp = &fmon; *mtmp;) { 1057. if ((*mtmp)->mhp <= 0) { 1058. struct monst *freetmp = *mtmp; 1059. *mtmp = (*mtmp)->nmon; 1060. dealloc_monst(freetmp); 1061. } else 1062. mtmp = &(*mtmp)->nmon; 1063. } 1064. } 1065. 1066. #endif /* OVL1 */ 1067. #ifdef OVLB 1068. 1069. /* called when monster is moved to larger structure */ 1070. void 1071. replmon(mtmp, mtmp2) 1072. register struct monst *mtmp, *mtmp2; 1073. { 1074. struct obj *otmp; 1075. 1076. /* transfer the monster's inventory */ 1077. for (otmp = mtmp2->minvent; otmp; otmp = otmp->nobj) { 1078. #ifdef DEBUG 1079. if (otmp->where != OBJ_MINVENT || otmp->ocarry != mtmp) 1080. panic("replmon: minvent inconsistency"); 1081. #endif 1082. otmp->ocarry = mtmp2; 1083. } 1084. mtmp->minvent = 0; 1085. 1086. /* remove the old monster from the map and from `fmon' list */ 1087. relmon(mtmp); 1088. 1089. /* finish adding its replacement */ 1090. place_monster(mtmp2, mtmp2->mx, mtmp2->my); 1091. if (mtmp2->wormno) /* update level.monsters[wseg->wx][wseg->wy] */ 1092. place_wsegs(mtmp2); /* locations to mtmp2 not mtmp. */ 1093. if (emits_light(mtmp2->data)) { 1094. /* since this is so rare, we don't have any `mon_move_light_source' */ 1095. new_light_source(mtmp2->mx, mtmp2->my, 1096. emits_light(mtmp2->data), 1097. LS_MONSTER, (genericptr_t)mtmp2); 1098. /* here we rely on the fact that `mtmp' hasn't actually been deleted */ 1099. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 1100. } 1101. mtmp2->nmon = fmon; 1102. fmon = mtmp2; 1103. if (u.ustuck == mtmp) u.ustuck = mtmp2; 1104. #ifdef STEED 1105. if (u.usteed == mtmp) u.usteed = mtmp2; 1106. #endif 1107. if (mtmp2->isshk) replshk(mtmp,mtmp2); 1108. 1109. /* discard the old monster */ 1110. dealloc_monst(mtmp); 1111. } 1112. 1113. /* release mon from display and monster list */ 1114. void 1115. relmon(mon) 1116. register struct monst *mon; 1117. { 1118. register struct monst *mtmp; 1119. 1120. if (fmon == (struct monst *)0) panic ("relmon: no fmon available."); 1121. 1122. remove_monster(mon->mx, mon->my); 1123. 1124. if(mon == fmon) fmon = fmon->nmon; 1125. else { 1126. for(mtmp = fmon; mtmp && mtmp->nmon != mon; mtmp = mtmp->nmon) ; 1127. if(mtmp) mtmp->nmon = mon->nmon; 1128. else panic("relmon: mon not in list."); 1129. } 1130. } 1131. 1132. /* remove effects of mtmp from other data structures */ 1133. STATIC_OVL void 1134. m_detach(mtmp, mptr) 1135. struct monst *mtmp; 1136. struct permonst *mptr; /* reflects mtmp->data _prior_ to mtmp's death */ 1137. { 1138. if(mtmp->mleashed) m_unleash(mtmp); 1139. /* to prevent an infinite relobj-flooreffects-hmon-killed loop */ 1140. mtmp->mtrapped = 0; 1141. mtmp->mhp = 0; /* simplify some tests: force mhp to 0 */ 1142. relobj(mtmp, 0, FALSE); 1143. remove_monster(mtmp->mx, mtmp->my); 1144. if (emits_light(mptr)) 1145. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 1146. newsym(mtmp->mx,mtmp->my); 1147. unstuck(mtmp); 1148. fill_pit(mtmp->mx, mtmp->my); 1149. 1150. if(mtmp->isshk) shkgone(mtmp); 1151. if(mtmp->wormno) wormgone(mtmp); 1152. } 1153. 1154. /* find the worn amulet of life saving which will save a monster */ 1155. struct obj * 1156. mlifesaver(mon) 1157. struct monst *mon; 1158. { 1159. if (!nonliving(mon->data)) { 1160. struct obj *otmp = which_armor(mon, W_AMUL); 1161. 1162. if (otmp && otmp->otyp == AMULET_OF_LIFE_SAVING) 1163. return otmp; 1164. } 1165. return (struct obj *)0; 1166. } 1167. 1168. STATIC_OVL void 1169. lifesaved_monster(mtmp) 1170. struct monst *mtmp; 1171. { 1172. struct obj *lifesave = mlifesaver(mtmp); 1173. 1174. if (lifesave) { 1175. /* not canseemon; amulets are on the head, so you don't want */ 1176. /* to show this for a long worm with only a tail visible. */ 1177. /* Nor do you check invisibility, because glowing and disinte- */ 1178. /* grating amulets are always visible. */ 1179. if (cansee(mtmp->mx, mtmp->my)) { 1180. pline("But wait..."); 1181. pline("%s medallion begins to glow!", 1182. s_suffix(Monnam(mtmp))); 1183. makeknown(AMULET_OF_LIFE_SAVING); 1184. pline("%s looks much better!", Monnam(mtmp)); 1185. pline_The("medallion crumbles to dust!"); 1186. } 1187. m_useup(mtmp, lifesave); 1188. if (mtmp->mhpmax <= 0) mtmp->mhpmax = 10; 1189. mtmp->mhp = mtmp->mhpmax; 1190. mtmp->mcanmove = 1; 1191. mtmp->mfrozen = 0; 1192. if (mtmp->mtame && !mtmp->isminion) { 1193. struct edog *edog = EDOG(mtmp); 1194. if (edog->hungrytime < moves+500) 1195. edog->hungrytime = moves+500; 1196. wary_dog(mtmp, FALSE); 1197. } 1198. if (mvitals[monsndx(mtmp->data)].mvflags & G_GENOD) { 1199. if (cansee(mtmp->mx, mtmp->my)) 1200. pline("Unfortunately %s is still genocided...", 1201. mon_nam(mtmp)); 1202. } else 1203. return; 1204. } 1205. mtmp->mhp = 0; 1206. } 1207. 1208. void 1209. mondead(mtmp) 1210. register struct monst *mtmp; 1211. { 1212. struct permonst *mptr; 1213. int tmp; 1214. 1215. if(mtmp->isgd) { 1216. /* if we're going to abort the death, it *must* be before 1217. * the m_detach or there will be relmon problems later */ 1218. if(!grddead(mtmp)) return; 1219. } 1220. lifesaved_monster(mtmp); 1221. if (mtmp->mhp > 0) return; 1222. 1223. #ifdef STEED 1224. /* Player is thrown from his steed when it dies */ 1225. if (mtmp == u.usteed) 1226. dismount_steed(DISMOUNT_GENERIC); 1227. #endif 1228. 1229. mptr = mtmp->data; /* save this for m_detach() */ 1230. /* restore chameleon, lycanthropes to true form at death */ 1231. if (mtmp->cham) 1232. set_mon_data(mtmp, &mons[cham_to_pm[mtmp->cham]], -1); 1233. else if (mtmp->data == &mons[PM_WEREJACKAL]) 1234. set_mon_data(mtmp, &mons[PM_HUMAN_WEREJACKAL], -1); 1235. else if (mtmp->data == &mons[PM_WEREWOLF]) 1236. set_mon_data(mtmp, &mons[PM_HUMAN_WEREWOLF], -1); 1237. else if (mtmp->data == &mons[PM_WERERAT]) 1238. set_mon_data(mtmp, &mons[PM_HUMAN_WERERAT], -1); 1239. 1240. /* if MAXMONNO monsters of a given type have died, and it 1241. * can be done, extinguish that monster. 1242. * 1243. * mvitals[].died does double duty as total number of dead monsters 1244. * and as experience factor for the player killing more monsters. 1245. * this means that a dragon dying by other means reduces the 1246. * experience the player gets for killing a dragon directly; this 1247. * is probably not too bad, since the player likely finagled the 1248. * first dead dragon via ring of conflict or pets, and extinguishing 1249. * based on only player kills probably opens more avenues of abuse 1250. * for rings of conflict and such. 1251. */ 1252. tmp = monsndx(mtmp->data); 1253. if (mvitals[tmp].died < 255) mvitals[tmp].died++; 1254. #ifdef MAIL 1255. /* if the mail daemon dies, no more mail delivery. -3. */ 1256. if (tmp == PM_MAIL_DAEMON) mvitals[tmp].mvflags |= G_GENOD; 1257. #endif 1258. 1259. #ifdef KOPS 1260. if (mtmp->data->mlet == S_KOP) { 1261. /* Dead Kops may come back. */ 1262. switch(rnd(5)) { 1263. case 1: /* returns near the stairs */ 1264. (void) makemon(mtmp->data,xdnstair,ydnstair,NO_MM_FLAGS); 1265. break; 1266. case 2: /* randomly */ 1267. (void) makemon(mtmp->data,0,0,NO_MM_FLAGS); 1268. break; 1269. default: 1270. break; 1271. } 1272. } 1273. #endif 1274. if(mtmp->iswiz) wizdead(); 1275. if(mtmp->data->msound == MS_NEMESIS) nemdead(); 1276. if(glyph_is_invisible(levl[mtmp->mx][mtmp->my].glyph)) 1277. unmap_object(mtmp->mx, mtmp->my); 1278. m_detach(mtmp, mptr); 1279. } 1280. 1281. STATIC_OVL boolean 1282. corpse_chance(mon) 1283. struct monst *mon; 1284. { 1285. struct permonst *mdat = mon->data; 1286. int i, tmp; 1287. 1288. 1289. if (mdat == &mons[PM_VLAD_THE_IMPALER] || mdat->mlet == S_LICH) { 1290. if (cansee(mon->mx, mon->my)) 1291. pline("%s%ss body crumbles into dust.", Monnam(mon), 1292. canseemon(mon) ? "'" : ""); 1293. return FALSE; 1294. } 1295. 1296. /* Gas spores always explode upon death */ 1297. for(i = 0; i < NATTK; i++) { 1298. if (mdat->mattk[i].aatyp == AT_BOOM) { 1299. char buf[BUFSZ]; 1300. 1301. if (mdat->mattk[i].damn) 1302. tmp = d((int)mdat->mattk[i].damn, 1303. (int)mdat->mattk[i].damd); 1304. else if(mdat->mattk[i].damd) 1305. tmp = d((int)mdat->mlevel+1, (int)mdat->mattk[i].damd); 1306. else tmp = 0; 1307. Sprintf(buf, "%s explosion", s_suffix(mdat->mname)); 1308. killer = buf; 1309. killer_format = KILLED_BY_AN; 1310. explode(mon->mx, mon->my, -1, tmp, MON_EXPLODE); 1311. return (FALSE); 1312. } 1313. } 1314. 1315. /* must duplicate this below check in xkilled() since it results in 1316. * creating no objects as well as no corpse 1317. */ 1318. if ( 1319. #ifdef REINCARNATION 1320. Is_rogue_level(&u.uz) || 1321. #endif 1322. (level.flags.graveyard && is_undead(mdat) && rn2(3))) 1323. return FALSE; 1324. 1325. if (bigmonst(mdat) || mdat == &mons[PM_LIZARD] 1326. || is_golem(mdat) 1327. || is_mplayer(mdat) 1328. || is_rider(mdat)) 1329. return TRUE; 1330. return (boolean) (!rn2((int) 1331. (2 + ((int)(mdat->geno & G_FREQ)<2) + verysmall(mdat)))); 1332. } 1333. 1334. /* drop (perhaps) a cadaver and remove monster */ 1335. void 1336. mondied(mdef) 1337. register struct monst *mdef; 1338. { 1339. mondead(mdef); 1340. if (mdef->mhp > 0) return; /* lifesaved */ 1341. 1342. if (corpse_chance(mdef)) 1343. (void) make_corpse(mdef); 1344. } 1345. 1346. /* monster disappears, not dies */ 1347. void 1348. mongone(mdef) 1349. register struct monst *mdef; 1350. { 1351. #ifdef STEED 1352. /* Player is thrown from his steed when it disappears */ 1353. if (mdef == u.usteed) 1354. dismount_steed(DISMOUNT_GENERIC); 1355. #endif 1356. 1357. discard_minvent(mdef); /* release monster's inventory */ 1358. mdef->mgold = 0L; 1359. m_detach(mdef, mdef->data); 1360. } 1361. 1362. /* drop a statue or rock and remove monster */ 1363. void 1364. monstone(mdef) 1365. register struct monst *mdef; 1366. { 1367. struct obj *otmp, *obj; 1368. xchar x = mdef->mx, y = mdef->my; 1369. 1370. /* we have to make the statue before calling mondead, to be able to 1371. * put inventory in it, and we have to check for lifesaving before 1372. * making the statue.... 1373. */ 1374. lifesaved_monster(mdef); 1375. if (mdef->mhp > 0) return; 1376. 1377. mdef->mtrapped = 0; /* (see m_detach) */ 1378. 1379. if((int)mdef->data->msize > MZ_TINY || 1380. !rn2(2 + ((int) (mdef->data->geno & G_FREQ) > 2))) { 1381. otmp = mk_named_object(STATUE, mdef->data, x, y, 1382. mdef->mnamelth ? NAME(mdef) : (char *)0); 1383. /* some objects may end up outside the statue */ 1384. while ((obj = mdef->minvent) != 0) { 1385. obj_extract_self(obj); 1386. obj->owornmask = 0L; 1387. if (obj->otyp == BOULDER || 1388. #if 0 /* monsters don't carry statues */ 1389. (obj->otyp == STATUE && mons[obj->corpsenm].msize >= mdef->data->msize) || 1390. #endif 1391. obj_resists(obj, 0, 0)) { 1392. if (flooreffects(obj, x, y, "fall")) continue; 1393. place_object(obj, x, y); 1394. } else { 1395. if (obj->lamplit) end_burn(obj, TRUE); 1396. add_to_container(otmp, obj); 1397. } 1398. } 1399. if (mdef->mgold) { 1400. struct obj *au; 1401. au = mksobj(GOLD_PIECE, FALSE, FALSE); 1402. au->quan = mdef->mgold; 1403. au->owt = weight(au); 1404. add_to_container(otmp, au); 1405. mdef->mgold = 0; 1406. } 1407. otmp->owt = weight(otmp); 1408. } else 1409. otmp = mksobj_at(ROCK, x, y, TRUE); 1410. 1411. stackobj(otmp); 1412. /* mondead() already does this, but we must do it before the newsym */ 1413. if(glyph_is_invisible(levl[x][y].glyph)) 1414. unmap_object(x, y); 1415. if (cansee(x, y)) newsym(x,y); 1416. mondead(mdef); 1417. } 1418. 1419. /* another monster has killed the monster mdef */ 1420. void 1421. monkilled(mdef, fltxt, how) 1422. register struct monst *mdef; 1423. const char *fltxt; 1424. int how; 1425. { 1426. boolean be_sad = FALSE; /* true if unseen pet is killed */ 1427. 1428. if ((mdef->wormno ? worm_known(mdef) : cansee(mdef->mx, mdef->my)) 1429. && fltxt) 1430. pline("%s is %s%s%s!", Monnam(mdef), 1431. nonliving(mdef->data) ? "destroyed" : "killed", 1432. *fltxt ? " by the " : "", 1433. fltxt 1434. ); 1435. else 1436. be_sad = (mdef->mtame != 0); 1437. 1438. /* no corpses if digested or disintegrated */ 1439. if(how == AD_DGST || how == -AD_RBRE) 1440. mondead(mdef); 1441. else 1442. mondied(mdef); 1443. 1444. if (be_sad && mdef->mhp <= 0) 1445. You("have a sad feeling for a moment, then it passes."); 1446. } 1447. 1448. void 1449. unstuck(mtmp) 1450. register struct monst *mtmp; 1451. { 1452. if(u.ustuck == mtmp) { 1453. if(u.uswallow){ 1454. u.ux = mtmp->mx; 1455. u.uy = mtmp->my; 1456. u.uswallow = 0; 1457. u.uswldtim = 0; 1458. if (Punished) placebc(); 1459. vision_full_recalc = 1; 1460. docrt(); 1461. } 1462. u.ustuck = 0; 1463. } 1464. } 1465. 1466. void 1467. killed(mtmp) 1468. register struct monst *mtmp; 1469. { 1470. xkilled(mtmp, 1); 1471. } 1472. 1473. /* the player has killed the monster mtmp */ 1474. void 1475. xkilled(mtmp, dest) 1476. register struct monst *mtmp; 1477. /* 1478. * Dest=1, normal; dest=0, don't print message; dest=2, don't drop corpse 1479. * either; dest=3, message but no corpse 1480. */ 1481. int dest; 1482. { 1483. register int tmp, x = mtmp->mx, y = mtmp->my; 1484. register struct permonst *mdat; 1485. int mndx; 1486. register struct obj *otmp; 1487. register struct trap *t; 1488. boolean redisp = FALSE; 1489. boolean wasinside = u.uswallow && (u.ustuck == mtmp); 1490. 1491. 1492. /* KMH, conduct */ 1493. u.uconduct.killer++; 1494. 1495. if (dest & 1) { 1496. if(!wasinside && !canspotmon(mtmp)) 1497. You("destroy it!"); 1498. else { 1499. You("destroy %s!", 1500. mtmp->mtame ? x_monnam(mtmp, 0, "poor", 0) 1501. : mon_nam(mtmp)); 1502. } 1503. } 1504. 1505. if (mtmp->mtrapped && 1506. ((t = t_at(x, y)) && (t->ttyp == PIT || t->ttyp == SPIKED_PIT)) && 1507. sobj_at(BOULDER, x, y)) 1508. dest ^= 2; /* 1509. * Prevent corpses/treasure being created "on top" 1510. * of the boulder that is about to fall in. This is 1511. * out of order, but cannot be helped unless this 1512. * whole routine is rearranged. 1513. */ 1514. 1515. /* your pet knows who just killed it...watch out */ 1516. if (mtmp->mtame) EDOG(mtmp)->killed_by_u = 1; 1517. 1518. /* dispose of monster and make cadaver */ 1519. if(stoned) monstone(mtmp); 1520. else mondead(mtmp); 1521. 1522. if (mtmp->mhp > 0) { /* monster lifesaved */ 1523. /* Cannot put the non-visible lifesaving message in 1524. * lifesaved_monster() since the message appears only when you 1525. * kill it (as opposed to visible lifesaving which always 1526. * appears). 1527. */ 1528. if (!cansee(x,y)) pline("Maybe not..."); 1529. return; 1530. } 1531. 1532. mdat = mtmp->data; /* note: mondead can change mtmp->data */ 1533. mndx = monsndx(mdat); 1534. 1535. if (stoned) { 1536. stoned = FALSE; 1537. goto cleanup; 1538. } 1539. 1540. if((dest & 2) 1541. #ifdef REINCARNATION 1542. || Is_rogue_level(&u.uz) 1543. #endif 1544. || (level.flags.graveyard && is_undead(mdat) && rn2(3))) 1545. goto cleanup; 1546. 1547. #ifdef MAIL 1548. if(mdat == &mons[PM_MAIL_DAEMON]) { 1549. stackobj(mksobj_at(SCR_MAIL, x, y, FALSE)); 1550. redisp = TRUE; 1551. } 1552. #endif 1553. if(!accessible(x, y) && !is_pool(x, y)) { 1554. /* might be mimic in wall or corpse in lava */ 1555. redisp = TRUE; 1556. if(wasinside) spoteffects(); 1557. } else if(x != u.ux || y != u.uy) { 1558. /* might be here after swallowed */ 1559. if (!rn2(6) && !(mvitals[mndx].mvflags & G_NOCORPSE) 1560. #ifdef KOPS 1561. && mdat->mlet != S_KOP 1562. #endif 1563. ) { 1564. int typ; 1565. 1566. otmp = mkobj_at(RANDOM_CLASS, x, y, TRUE); 1567. /* Don't create large objects from small monsters */ 1568. typ = otmp->otyp; 1569. if (mdat->msize < MZ_HUMAN && typ != FOOD_RATION 1570. && typ != LEASH 1571. && typ != FIGURINE 1572. && (otmp->owt > 3 || 1573. objects[typ].oc_big /*oc_bimanual/oc_bulky*/ || 1574. is_spear(otmp) || is_pole(otmp) || 1575. typ == MORNING_STAR)) { 1576. delobj(otmp); 1577. } else redisp = TRUE; 1578. } 1579. /* Whether or not it always makes a corpse is, in theory, 1580. * different from whether or not the corpse is "special"; 1581. * if we want both, we have to specify it explicitly. 1582. */ 1583. if (corpse_chance(mtmp)) 1584. (void) make_corpse(mtmp); 1585. } 1586. if(redisp) newsym(x,y); 1587. cleanup: 1588. /* punish bad behaviour */ 1589. if(is_human(mdat) && (!always_hostile(mdat) && mtmp->malign <= 0) && 1590. (mndx < PM_ARCHEOLOGIST || mndx > PM_WIZARD) && 1591. u.ualign.type != A_CHAOTIC) { 1592. HTelepat &= ~INTRINSIC; 1593. change_luck(-2); 1594. You("murderer!"); 1595. if (Blind && !Blind_telepat) 1596. see_monsters(); /* Can't sense monsters any more. */ 1597. } 1598. if((mtmp->mpeaceful && !rn2(2)) || mtmp->mtame) change_luck(-1); 1599. if (is_unicorn(mdat) && 1600. sgn(u.ualign.type) == sgn(mdat->maligntyp)) { 1601. change_luck(-5); 1602. You_feel("guilty..."); 1603. } 1604. 1605. /* give experience points */ 1606. tmp = experience(mtmp, (int)mvitals[mndx].died + 1); 1607. more_experienced(tmp, 0); 1608. newexplevel(); /* will decide if you go up */ 1609. 1610. /* adjust alignment points */ 1611. if (mdat->msound == MS_LEADER) { /* REAL BAD! */ 1612. adjalign(-(u.ualign.record+(int)ALIGNLIM/2)); 1613. pline("That was %sa bad idea...", 1614. u.uevent.qcompleted ? "probably " : ""); 1615. } else if (mdat->msound == MS_NEMESIS) /* Real good! */ 1616. adjalign((int)(ALIGNLIM/4)); 1617. else if (mdat->msound == MS_GUARDIAN) { /* Bad */ 1618. adjalign(-(int)(ALIGNLIM/8)); 1619. if (!Hallucination) pline("That was probably a bad idea..."); 1620. else pline("Whoopsie-daisy!"); 1621. }else if (mtmp->ispriest) { 1622. adjalign((p_coaligned(mtmp)) ? -2 : 2); 1623. /* cancel divine protection for killing your priest */ 1624. if (p_coaligned(mtmp)) u.ublessed = 0; 1625. if (mdat->maligntyp == A_NONE) 1626. adjalign((int)(ALIGNLIM / 4)); /* BIG bonus */ 1627. } else if (mtmp->mtame) { 1628. adjalign(-15); /* bad!! */ 1629. /* your god is mighty displeased... */ 1630. if (!Hallucination) pline("You hear the rumble of distant thunder..."); 1631. else pline("You hear the studio audience applaud!"); 1632. } else if (mtmp->mpeaceful) 1633. adjalign(-5); 1634. 1635. /* malign was already adjusted for u.ualign.type and randomization */ 1636. adjalign(mtmp->malign); 1637. } 1638. 1639. /* changes the monster into a stone monster of the same type */ 1640. /* this should only be called when poly_when_stoned() is true */ 1641. void 1642. mon_to_stone(mtmp) 1643. register struct monst *mtmp; 1644. { 1645. if(mtmp->data->mlet == S_GOLEM) { 1646. /* it's a golem, and not a stone golem */ 1647. if(canseemon(mtmp)) 1648. pline("%s solidifies...", Monnam(mtmp)); 1649. (void) newcham(mtmp, &mons[PM_STONE_GOLEM]); 1650. if(canseemon(mtmp)) 1651. pline("Now it's %s.", an(mtmp->data->mname)); 1652. } else 1653. impossible("Can't polystone %s!", a_monnam(mtmp)); 1654. } 1655. 1656. void 1657. mnexto(mtmp) /* Make monster mtmp next to you (if possible) */ 1658. struct monst *mtmp; 1659. { 1660. coord mm; 1661. 1662. #ifdef STEED 1663. if (mtmp == u.usteed) { 1664. /* Keep your steed in sync with you instead */ 1665. mtmp->mx = u.ux; 1666. mtmp->my = u.uy; 1667. return; 1668. } 1669. #endif 1670. 1671. if(!enexto(&mm, u.ux, u.uy, mtmp->data)) return; 1672. rloc_to(mtmp, mm.x, mm.y); 1673. return; 1674. } 1675. 1676. /* mnearto() 1677. * Put monster near (or at) location if possible. 1678. * Returns: 1679. * 1 - if a monster was moved from x, y to put mtmp at x, y. 1680. * 0 - in most cases. 1681. */ 1682. boolean 1683. mnearto(mtmp,x,y,move_other) 1684. register struct monst *mtmp; 1685. xchar x, y; 1686. boolean move_other; /* make sure mtmp gets to x, y! so move m_at(x, y) */ 1687. { 1688. struct monst *othermon = (struct monst *)0; 1689. xchar newx, newy; 1690. coord mm; 1691. 1692. if ((mtmp->mx == x) && (mtmp->my == y)) return(FALSE); 1693. 1694. if (move_other && (othermon = m_at(x, y))) { 1695. if (othermon->wormno) 1696. remove_worm(othermon); 1697. else 1698. remove_monster(x, y); 1699. } 1700. 1701. newx = x; 1702. newy = y; 1703. 1704. if (!goodpos(newx, newy, mtmp)) { 1705. /* actually we have real problems if enexto ever fails. 1706. * migrating_mons that need to be placed will cause 1707. * no end of trouble. 1708. */ 1709. if (!enexto(&mm, newx, newy, mtmp->data)) return(FALSE); 1710. newx = mm.x; newy = mm.y; 1711. } 1712. 1713. rloc_to(mtmp, newx, newy); 1714. 1715. if (move_other && othermon) { 1716. othermon->mx = othermon->my = 0; 1717. (void) mnearto(othermon, x, y, FALSE); 1718. if ((othermon->mx != x) || (othermon->my != y)) 1719. return(TRUE); 1720. } 1721. 1722. return(FALSE); 1723. } 1724. 1725. 1726. static const char *poiseff[] = { 1727. 1728. " feel weaker", "r brain is on fire", 1729. "r judgement is impaired", "r muscles won't obey you", 1730. " feel very sick", " break out in hives" 1731. }; 1732. 1733. void 1734. poisontell(typ) 1735. 1736. int typ; 1737. { 1738. pline("You%s.", poiseff[typ]); 1739. } 1740. 1741. void 1742. poisoned(string, typ, pname, fatal) 1743. register const char *string, *pname; 1744. register int typ, fatal; 1745. { 1746. register int i, plural; 1747. boolean thrown_weapon = !strncmp(string, "poison", 6); 1748. /* admittedly a kludge... */ 1749. 1750. if(strcmp(string, "blast") && !thrown_weapon) { 1751. /* 'blast' has already given a 'poison gas' message */ 1752. /* so have "poison arrow", "poison dart", etc... */ 1753. plural = (string[strlen(string) - 1] == 's')? 1 : 0; 1754. /* avoid "The" Orcus's sting was poisoned... */ 1755. pline("%s%s %s poisoned!", isupper(*string) ? "" : "The ", 1756. string, plural ? "were" : "was"); 1757. } 1758. 1759. if(Poison_resistance) { 1760. if(!strcmp(string, "blast")) shieldeff(u.ux, u.uy); 1761. pline_The("poison doesn't seem to affect you."); 1762. return; 1763. } 1764. i = rn2(fatal + 20*thrown_weapon); 1765. if(i == 0 && typ != A_CHA) { 1766. u.uhp = -1; 1767. pline_The("poison was deadly..."); 1768. } else if(i <= 5) { 1769. /* Check that a stat change was made */ 1770. if (adjattrib(typ, thrown_weapon ? -1 : -rn1(3,3), 1)) 1771. pline("You%s!", poiseff[typ]); 1772. } else { 1773. i = thrown_weapon ? rnd(6) : rn1(10,6); 1774. if(Half_physical_damage) i = (i+1) / 2; 1775. losehp(i, pname, KILLED_BY_AN); 1776. } 1777. if(u.uhp < 1) { 1778. killer_format = KILLED_BY_AN; 1779. killer = pname; 1780. done(POISONING); 1781. } 1782. (void) encumber_msg(); 1783. } 1784. 1785. /* monster responds to player action; not the same as a passive attack */ 1786. /* assumes reason for response has been tested, and response _must_ be made */ 1787. void 1788. m_respond(mtmp) 1789. register struct monst *mtmp; 1790. { 1791. if(mtmp->data->msound == MS_SHRIEK) { 1792. if(flags.soundok) { 1793. pline("%s shrieks.", Monnam(mtmp)); 1794. stop_occupation(); 1795. } 1796. if (!rn2(10)) { 1797. if (!rn2(13)) 1798. (void) makemon(&mons[PM_PURPLE_WORM], 0, 0, NO_MM_FLAGS); 1799. else 1800. (void) makemon((struct permonst *)0, 0, 0, NO_MM_FLAGS); 1801. 1802. } 1803. aggravate(); 1804. } 1805. if(mtmp->data == &mons[PM_MEDUSA] && !mtmp->mcan) { 1806. register int i; 1807. for(i = 0; i < NATTK; i++) 1808. if(mtmp->data->mattk[i].aatyp == AT_GAZE) { 1809. (void) gazemu(mtmp, &mtmp->data->mattk[i]); 1810. break; 1811. } 1812. } 1813. } 1814. 1815. #endif /* OVLB */ 1816. #ifdef OVL2 1817. 1818. void 1819. setmangry(mtmp) 1820. register struct monst *mtmp; 1821. { 1822. mtmp->mstrategy &= ~STRAT_WAITMASK; 1823. if(!mtmp->mpeaceful) return; 1824. if(mtmp->mtame) return; 1825. mtmp->mpeaceful = 0; 1826. if(mtmp->ispriest) { 1827. if(p_coaligned(mtmp)) adjalign(-5); /* very bad */ 1828. else adjalign(2); 1829. } else 1830. adjalign(-1); /* attacking peaceful monsters is bad */ 1831. if(humanoid(mtmp->data) || mtmp->isshk || mtmp->isgd) 1832. pline("%s gets angry!", Monnam(mtmp)); 1833. else if (flags.verbose && flags.soundok) growl(mtmp); 1834. 1835. /* attacking your own quest leader will anger his or her guardians */ 1836. if (!flags.mon_moving && /* should always be the case here */ 1837. mtmp->data == &mons[quest_info(MS_LEADER)]) { 1838. struct monst *mon; 1839. struct permonst *q_guardian = &mons[quest_info(MS_GUARDIAN)]; 1840. int got_mad = 0; 1841. 1842. /* guardians will sense this attack even if they can't see it */ 1843. for (mon = fmon; mon; mon = mon->nmon) 1844. if (mon->data == q_guardian && mon->mpeaceful) { 1845. mon->mpeaceful = 0; 1846. if (canseemon(mon)) ++got_mad; 1847. } 1848. if (got_mad && !Hallucination) 1849. pline_The("%s appear%s to be angry too...", 1850. got_mad == 1 ? q_guardian->mname : 1851. makeplural(q_guardian->mname), 1852. got_mad == 1 ? "s" : ""); 1853. } 1854. } 1855. 1856. void 1857. wakeup(mtmp) 1858. register struct monst *mtmp; 1859. { 1860. mtmp->msleeping = 0; 1861. mtmp->meating = 0; /* assume there's no salvagable food left */ 1862. setmangry(mtmp); 1863. if(mtmp->m_ap_type) seemimic(mtmp); 1864. } 1865. 1866. /* Wake up nearby monsters. */ 1867. void 1868. wake_nearby() 1869. { 1870. register struct monst *mtmp; 1871. 1872. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1873. if (distu(mtmp->mx,mtmp->my) < u.ulevel*20) { 1874. mtmp->msleeping = 0; 1875. if (mtmp->mtame) EDOG(mtmp)->whistletime = moves; 1876. } 1877. } 1878. } 1879. 1880. /* Wake up monsters near some particular location. */ 1881. void 1882. wake_nearto(x, y, distance) 1883. register int x, y, distance; 1884. { 1885. register struct monst *mtmp; 1886. 1887. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1888. if (mtmp->msleeping && (distance == 0 || 1889. dist2(mtmp->mx, mtmp->my, x, y) < distance)) 1890. mtmp->msleeping = 0; 1891. } 1892. } 1893. 1894. /* NOTE: we must check for mimicry before calling this routine */ 1895. void 1896. seemimic(mtmp) 1897. register struct monst *mtmp; 1898. { 1899. /* 1900. * Discovered mimics don't block light. 1901. */ 1902. if ((mtmp->m_ap_type == M_AP_FURNITURE && 1903. (mtmp->mappearance==S_hcdoor || mtmp->mappearance==S_vcdoor))|| 1904. (mtmp->m_ap_type == M_AP_OBJECT && mtmp->mappearance == BOULDER)) 1905. unblock_point(mtmp->mx,mtmp->my); 1906. 1907. mtmp->m_ap_type = M_AP_NOTHING; 1908. mtmp->mappearance = 0; 1909. newsym(mtmp->mx,mtmp->my); 1910. } 1911. 1912. /* force all chameleons to become normal */ 1913. void 1914. rescham() 1915. { 1916. register struct monst *mtmp; 1917. int mcham; 1918. 1919. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1920. mcham = (int) mtmp->cham; 1921. if (mcham) { 1922. mtmp->cham = CHAM_ORDINARY; 1923. (void) newcham(mtmp, &mons[cham_to_pm[mcham]]); 1924. } 1925. if(is_were(mtmp->data) && mtmp->data->mlet != S_HUMAN) 1926. new_were(mtmp); 1927. if(mtmp->m_ap_type && cansee(mtmp->mx, mtmp->my)) { 1928. seemimic(mtmp); 1929. /* we pretend that the mimic doesn't */ 1930. /* know that it has been unmasked. */ 1931. mtmp->msleeping = 1; 1932. } 1933. } 1934. } 1935. 1936. /* Let the chameleons change again -dgk */ 1937. void 1938. restartcham() 1939. { 1940. register struct monst *mtmp; 1941. 1942. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 1943. mtmp->cham = pm_to_cham(monsndx(mtmp->data)); 1944. if (mtmp->data->mlet == S_MIMIC && mtmp->msleeping && 1945. cansee(mtmp->mx, mtmp->my)) { 1946. set_mimic_sym(mtmp); 1947. newsym(mtmp->mx,mtmp->my); 1948. } 1949. } 1950. } 1951. 1952. /* called when restoring a monster from a saved level; protection 1953. against shape-changing might be different now than it was at the 1954. time the level was saved. */ 1955. void 1956. restore_cham(mon) 1957. struct monst *mon; 1958. { 1959. int mcham; 1960. 1961. if (Protection_from_shape_changers) { 1962. mcham = (int) mon->cham; 1963. if (mcham) { 1964. mon->cham = CHAM_ORDINARY; 1965. (void) newcham(mon, &mons[cham_to_pm[mcham]]); 1966. } else if (is_were(mon->data) && !is_human(mon->data)) { 1967. new_were(mon); 1968. } 1969. } else { 1970. mon->cham = pm_to_cham(monsndx(mon->data)); 1971. } 1972. } 1973. 1974. /* unwatched hiders may hide again; if so, a 1 is returned. */ 1975. STATIC_OVL boolean 1976. restrap(mtmp) 1977. register struct monst *mtmp; 1978. { 1979. if(mtmp->cham || mtmp->mcan || mtmp->m_ap_type || 1980. cansee(mtmp->mx, mtmp->my) || rn2(3) || (mtmp == u.ustuck)) 1981. return(FALSE); 1982. 1983. if(mtmp->data->mlet == S_MIMIC) { 1984. set_mimic_sym(mtmp); 1985. return(TRUE); 1986. } else 1987. if(levl[mtmp->mx][mtmp->my].typ == ROOM) { 1988. mtmp->mundetected = 1; 1989. return(TRUE); 1990. } 1991. 1992. return(FALSE); 1993. } 1994. 1995. short *animal_list = 0; /* list of PM values for animal monsters */ 1996. int animal_list_count; 1997. 1998. void 1999. mon_animal_list(construct) 2000. boolean construct; 2001. { 2002. if (construct) { 2003. short animal_temp[SPECIAL_PM]; 2004. int i, n; 2005. 2006. /* if (animal_list) impossible("animal_list already exists"); */ 2007. 2008. for (n = 0, i = LOW_PM; i < SPECIAL_PM; i++) 2009. if (is_animal(&mons[i])) animal_temp[n++] = i; 2010. /* if (n == 0) animal_temp[n++] = NON_PM; */ 2011. 2012. animal_list = (short *)alloc(n * sizeof *animal_list); 2013. (void) memcpy((genericptr_t)animal_list, 2014. (genericptr_t)animal_temp, 2015. n * sizeof *animal_list); 2016. animal_list_count = n; 2017. } else { /* release */ 2018. if (animal_list) free((genericptr_t)animal_list), animal_list = 0; 2019. animal_list_count = 0; 2020. } 2021. } 2022. 2023. STATIC_OVL int 2024. pick_animal() 2025. { 2026. if (!animal_list) mon_animal_list(TRUE); 2027. 2028. return animal_list[rn2(animal_list_count)]; 2029. } 2030. 2031. STATIC_OVL int 2032. select_newcham_form(mon) 2033. struct monst *mon; 2034. { 2035. int mndx = NON_PM; 2036. 2037. switch (mon->cham) { 2038. case CHAM_SANDESTIN: 2039. if (rn2(7)) mndx = pick_nasty(); 2040. break; 2041. case CHAM_DOPPELGANGER: 2042. if (!rn2(7)) mndx = pick_nasty(); 2043. else if (rn2(3)) mndx = rn1(PM_WIZARD - PM_ARCHEOLOGIST + 1, 2044. PM_ARCHEOLOGIST); 2045. break; 2046. case CHAM_CHAMELEON: 2047. if (!rn2(3)) mndx = pick_animal(); 2048. break; 2049. case CHAM_ORDINARY: 2050. break; 2051. } 2052. if (mndx == NON_PM) mndx = rn1(SPECIAL_PM - LOW_PM, LOW_PM); 2053. return mndx; 2054. } 2055. 2056. /* make a chameleon look like a new monster; returns 1 if it actually changed */ 2057. int 2058. newcham(mtmp, mdat) 2059. struct monst *mtmp; 2060. struct permonst *mdat; 2061. { 2062. int mhp, hpn, hpd; 2063. int mndx, tryct; 2064. struct permonst *olddata = mtmp->data; 2065. 2066. /* mdat = 0 -> caller wants a random monster shape */ 2067. tryct = 0; 2068. if (mdat == 0) { 2069. while (++tryct <= 100) { 2070. mndx = select_newcham_form(mtmp); 2071. mdat = &mons[mndx]; 2072. if ((mvitals[mndx].mvflags & G_GENOD) != 0 || 2073. is_placeholder(mdat)) continue; 2074. /* polyok rules out all M2_PNAME and M2_WERE's; 2075. select_newcham_form might deliberately pick a player 2076. character type, so we can't arbitrarily rule out all 2077. human forms any more */ 2078. if (is_mplayer(mdat) || (!is_human(mdat) && polyok(mdat))) 2079. break; 2080. } 2081. if (tryct > 100) return 0; /* Should never happen */ 2082. } 2083. 2084. if(is_male(mdat)) { 2085. if(mtmp->female) mtmp->female = FALSE; 2086. } else if (is_female(mdat)) { 2087. if(!mtmp->female) mtmp->female = TRUE; 2088. } else if (!is_neuter(mdat)) { 2089. if(!rn2(10)) mtmp->female = !mtmp->female; 2090. } 2091. 2092. if (In_endgame(&u.uz) && is_mplayer(olddata)) { 2093. /* mplayers start out as "Foo the Bar", but some of the 2094. * titles are inappropriate when polymorphed, particularly 2095. * into the opposite sex. players don't use ranks when 2096. * polymorphed, so dropping the rank for mplayers seems 2097. * reasonable. 2098. */ 2099. char *p = index(NAME(mtmp), ' '); 2100. if (p) { 2101. *p = '\0'; 2102. mtmp->mnamelth = p - NAME(mtmp) + 1; 2103. } 2104. } 2105. 2106. if(mdat == mtmp->data) return(0); /* still the same monster */ 2107. 2108. if(mtmp->wormno) { /* throw tail away */ 2109. wormgone(mtmp); 2110. place_monster(mtmp, mtmp->mx, mtmp->my); 2111. } 2112. 2113. hpn = mtmp->mhp; 2114. hpd = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 2115. if(!hpd) hpd = 4; 2116. 2117. mtmp->m_lev = adj_lev(mdat); /* new monster level */ 2118. 2119. mhp = (mtmp->m_lev < 50) ? ((int)mtmp->m_lev)*8 : mdat->mlevel; 2120. if(!mhp) mhp = 4; 2121. 2122. /* new hp: same fraction of max as before */ 2123. #ifndef LINT 2124. mtmp->mhp = (int)(((long)hpn*(long)mhp)/(long)hpd); 2125. #endif 2126. if(mtmp->mhp < 0) mtmp->mhp = hpn; /* overflow */ 2127. /* Unlikely but not impossible; a 1HD creature with 1HP that changes into a 2128. 0HD creature will require this statement */ 2129. if (!mtmp->mhp) mtmp->mhp = 1; 2130. 2131. /* and the same for maximum hit points */ 2132. hpn = mtmp->mhpmax; 2133. #ifndef LINT 2134. mtmp->mhpmax = (int)(((long)hpn*(long)mhp)/(long)hpd); 2135. #endif 2136. if(mtmp->mhpmax < 0) mtmp->mhpmax = hpn; /* overflow */ 2137. if (!mtmp->mhpmax) mtmp->mhpmax = 1; 2138. 2139. /* take on the new form... */ 2140. set_mon_data(mtmp, mdat, 0); 2141. 2142. if (emits_light(olddata) != emits_light(mtmp->data)) { 2143. /* used to give light, now doesn't, or vice versa, 2144. or light's range has changed */ 2145. if (emits_light(olddata)) 2146. del_light_source(LS_MONSTER, (genericptr_t)mtmp); 2147. if (emits_light(mtmp->data)) 2148. new_light_source(mtmp->mx, mtmp->my, emits_light(mtmp->data), 2149. LS_MONSTER, (genericptr_t)mtmp); 2150. } 2151. mtmp->perminvis = pm_invisible(mdat); 2152. mtmp->minvis = mtmp->invis_blkd ? 0 : mtmp->perminvis; 2153. if (!(hides_under(mdat) && OBJ_AT(mtmp->mx, mtmp->my)) && 2154. !(mdat->mlet == S_EEL && is_pool(mtmp->mx, mtmp->my))) 2155. mtmp->mundetected = 0; 2156. if (u.ustuck == mtmp) { 2157. if(u.uswallow) { 2158. if(!attacktype(mdat,AT_ENGL)) { 2159. /* Does mdat care? */ 2160. if (!noncorporeal(mdat) && !amorphous(mdat) && 2161. !is_whirly(mdat) && 2162. (mdat != &mons[PM_YELLOW_LIGHT])) { 2163. You("break out of %s%s!", mon_nam(mtmp), 2164. (is_animal(mdat)? 2165. "'s stomach" : "")); 2166. mtmp->mhp = 1; /* almost dead */ 2167. } 2168. expels(mtmp, olddata, FALSE); 2169. } 2170. } else if (!sticks(mdat) && !sticks(youmonst.data)) 2171. unstuck(mtmp); 2172. } 2173. 2174. #ifndef DCC30_BUG 2175. if (mdat == &mons[PM_LONG_WORM] && (mtmp->wormno = get_wormno()) != 0) { 2176. #else 2177. /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the 2178. * same expression. 2179. */ 2180. if (mdat == &mons[PM_LONG_WORM] && 2181. (mtmp->wormno = get_wormno(), mtmp->wormno != 0)) { 2182. #endif 2183. /* we can now create worms with tails - 11/91 */ 2184. initworm(mtmp, rn2(5)); 2185. if (count_wsegs(mtmp)) 2186. place_worm_tail_randomly(mtmp, mtmp->mx, mtmp->my); 2187. } 2188. 2189. newsym(mtmp->mx,mtmp->my); 2190. 2191. mon_break_armor(mtmp); 2192. if (!(mtmp->misc_worn_check & W_ARMG)) 2193. mselftouch(mtmp, "No longer petrify-resistant, ", 2194. !flags.mon_moving); 2195. possibly_unwield(mtmp); 2196. m_dowear(mtmp, FALSE); 2197. 2198. /* This ought to re-test can_carry() on each item in the inventory 2199. * rather than just checking ex-giants & boulders, but that'd be 2200. * pretty expensive to perform. If implemented, then perhaps 2201. * minvent should be sorted in order to drop heaviest items first. 2202. */ 2203. /* former giants can't continue carrying boulders */ 2204. if (mtmp->minvent && !throws_rocks(mdat)) { 2205. register struct obj *otmp, *otmp2; 2206. 2207. for (otmp = mtmp->minvent; otmp; otmp = otmp2) { 2208. otmp2 = otmp->nobj; 2209. if (otmp->otyp == BOULDER) { 2210. obj_extract_self(otmp); 2211. /* probably ought to give some "drop" message here */ 2212. if (flooreffects(otmp, mtmp->mx, mtmp->my, "")) continue; 2213. place_object(otmp, mtmp->mx, mtmp->my); 2214. } 2215. } 2216. } 2217. 2218. return(1); 2219. } 2220. 2221. /* sometimes an egg will be special */ 2222. #define BREEDER_EGG (!rn2(77)) 2223. 2224. /* 2225. * Determine if the given monster number can be hatched from an egg. 2226. * Return the monster number to use as the egg's corpsenm. Return 2227. * NON_PM if the given monster can't be hatched. 2228. */ 2229. int 2230. can_be_hatched(mnum) 2231. int mnum; 2232. { 2233. mnum = little_to_big(mnum); 2234. /* 2235. * Queen bees lay killer bee eggs (usually), but killer bees don't 2236. * grow into queen bees. Ditto for [winged-]gargoyles. 2237. */ 2238. if (mnum == PM_KILLER_BEE || mnum == PM_GARGOYLE || 2239. (lays_eggs(&mons[mnum]) && (BREEDER_EGG || 2240. (mnum != PM_QUEEN_BEE && mnum != PM_WINGED_GARGOYLE)))) 2241. return mnum; 2242. return NON_PM; 2243. } 2244. 2245. /* type of egg laid by #sit; usually matches parent */ 2246. int 2247. egg_type_from_parent(mnum, force_ordinary) 2248. int mnum; /* parent monster; caller must handle lays_eggs() check */ 2249. boolean force_ordinary; 2250. { 2251. if (force_ordinary || !BREEDER_EGG) { 2252. if (mnum == PM_QUEEN_BEE) mnum = PM_KILLER_BEE; 2253. else if (mnum == PM_WINGED_GARGOYLE) mnum = PM_GARGOYLE; 2254. } 2255. return mnum; 2256. } 2257. 2258. /* decide whether an egg of the indicated monster type is viable; */ 2259. /* also used to determine whether an egg or tin can be created... */ 2260. boolean 2261. dead_species(m_idx, egg) 2262. int m_idx; 2263. boolean egg; 2264. { 2265. /* 2266. * For monsters with both baby and adult forms, genociding either 2267. * form kills all eggs of that monster. Monsters with more than 2268. * two forms (small->large->giant mimics) are more or less ignored; 2269. * fortunately, none of them have eggs. Species extinction due to 2270. * overpopulation does not kill eggs. 2271. */ 2272. return (boolean) 2273. (m_idx >= LOW_PM && 2274. ((mvitals[m_idx].mvflags & G_GENOD) != 0 || 2275. (egg && 2276. (mvitals[big_to_little(m_idx)].mvflags & G_GENOD) != 0))); 2277. } 2278. 2279. /* kill off any eggs of genocided monsters */ 2280. STATIC_OVL void 2281. kill_eggs(obj_list) 2282. struct obj *obj_list; 2283. { 2284. struct obj *otmp; 2285. 2286. for (otmp = obj_list; otmp; otmp = otmp->nobj) 2287. if (otmp->otyp == EGG) { 2288. if (dead_species(otmp->corpsenm, TRUE)) { 2289. /* 2290. * It seems we could also just catch this when 2291. * it attempted to hatch, so we wouldn't have to 2292. * search all of the objlists.. or stop all 2293. * hatch timers based on a corpsenm. 2294. */ 2295. kill_egg(otmp); 2296. } 2297. #if 0 /* not used */ 2298. } else if (otmp->otyp == TIN) { 2299. if (dead_species(otmp->corpsenm, FALSE)) 2300. otmp->corpsenm = NON_PM; /* empty tin */ 2301. } else if (otmp->otyp == CORPSE) { 2302. if (dead_species(otmp->corpsenm, FALSE)) 2303. ; /* not yet implemented... */ 2304. #endif 2305. } else if (Has_contents(otmp)) { 2306. kill_eggs(otmp->cobj); 2307. } 2308. } 2309. 2310. /* kill all members of genocided species */ 2311. void 2312. kill_genocided_monsters() 2313. { 2314. struct monst *mtmp, *mtmp2; 2315. boolean kill_cham[CHAM_MAX_INDX+1]; 2316. int mndx; 2317. 2318. kill_cham[CHAM_ORDINARY] = FALSE; /* (this is mndx==0) */ 2319. for (mndx = 1; mndx <= CHAM_MAX_INDX; mndx++) 2320. kill_cham[mndx] = (mvitals[cham_to_pm[mndx]].mvflags & G_GENOD) != 0; 2321. /* 2322. * Called during genocide, and again upon level change. The latter 2323. * catches up with any migrating monsters as they finally arrive at 2324. * their intended destinations, so possessions get deposited there. 2325. * 2326. * Chameleon handling: 2327. * 1) if chameleons have been genocided, destroy them 2328. * regardless of current form; 2329. * 2) otherwise, force every chameleon which is imitating 2330. * any genocided species to take on a new form. 2331. */ 2332. for (mtmp = fmon; mtmp; mtmp = mtmp2) { 2333. mtmp2 = mtmp->nmon; 2334. mndx = monsndx(mtmp->data); 2335. if ((mvitals[mndx].mvflags & G_GENOD) || kill_cham[mtmp->cham]) { 2336. if (mtmp->cham && !kill_cham[mtmp->cham]) 2337. (void) newcham(mtmp, (struct permonst *)0); 2338. else 2339. mondead(mtmp); 2340. } 2341. if (mtmp->minvent) kill_eggs(mtmp->minvent); 2342. } 2343. 2344. kill_eggs(invent); 2345. kill_eggs(fobj); 2346. kill_eggs(level.buriedobjlist); 2347. } 2348. 2349. #endif /* OVL2 */ 2350. #ifdef OVLB 2351. 2352. void 2353. golemeffects(mon, damtype, dam) 2354. register struct monst *mon; 2355. int damtype, dam; 2356. { 2357. int heal = 0, slow = 0; 2358. 2359. if (mon->data == &mons[PM_FLESH_GOLEM]) { 2360. if (damtype == AD_ELEC) heal = dam / 6; 2361. else if (damtype == AD_FIRE || damtype == AD_COLD) slow = 1; 2362. } else if (mon->data == &mons[PM_IRON_GOLEM]) { 2363. if (damtype == AD_ELEC) slow = 1; 2364. else if (damtype == AD_FIRE) heal = dam; 2365. } else { 2366. return; 2367. } 2368. if (slow) { 2369. if (mon->mspeed != MSLOW) { 2370. unsigned int oldspeed = mon->mspeed; 2371. 2372. mon_adjust_speed(mon, -1); 2373. if (mon->mspeed != oldspeed && cansee(mon->mx, mon->my)) 2374. pline("%s seems to be moving slower.", Monnam(mon)); 2375. } 2376. } 2377. if (heal) { 2378. if (mon->mhp < mon->mhpmax) { 2379. mon->mhp += dam; 2380. if (mon->mhp > mon->mhpmax) mon->mhp = mon->mhpmax; 2381. if (cansee(mon->mx, mon->my)) 2382. pline("%s seems healthier.", Monnam(mon)); 2383. } 2384. } 2385. } 2386. 2387. boolean 2388. angry_guards(silent) 2389. register boolean silent; 2390. { 2391. register struct monst *mtmp; 2392. register int ct = 0, nct = 0, sct = 0, slct = 0; 2393. 2394. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2395. if((mtmp->data == &mons[PM_WATCHMAN] || 2396. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 2397. && mtmp->mpeaceful) { 2398. ct++; 2399. if(cansee(mtmp->mx, mtmp->my) && mtmp->mcanmove) { 2400. if (distu(mtmp->mx, mtmp->my) == 2) nct++; 2401. else sct++; 2402. } 2403. if (mtmp->msleeping || mtmp->mfrozen) { 2404. slct++; 2405. mtmp->msleeping = mtmp->mfrozen = 0; 2406. } 2407. mtmp->mpeaceful = 0; 2408. } 2409. } 2410. if(ct) { 2411. if(!silent) { /* do we want pline msgs? */ 2412. if(slct) pline_The("guard%s wake%s up!", 2413. slct > 1 ? "s" : "", slct == 1 ? "s" : ""); 2414. if(nct || sct) { 2415. if(nct) pline_The("guard%s get%s angry!", 2416. nct == 1 ? "" : "s", nct == 1 ? "s" : ""); 2417. else if(!Blind) 2418. You("see %sangry guard%s approaching!", 2419. sct == 1 ? "an " : "", sct > 1 ? "s" : ""); 2420. } else if(flags.soundok) 2421. You_hear("the shrill sound of a guard's whistle."); 2422. } 2423. return(TRUE); 2424. } 2425. return(FALSE); 2426. } 2427. 2428. void 2429. pacify_guards() 2430. { 2431. register struct monst *mtmp; 2432. 2433. for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 2434. if (mtmp->data == &mons[PM_WATCHMAN] || 2435. mtmp->data == &mons[PM_WATCH_CAPTAIN]) 2436. mtmp->mpeaceful = 1; 2437. } 2438. } 2439. #endif /* OVLB */ 2440. 2441. /*mon.c*/
Alternative Linked Data Views: ODE     Raw Data in: CXML | CSV | RDF ( N-Triples N3/Turtle JSON XML ) | OData ( Atom JSON ) | Microdata ( JSON HTML) | JSON-LD    About   
This material is Open Knowledge   W3C Semantic Web Technology [RDF Data] Valid XHTML + RDFa
OpenLink Virtuoso version 07.20.3217, on Linux (x86_64-pc-linux-gnu), Standard Edition
Data on this page belongs to its respective rights holders.
Virtuoso Faceted Browser Copyright © 2009-2012 OpenLink Software