PropertyValue
rdfs:label
  • Source:NetHack 3.1.0/fountain.c
rdfs:comment
  • Below is the full text to fountain.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/fountain.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/property/wikiPageUsesTemplate
abstract
  • Below is the full text to fountain.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/fountain.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 1. /* SCCS Id: @(#)fountain.c 3.1 92/12/19 */ 2. /* Copyright Scott R. Turner, srt@ucla, 10/27/86 */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. /* Code for drinking from fountains. */ 6. 7. #include "hack.h" 8. 9. static void NDECL(dowatersnakes); 10. static void NDECL(dowaterdemon); 11. static void NDECL(dowaternymph); 12. STATIC_PTR void FDECL(gush, (int,int,genericptr_t)); 13. static void NDECL(dofindgem); 14. 15. static void 16. dowatersnakes() /* Fountain of snakes! */ 17. { 18. register int num = rn1(5,2); 19. struct monst *mtmp; 20. 21. if (!(mons[PM_WATER_MOCCASIN].geno & (G_GENOD | G_EXTINCT))) { 22. if (!Blind) 23. pline("An endless stream of %s pours forth!", 24. Hallucination ? makeplural(rndmonnam()) : "snakes"); 25. else 26. You("hear something hissing!"); 27. while(num-- > 0) 28. if((mtmp = makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy)) && 29. t_at(mtmp->mx, mtmp->my)) 30. (void) mintrap(mtmp); 31. } else 32. pline("The fountain bubbles furiously for a moment, then calms."); 33. } 34. 35. static 36. void 37. dowaterdemon() /* Water demon */ 38. { 39. register struct monst *mtmp; 40. 41. if(mons[PM_WATER_DEMON].geno & (G_GENOD | G_EXTINCT)) return; 42. if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy))) { 43. if (!Blind) 44. You("have unleashed %s!", a_monnam(mtmp)); 45. else 46. You("feel the presence of evil."); 47. 48. /* Give those on low levels a (slightly) better chance of survival */ 49. if ( rnd(100) > (80 + level_difficulty())) { 50. pline("Grateful for %s release, %s grants you a wish!", 51. Blind ? "its" : "his", Blind ? "it" : "he" ); 52. makewish(); 53. mongone(mtmp); 54. } else if (t_at(mtmp->mx, mtmp->my)) 55. (void) mintrap(mtmp); 56. } 57. } 58. 59. static void 60. dowaternymph() /* Water Nymph */ 61. { 62. register struct monst *mtmp; 63. 64. if(mons[PM_WATER_NYMPH].geno & (G_GENOD | G_EXTINCT)) return; 65. if((mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy))) { 66. if (!Blind) 67. You("have attracted %s!", a_monnam(mtmp)); 68. else 69. You("hear a seductive voice."); 70. mtmp->msleep = 0; 71. if (t_at(mtmp->mx, mtmp->my)) 72. (void) mintrap(mtmp); 73. } else 74. if (!Blind) 75. pline("A large bubble rises to the surface and pops."); 76. else 77. You("hear a loud pop."); 78. } 79. 80. void 81. dogushforth(drinking) /* Gushing forth along LOS from (u.ux, u.uy) */ 82. int drinking; 83. { 84. int madepool = 0; 85. 86. do_clear_area(u.ux, u.uy, 7, gush, (genericptr_t)&madepool); 87. if (!madepool) 88. if (drinking) 89. Your("thirst is quenched."); 90. else 91. pline("Water sprays all over you."); 92. } 93. 94. STATIC_PTR void 95. gush(x, y, poolcnt) 96. int x, y; 97. genericptr_t poolcnt; 98. { 99. register struct monst *mtmp; 100. 101. if (((x+y)%2) || (x == u.ux && y == u.uy) || 102. (rn2(1 + distmin(u.ux, u.uy, x, y))) || 103. (levl[x][y].typ != ROOM) || t_at(x,y) || 104. (sobj_at(BOULDER, x, y)) || nexttodoor(x, y)) 105. return; 106. 107. if (!((*(int *)poolcnt)++)) 108. pline("Water gushes forth from the overflowing fountain!"); 109. 110. /* Put a pool at x, y */ 111. 112. levl[x][y].typ = POOL; 113. 114. if ((mtmp = m_at(x, y)) != 0) 115. (void) minwater(mtmp); 116. else 117. newsym(x,y); 118. } 119. 120. static void 121. dofindgem() /* Find a gem in the sparkling waters. */ 122. { 123. if (!Blind) You("spot a gem in the sparkling waters!"); 124. (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1), 125. u.ux, u.uy, FALSE); 126. levl[u.ux][u.uy].looted |= F_LOOTED; 127. newsym(u.ux, u.uy); 128. exercise(A_WIS, TRUE); /* a discovery! */ 129. } 130. 131. void 132. dryup(x,y) 133. xchar x, y; 134. { 135. boolean isyou = (x == u.ux && y == u.uy); 136. 137. if (IS_FOUNTAIN(levl[x][y].typ) && 138. (!rn2(3) || (levl[x][y].looted & F_WARNED))) { 139. s_level *slev = Is_special(&u.uz); 140. if(isyou && slev && slev->flags.town && 141. !(levl[x][y].looted & F_WARNED)) { 142. struct monst *mtmp; 143. levl[x][y].looted |= F_WARNED; 144. /* Warn about future fountain use. */ 145. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 146. if((mtmp->data == &mons[PM_WATCHMAN] || 147. mtmp->data == &mons[PM_WATCH_CAPTAIN]) && 148. couldsee(mtmp->mx, mtmp->my) && 149. mtmp->mpeaceful) { 150. pline("%s yells:", Amonnam(mtmp)); 151. verbalize("Hey, stop using that fountain!"); 152. break; 153. } 154. } 155. /* You can see or hear this effect */ 156. if(!mtmp) pline("The waterflow reduces to a trickle."); 157. return; 158. } 159. #ifdef WIZARD 160. if (isyou && wizard) { 161. if (yn("Dry up fountain?") == 'n') 162. return; 163. } 164. #endif 165. if (cansee(x,y)) pline("The fountain dries up!"); 166. levl[x][y].typ = ROOM; 167. levl[x][y].looted = 0; 168. levl[x][y].blessedftn = 0; 169. /* The location is seen if the hero/monster is invisible */ 170. /* or felt if the hero is blind. */ 171. newsym(x, y); 172. level.flags.nfountains--; 173. if(isyou && slev && slev->flags.town) 174. (void) angry_guards(FALSE); 175. } 176. } 177. 178. void 179. drinkfountain() 180. { 181. /* What happens when you drink from a fountain? */ 182. register boolean mgkftn = (levl[u.ux][u.uy].blessedftn == 1); 183. register int fate = rnd(30); 184. 185. if (Levitation) { 186. You("are floating high above the fountain."); 187. return; 188. } 189. 190. if (mgkftn && u.uluck >= 0 && fate >= 10) { 191. int i, ii, littleluck = (u.uluck < 4); 192. 193. pline("Wow! This makes you feel great!"); 194. /* blessed restore ability */ 195. for (ii = 0; ii < A_MAX; ii++) 196. if (ABASE(ii) < AMAX(ii)) { 197. ABASE(ii) = AMAX(ii); 198. flags.botl = 1; 199. } 200. /* gain ability, blessed if "natural" luck is high */ 201. i = rn2(A_MAX); /* start at a random attribute */ 202. for (ii = 0; ii < A_MAX; ii++) { 203. if (adjattrib(i, 1, littleluck ? -1 : 0) && littleluck) 204. break; 205. if (++i >= A_MAX) i = 0; 206. } 207. display_nhwindow(WIN_MESSAGE, FALSE); 208. pline("A wisp of vapor escapes the fountain...."); 209. exercise(A_WIS, TRUE); 210. levl[u.ux][u.uy].blessedftn = 0; 211. return; 212. } 213. 214. if (fate < 10) { 215. pline("The cool draught refreshes you."); 216. u.uhunger += rnd(10); /* don't choke on water */ 217. newuhs(FALSE); 218. if(mgkftn) return; 219. } else { 220. switch (fate) { 221. 222. case 19: /* Self-knowledge */ 223. 224. You("feel self-knowledgeable...."); 225. display_nhwindow(WIN_MESSAGE, FALSE); 226. enlightenment(FALSE); 227. exercise(A_WIS, TRUE); 228. pline("The feeling subsides."); 229. break; 230. 231. case 20: /* Foul water */ 232. 233. pline("The water is foul! You gag and vomit."); 234. morehungry(rn1(20, 11)); 235. vomit(); 236. break; 237. 238. case 21: /* Poisonous */ 239. 240. pline("The water is contaminated!"); 241. if (Poison_resistance) { 242. #ifdef TUTTI_FRUTTI 243. pline("Perhaps it is runoff from the nearby %s farm.", pl_fruit); 244. #else 245. pline("Perhaps it is runoff from the nearby orange farm."); 246. #endif 247. losehp(rnd(4),"unrefrigerated sip of juice", 248. KILLED_BY_AN); 249. break; 250. } 251. losestr(rn1(4,3)); 252. losehp(rnd(10),"contaminated water", KILLED_BY); 253. exercise(A_CON, FALSE); 254. break; 255. 256. case 22: /* Fountain of snakes! */ 257. 258. dowatersnakes(); 259. break; 260. 261. case 23: /* Water demon */ 262. dowaterdemon(); 263. break; 264. 265. case 24: /* Curse an item */ { 266. register struct obj *obj; 267. 268. pline("This water's no good!"); 269. morehungry(rn1(20, 11)); 270. exercise(A_CON, FALSE); 271. for(obj = invent; obj ; obj = obj->nobj) 272. if (!rn2(5)) curse(obj); 273. break; 274. } 275. 276. case 25: /* See invisible */ 277. 278. You("see an image of someone stalking you."); 279. pline("But it disappears."); 280. HSee_invisible |= FROMOUTSIDE; 281. newsym(u.ux,u.uy); 282. exercise(A_WIS, TRUE); 283. break; 284. 285. case 26: /* See Monsters */ 286. 287. (void) monster_detect((struct obj *)0, 0); 288. exercise(A_WIS, TRUE); 289. break; 290. 291. case 27: /* Find a gem in the sparkling waters. */ 292. 293. if (!levl[u.ux][u.uy].looted) { 294. dofindgem(); 295. break; 296. } 297. 298. case 28: /* Water Nymph */ 299. 300. dowaternymph(); 301. break; 302. 303. case 29: /* Scare */ { 304. register struct monst *mtmp; 305. 306. pline("This water gives you bad breath!"); 307. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 308. mtmp->mflee = 1; 309. } 310. break; 311. 312. case 30: /* Gushing forth in this room */ 313. 314. dogushforth(TRUE); 315. break; 316. 317. default: 318. 319. pline("This tepid water is tasteless."); 320. break; 321. } 322. } 323. dryup(u.ux, u.uy); 324. } 325. 326. void 327. dipfountain(obj) 328. register struct obj *obj; 329. { 330. if (Levitation) { 331. You("are floating high above the fountain."); 332. return; 333. } 334. 335. /* Don't grant Excalibur when there's more than one object. */ 336. /* (quantity could be > 1 if merged daggers got polymorphed) */ 337. if (obj->otyp == LONG_SWORD && obj->quan == 1L 338. && u.ulevel >= 5 && !rn2(6) 339. && !obj->oartifact 340. && !exist_artifact(LONG_SWORD, artiname(ART_EXCALIBUR))) { 341. if (u.ualign.type != A_LAWFUL) { 342. /* Ha! Trying to cheat her. */ 343. pline("A freezing mist rises from the water and envelopes the sword."); 344. pline("The fountain disappears!"); 345. curse(obj); 346. if (obj->spe > -6 && !rn2(3)) obj->spe--; 347. obj->oerodeproof = FALSE; 348. exercise(A_WIS, FALSE); 349. } else { 350. /* The lady of the lake acts! - Eric Backus */ 351. /* Be *REAL* nice */ 352. pline("From the murky depths, a hand reaches up to bless the sword."); 353. pline("As the hand retreats, the fountain disappears!"); 354. obj = oname(obj, artiname(ART_EXCALIBUR), 1); 355. bless(obj); 356. obj->oeroded = 0; 357. obj->oerodeproof = TRUE; 358. exercise(A_WIS, TRUE); 359. } 360. levl[u.ux][u.uy].typ = ROOM; 361. levl[u.ux][u.uy].looted = 0; 362. if(Invisible) newsym(u.ux, u.uy); 363. level.flags.nfountains--; 364. return; 365. } else (void) get_wet(obj); 366. 367. switch (rnd(30)) { 368. case 16: /* Curse the item */ 369. curse(obj); 370. break; 371. case 17: 372. case 18: 373. case 19: 374. case 20: /* Uncurse the item */ 375. if(obj->cursed) { 376. if (!Blind) 377. pline("The water glows for a moment."); 378. uncurse(obj); 379. } else { 380. pline("A feeling of loss comes over you."); 381. } 382. break; 383. case 21: /* Water Demon */ 384. dowaterdemon(); 385. break; 386. case 22: /* Water Nymph */ 387. dowaternymph(); 388. break; 389. case 23: /* an Endless Stream of Snakes */ 390. dowatersnakes(); 391. break; 392. case 24: /* Find a gem */ 393. dofindgem(); 394. break; 395. case 25: /* Water gushes forth */ 396. dogushforth(FALSE); 397. break; 398. case 26: /* Strange feeling */ 399. pline("A strange tingling runs up your %s.", 400. body_part(ARM)); 401. break; 402. case 27: /* Strange feeling */ 403. You("feel a sudden chill."); 404. break; 405. case 28: /* Strange feeling */ 406. pline("An urge to take a bath overwhelms you."); 407. if (u.ugold > 10) { 408. u.ugold -= somegold() / 10; 409. You("lost some of your gold in the fountain!"); 410. levl[u.ux][u.uy].looted &= ~F_LOOTED; 411. exercise(A_WIS, FALSE); 412. } 413. break; 414. case 29: /* You see coins */ 415. 416. /* We make fountains have more coins the closer you are to the 417. * surface. After all, there will have been more people going 418. * by. Just like a shopping mall! Chris Woodbury */ 419. 420. mkgold((long) 421. (rnd((dunlevs_in_dungeon(&u.uz)-dunlev(&u.uz)+1)*2)+5), 422. u.ux, u.uy); 423. if (!Blind) 424. pline("Far below you, you see coins glistening in the water."); 425. exercise(A_WIS, TRUE); 426. break; 427. } 428. dryup(u.ux, u.uy); 429. } 430. 431. #ifdef SINKS 432. void 433. breaksink(x,y) 434. int x, y; 435. { 436. if(cansee(x,y) || (x == u.ux && y == u.uy)) 437. pline("The pipes break! Water spurts out!"); 438. level.flags.nsinks--; 439. levl[x][y].doormask = 0; 440. levl[x][y].typ = FOUNTAIN; 441. level.flags.nfountains++; 442. newsym(x,y); 443. } 444. 445. void 446. drinksink() 447. { 448. if (Levitation) { 449. You("are floating high above the sink."); 450. return; 451. } 452. switch(rn2(20)) { 453. static struct obj NEARDATA *otmp; 454. case 0: You("take a sip of very cold water."); 455. break; 456. case 1: You("take a sip of very warm water."); 457. break; 458. case 2: You("take a sip of scalding hot water."); 459. if (Fire_resistance) 460. pline("It seems quite tasty."); 461. else losehp(rnd(6), "sipping boiling water", KILLED_BY); 462. break; 463. case 3: if (mons[PM_SEWER_RAT].geno & (G_GENOD | G_EXTINCT)) 464. pline("The sink seems quite dirty."); 465. else { 466. static struct monst NEARDATA *mtmp; 467. 468. mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy); 469. pline("Eek! There's %s in the sink!", 470. Blind ? "something squirmy" : 471. a_monnam(mtmp)); 472. } 473. break; 474. case 4: do { 475. otmp = mkobj(POTION_CLASS,FALSE); 476. if (otmp->otyp == POT_WATER) { 477. obfree(otmp, (struct obj *)0); 478. otmp = (struct obj *) 0; 479. } 480. } while(!otmp); 481. otmp->cursed = otmp->blessed = 0; 482. if (Blind) 483. pline("The sink emits some odd liquid."); 484. else 485. pline("The sink emits a stream of %s water.", 486. Hallucination ? hcolor() : 487. OBJ_DESCR(objects[otmp->otyp])); 488. otmp->dknown = !(Blind || Hallucination); 489. otmp->quan++; /* Avoid panic upon useup() */ 490. otmp->corpsenm = 1; /* kludge for docall() */ 491. (void) dopotion(otmp); 492. obfree(otmp, (struct obj *)0); 493. break; 494. case 5: if (!(levl[u.ux][u.uy].looted & S_LRING)) { 495. You("find a ring in the sink!"); 496. (void) mkobj_at(RING_CLASS, u.ux, u.uy, TRUE); 497. levl[u.ux][u.uy].looted |= S_LRING; 498. exercise(A_WIS, TRUE); 499. } else pline("Some dirty water backs up in the drain."); 500. break; 501. case 6: breaksink(u.ux,u.uy); 502. break; 503. case 7: pline("The water moves as though of its own will!"); 504. if ((mons[PM_WATER_ELEMENTAL].geno & (G_GENOD | G_EXTINCT)) 505. || !makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy)) 506. pline("But it quiets down."); 507. break; 508. case 8: pline("Yuk, this water tastes awful."); 509. more_experienced(1,0); 510. newexplevel(); 511. break; 512. case 9: pline("Gaggg... this tastes like sewage! You vomit."); 513. morehungry(rn1(30-ACURR(A_CON), 11)); 514. vomit(); 515. break; 516. #ifdef POLYSELF 517. case 10: pline("This water contains toxic wastes!"); 518. You("undergo a freakish metamorphosis!"); 519. polyself(); 520. break; 521. #endif 522. /* more odd messages --JJB */ 523. case 11: You("hear clanking from the pipes...."); 524. break; 525. case 12: You("hear snatches of song from among the sewers...."); 526. break; 527. case 19: if (Hallucination) { 528. pline("From the murky drain, a hand reaches up... --oops--"); 529. break; 530. } 531. default: You("take a sip of %s water.", 532. rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot"); 533. } 534. } 535. #endif /* SINKS */ 536. 537. /*fountain.c*/