Source:NetHack 3.2.0/fountain.c

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