Source:NetHack 2.2a/potion.c

Below is the full text to potion.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/potion.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)potion.c	2.1	87/09/29 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.     4.    #include "hack.h"  5.    extern int float_down; 6.   extern char *nomovemsg; 7.   extern struct monst youmonst; 8.   extern struct monst *makemon; 9.   char *hcolor; 10.  #ifdef KAA 11.  char *xname; 12.  extern char pl_character[]; 13.  #endif 14.  #ifdef FOUNTAINS 15.  extern int drinkfountain; 16.  extern int dipfountain; 17.  #endif 18.   19.   int	nothing, unkn; 20.   21.   dodrink { 22.  	register struct obj *otmp; 23.  	register int	retval; 24.   25.   #ifdef FOUNTAINS 26.   27.         /* Is there something to drink here, i.e., a fountain? */ 28.          if (IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 29.  	  pline("Drink from the fountain? [ny] "); 30.  	  if(readchar == 'y') { 31.  	    (void) drinkfountain; 32.  	    return(0); 33.  	  }  34.          }    35.    36.   #endif /* FOUNTAINS /**/ 37.   38.   	nothing = unkn = 0; 39.  	otmp = getobj("!", "drink"); 40.  	if(!otmp) return(0); 41.  	if(!strcmp(objects[otmp->otyp].oc_descr, "smoky") && !rn2(13)) { 42.  		ghost_from_bottle; 43.  		goto use_it; 44.  	}  45.   	if((retval = peffects(otmp)) >= 0) return(retval); 46.   47.   	if(nothing) { 48.  	    unkn++; 49.  	    pline("You have a %s feeling for a moment, then it passes.",  50.   		  Hallucination ? "normal" : "peculiar"); 51.  	}  52.   	if(otmp->dknown && !objects[otmp->otyp].oc_name_known) { 53.  		if(!unkn) { 54.  			objects[otmp->otyp].oc_name_known = 1; 55.  			more_experienced(0,10); 56.  		} else if(!objects[otmp->otyp].oc_uname) 57.  			docall(otmp); 58.  	}  59.   use_it: 60.  	useup(otmp); 61.  	return(1); 62.  }  63.    64.   peffects(otmp) 65.  	register struct obj	*otmp; 66.  {  67.   	register struct obj	*objs; 68.  	register struct monst	*mtmp; 69.   70.   	switch(otmp->otyp){ 71.  	case POT_RESTORE_STRENGTH: 72.  #ifdef SPELLS 73.  	case SPE_RESTORE_STRENGTH: 74.  #endif 75.  		unkn++; 76.  		pline("Wow!  This makes you feel great!"); 77.  		if(u.ustr < u.ustrmax) { 78.  			u.ustr = u.ustrmax; 79.  			flags.botl = 1; 80.  		}  81.   		break; 82.  #ifdef KAA 83.  	case POT_HALLUCINATION: 84.  		if (Hallucination) nothing++; 85.  		else pline("Oh wow!  Everything looks so cosmic!"); 86.  		Hallucination += rn1(100,750); 87.  		setsee; 88.  		break; 89.  	case POT_HOLY_WATER: 90.  		unkn++; 91.  		if(index("VWZ&",u.usym)) { 92.  			pline("This burns like acid!"); 93.  			/* should never kill you, but... */ 94.   			losehp(d(2,6), "potion of holy water"); 95.  		} else { 96.  			pline("You feel full of awe."); 97.  			if (Sick) Sick=0; 98.  			if (HConfusion) HConfusion=0; 99.  		}  100.  #else 101. 	case POT_HOLY_WATER: 102. 	case POT_HALLUCINATION: 103. #endif 104. 		break; 105. 	case POT_BOOZE: 106. 		unkn++; 107. 		pline("Ooph!  This tastes like liquid fire!"); 108. 		HConfusion += d(3,8); 109. 		/* the whiskey makes us feel better */ 110. 		if(u.uhp < u.uhpmax) losehp(-1, "bottle of whiskey"); 111. 		if(!rn2(4)) { 112. 			pline("You pass out."); 113. 			multi = -rnd(15); 114. 			nomovemsg = "You awake with a headache."; 115. 		}  116.  		break; 117. 	case POT_INVISIBILITY: 118. #ifdef SPELLS 119. 	case SPE_INVISIBILITY: 120. #endif 121. 		if(Invis || See_invisible) 122. 		  nothing++; 123. 		else { 124. 		  if(!Blind) 125. 		    pline("Gee!  All of a sudden, you can't see yourself."); 126. 		  else 127. 		    pline("You feel rather airy."), unkn++; 128. 		  newsym(u.ux,u.uy); 129. 		}  130.  		HInvis += rn1(15,31); 131. 		break; 132. 	case POT_FRUIT_JUICE: 133. 		pline("This tastes like fruit juice."); 134. 		lesshungry(20); 135. 		break; 136. 	case POT_HEALING: 137. 		pline("You begin to feel better."); 138. 		healup(rnd(10), 1, 1, 1); 139. 		break; 140. 	case POT_PARALYSIS: 141. 		if(Levitation) 142. 			pline("You are motionlessly suspended."); 143. 		else 144. 			pline("Your feet are frozen to the floor!"); 145. 		nomul(-(rn1(10,25))); 146. 		break; 147. 	case POT_MONSTER_DETECTION: 148. #ifdef SPELLS 149. 	case SPE_DETECT_MONSTERS: 150. #endif 151. 		if(!fmon) { 152. 			strange_feeling(otmp, "You feel threatened."); 153. 			return(1); 154. 		} else { 155. 			cls; 156. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 157. 				if(mtmp->mx > 0) 158. 				at(mtmp->mx,mtmp->my,Hallucination ? rndmonsym :  159.  				mtmp->data->mlet); 160. 			prme; 161. 			pline("You sense the presence of monsters."); 162. 			more; 163. 			docrt; 164. 		}  165.  		break; 166. 	case POT_OBJECT_DETECTION: 167. #ifdef SPELLS 168. 	case SPE_DETECT_TREASURE: 169. #endif 170. 		if(!fobj) { 171. 			strange_feeling(otmp, "You feel a pull downward."); 172. 			return(1); 173. 		} else { 174. 		    for(objs = fobj; objs; objs = objs->nobj) 175. 			if(objs->ox != u.ux || objs->oy != u.uy) 176. 				goto outobjmap; 177. 		    pline("You sense the presence of objects close nearby."); 178. 		    break; 179. 		outobjmap: 180. 			cls; 181. 			for(objs = fobj; objs; objs = objs->nobj) 182. 				at(objs->ox,objs->oy,Hallucination ? rndobjsym  183.  				 : objs->olet); 184.  185.  			/* monster possessions added by GAN 12/16/86 */ 186. 			for(mtmp = fmon ; mtmp ; mtmp = mtmp->nmon) 187. 				if(mtmp->minvent) 188. 					for(objs = mtmp->minvent; objs ;  189.  					    objs = objs->nobj) 190. 						at(mtmp->mx,mtmp->my,objs->olet); 191. 			prme; 192. 			pline("You sense the presence of objects."); 193. 			more; 194. 			docrt; 195. 		}  196.  		break; 197. 	case POT_SICKNESS: 198. 		pline("Yech! This stuff tastes like poison."); 199. 		if(Poison_resistance) 200.     pline("(But in fact it was biologically contaminated orange juice.)"); 201. #ifdef KAA 202. 		if (pl_character[0] == 'H') 203. 			pline("Fortunately you have been immunized!"); 204. 		else { 205. #endif 206. 			losestr((Poison_resistance) ? 1 : rn1(4,3)); 207. 			if(!Poison_resistance) 208. 				losehp(rnd(10), "contaminated potion"); 209. #ifdef KAA 210. 		}  211.  #endif 212. 		if(Hallucination) { 213. 			pline("You are shocked back to your senses!"); 214. 			Hallucination=1; 215. 		}  216.  		break; 217. 	case POT_CONFUSION: 218. 		if(!Confusion) 219. 		    if (Hallucination) { 220. 			pline("What a trippy feeling!"); 221. 			unkn++; 222. 		    } else 223. 			pline("Huh, What?  Where am I?"); 224. 		else	nothing++; 225. 		HConfusion += rn1(7,16); 226. 		break; 227. 	case POT_GAIN_STRENGTH: 228. 		pline("Wow do you feel strong!"); 229. 		gainstr(0); 230. 		break; 231. 	case POT_SPEED: 232. 		if(Wounded_legs) { 233. 			heal_legs; 234. 			unkn++; 235. 			break; 236. 		}		/* and fall through */ 237. #ifdef SPELLS 238. 	case SPE_HASTE_SELF: 239. #endif 240. 		if(!(Fast & ~INTRINSIC)) 241. 			pline("You are suddenly moving much faster."); 242. 		else 243. 			pline("Your legs get new energy."), unkn++; 244. 		Fast += rn1(10,100); 245. 		break; 246. 	case POT_BLINDNESS: 247. 		if(!Blind) 248. 			if (Hallucination) 249. 				pline("Bummer!  Everything is dark!  Help!"); 250. 			else 251. 				pline("A cloud of darkness falls upon you."); 252. 		else	nothing++; 253. 		Blinded += rn1(100,250); 254. 		seeoff(0); 255. 		break; 256. 	case POT_GAIN_LEVEL: 257. 		pluslvl; 258. 		break; 259. 	case POT_EXTRA_HEALING: 260. 		pline("You feel much better."); 261. 		healup(d(2,20)+1, 2, 1, 1); 262. 		if(Hallucination) Hallucination = 1; 263. 		break; 264. 	case POT_LEVITATION: 265. #ifdef SPELLS 266. 	case SPE_LEVITATION: 267. #endif 268. 		if(!Levitation) 269. 			float_up; 270. 		else 271. 			nothing++; 272. 		Levitation += rnd(100); 273. 		u.uprops[PROP(RIN_LEVITATION)].p_tofn = float_down; 274. 		break; 275. 	case POT_GAIN_ENERGY:			/* M. Stephenson */ 276. #ifdef SPELLS 277. 		{	register int	 num; 278. 			if(Confusion) { 279. 			    pline("You feel feverish."); 280. 			    unkn++; 281. 			} else 282. 			    pline("Magical energies course through your body."); 283. 			num = rnd(5) + 1; 284. 			u.uenmax += num; 285. 			u.uen += num; 286. 			flags.botl = 1; 287. 			break; 288. 		}  289.  #else 290. 		pline("This potion tastes weird!"); 291. 		break; 292. #endif 293. 	default: 294. 		impossible("What a funny potion! (%u)", otmp->otyp); 295. 		return(0); 296. 	}  297.  	return(-1); 298. }  299.   300.  healup(nhp, nxtra, curesick, cureblind) 301. 	int	nhp, nxtra; 302. 	register boolean curesick, cureblind; 303. {  304.  #ifdef KAA 305. 	if (u.mtimedone & nhp) { 306. 		u.mh += rnd(nhp); 307. 		if (u.mh > u.mhmax) u.mh = (u.mhmax + nxtra); 308. 	}  309.  #endif 310. 	if(nhp)	{ 311. 		u.uhp += nhp; 312. 		if(u.uhp > u.uhpmax)	u.uhp = (u.uhpmax += nxtra); 313. 	}  314.  	if(Blind && cureblind)	Blinded = 1;	/* see on next move */ 315. 	if(Sick && curesick)	Sick = 0; 316. 	flags.botl = 1; 317. 	return; 318. }  319.   320.  pluslvl 321. {  322.  	register num; 323.  324.  	pline("You feel more experienced."); 325. 	num = rnd(10); 326. 	u.uhpmax += num; 327. 	u.uhp += num; 328. #ifdef SPELLS 329. 	num = rnd(u.ulevel/2+1) + 1;		/* M. Stephenson */ 330. 	u.uenmax += num; 331. 	u.uen += num; 332. #endif 333. 	if(u.ulevel < 14) { 334. 		extern long newuexp; 335.  336.  		u.uexp = newuexp+1; 337. 		pline("Welcome to experience level %u.", ++u.ulevel); 338. 	}  339.  	flags.botl = 1; 340. }  341.   342.  strange_feeling(obj,txt) 343. register struct obj *obj; 344. register char *txt; 345. {  346.  	if(flags.beginner) 347. 		pline("You have a %s feeling for a moment, then it passes.",  348.  		Hallucination ? "normal" : "strange"); 349. 	else 350. 		pline(txt); 351. 	if(!objects[obj->otyp].oc_name_known && !objects[obj->otyp].oc_uname) 352. 		docall(obj); 353. 	useup(obj); 354. }  355.   356.  char *bottlenames[] = { 357. 	"bottle", "phial", "flagon", "carafe", "flask", "jar", "vial" 358. };  359.   360.  potionhit(mon, obj) 361. register struct monst *mon; 362. register struct obj *obj; 363. {  364.  	extern char *xname; 365. 	register char *botlnam = bottlenames[rn2(SIZE(bottlenames))]; 366. 	boolean uclose, isyou = (mon == &youmonst); 367.  368.  	if(isyou) { 369. 		uclose = TRUE; 370. 		pline("The %s crashes on your head and breaks into shivers.",  371.  			botlnam); 372. 		losehp(rnd(2), "thrown potion"); 373. 	} else { 374. 		uclose = (dist(mon->mx,mon->my) < 3); 375. 		/* perhaps 'E' and 'a' have no head? */ 376.  		pline("The %s crashes on %s's head and breaks into shivers.",  377.  			botlnam, monnam(mon)); 378. 		if(rn2(5) && mon->mhp > 1) 379. 			mon->mhp--; 380. 	}  381.  	pline("The %s evaporates.", xname(obj)); 382.  383.  #ifdef KAA 384. 	if(!isyou) switch (obj->otyp) { 385. #else 386. 	if(!isyou && !rn2(3)) switch(obj->otyp) { 387. #endif 388.  389.  	case POT_RESTORE_STRENGTH: 390. 	case POT_GAIN_STRENGTH: 391. 	case POT_HEALING: 392. 	case POT_EXTRA_HEALING: 393. 		if(mon->mhp < mon->mhpmax) { 394. 			mon->mhp = mon->mhpmax; 395. 			pline("%s looks sound and hale again!", Monnam(mon)); 396. 		}  397.  		break; 398. 	case POT_SICKNESS: 399. 		if((mon->mhpmax > 3) && !resist(mon, '!', 0, NOTELL)) 400. 			mon->mhpmax /= 2; 401. 		if((mon->mhp > 2) && !resist(mon, '!', 0, NOTELL)) 402. 			mon->mhp /= 2; 403. #ifdef KAA 404. 		pline("%s looks rather ill.", Monnam(mon)); 405. #endif 406. 		break; 407. 	case POT_CONFUSION: 408. 	case POT_BOOZE: 409. 		if(!resist(mon, '!', 0, NOTELL))  mon->mconf = 1; 410. 		break; 411. 	case POT_INVISIBILITY: 412. 		unpmon(mon); 413. 		mon->minvis = 1; 414. 		pmon(mon); 415. 		break; 416. 	case POT_PARALYSIS: 417. 		mon->mfroz = 1; 418. 		break; 419. 	case POT_SPEED: 420. 		mon->mspeed = MFAST; 421. 		break; 422. 	case POT_BLINDNESS: 423. 		mon->mblinded |= 64 + rn2(32) + 424. 				      rn2(32) * !resist(mon, '!', 0, NOTELL); 425. 		break; 426. #ifdef KAA 427. 	case POT_HOLY_WATER: 428. 		if (index("ZVW &", mon->data->mlet)) { 429. 			pline("%s shrieks in pain!", Monnam(mon)); 430. 			mon->mhp -= d(2,6); 431. 			if (mon->mhp <1) killed(mon); 432. 		}  433.  		break; 434. #endif 435. /*	  436.  	case POT_GAIN_LEVEL: 437. 	case POT_LEVITATION: 438. 	case POT_FRUIT_JUICE: 439. 	case POT_MONSTER_DETECTION: 440. 	case POT_OBJECT_DETECTION: 441. 		break; 442. */  443.  	}  444.  	if(uclose && rn2(5)) 445. 		potionbreathe(obj); 446. 	obfree(obj, Null(obj)); 447. }  448.   449.  potionbreathe(obj) 450. register struct obj *obj; 451. {  452.  	switch(obj->otyp) { 453. 	case POT_RESTORE_STRENGTH: 454. 	case POT_GAIN_STRENGTH: 455. 		if(u.ustr < u.ustrmax) u.ustr++, flags.botl = 1; 456. 		break; 457. 	case POT_HEALING: 458. 	case POT_EXTRA_HEALING: 459. 		if(u.uhp < u.uhpmax) u.uhp++, flags.botl = 1; 460. 		break; 461. 	case POT_SICKNESS: 462. 		if(u.uhp <= 5) u.uhp = 1; else u.uhp -= 5; 463. 		flags.botl = 1; 464. 		break; 465. 	case POT_HALLUCINATION: 466. #ifdef KAA 467. 		pline("You have a vision for a moment."); 468. 		break; 469. #endif 470. 	case POT_CONFUSION: 471. 	case POT_BOOZE: 472. 		if(!Confusion) 473. 			pline("You feel somewhat dizzy."); 474. 		HConfusion += rnd(5); 475. 		break; 476. 	case POT_INVISIBILITY: 477. 		pline("For an instant you could see through yourself!"); 478. 		break; 479. 	case POT_PARALYSIS: 480. 		pline("Something seems to be holding you."); 481. 		nomul(-rnd(5)); 482. 		break; 483. 	case POT_SPEED: 484. 		Fast += rnd(5); 485. 		pline("Your knees seem more flexible now."); 486. 		break; 487. 	case POT_BLINDNESS: 488. 		if(!Blind) pline("It suddenly gets dark."); 489. 		Blinded += rnd(5); 490. 		seeoff(0); 491. 		break; 492. /*	  493.  	case POT_GAIN_LEVEL: 494. 	case POT_LEVITATION: 495. 	case POT_FRUIT_JUICE: 496. 	case POT_MONSTER_DETECTION: 497. 	case POT_OBJECT_DETECTION: 498. 		break; 499. */  500.  	}  501.  	/* note: no obfree */ 502. }  503.   504.  /*  505.   * -- rudimentary -- to do this correctly requires much more work 506.  * -- all sharp weapons get one or more qualities derived from the potions 507.  * -- texts on scrolls may be (partially) wiped out; do they become blank? 508.  * --   or does their effect change, like under Confusion? 509.  * -- all objects may be made invisible by POT_INVISIBILITY 510.  * -- If the flask is small, can one dip a large object? Does it magically 511.  * --   become a jug? Etc. 512.  */  513.  dodip{ 514. 	register struct obj *potion, *obj; 515. #ifdef KAA 516. 	char *tmp; 517. #endif 518.  519.  	if(!(obj = getobj("#", "dip"))) 520. 		return(0); 521. #ifdef FOUNTAINS 522. 	/* Is there something to dip into here, i.e., a fountain? */ 523.  	if (levl[u.ux][u.uy].typ == FOUNTAIN) { 524. 		pline("Dip it in the fountain? [ny] "); 525. 		if(readchar == 'y') { 526. 			dipfountain(obj); 527. 			return(1); 528. 		}  529.  	}  530.  #endif 531. 	if(!(potion = getobj("!", "dip into"))) 532. 		return(0); 533. #ifndef KAA 534. 	pline("Interesting..."); 535. #else 536. 	if(potion->otyp == POT_HOLY_WATER) { 537. 		if (obj->cursed) { 538. 			obj->cursed=0; 539. 			pline("Your %s %s.", aobjnam(obj,"softly glow"),  540.  			Hallucination ? hcolor : "amber"); 541. 	poof:	useup(potion); 542. 			return(1); 543. 		} else if(obj->otyp >= ARROW && obj->otyp <= SPEAR) { 544. 			obj->dknown=1; 545. 			tmp = Hallucination ? hcolor : "light blue"; 546. 	/* dknown for weapons is meaningless, so it's free to be reused. */ 547.  			pline("Your %s with a%s %s aura.", aobjnam(obj,"softly glow"),  548.  			index("aeiou",*tmp) ? "n" : "", tmp); 549. 			goto poof; 550. 		}  551.  	}  552.  #endif 553. 	if(obj->otyp == ARROW || obj->otyp == DART ||  554.  	   obj->otyp == CROSSBOW_BOLT || obj->otyp == SHURIKEN) { 555. 		if(potion->otyp == POT_SICKNESS) { 556. 			char buf[BUFSZ]; 557. 			useup(potion); 558. 			if(obj->spe < 7) obj->spe++;	/* %% */ 559. 			sprintf(buf, xname(potion)); 560. 			pline("The %s forms a coating on the %s.",  561.  				buf, xname(obj)); 562. 		}  563.  	}  564.  #ifdef HARD 565. 	else	if (!rn2(4)) useup(potion); 566. #endif 567. #ifdef KAA 568. 	pline("Interesting..."); 569. #endif 570. 	return(1); 571. }  572.   573.  ghost_from_bottle{ 574. 	extern struct permonst pm_ghost; 575. 	register struct monst *mtmp; 576.  577.  	if(!(mtmp = makemon(PM_GHOST,u.ux,u.uy))){ 578. 		pline("This bottle turns out to be empty."); 579. 		return; 580. 	}  581.  	mnexto(mtmp); 582. 	pline("As you open the bottle, an enormous ghost emerges!"); 583. 	pline("You are frightened to death, and unable to move."); 584. 	nomul(-3); 585. }  586.   587.  gainstr(inc) 588. register int	inc; 589. {  590.  	if (inc) u.ustr++; 591. 	else { 592. 	         if (u.ustr < 18) u.ustr += (rn2(4) ? 1 : rnd(6) ); 593. 		 else if (u.ustr < 103) u.ustr += rnd(10); 594. 		 else u.ustr++; 595. 	       }  596.   597.  	if(u.ustr > 118)	u.ustr = 118; 598. 	if(u.ustr > u.ustrmax)	u.ustrmax = u.ustr; 599. 	flags.botl = 1; 600. }