About: Source:NetHack 3.0.0/uhitm.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 uhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/uhitm.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.0.0/uhitm.c
rdfs:comment
  • Below is the full text to uhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/uhitm.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 uhitm.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/uhitm.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)uhitm.c 3.0 88/04/11 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #ifdef NAMED_ITEMS 7. # include "artifact.h" 8. #endif 9. 10. static boolean hitum(); 11. #ifdef POLYSELF 12. static boolean hmonas(); 13. #endif 14. static int passive(); 15. 16. #ifdef WORM 17. extern boolean notonhead; 18. #endif 19. 20. struct monst * 21. clone_mon(mon) 22. struct monst *mon; 23. { 24. coord mm; 25. struct monst *m2; 26. 27. mm.x = mon->mx; 28. mm.y = mon->my; 29. enexto(&mm, mm.x, mm.y); 30. if (levl[mm.x][mm.y].mmask || mon->mhp <= 1) return (struct monst *)0; 31. m2 = newmonst(0); 32. *m2 = *mon; /* copy condition of old monster */ 33. m2->nmon = fmon; 34. fmon = m2; 35. m2->m_id = flags.ident++; 36. m2->mx = mm.x; 37. m2->my = mm.y; 38. 39. m2->minvent = (struct obj *) 0; /* objects don't clone */ 40. m2->mleashed = FALSE; 41. m2->mgold = 0L; 42. /* Max HP the same, but current HP halved for both. The caller 43. * might want to override this by halving the max HP also. 44. */ 45. m2->mhpmax = mon->mhpmax; 46. m2->mhp = mon->mhp /= 2; 47. 48. /* since shopkeepers and guards will only be cloned if they've been 49. * polymorphed away from their original forms, the clone doesn't have 50. * room for the extra information. we also don't want two shopkeepers 51. * around for the same shop. 52. * similarly, clones of named monsters don't have room for the name, 53. * so we just make the clone unnamed instead of bothering to create 54. * a clone with room and copying over the name from the right place 55. * (which changes if the original was a shopkeeper or guard). 56. */ 57. if (mon->isshk) m2->isshk = FALSE; 58. if (mon->isgd) m2->isgd = FALSE; 59. #if defined(ALTARS) && defined(THEOLOGY) 60. if (mon->ispriest) m2->ispriest = FALSE; 61. #endif 62. m2->mxlth = 0; 63. m2->mnamelth = 0; 64. m2->mdispl = 0; 65. pmon(m2); /* display the new monster */ 66. levl[m2->mx][m2->my].mmask = 1; 67. if (mon->mtame) (void) tamedog(m2, (struct obj *)0); 68. return m2; 69. } 70. 71. boolean 72. special_case(mtmp) 73. /* Moved this code from attack() in order to */ 74. /* avoid having to duplicate it in dokick. */ 75. register struct monst *mtmp; 76. { 77. if (flags.confirm && (mtmp->mpeaceful || mtmp->mtame) && !Confusion 78. && !Hallucination && (!mtmp->mhide || !mtmp->mundetected) 79. && (!mtmp->mimic || Protection_from_shape_changers)) { 80. if (Blind ? Telepat : (!mtmp->minvis || See_invisible)) { 81. pline("Really attack %s? ", mon_nam(mtmp)); 82. (void) fflush(stdout); 83. if (yn() != 'y') { 84. flags.move = 0; 85. return(TRUE); 86. } 87. } 88. } 89. 90. if(mtmp->mimic && !Protection_from_shape_changers) { 91. if(!u.ustuck && !mtmp->mflee && dmgtype(mtmp->data,AD_STCK)) 92. u.ustuck = mtmp; 93. if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == DOOR_SYM) 94. #ifdef SPELLS 95. { 96. if (okdoor(u.ux+u.dx, u.uy+u.dy)) 97. #endif 98. pline("The door actually was %s.", defmonnam(mtmp)); 99. #ifdef SPELLS 100. else 101. pline("That spellbook was %s.", defmonnam(mtmp)); 102. } 103. #endif 104. else if (levl[u.ux+u.dx][u.uy+u.dy].scrsym == GOLD_SYM) 105. pline("That gold was %s!", defmonnam(mtmp)); 106. else 107. pline("Wait! That's %s!", defmonnam(mtmp)); 108. wakeup(mtmp); /* clears mtmp->mimic */ 109. return(TRUE); 110. } 111. 112. if(mtmp->mhide && mtmp->mundetected && !canseemon(mtmp)) { 113. mtmp->mundetected = 0; 114. if (!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { 115. register struct obj *obj; 116. 117. if(levl[mtmp->mx][mtmp->my].omask == 1) { 118. if(obj = o_at(mtmp->mx,mtmp->my)) 119. pline("Wait! There's %s hiding under %s!", 120. defmonnam(mtmp), doname(obj)); 121. } else if (levl[mtmp->mx][mtmp->my].gmask == 1) 122. pline("Wait! There's %s hiding under some gold!", 123. defmonnam(mtmp)); 124. wakeup(mtmp); 125. return(TRUE); 126. } 127. } 128. return(FALSE); 129. } 130. 131. 132. /* try to attack; return FALSE if monster evaded */ 133. /* u.dx and u.dy must be set */ 134. boolean 135. attack(mtmp) 136. register struct monst *mtmp; 137. { 138. schar tmp = 0; 139. register struct permonst *mdat = mtmp->data; 140. 141. if(unweapon) { 142. unweapon=FALSE; 143. if(flags.verbose) 144. if(uwep) 145. You("begin bashing monsters with your %s.", 146. aobjnam(uwep, NULL)); 147. else 148. #ifdef POLYSELF 149. if (!cantwield(uasmon)) 150. #endif 151. You("begin bashing monsters with your %s hands.", 152. uarmg ? "gloved" : "bare"); /* Del Lamb */ 153. } 154. /* andrew@orca: prevent unlimited pick-axe attacks */ 155. u_wipe_engr(3); 156. 157. if(mdat->mlet == S_LEPRECHAUN && !mtmp->mfroz && !mtmp->msleep && 158. !mtmp->mconf && mtmp->mcansee && !rn2(7) && 159. (m_move(mtmp, 0) == 2 || /* he died */ 160. mtmp->mx != u.ux+u.dx || mtmp->my != u.uy+u.dy)) /* he moved */ 161. return(FALSE); 162. 163. /* This section of code provides protection against accidentally 164. * hitting peaceful (like '@') and tame (like 'd') monsters. 165. * There is protection only if you're not blind, confused, or hallu- 166. * cinating. 167. */ 168. /* changes by wwp 5/16/85 */ 169. if (!Blind && !Confusion && !Hallucination && flags.safe_dog && 170. (mdat->mlet == S_DOG || mdat->mlet == S_FELINE) && mtmp->mtame) { 171. mtmp->mflee = 1; 172. mtmp->mfleetim = rnd(6); 173. if (mtmp->mnamelth) 174. You("stop to avoid hitting %s.", NAME(mtmp)); 175. else 176. You("stop to avoid hitting your %s.", 177. mdat->mname); 178. return(TRUE); 179. } 180. 181. /* moved code to a separate function to share with dokick */ 182. if(special_case(mtmp)) return(TRUE); 183. 184. #ifdef POLYSELF 185. if(u.umonnum >= 0) { /* certain "pacifist" monsters don't attack */ 186. set_uasmon(); 187. if(noattacks(uasmon)) { 188. You("have no way to attack monsters physically."); 189. return(TRUE); 190. } 191. } 192. tmp = Luck + mdat->ac + abon() + 193. ((u.umonnum >= 0) ? uasmon->mlevel : u.ulevel); 194. #else 195. tmp = Luck + u.ulevel + mdat->ac + abon(); 196. #endif 197. 198. /* it is unchivalrous to attack the defenseless or from behind */ 199. if (pl_character[0] == 'K' && u.ualigntyp == U_LAWFUL && 200. (mtmp->mfroz || mtmp->msleep || mtmp->mflee) && 201. u.ualign > -10) adjalign(-1); 202. 203. /* Adjust vs. (and possibly modify) monster state. */ 204. 205. if(mtmp->mstun) tmp += 2; 206. if(mtmp->mflee) tmp += 2; 207. 208. if(mtmp->msleep) { 209. mtmp->msleep = 0; 210. tmp += 2; 211. } 212. if(mtmp->mfroz) { 213. tmp += 4; 214. if(!rn2(10)) mtmp->mfroz = 0; 215. } 216. if (is_orc(mtmp->data) && pl_character[0]=='E') tmp++; 217. 218. /* with a lot of luggage, your agility diminishes */ 219. tmp -= (inv_weight() + 40)/20; 220. if(u.utrap) tmp -= 3; 221. 222. #ifdef POLYSELF 223. if(u.umonnum >= 0) (void) hmonas(mtmp, tmp); 224. else { 225. #endif 226. if(uwep) tmp += hitval(uwep, mdat); 227. (void) hitum(mtmp, tmp); 228. #ifdef POLYSELF 229. } 230. #endif 231. 232. return(TRUE); 233. } 234. 235. static boolean 236. known_hitum(mon, mhit) /* returns TRUE if monster still lives */ 237. /* Made into a separate function because in some cases we want to know 238. * in the calling function whether we hit. 239. */ 240. register struct monst *mon; 241. register int mhit; 242. { 243. register boolean malive = TRUE; 244. 245. stoned = FALSE; /* this refers to the thing hit, not you */ 246. 247. if(!mhit) { 248. if(!Blind && flags.verbose) You("miss %s.", mon_nam(mon)); 249. else You("miss it."); 250. if(is_human(mon->data) && !(mon->msleep || mon->mfroz)) 251. wakeup(mon); 252. } else { 253. /* we hit the monster; be careful: it might die! */ 254. 255. #ifdef WORM 256. if (mon->mx != u.ux+u.dx || mon->my != u.uy+u.dy) 257. notonhead = TRUE; 258. #endif 259. if((malive = hmon(mon, uwep, 0)) == TRUE) { 260. /* monster still alive */ 261. if(!rn2(25) && mon->mhp < mon->mhpmax/2) { 262. mon->mflee = 1; 263. if(!rn2(3)) mon->mfleetim = rnd(100); 264. if(u.ustuck == mon && !u.uswallow 265. #ifdef POLYSELF 266. && !sticks(uasmon) 267. #endif 268. ) 269. u.ustuck = 0; 270. } 271. #ifdef WORM 272. if(mon->wormno) 273. cutworm(mon, u.ux+u.dx, u.uy+u.dy, 274. uwep ? uwep->otyp : 0); 275. #endif 276. } 277. #if defined(ALTARS) && defined(THEOLOGY) 278. if(mon->ispriest && !rn2(2)) ghod_hitsu(); 279. #endif 280. } 281. return(malive); 282. } 283. 284. static boolean 285. hitum(mon, tmp) /* returns TRUE if monster still lives */ 286. struct monst *mon; 287. int tmp; 288. { 289. static int malive; 290. boolean mhit = !((tmp <= rnd(20)) && !u.uswallow); 291. 292. malive = known_hitum(mon, mhit); 293. (void) passive(mon, mhit, malive); 294. return(malive); 295. } 296. 297. boolean /* general "damage monster" routine */ 298. hmon(mon, obj, thrown) /* return TRUE if mon still alive */ 299. register struct monst *mon; 300. register struct obj *obj; 301. register int thrown; 302. { 303. register int tmp; 304. boolean hittxt = FALSE; 305. boolean get_dmg_bonus = TRUE; 306. boolean ispoisoned = FALSE; 307. 308. wakeup(mon); 309. if(!obj) { 310. tmp = rnd(2); /* attack with bare hands */ 311. if(mon->data == &mons[PM_COCKATRICE] && !uarmg 312. #ifdef POLYSELF 313. && !resists_ston(uasmon) 314. #endif 315. ) { 316. 317. kludge("You hit %s with your bare %s.", 318. mon_nam(mon), makeplural(body_part(HAND))); 319. You("turn to stone..."); 320. done_in_by(mon); 321. } 322. } else { 323. if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE || 324. obj->olet == ROCK_SYM) { 325. 326. if(mon->data == &mons[PM_RUST_MONSTER] && obj == uwep && 327. objects[obj->otyp].oc_material == METAL && 328. obj->spe > -2) { 329. if(obj->rustfree) { 330. pline("The rust on your %s vanishes instantly!", 331. is_sword(obj) ? "sword" : "weapon"); 332. } else if(obj->blessed && rnl(4)) 333. pline("Somehow your %s is not affected!", 334. is_sword(obj) ? "sword" : "weapon"); 335. else { 336. Your("%s!", aobjnam(uwep, "corrode")); 337. uwep->spe--; 338. } 339. } 340. 341. if(obj == uwep && (obj->otyp > VOULGE || obj->otyp < BOOMERANG) 342. && obj->otyp != PICK_AXE) 343. tmp = rnd(2); 344. else { 345. tmp = dmgval(obj, mon->data); 346. #ifdef NAMED_ITEMS 347. if(spec_ability(obj, SPFX_DRLI) && 348. !resists_drli(mon->data)) { 349. if (!Blind) { 350. pline("The %s blade draws the life from %s!", 351. Hallucination ? hcolor() : black, 352. mon_nam(mon)); 353. hittxt = TRUE; 354. } 355. if (mon->m_lev == 0) tmp = mon->mhp; 356. else { 357. int drain = rnd(8); 358. tmp += drain; 359. mon->mhpmax -= drain; 360. mon->m_lev--; 361. } 362. } 363. #endif 364. if(!thrown && obj == uwep && obj->otyp == BOOMERANG && 365. !rnl(3)) { 366. kludge("As you hit %s, the boomerang breaks into splinters.", 367. mon_nam(mon)); 368. useup(obj); 369. hittxt = TRUE; 370. tmp++; 371. } 372. if(thrown && (obj->otyp >= ARROW && obj->otyp <= SHURIKEN)){ 373. if(((uwep && objects[obj->otyp].w_propellor == 374. -objects[uwep->otyp].w_propellor) 375. || obj->otyp==DART || obj->otyp==SHURIKEN) && 376. obj->opoisoned) 377. ispoisoned = TRUE; 378. } 379. } 380. } else if(obj->olet == POTION_SYM) { 381. if (obj->quan > 1) setuwep(splitobj(obj, 1)); 382. else setuwep((struct obj *)0); 383. freeinv(obj); 384. potionhit(mon,obj); 385. hittxt = TRUE; 386. tmp = 1; 387. } else switch(obj->otyp) { 388. case HEAVY_IRON_BALL: 389. tmp = rnd(25); break; 390. case BOULDER: 391. tmp = rnd(20); break; 392. #ifdef MEDUSA 393. case MIRROR: 394. You("break your mirror. That's bad luck!"); 395. change_luck(-2); 396. useup(obj); 397. return(TRUE); 398. #endif 399. case EXPENSIVE_CAMERA: 400. You("succeed in destroying your camera. Congratulations!"); 401. useup(obj); 402. return(TRUE); 403. case CORPSE: /* fixed by polder@cs.vu.nl */ 404. if(obj->corpsenm == PM_COCKATRICE) { 405. kludge("You hit %s with the cockatrice corpse.", 406. mon_nam(mon)); 407. if(resists_ston(mon->data)) { 408. tmp = 1; 409. hittxt = TRUE; 410. break; 411. } 412. kludge("%s turns to stone.", Monnam(mon)); 413. stoned = TRUE; 414. xkilled(mon,0); 415. return(FALSE); 416. } 417. tmp = bigmonst(&mons[obj->corpsenm]) ? 5 : 2 ; 418. break; 419. case EGG: /* only possible if hand-to-hand */ 420. if(obj->corpsenm > -1 421. && obj->corpsenm != PM_COCKATRICE 422. && mon->data==&mons[PM_COCKATRICE]) { 423. kludge("You hit %s with the %s egg%s.", 424. mon_nam(mon), 425. mons[obj->corpsenm].mname, 426. (obj->quan==1) ? "" : "s"); 427. hittxt = TRUE; 428. pline("The egg%sn't live any more...", 429. (obj->quan==1) ? " is" : "s are"); 430. obj->otyp = ROCK; 431. obj->olet = GEM_SYM; 432. obj->known = obj->dknown = 0; 433. obj->owt = weight(obj); 434. } 435. tmp = 1; 436. break; 437. case CLOVE_OF_GARLIC: /* no effect against demons */ 438. if(is_undead(mon->data)) mon->mflee = 1; 439. tmp = 1; 440. break; 441. case CREAM_PIE: 442. #ifdef POLYSELF 443. case BLINDING_VENOM: 444. if(Blind) 445. pline(obj->otyp==CREAM_PIE ? "Splat!" : "Splash!"); 446. else if (obj->otyp == BLINDING_VENOM) 447. pline("The venom blinds %s%s!", mon_nam(mon), 448. mon->mcansee ? "" : " further"); 449. #else 450. if(Blind) pline("Splat!"); 451. #endif 452. else 453. pline("The cream pie splashes over %s%s!", 454. mon_nam(mon), 455. (haseyes(mon->data) && 456. mon->data != &mons[PM_FLOATING_EYE]) 457. ? "'s face" : ""); 458. if(mon->msleep) mon->msleep = 0; 459. setmangry(mon); 460. mon->mcansee = 0; 461. if((mon->mblinded + tmp) > 127) mon->mblinded = 127; 462. else mon->mblinded += tmp; 463. hittxt = TRUE; 464. get_dmg_bonus = FALSE; 465. tmp = 0; 466. break; 467. #ifdef POLYSELF 468. case ACID_VENOM: /* only possible if thrown */ 469. if(resists_acid(mon->data)) { 470. kludge("Your venom hits %s harmlessly.", 471. mon_nam(mon)); 472. tmp = 0; 473. } else { 474. kludge("Your venom burns %s!", mon_nam(mon)); 475. tmp = dmgval(obj, mon->data); 476. } 477. hittxt = TRUE; 478. get_dmg_bonus = FALSE; 479. break; 480. #endif 481. default: 482. /* non-weapons can damage because of their weight */ 483. /* (but not too much) */ 484. tmp = obj->owt/10; 485. if(tmp < 1) tmp = 1; 486. else tmp = rnd(tmp); 487. if(tmp > 6) tmp = 6; 488. } 489. } 490. 491. /****** NOTE: perhaps obj is undefined!! (if !thrown && BOOMERANG) 492. * *OR* if attacking bare-handed!! */ 493. 494. if (get_dmg_bonus) { 495. tmp += u.udaminc; 496. /* If you throw using a propellor, you don't get a strength 497. * bonus but you do get an increase-damage bonus. 498. */ 499. if(!obj || !uwep || 500. (obj->olet != GEM_SYM && obj->olet != WEAPON_SYM) || 501. objects[obj->otyp].w_propellor != 502. -objects[uwep->otyp].w_propellor) 503. tmp += dbon(); 504. } 505. 506. /* TODO: Fix this up. multiple engulf attacks now exist. 507. if(u.uswallow) { 508. if((tmp -= u.uswldtim) <= 0) { 509. Your("%s are no longer able to hit.", 510. makeplural(body_part(ARM))); 511. return(TRUE); 512. } 513. } 514. */ 515. if (ispoisoned) { 516. /* OK to reference obj because ispoisoned can only be set 517. * when obj is a throwing weapon */ 518. hit(xname(obj), mon, exclam(tmp)); 519. hittxt = TRUE; 520. if(resists_poison(mon->data)) 521. kludge("The poison doesn't seem to affect %s.", mon_nam(mon)); 522. else if (rn2(10)) 523. tmp += rnd(6); 524. else { 525. pline("The poison was deadly..."); 526. xkilled(mon,0); 527. return FALSE; 528. } 529. } 530. if(tmp < 1) tmp = 1; 531. 532. mon->mhp -= tmp; 533. if(mon->mhp < 1) { 534. killed(mon); 535. return(FALSE); 536. } 537. if(mon->mtame && (!mon->mflee || mon->mfleetim)) { 538. #ifdef SOUNDS 539. if (rn2(8)) yelp(mon); 540. else growl(mon); /* give them a moment's worry */ 541. #endif 542. mon->mtame--; 543. mon->mflee = 1; /* Rick Richardson */ 544. mon->mfleetim += 10*rnd(tmp); 545. } 546. if((mon->data == &mons[PM_BLACK_PUDDING] || 547. mon->data == &mons[PM_BROWN_PUDDING]) && uwep && 548. uwep == obj && objects[obj->otyp].oc_material == METAL 549. && mon->mhp > 1 && !thrown && !mon->mcan) { 550. 551. if (clone_mon(mon)) { 552. pline("%s divides as you hit it!", Monnam(mon)); 553. hittxt = TRUE; 554. } 555. } 556. 557. if(!hittxt) { 558. if(thrown) 559. /* thrown => obj exists */ 560. hit(xname(obj), mon, exclam(tmp) ); 561. else if(Blind || !flags.verbose) You("hit it."); 562. else You("hit %s%s", mon_nam(mon), exclam(tmp)); 563. } 564. 565. if(u.umconf && !thrown) { 566. if(!Blind) { 567. Your("%s stop glowing %s.", 568. makeplural(body_part(HAND)), 569. Hallucination ? hcolor() : red); 570. } 571. if(!resist(mon, '+', 0, NOTELL)) mon->mconf = 1; 572. if(!mon->mstun && !mon->mfroz && !mon->msleep && 573. !Blind && mon->mconf) 574. pline("%s appears confused.", Monnam(mon)); 575. u.umconf = 0; 576. } 577. return(TRUE); /* mon still alive */ 578. } 579. 580. #ifdef POLYSELF 581. static int 582. damageum(mdef, mattk) 583. register struct monst *mdef; 584. register struct attack *mattk; 585. { 586. register struct permonst *pd = mdef->data; 587. register int tmp = d((int)mattk->damn, (int)mattk->damd); 588. 589. stoned = FALSE; 590. if (is_demon(uasmon) && !rn2(13) && !uwep 591. #ifdef HARD 592. && u.umonnum != PM_SUCCUBUS && u.umonnum != PM_INCUBUS 593. && u.umonnum != PM_BALROG 594. #endif 595. ) { 596. struct monst *dtmp; 597. pline("Some hell-p has arrived!"); 598. /* if((dtmp = mkmon_at(uasmon, u.ux, u.uy)))*/ 599. /* if((dtmp = makemon(uasmon, u.ux, u.uy)))*/ 600. if((dtmp = makemon(&mons[ndemon()], u.ux, u.uy))) 601. (void)tamedog(dtmp, (struct obj *)0); 602. return(0); 603. } 604. 605. switch(mattk->adtyp) { 606. case AD_STUN: 607. if(!Blind) 608. pline("%s staggers for a moment.", Monnam(mdef)); 609. mdef->mstun = 1; 610. /* fall through to next case */ 611. case AD_WERE: /* no effect on monsters */ 612. case AD_PHYS: 613. if(mattk->aatyp == AT_WEAP) { 614. if(uwep) tmp = 0; 615. } else if(mattk->aatyp == AT_KICK) 616. if(thick_skinned(mdef->data)) tmp = 0; 617. break; 618. case AD_FIRE: 619. #ifdef GOLEMS 620. golemeffects(mdef, AD_FIRE, tmp); 621. #endif /* GOLEMS */ 622. if(resists_fire(pd)) { 623. shieldeff(mdef->mx, mdef->my); 624. tmp = 0; 625. } else { 626. if(!Blind) pline("%s is on fire!", Monnam(mdef)); 627. tmp += destroy_mitem(mdef, SCROLL_SYM, AD_FIRE); 628. tmp += destroy_mitem(mdef, POTION_SYM, AD_FIRE); 629. #ifdef SPELLS 630. tmp += destroy_mitem(mdef, SPBOOK_SYM, AD_FIRE); 631. #endif 632. } 633. break; 634. case AD_COLD: 635. #ifdef GOLEMS 636. golemeffects(mdef, AD_COLD, tmp); 637. #endif /* GOLEMS */ 638. if(resists_cold(pd)) { 639. shieldeff(mdef->mx, mdef->my); 640. tmp = 0; 641. } else { 642. if(!Blind) pline("%s is covered in frost.", Monnam(mdef)); 643. tmp += destroy_mitem(mdef, POTION_SYM, AD_COLD); 644. } 645. break; 646. case AD_ELEC: 647. #ifdef GOLEMS 648. golemeffects(mdef, AD_ELEC, tmp); 649. #endif /* GOLEMS */ 650. if(resists_elec(pd)) { 651. shieldeff(mdef->mx, mdef->my); 652. tmp = 0; 653. } 654. break; 655. case AD_ACID: 656. if(resists_acid(pd)) tmp = 0; 657. break; 658. case AD_STON: 659. if(!resists_ston(pd)) { 660. stoned = TRUE; 661. if(!Blind) pline("%s turns to stone.", Monnam(mdef)); 662. xkilled(mdef, 0); 663. return(2); 664. } 665. tmp = 0; /* no damage if this fails */ 666. break; 667. #ifdef SEDUCE 668. case AD_SSEX: 669. #endif 670. case AD_SEDU: 671. case AD_SITM: 672. if(mdef->minvent) { 673. struct obj *otmp, *addinv(), *stealoid; 674. int isize = inv_cnt(); 675. 676. stealoid = (struct obj *)0; 677. if (is_mercenary(pd)) { 678. for(otmp = mdef->minvent; otmp; otmp=otmp->nobj) 679. if (otmp->otyp >= PLATE_MAIL && otmp->otyp 680. <= ELVEN_CLOAK) stealoid = otmp; 681. } 682. if (stealoid) { 683. boolean stolen = FALSE; 684. /* Is "he"/"his" always correct? */ 685. kludge("You seduce %s and he starts to take off his clothes.", 686. mon_nam(mdef)); 687. while(mdef->minvent) { 688. otmp = mdef->minvent; 689. mdef->minvent = otmp->nobj; 690. if (!stolen && otmp==stealoid) { 691. if(isize < 52) { 692. otmp = addinv(otmp); 693. isize++; 694. } else dropy(otmp); 695. stealoid = otmp; 696. stolen = TRUE; 697. } else { 698. if(isize < 52) { 699. otmp = addinv(otmp); 700. isize++; 701. } else dropy(otmp); 702. You("steal: "); 703. prinv(otmp); 704. } 705. } 706. if (!stolen) 707. impossible("Player steal fails!"); 708. else { 709. kludge("%s finishes taking off his suit.", 710. Monnam(mdef)); 711. You("steal a %s.", xname(stealoid)); 712. #ifdef ARMY 713. mdef->data = &mons[PM_UNARMORED_SOLDIER]; 714. #endif 715. } 716. } else { 717. otmp = mdef->minvent; 718. mdef->minvent = otmp->nobj; 719. if(isize < 52) otmp = addinv(otmp); 720. else dropy(otmp); 721. You("steal: "); 722. prinv(otmp); 723. } 724. } 725. tmp = 0; 726. break; 727. case AD_SGLD: 728. if (mdef->mgold) { 729. u.ugold += mdef->mgold; 730. mdef->mgold = 0; 731. Your("purse feels heavier."); 732. } 733. tmp = 0; 734. break; 735. case AD_TLPT: 736. if(tmp <= 0) tmp = 1; 737. if(tmp < mdef->mhp) { 738. rloc(mdef); 739. if(!Blind) pline("%s suddenly disappears!", Monnam(mdef)); 740. } 741. break; 742. case AD_BLND: 743. if(haseyes(pd)) { 744. 745. if(!Blind) pline("%s is blinded.", Monnam(mdef)); 746. mdef->mcansee = 0; 747. mdef->mblinded += tmp; 748. } 749. tmp = 0; 750. break; 751. case AD_CURS: 752. if (night() && !rn2(10) && !mdef->mcan) { 753. #ifdef GOLEMS 754. if (mdef->data == &mons[PM_CLAY_GOLEM]) { 755. if (!Blind) 756. pline("Some writing vanishes from %s's head!", 757. mon_nam(mdef)); 758. xkilled(mdef, 0); 759. return 2; 760. } 761. #endif /* GOLEMS */ 762. mdef->mcan = 1; 763. You("chuckle."); 764. } 765. tmp = 0; 766. break; 767. case AD_DRLI: 768. if(rn2(2) && !resists_drli(pd)) { 769. int xtmp = d(2,6); 770. kludge("%s suddenly seems weaker!", Monnam(mdef)); 771. mdef->mhpmax -= xtmp; 772. if ((mdef->mhp -= xtmp) <= 0 || !mdef->m_lev--) { 773. kludge("%s dies.", Monnam(mdef)); 774. xkilled(mdef,0); 775. return(2); 776. } 777. } 778. tmp = 0; 779. break; 780. case AD_RUST: 781. #ifdef GOLEMS 782. if (pd == &mons[PM_IRON_GOLEM]) { 783. kludge("%s falls to pieces!", Monnam(mdef)); 784. xkilled(mdef,0); 785. return(2); 786. } 787. #endif /* GOLEMS */ 788. tmp = 0; 789. break; 790. case AD_DCAY: 791. #ifdef GOLEMS 792. if (pd == &mons[PM_WOOD_GOLEM] || 793. pd == &mons[PM_LEATHER_GOLEM]) { 794. kludge("%s falls to pieces!", Monnam(mdef)); 795. xkilled(mdef,0); 796. return(2); 797. } 798. #endif /* GOLEMS */ 799. case AD_DRST: 800. case AD_DRDX: 801. case AD_DRCO: 802. if (!rn2(8)) { 803. Your("%s was poisoned!", mattk->aatyp==AT_BITE ? 804. "bite" : "sting"); 805. if (resists_poison(mdef->data)) 806. kludge("The poison doesn't seem to affect %s.", 807. mon_nam(mdef)); 808. else { 809. if (!rn2(10)) { 810. Your("poison was deadly..."); 811. tmp = mdef->mhp; 812. } else tmp += rn1(10,6); 813. } 814. } 815. break; 816. case AD_WRAP: 817. case AD_STCK: 818. if (!sticks(mdef->data)) 819. u.ustuck = mdef; /* it's now stuck to you */ 820. break; 821. default: tmp = 0; 822. break; 823. } 824. if(!tmp) return(1); 825. 826. if((mdef->mhp -= tmp) < 1) { 827. 828. if(mdef->mtame) { 829. if(!Blind) You("killed your %s!", mon_nam(mdef)); 830. else You("feel embarrassed for a moment."); 831. } else { 832. if(!Blind && flags.verbose) pline("%s is killed!", Monnam(mdef)); 833. else You("kill it!"); 834. } 835. xkilled(mdef, 0); 836. return(2); 837. } 838. return(1); 839. } 840. 841. static int 842. explum(mdef, mattk) 843. register struct monst *mdef; 844. register struct attack *mattk; 845. { 846. switch(mattk->adtyp) { 847. case AD_BLND: 848. if(mdef->data->mlet != S_YLIGHT) { 849. kludge("%s is blinded by your flash of light!", Monnam(mdef)); 850. if (!mdef->mblinded) { 851. mdef->mblinded += rn2(25); 852. mdef->mcansee = 0; 853. } 854. } 855. break; 856. case AD_COLD: 857. You("explode!"); 858. if (!resists_cold(mdef->data)) { 859. kludge("%s gets blasted!", Monnam(mdef)); 860. mdef->mhp -= d(6,6); 861. if (mdef->mhp <= 0) { 862. killed(mdef); 863. return(2); 864. } 865. #ifdef GOLEMS 866. } else if (is_golem(mdef->data)) { 867. golemeffects(mdef, AD_COLD, d(6,6)); 868. shieldeff(mdef->mx, mdef->my); 869. #endif /* GOLEMS */ 870. } else { 871. shieldeff(mdef->mx, mdef->my); 872. kludge("The blast doesn't seem to affect %s.", 873. mon_nam(mdef)); 874. } 875. break; 876. default: break; 877. } 878. return(1); 879. } 880. 881. static int 882. gulpum(mdef,mattk) 883. register struct monst *mdef; 884. register struct attack *mattk; 885. { 886. register int tmp; 887. register int dam = d((int)mattk->damn, (int)mattk->damd); 888. /* Not totally the same as for real monsters. Specifically, these 889. * don't take multiple moves. (It's just too hard, for too little 890. * result, to program monsters which attack from inside you, which 891. * would be necessary if done accurately.) Instead, we arbitrarily 892. * kill the monster immediately for AD_DGST and we regurgitate them 893. * after exactly 1 round of attack otherwise. -KAA 894. */ 895. 896. #ifdef WORM 897. if(mdef->wormno) return 0; 898. #endif 899. if(u.uhunger < 1500 && !u.uswallow) { 900. 901. if(mdef->data->mlet != S_COCKATRICE) { 902. #ifdef LINT /* static char msgbuf[BUFSZ]; */ 903. char msgbuf[BUFSZ]; 904. #else 905. static char msgbuf[BUFSZ]; 906. #endif 907. /* TODO: get the symbol display also to work (monster symbol is removed from 908. * the screen and you moved onto it, then you get moved back and it gets 909. * moved back if the monster survives--just like when monsters swallow you. 910. */ 911. kludge("You engulf %s!", mon_nam(mdef)); 912. switch(mattk->adtyp) { 913. case AD_DGST: 914. u.uhunger += 20*mdef->mhpmax; 915. newuhs(FALSE); 916. xkilled(mdef,2); 917. Sprintf(msgbuf, "You totally digest %s.", 918. Blind ? "it" : mon_nam(mdef)); 919. if ((tmp = mdef->mhpmax/5)) { 920. kludge("You digest %s.", mon_nam(mdef)); 921. nomul(-tmp); 922. nomovemsg = msgbuf; 923. } else pline(msgbuf); 924. return(2); 925. case AD_PHYS: 926. kludge("%s is pummeled with your debris!",Monnam(mdef)); 927. break; 928. case AD_ACID: 929. kludge("%s is covered with your goo!", Monnam(mdef)); 930. if (resists_acid(mdef->data)) { 931. kludge("It seems harmless to %s.", mon_nam(mdef)); 932. dam = 0; 933. } 934. break; 935. case AD_BLND: 936. if (mdef->mcansee) 937. kludge("%s can't see in there!", Monnam(mdef)); 938. mdef->mcansee = 0; 939. dam += mdef->mblinded; 940. if (dam > 127) dam = 127; 941. mdef->mblinded = dam; 942. dam = 0; 943. break; 944. case AD_ELEC: 945. if (rn2(2)) { 946. kludge("The air around %s crackles with electricity.", mon_nam(mdef)); 947. if (resists_elec(mdef->data)) { 948. kludge("%s seems unhurt.", Monnam(mdef)); 949. dam = 0; 950. } 951. #ifdef GOLEMS 952. golemeffects(mdef,(int)mattk->adtyp,dam); 953. #endif 954. } else dam = 0; 955. break; 956. case AD_COLD: 957. if (rn2(2)) { 958. if (resists_cold(mdef->data)) { 959. kludge("%s seems mildly chilly.", Monnam(mdef)); 960. dam = 0; 961. } else 962. kludge("%s is freezing to death!",Monnam(mdef)); 963. #ifdef GOLEMS 964. golemeffects(mdef,(int)mattk->adtyp,dam); 965. #endif 966. } else dam = 0; 967. break; 968. case AD_FIRE: 969. if (rn2(2)) { 970. if (resists_fire(mdef->data)) { 971. kludge("%s seems mildly hot.", Monnam(mdef)); 972. dam = 0; 973. } else 974. kludge("%s is burning to a crisp!",Monnam(mdef)); 975. #ifdef GOLEMS 976. golemeffects(mdef,(int)mattk->adtyp,dam); 977. #endif 978. } else dam = 0; 979. break; 980. } 981. if ((mdef->mhp -= dam) <= 0) { 982. kludge("%s is killed!", Monnam(mdef)); 983. xkilled(mdef,0); 984. return(2); 985. } 986. kludge("You regurgitate %s!", mon_nam(mdef)); 987. if (Blind) 988. pline("Obviously, you didn't like its taste."); 989. else 990. pline("Obviously, you didn't like %s's taste.", 991. mon_nam(mdef)); 992. } else { 993. kludge("You bite into %s", mon_nam(mdef)); 994. You("turn to stone..."); 995. killer = "poor choice of food"; 996. done("stoned"); 997. } 998. } 999. return(0); 1000. } 1001. 1002. static void 1003. missum(mdef) 1004. register struct monst *mdef; 1005. { 1006. #ifdef POLYSELF 1007. if (u.usym==S_NYMPH 1008. # ifdef SEDUCE 1009. || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mdef)) 1010. # endif 1011. ) 1012. kludge("You pretend to be friendly to %s.", mon_nam(mdef)); 1013. else 1014. #endif 1015. if(!Blind && flags.verbose) You("miss %s.", mon_nam(mdef)); 1016. else You("miss it."); 1017. if(is_human(mdef->data) && !(mdef->msleep || mdef->mfroz)) 1018. wakeup(mdef); 1019. } 1020. 1021. static boolean 1022. hmonas(mon, tmp) /* attack monster as a monster. */ 1023. register struct monst *mon; 1024. register int tmp; 1025. { 1026. register struct attack *mattk; 1027. int i, sum[NATTK]; 1028. int nsum = 0; 1029. schar dhit; 1030. 1031. for(i = 0; i < NATTK; i++) { 1032. 1033. mattk = &(uasmon->mattk[i]); 1034. switch(mattk->aatyp) { 1035. case AT_WEAP: 1036. use_weapon: 1037. /* Certain monsters don't use weapons when encountered as enemies, 1038. * but players who polymorph into them have hands or claws and thus 1039. * should be able to use weapons. This shouldn't prohibit the use 1040. * of most special abilities, either. 1041. */ 1042. /* Potential problem: if the monster gets multiple weapon attacks, 1043. * we currently allow the player to get each of these as a weapon 1044. * attack. Is this really desirable? 1045. */ 1046. if(uwep) tmp += hitval(uwep, mon->data); 1047. dhit = !((tmp <= rnd(20)) && !u.uswallow); 1048. /* Enemy dead, before any special abilities used */ 1049. if (!known_hitum(mon,dhit)) return 0; 1050. /* Do not print "You hit" message, since known_hitum 1051. * already did it. 1052. */ 1053. if (dhit && mattk->adtyp != AD_SPEL 1054. && mattk->adtyp != AD_PHYS) 1055. sum[i] = damageum(mon,mattk); 1056. else sum[i] = 0; 1057. break; 1058. case AT_CLAW: 1059. if (i==0 && uwep && humanoid(uasmon)) goto use_weapon; 1060. case AT_KICK: 1061. case AT_BITE: 1062. case AT_STNG: 1063. case AT_TUCH: 1064. case AT_BUTT: 1065. if (i==0 && uwep && (u.usym==S_LICH 1066. )) goto use_weapon; 1067. if(dhit = (tmp > rnd(20) || u.uswallow)) { 1068. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */ 1069. if (!u.uswallow && (u.usym==S_NYMPH 1070. #ifdef SEDUCE 1071. || ((u.umonnum==PM_INCUBUS || u.umonnum==PM_SUCCUBUS) && !incompatible(mon)) 1072. #endif 1073. )) { 1074. kludge("You %s %s %s.", mon->mblinded ? "talk to" : "smile at", 1075. mon_nam(mon), 1076. incompatible(mon) ? "engagingly" : "seductively"); 1077. } 1078. /* <----- <----- <----- <----- <----- <----- <----- <----- <----- */ 1079. else if (mattk->aatyp == AT_KICK) 1080. kludge("You kick %s.", mon_nam(mon)); 1081. else if (mattk->aatyp == AT_BITE) 1082. kludge("You bite %s.", mon_nam(mon)); 1083. else if (mattk->aatyp == AT_STNG) 1084. kludge("You sting %s.", mon_nam(mon)); 1085. else if (mattk->aatyp == AT_BUTT) 1086. kludge("You butt %s.", mon_nam(mon)); 1087. else if (mattk->aatyp == AT_TUCH) 1088. kludge("You touch %s.", mon_nam(mon)); 1089. else kludge("You hit %s.", mon_nam(mon)); 1090. sum[i] = damageum(mon, mattk); 1091. } else { 1092. missum(mon); 1093. sum[i] = 0; 1094. } 1095. break; 1096. 1097. case AT_HUGS: 1098. /* automatic if prev two attacks succeed, or if 1099. * already grabbed in a previous attack 1100. */ 1101. dhit = 1; 1102. if (sticks(mon->data)) sum[i] = 0; 1103. else if (mon==u.ustuck) { 1104. kludge("%s is being %s.", Monnam(mon), 1105. #ifdef GOLEMS 1106. u.umonnum==PM_ROPE_GOLEM ? "choked": 1107. #endif 1108. "crushed"); 1109. sum[i] = damageum(mon, mattk); 1110. } else if(sum[i-1] && sum[i-2]) { 1111. kludge("You grab %s!", mon_nam(mon)); 1112. u.ustuck = mon; 1113. sum[i] = damageum(mon, mattk); 1114. } else sum[i] = 0; 1115. break; 1116. 1117. case AT_EXPL: /* automatic hit if next to */ 1118. dhit = -1; 1119. sum[i] = explum(mon, mattk); 1120. break; 1121. 1122. case AT_ENGL: 1123. if((dhit = (tmp > rnd(20+i)))) 1124. sum[i]= gulpum(mon,mattk); 1125. else { 1126. missum(mon); 1127. sum[i] = 0; 1128. } 1129. break; 1130. 1131. case AT_MAGC: 1132. /* No check for uwep; if wielding nothing we want to 1133. * do the normal 1-2 points bare hand damage... 1134. */ 1135. if (i==0 && (u.usym==S_KOBOLD 1136. || u.usym==S_ORC 1137. || u.usym==S_GNOME 1138. )) goto use_weapon; 1139. 1140. case AT_NONE: 1141. sum[i] = 0; 1142. continue; 1143. /* Not break--avoid passive attacks from enemy */ 1144. 1145. default: /* Strange... */ 1146. impossible("strange attack of yours (%d)", 1147. mattk->aatyp); 1148. case AT_BREA: 1149. case AT_SPIT: 1150. case AT_GAZE: /* all done using #monster command */ 1151. sum[i] = dhit = 0; 1152. break; 1153. } 1154. if (dhit == -1) 1155. rehumanize(); 1156. if(sum[i] == 2) return(passive(mon, 1, 0)); /* defender dead */ 1157. else { 1158. (void) passive(mon, sum[i], 1); 1159. nsum |= sum[i]; 1160. } 1161. if (uasmon == &playermon) 1162. break; /* No extra attacks if no longer a monster */ 1163. if (multi < 0) 1164. break; /* If paralyzed while attacking, i.e. floating eye */ 1165. } 1166. return(nsum); 1167. } 1168. 1169. #endif 1170. 1171. /* Special (passive) attacks on you by monsters done here. */ 1172. 1173. static int 1174. passive(mon, mhit, malive) 1175. register struct monst *mon; 1176. register boolean mhit; 1177. register int malive; 1178. { 1179. register struct permonst *ptr = mon->data; 1180. register int i, tmp; 1181. 1182. for(i = 0; ; i++) { 1183. if(i >= NATTK) return(malive | mhit); /* no passive attacks */ 1184. if(ptr->mattk[i].aatyp == AT_NONE) break; /* try this one */ 1185. } 1186. 1187. /* These affect you even if they just died */ 1188. 1189. switch(ptr->mattk[i].adtyp) { 1190. 1191. case AD_ACID: 1192. if(mhit && rn2(2)) { 1193. if (Blind || !flags.verbose) You("are splashed!"); 1194. else You("are splashed by %s's acid!", mon_nam(mon)); 1195. 1196. tmp = d((int)mon->m_lev, (int)ptr->mattk[i].damd); 1197. #ifdef POLYSELF 1198. if(!resists_acid(uasmon)) 1199. #endif 1200. mdamageu(mon, tmp); 1201. if(!rn2(30)) corrode_armor(); 1202. } 1203. if(mhit && !rn2(6)) corrode_weapon(); 1204. break; 1205. case AD_MAGM: 1206. /* wrath of gods for attacking Oracle */ 1207. if(Antimagic) { 1208. shieldeff(u.ux, u.uy); 1209. pline("A hail of magic missiles narrowly misses you!"); 1210. } else { 1211. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1212. You("are hit by magic missiles appearing from thin air!"); 1213. mdamageu(mon, tmp); 1214. } 1215. break; 1216. default: 1217. break; 1218. } 1219. 1220. /* These only affect you if they still live */ 1221. 1222. if(malive && !mon->mcan && rn2(3)) { 1223. 1224. switch(ptr->mattk[i].adtyp) { 1225. 1226. case AD_PLYS: /* specifically floating eye */ 1227. if(canseemon(mon)) { 1228. 1229. tmp = -d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1230. if(mon->mcansee) { 1231. if(Reflecting & W_AMUL) { 1232. makeknown(AMULET_OF_REFLECTION); 1233. pline("%s's gaze is reflected by your medallion.", 1234. Monnam(mon)); 1235. } else if(Reflecting & W_ARMS) { 1236. makeknown(SHIELD_OF_REFLECTION); 1237. pline("%s's gaze is reflected by your shield.", 1238. Monnam(mon)); 1239. } else { 1240. You("are frozen by %s's gaze!", mon_nam(mon)); 1241. nomul((ACURR(A_WIS) > 12 || rn2(4)) ? tmp : -120); 1242. } 1243. } else { 1244. pline("%s cannot defend itself.", Amonnam(mon,"blind")); 1245. if(!rn2(500)) change_luck(-1); 1246. } 1247. } 1248. break; 1249. case AD_COLD: /* brown mold or blue jelly */ 1250. if(dist(mon->mx, mon->my) <= 3) { 1251. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1252. if(Cold_resistance) { 1253. shieldeff(u.ux, u.uy); 1254. You("feel a mild chill."); 1255. #ifdef POLYSELF 1256. #ifdef GOLEMS 1257. ugolemeffects(AD_COLD, tmp); 1258. #endif /* GOLEMS */ 1259. #endif 1260. tmp = 0; 1261. break; 1262. } 1263. You("are suddenly very cold!"); 1264. mdamageu(mon, tmp); 1265. /* monster gets stronger with your heat! */ 1266. mon->mhp += tmp / 2; 1267. if (mon->mhpmax < mon->mhp) mon->mhpmax = mon->mhp; 1268. /* at a certain point, the monster will reproduce! */ 1269. if(mon->mhpmax > ((mon->m_lev+1) * 8)) { 1270. register struct monst *mtmp; 1271. 1272. if(mtmp = clone_mon(mon)) { 1273. mtmp->mhpmax = mon->mhpmax /= 2; 1274. if(!Blind) 1275. pline("%s multiplies from your heat!", 1276. Monnam(mon)); 1277. } 1278. } 1279. } 1280. break; 1281. case AD_STUN: /* specifically yellow mold */ 1282. if(!Stunned) 1283. make_stunned((long)d((int)mon->m_lev+1, (int)ptr->mattk[i].damd), TRUE); 1284. break; 1285. case AD_FIRE: 1286. if(dist(mon->mx, mon->my) <= 3) { 1287. tmp = d((int)mon->m_lev+1, (int)ptr->mattk[i].damd); 1288. if(Fire_resistance) { 1289. shieldeff(u.ux, u.uy); 1290. You("feel mildly warm."); 1291. #ifdef POLYSELF 1292. #ifdef GOLEMS 1293. ugolemeffects(AD_FIRE, tmp); 1294. #endif /* GOLEMS */ 1295. #endif 1296. tmp = 0; 1297. break; 1298. } 1299. You("are suddenly very hot!"); 1300. mdamageu(mon, tmp); 1301. } 1302. break; 1303. default: 1304. break; 1305. } 1306. } 1307. return(malive | mhit); 1308. }
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