Source:NetHack 1.3d/potion.c

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