Source:NetHack 1.3d/apply.c

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

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

1.   /*	SCCS Id: @(#)apply.c	1.3	87/07/14 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* apply.c - version 1.0.3 */ 4.    5.    #include	"hack.h"  6.    #include	"edog.h"  7.    #include	"mkroom.h"  8.    static struct monst *bchit; 9.   extern struct obj *addinv; 10.  extern struct trap *maketrap; 11.  extern int (*occupation); 12.  extern char *occtxt; 13.  extern char quitchars[]; 14.  extern char pl_character[]; 15.   16.   #ifdef KAA 17.  extern boolean unweapon; 18.  #endif 19.  static use_camera, use_ice_box, use_whistle; 20.  static use_magic_whistle, use_pick_axe; 21.  #ifdef MARKER 22.  extern int dowrite; 23.  #endif 24.   25.   doapply { 26.  	register struct obj *obj; 27.  	register int res = 1; 28.   29.   	obj = getobj("(", "use or apply");  30.   	if(!obj) return(0);  31.    32.   	switch(obj->otyp){  33.   	case EXPENSIVE_CAMERA:  34.   		use_camera(obj); break;  35.   	case ICE_BOX:  36.   		use_ice_box(obj); break;  37.   	case PICK_AXE:  38.   		res = use_pick_axe(obj);  39.   		break;  40.    41.   	case MAGIC_WHISTLE:  42.   		if(pl_character[0] == 'W' || u.ulevel > 9) {  43.   			use_magic_whistle(obj);  44.   			break;  45.   		}  46.   		/* fall into next case */  47.   	case WHISTLE:  48.   		use_whistle(obj);  49.   		break;  50.   #ifdef WALKIES  51.   	case LEASH:  52.   		use_leash(obj);  53.   		break;  54.   #endif  55.   #ifdef MARKER  56.   	case MAGIC_MARKER:  57.   		dowrite(obj);  58.   		break;  59.   #endif  60.   	case CAN_OPENER:  61.   		if(!carrying(TIN)) {  62.   			pline("You have no can to open.");  63.   			goto xit;  64.   		}  65.   		pline("You cannot open a tin without eating its contents."); 66.  		pline("In order to eat, use the 'e' command."); 67.  		if(obj != uwep) 68.      pline("Opening the tin will be much easier if you wield the can-opener."); 69.  		goto xit; 70.   71.   #ifdef KAA 72.  	case STETHOSCOPE: 73.  		res = use_stethoscope(obj); 74.  		break; 75.  #endif 76.  	default: 77.  		pline("Sorry, I don't know how to use that."); 78.  	xit: 79.  		nomul(0); 80.  		return(0); 81.  	}  82.   	nomul(0); 83.  	return(res); 84.  }  85.    86.   /* ARGSUSED */ 87.  static 88.  use_camera(obj) /* register */ struct obj *obj; { 89.  register struct monst *mtmp; 90.  	if(!getdir(1)){		/* ask: in what direction? */ 91.   		flags.move = multi = 0; 92.  		return; 93.  	}  94.   	if(u.uswallow) { 95.  		pline("You take a picture of %s's stomach.", monnam(u.ustuck)); 96.  		return; 97.  	}  98.   	if(u.dz) { 99.  		pline("You take a picture of the %s.",  100.  			(u.dz > 0) ? "floor" : "ceiling"); 101. 		return; 102. 	}  103.  #ifdef KAA 104. 	if(!u.dx && !u.dy && !u.dz) { 105. 		if(!Blind) { 106. 			pline("You are blinded by the flash!"); 107. 			Blind += rnd(25); 108. 			seeoff(0); 109. 		}  110.  		return; 111. 	}  112.  #endif 113. 	if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) { 114. 		if(mtmp->msleep){ 115. 			mtmp->msleep = 0; 116. 			pline("The flash awakens %s.", monnam(mtmp)); /* a3 */ 117. 		} else 118. 		if(mtmp->data->mlet != 'y') 119. 		if(mtmp->mcansee || mtmp->mblinded){ 120. 			register int tmp = dist(mtmp->mx,mtmp->my); 121. 			register int tmp2; 122. 			if(cansee(mtmp->mx,mtmp->my)) 123. 			  pline("%s is blinded by the flash!", Monnam(mtmp)); 124. 			setmangry(mtmp); 125. 			if(tmp < 9 && !mtmp->isshk && rn2(4)) { 126. 				mtmp->mflee = 1; 127. 				if(rn2(4)) mtmp->mfleetim = rnd(100); 128. 			}  129.  			if(tmp < 3) mtmp->mcansee  = mtmp->mblinded = 0; 130. 			else { 131. 				tmp2 = mtmp->mblinded; 132. 				tmp2 += rnd(1 + 50/tmp); 133. 				if(tmp2 > 127) tmp2 = 127; 134. 				mtmp->mblinded = tmp2; 135. 				mtmp->mcansee = 0; 136. 			}  137.  		}  138.  	}  139.  }  140.   141.  #ifdef KAA 142. /* Strictly speaking it makes no sense for usage of a stethoscope to  143. not take any time; however, unless it did, the stethoscope would be 144. almost useless. */ 145.  static use_stethoscope(obj) register struct obj *obj; { 146. register struct monst *mtmp; 147. register struct rm *lev; 148. register int rx, ry; 149. 	if(!freehand) { 150. 		pline("You have no free hand!"); 151. 		return(1); 152. 	}  153.  	if (!getdir(1)) { 154. 		flags.move=multi=0; 155. 		return(0); 156. 	}  157.  	if(u.dz < 0 || (u.dz && Levitation)) { 158. 		pline("You can't reach the %s!", u.dz<0 ? "ceiling" : "floor"); 159. 		return(1); 160. 	}  161.  	if(u.dz) { 162. 		pline("The floor seems healthy enough."); 163. 		return(0); 164. 	}  165.  	if (Confusion) confdir; 166. 	rx = u.ux + u.dx; ry = u.uy + u.dy; 167. 	if(u.uswallow) { 168. 		mstatusline(u.ustuck); 169. 		return(0); 170. 	}  171.  	if(mtmp=m_at(rx,ry)) { 172. 		mstatusline(mtmp); 173. 		return(0); 174. 	}  175.  	if (!isok(rx,ry)) { 176. 		pline("You hear the sounds at the end of the universe."); 177. 		return(0); 178. 	}  179.  	lev = &levl[rx][ry]; 180. 	if(lev->typ == SDOOR) { 181. 		pline("You hear a hollow sound!  This must be a secret door!"); 182. 		lev->typ = DOOR; 183. #ifdef DGK 184. 		atl(rx, ry, symbol.door); 185. #else 186. 		atl(rx, ry, DOOR_SYM); 187. #endif 188. 		return(0); 189. 	}  190.  	if(lev->typ == SCORR) { 191. 		pline("You hear a hollow sound!  This must be a secret passage!"); 192. 		lev->typ = CORR; 193. 		atl(rx, ry, CORR_SYM); 194. 		return(0); 195. 	}  196.  	pline("You hear nothing special."); 197. 	return(0); 198. }  199.  #endif 200. 	  201.  static 202. struct obj *current_ice_box;	/* a local variable of use_ice_box, to be  203. used by its local procedures in/ck_ice_box */ 204. static 205. in_ice_box(obj) register struct obj *obj; { 206. 	if(obj == current_ice_box ||  207.  		(Punished && (obj == uball || obj == uchain))){ 208. 		pline("You must be kidding."); 209. 		return(0); 210. 	}  211.  	if(obj->owornmask & (W_ARMOR | W_RING)) { 212. 		pline("You cannot refrigerate something you are wearing."); 213. 		return(0); 214. 	}  215.  	if(obj->owt + current_ice_box->owt > 70) { 216. 		pline("It won't fit."); 217. 		return(1);	/* be careful! */ 218.  	}  219.  	if(obj == uwep) { 220. 		if(uwep->cursed) { 221. 			pline("Your weapon is welded to your hand!"); 222. 			return(0); 223. 		}  224.  		setuwep((struct obj *) 0); 225. 	}  226.  	current_ice_box->owt += obj->owt; 227. 	freeinv(obj); 228. 	obj->o_cnt_id = current_ice_box->o_id; 229. 	obj->nobj = fcobj; 230. 	fcobj = obj; 231. 	obj->age = moves - obj->age;	/* actual age */ 232. 	return(1); 233. }  234.   235.  static 236. ck_ice_box(obj) register struct obj *obj; { 237. 	return(obj->o_cnt_id == current_ice_box->o_id); 238. }  239.   240.  static 241. out_ice_box(obj) register struct obj *obj; { 242. register struct obj *otmp; 243. 	if(obj == fcobj) fcobj = fcobj->nobj; 244. 	else { 245. 		for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj) 246. 			if(!otmp->nobj) panic("out_ice_box"); 247. 		otmp->nobj = obj->nobj; 248. 	}  249.  	current_ice_box->owt -= obj->owt; 250. 	obj->age = moves - obj->age;	/* simulated point of time */ 251. 	(void) addinv(obj); 252. }  253.   254.  static 255. use_ice_box(obj) register struct obj *obj; { 256. register int cnt = 0; 257. register struct obj *otmp; 258. 	current_ice_box = obj;	/* for use by in/out_ice_box */ 259. 	for(otmp = fcobj; otmp; otmp = otmp->nobj) 260. 		if(otmp->o_cnt_id == obj->o_id) 261. 			cnt++; 262. 	if(!cnt) pline("Your ice-box is empty."); 263. 	else { 264. 	    pline("Do you want to take something out of the ice-box? [yn] "); 265. 	    if(readchar == 'y') 266. 		if(askchain(fcobj, (char *) 0, 0, out_ice_box, ck_ice_box, 0)) 267. 		    return; 268. 		pline("That was all. Do you wish to put something in? [yn] "); 269. 		if(readchar != 'y') return; 270. 	}  271.  	/* call getobj: 0: allow cnt; #: allow all types; %: expect food */ 272. 	otmp = getobj("0#%", "put in"); 273. 	if(!otmp || !in_ice_box(otmp)) 274. 		flags.move = multi = 0; 275. }  276.   277.  static 278. struct monst * 279. bchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; { 280. 	register struct monst *mtmp = (struct monst *) 0; 281. 	register int bchx = u.ux, bchy = u.uy; 282.  283.  	if(sym) Tmp_at(-1, sym);	/* open call */ 284. 	while(range--) { 285. 		bchx += ddx; 286. 		bchy += ddy; 287. 		if(mtmp = m_at(bchx,bchy)) 288. 			break; 289. 		if(!ZAP_POS(levl[bchx][bchy].typ)) { 290. 			bchx -= ddx; 291. 			bchy -= ddy; 292. 			break; 293. 		}  294.  		if(sym) Tmp_at(bchx, bchy); 295. 	}  296.  	if(sym) Tmp_at(-1, -1); 297. 	return(mtmp); 298. }  299.   300.  /* ARGSUSED */ 301. static 302. use_whistle(obj) struct obj *obj; { 303. register struct monst *mtmp = fmon; 304. 	pline("You produce a high whistling sound."); 305. 	while(mtmp) { 306. 		if(dist(mtmp->mx,mtmp->my) < u.ulevel*20) { 307. 			if(mtmp->msleep) 308. 				mtmp->msleep = 0; 309. 			if(mtmp->mtame) 310. 				EDOG(mtmp)->whistletime = moves; 311. 		}  312.  		mtmp = mtmp->nmon; 313. 	}  314.  }  315.   316.  /* ARGSUSED */ 317. static 318. use_magic_whistle(obj) struct obj *obj; { 319. register struct monst *mtmp = fmon; 320. 	pline("You produce a strange whistling sound."); 321. 	while(mtmp) { 322. 		if(mtmp->mtame) mnexto(mtmp); 323. 		mtmp = mtmp->nmon; 324. 	}  325.  }  326.   327.  #ifdef WALKIES 328. /* ARGSUSED */ 329. static 330. use_leash(obj) struct obj *obj; { 331. register struct monst *mtmp = fmon; 332.  333.  	while(mtmp && !mtmp->mleashed) mtmp = mtmp->nmon; 334.  335.  	if(mtmp) { 336.  337.  		if (next_to(mtmp))  { 338.  339.  			mtmp->mleashed = 0; 340. 			pline("You remove the leash from your %s.",  341.  				 mtmp->data->mname); 342. 		} else	pline("You must be next to your %s to unleash him.",  343.  				 mtmp->data->mname); 344. 	} else { 345.  346.  	    for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 347.  348.  		if(mtmp->mtame && next_to(mtmp)) { 349.  350.  			pline("You slip the leash around your %s.", mtmp->data->mname); 351. 			mtmp->mleashed = 1; 352. 			if(mtmp->msleep)  mtmp->msleep = 0; 353. 			return(0); 354. 		}  355.  	    }  356.  	    pline("There's nothing here to put a leash on."); 357. 	}  358.  	return(0); 359. }  360.   361.  next_to(mtmp) register struct monst *mtmp; { 362.  363.  	return((abs(u.ux - mtmp->mx) <= 1) && (abs(u.uy - mtmp->my) <= 1)); 364. }  365.  #endif 366.  367.  static int dig_effort;	/* effort expended on current pos */ 368. static uchar dig_level; 369. static coord dig_pos; 370. static boolean dig_down; 371.  372.  static 373. dig { 374. 	register struct rm *lev; 375. 	register dpx = dig_pos.x, dpy = dig_pos.y;  376. 377. 	/* perhaps a nymph stole his pick-axe while he was busy digging */ 378. 	/* or perhaps he teleported away */ 379. 	if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||  380.  	    dig_level != dlevel ||  381.  	    ((dig_down && (dpx != u.ux || dpy != u.uy)) || 382. 	     (!dig_down && dist(dpx,dpy) > 2))) 383. 		return(0); 384.  385.  	dig_effort += 10 + abon + uwep->spe + rn2(5); 386. 	if(dig_down) { 387. 		if(!xdnstair) { 388. 			pline("The floor here seems too hard to dig in."); 389. 			return(0); 390. 		}  391.  		if(dig_effort > 250) { 392. 			dighole; 393. 			return(0);	/* done with digging */ 394. 		}  395.  		if(dig_effort > 50) { 396. 			register struct trap *ttmp = t_at(dpx,dpy); 397.  398.  			if(!ttmp) { 399. 				ttmp = maketrap(dpx,dpy,PIT); 400. 				ttmp->tseen = 1; 401. 				pline("You have dug a pit."); 402. 				u.utrap = rn1(4,2); 403. 				u.utraptype = TT_PIT; 404. 				return(0); 405. 			}  406.  		}  407.  	} else 408. 	if(dig_effort > 100) { 409. 		register char *digtxt; 410. 		register struct obj *obj; 411.  412.  		lev = &levl[dpx][dpy]; 413. 		if(obj = sobj_at(ENORMOUS_ROCK, dpx, dpy)) { 414. 			fracture_rock(obj); 415. 			digtxt = "The rock falls apart."; 416. 		} else if(!lev->typ || lev->typ == SCORR) { 417. 			lev->typ = CORR; 418. 			digtxt = "You succeeded in cutting away some rock."; 419. 		} else if(lev->typ == HWALL || lev->typ == VWALL  420.  					    || lev->typ == SDOOR) { 421. 			lev->typ = xdnstair ? DOOR : ROOM; 422. 			digtxt = "You just made an opening in the wall."; 423. 		} else 424. 		  digtxt = "Now what exactly was it that you were digging in?"; 425. 		mnewsym(dpx, dpy); 426. 		prl(dpx, dpy); 427. 		pline(digtxt);		/* after mnewsym & prl */ 428. 		return(0); 429. 	} else { 430. 		if(IS_WALL(levl[dpx][dpy].typ)) { 431. 			register int rno = inroom(dpx,dpy); 432.  433.  			if(rno >= 0 && rooms[rno].rtype >= 8) { 434. 			  pline("This wall seems too hard to dig into."); 435. 			  return(0); 436. 			}  437.  		}  438.  		pline("You hit the rock with all your might."); 439. 	}  440.  	return(1); 441. }  442.   443.  /* When will hole be finished? Very rough indication used by shopkeeper. */ 444.  holetime { 445. 	return( (occupation == dig) ? (250 - dig_effort)/20 : -1); 446. }  447.   448.  dighole 449. {  450.  	register struct trap *ttmp = t_at(u.ux, u.uy); 451.  452.  	if(!xdnstair) { 453. 		pline("The floor here seems too hard to dig in."); 454. 	} else { 455. 		if(ttmp) 456. 			ttmp->ttyp = TRAPDOOR; 457. 		else 458. 			ttmp = maketrap(u.ux, u.uy, TRAPDOOR); 459. 		ttmp->tseen = 1; 460. 		pline("You've made a hole in the floor."); 461. 		if(!u.ustuck && !Levitation) {			/* KAA */ 462. 			if(inshop) 463. 				shopdig(1); 464. 			pline("You fall through ..."); 465. 			if(u.utraptype == TT_PIT) { 466. 				u.utrap = 0; 467. 				u.utraptype = 0; 468. 			}  469.  			goto_level(dlevel+1, FALSE); 470. 		}  471.  	}  472.  }  473.   474.  static 475. use_pick_axe(obj) 476. struct obj *obj; 477. {  478.  	char dirsyms[12]; 479. 	extern char sdir[]; 480. 	register char *dsp = dirsyms, *sdp = sdir; 481. 	register struct monst *mtmp; 482. 	register struct rm *lev; 483. 	register int rx, ry, res = 0; 484.  485.  #ifndef FREEHAND 486. 	/* edited by GAN 10/20/86 so that you can't apply the 487. 	 * pick-axe while wielding a cursed weapon 488. 	 */  489.  	if(!freehand)  { 490. 		pline("You have no free hand to dig with!"); 491. 		return(0); 492. 	}  493.  # ifdef KAA 494. 	if(cantwield(u.usym)) { 495. 		pline("You can't hold it strongly enough."); 496. 		return(0); 497. 	}  498.  # endif 499. #else 500. 	if(obj != uwep) { 501. 		if(uwep && uwep->cursed) { 502. 			/* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */ 503. 			pline("Since your weapon is welded to your hand,"); 504. 			pline("you cannot use that pick-axe."); 505. 			return(0); 506. 		}  507.  # ifdef KAA 508. 		if(cantwield(u.usym)) { 509. 			pline("You can't hold it strongly enough."); 510. 			return(0); 511. 		}  512.  		unweapon = TRUE; 513. # endif 514. 		pline("You now wield %s.", doname(obj)); 515. 		setuwep(obj); 516. 		res = 1; 517. 	}  518.  #endif 519. 	while(*sdp) { 520. 		(void) movecmd(*sdp);	/* sets u.dx and u.dy and u.dz */ 521. 		rx = u.ux + u.dx; 522. 		ry = u.uy + u.dy; 523. 		if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) && 524. 		    (IS_ROCK(levl[rx][ry].typ)  525.  		    || sobj_at(ENORMOUS_ROCK, rx, ry)))) 526. 			*dsp++ = *sdp; 527. 		sdp++; 528. 	}  529.  	*dsp = 0; 530. 	pline("In what direction do you want to dig? [%s] ", dirsyms); 531. 	if(!getdir(0))		/* no txt */ 532. 		return(res); 533. 	if(u.uswallow && attack(u.ustuck)) /* return(1) */; 534. 	else 535. 	if(u.dz < 0) 536. 		pline("You cannot reach the ceiling."); 537. 	else 538. #ifdef KAA 539. 	if(!u.dx && !u.dy && !u.dz) { 540. 		pline("You hit yourself with your own pick-axe."); 541. 		losehp(rnd(2)+dbon, "self-inflicted wound"); 542. 		flags.botl=1; 543. 		return(1); 544. 	}  545.  #endif 546. 	if(u.dz == 0) { 547. 		if(Confusion) 548. 			confdir; 549. 		rx = u.ux + u.dx; 550. 		ry = u.uy + u.dy; 551. 		if((mtmp = m_at(rx, ry)) && attack(mtmp)) 552. 			return(1); 553. 		if(!isok(rx, ry)) { 554. 			pline("Clash!"); 555. 			return(1); 556. 		}  557.  		lev = &levl[rx][ry]; 558. 		if(lev->typ == DOOR) 559. 			pline("Your %s against the door.",  560.  				aobjnam(obj, "clang")); 561. 		else if(!IS_ROCK(lev->typ)  562.  		     && !sobj_at(ENORMOUS_ROCK, rx, ry)) { 563. 			/* ACCESSIBLE or POOL */ 564. 			pline("You swing your %s through thin air.",  565.  				aobjnam(obj, (char *) 0)); 566. 		} else { 567. 			if(dig_pos.x != rx || dig_pos.y != ry  568.  			    || dig_level != dlevel || dig_down) { 569. 				dig_down = FALSE; 570. 				dig_pos.x = rx; 571. 				dig_pos.y = ry; 572. 				dig_level = dlevel; 573. 				dig_effort = 0; 574. 				pline("You start digging."); 575. 			} else 576. 				pline("You continue digging."); 577. #ifdef DGKMOD 578. 			set_occupation(dig, "digging", 0); 579. #else 580. 			occupation = dig; 581. 			occtxt = "digging"; 582. #endif 583. 		}  584.  	} else if(Levitation) { 585. 		pline("You cannot reach the floor."); 586. 	} else { 587. 		if(dig_pos.x != u.ux || dig_pos.y != u.uy  588.  		    || dig_level != dlevel || !dig_down) { 589. 			dig_down = TRUE; 590. 			dig_pos.x = u.ux; 591. 			dig_pos.y = u.uy; 592. 			dig_level = dlevel; 593. 			dig_effort = 0; 594. 			pline("You start digging in the floor."); 595. 			if(inshop) 596. 				shopdig(0); 597. 		} else 598. 			pline("You continue digging in the floor."); 599. #ifdef DGKMOD 600. 		set_occupation(dig, "digging", 0); 601. #else 602. 		occupation = dig; 603. 		occtxt = "digging"; 604. #endif 605. 	}  606.  	return(1); 607. }