Source:NetHack 3.0.0/do.c

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

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

1.   /*	SCCS Id: @(#)do.c	3.0	89/06/12 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) */ 6.    7.    #include "hack.h"  8. 9.   #if defined(DGK) && !defined(TOS) 10.  extern struct finfo fileinfo[]; 11.  #else 12.  extern boolean level_exists[]; 13.  #endif 14.   15.   static int drop P((struct obj *)); 16.   17.   static const char drop_types[] = { '0', GOLD_SYM, '#', 0 }; 18.   19.   int 20.  dodrop { 21.  	return(drop(getobj(drop_types, "drop"))); 22.  }  23.    24.   /* Used for objects which sometimes do special things when dropped; must be  25. * called with the object not in any chain. Returns 1 if the object is 26. * gone. 27.   */  28.   boolean 29.  flooreffects(obj,x,y) 30.  struct obj *obj; 31.  int x,y; 32.  {  33.   	if(obj->otyp == BOULDER && IS_POOL(levl[x][y].typ)) { 34.  #ifdef STRONGHOLD 35.  	    if(levl[x][y].typ == DRAWBRIDGE_UP) 36.  		levl[x][y].drawbridgemask |= DB_FLOOR; 37.  	    else 38.  #endif 39.  		levl[x][y].typ = ROOM; 40.  	    if (cansee(x,y)) 41.  		pline("There is a large splash as the boulder fills the %s.",  42.   			(levl[x][y].typ==POOL) ? "pool" : "moat"); 43.  	    else if (flags.soundok) 44.  		You("hear a splash."); 45.  	    obfree(obj, (struct obj *)0); 46.  	    mnewsym(x,y); 47.  	    if ((x != u.ux || y != u.uy || Invisible) && !Blind) 48.  		newsym(x,y); 49.  	    return TRUE; 50.  	}  51.   	return FALSE; 52.  }  53.    54.   #ifdef ALTARS 55.  void 56.  doaltarobj(obj)  /* obj is an object dropped on an altar */ 57.  	register struct obj *obj; 58.  {  59.   	if (Blind) return; 60.  	if (obj->blessed || obj->cursed) { 61.  		register const char *fcolor = Hallucination ? hcolor : 62.  					obj->blessed ? amber : black; 63.   64.   		pline("There is %s %s flash as %s hit%s the altar.",  65.   		      index(vowels, *fcolor) ? "an" : "a",  66.   		      fcolor,  67.   		      doname(obj),  68.   		      (obj->quan==1) ? "s" : ""); 69.  		if (!Hallucination) obj->bknown = 1; 70.  	} else { 71.  		pline("%s land%s on the altar.", Doname2(obj),  72.   			(obj->quan==1) ? "s" : ""); 73.  		obj->bknown = 1; 74.  	}  75.   }  76.   #endif 77.   78.   #ifdef SINKS 79.  static 80.  void 81.  trycall(obj) 82.  register struct obj *obj; 83.  {  84.   	if(!objects[obj->otyp].oc_name_known &&  85.   	   !objects[obj->otyp].oc_uname) 86.  	   docall(obj); 87.  }  88.    89.   static 90.  void 91.  dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */ 92.  register struct obj *obj; 93.  {  94.   	register struct obj *otmp,*otmp2; 95.  	register boolean ideed = TRUE; 96.   97.   	You("drop %s down the drain.", doname(obj)); 98.  	switch(obj->otyp) {	/* effects that can be noticed without eyes */ 99.  	    case RIN_SEARCHING: 100. 	You("thought your %s got lost in the sink, but there it is!",  101.  			xname(obj)); 102. 		dropx(obj); 103. 		trycall(obj); 104. 		return; 105. 	    case RIN_LEVITATION: 106. 		pline("The sink quivers upward for a moment."); 107. 		break; 108. 	    case RIN_POISON_RESISTANCE: 109. 		You("smell rotten %s.", makeplural(pl_fruit)); 110. 		break; 111. 	    case RIN_AGGRAVATE_MONSTER: 112. 		pline("Several flies buzz angrily around the sink."); 113. 		break; 114. 	    case RIN_SHOCK_RESISTANCE: 115. 		pline("Static electricity surrounds the sink."); 116. 		break; 117. 	    case RIN_CONFLICT: 118. 		You("hear loud noises coming from the drain."); 119. 		break; 120. 	    case RIN_GAIN_STRENGTH: 121. 		pline("The water flow seems %ser now.",  122.  			(obj->spe<0) ? "weak" : "strong"); 123. 		break; 124. 	    case RIN_INCREASE_DAMAGE: 125. 		pline("The water's force seems %ser now.",  126.  			(obj->spe<0) ? "small" : "great"); 127. 		break; 128. 	    default: 129. 		ideed = FALSE; 130. 		break; 131. 	}  132.  	if(!Blind && !ideed) { 133. 	    ideed = TRUE; 134. 	    switch(obj->otyp) {		/* effects that need eyes */ 135. 		case RIN_ADORNMENT: 136. 		    pline("The faucets flash brightly for a moment."); 137. 		    break; 138. 		case RIN_REGENERATION: 139. 		    pline("The sink looks as good as new."); 140. 		    break; 141. 		case RIN_INVISIBILITY: 142. 		    You("don't see anything happen to the sink."); 143. 		    break; 144. 		case RIN_SEE_INVISIBLE: 145. 		    You("see some air in the sink."); 146. 		    break; 147. 		case RIN_STEALTH: 148. 		pline("The sink seems to blend into the floor for a moment."); 149. 		    break; 150. 		case RIN_HUNGER: 151. 		    ideed = FALSE; 152. 		    for(otmp=fobj; otmp; otmp=otmp2) { 153. 			otmp2 = otmp->nobj; 154. 			if(otmp->ox == u.ux && otmp->oy == u.uy) 155. 			    if(otmp != uball && otmp != uchain) { 156. 				pline("Suddenly, %s vanishes from the sink!",  157.  							    doname(otmp)); 158. 			    delobj(otmp); 159. 			    ideed = TRUE; 160. 			}  161.  		    }  162.  		    break; 163. 		case RIN_FIRE_RESISTANCE: 164. 		pline("The hot water faucet flashes brightly for a moment."); 165. 		    break; 166. 		case RIN_COLD_RESISTANCE: 167. 		pline("The cold water faucet flashes brightly for a moment."); 168. 		    break; 169. 		case RIN_PROTECTION_FROM_SHAPE_CHAN: 170. 		    pline("The sink looks nothing like a fountain."); 171. 		    break; 172. 		case RIN_PROTECTION: 173. 		    pline("The sink glows %s for a moment.",  174.  			    Hallucination ? hcolor :  175.  			    (obj->spe<0) ? black : silver); 176. 		    break; 177. 		case RIN_WARNING: 178. 		    pline("The sink glows %s for a moment.",  179.  			    Hallucination ? hcolor : white); 180. 		    break; 181. 		case RIN_TELEPORTATION: 182. 		    pline("The sink momentarily vanishes."); 183. 		    break; 184. 		case RIN_TELEPORT_CONTROL: 185. 	    pline("The sink looks like it is being beamed aboard somewhere."); 186. 		    break; 187. #ifdef POLYSELF 188. 		case RIN_POLYMORPH: 189. 		    pline("The sink momentarily looks like a fountain."); 190. 		    break; 191. 		case RIN_POLYMORPH_CONTROL: 192. 	pline("The sink momentarily looks like a regularly erupting geyser."); 193. 		    break; 194. #endif 195. 	    }  196.  	}  197.  	if(ideed) 198. 	    trycall(obj); 199. 	else 200. 	    You("hear the ring bouncing down the drainpipe."); 201. 	if (!rn2(20)) { 202. 		pline("The sink backs up, leaving %s.", doname(obj)); 203. 		dropx(obj); 204. 	}  205.  	else 206. 		useup(obj); 207. }  208.  #endif 209.  210.  /* some common tests when trying to drop or throw items */ 211. boolean 212. canletgo(obj,word) 213. register struct obj *obj; 214. register char *word; 215. {  216.  	if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){ 217. 		You("cannot %s something you are wearing.",word); 218. 		return(FALSE); 219. 	}  220.  	if (obj->otyp == LOADSTONE && obj->cursed) { 221. 		obj->bknown = 1; 222. 		pline("For some reason, you cannot %s the stone%s!",  223.  			word,  224.  			obj->quan==1 ? "" : "s"); 225. 		return(FALSE); 226. 	}  227.  #ifdef WALKIES 228. 	if (obj->otyp == LEASH && obj->leashmon != 0) { 229. 		pline ("The leash is tied around your %s.",  230.  			body_part(HAND)); 231. 		return(FALSE); 232. 	}  233.  #endif 234. 	return(TRUE); 235. }  236.   237.  static int 238. drop(obj) register struct obj *obj; { 239. 	if(!obj) return(0); 240. 	if(obj->olet == GOLD_SYM) {		/* pseudo object */ 241. 		register long amount = OGOLD(obj); 242.  243.  /* Fix bug with dropping huge amounts of gold read as negative    KAA */ 244. 		if(amount < 0) { 245. 			u.ugold += amount; 246. 	pline("The LRS would be very interested to know you have that much."); 247. 		} else { 248. 			/* uswallow test added by GAN 01/29/87 */ 249. 			if(flags.verbose) 250. 			    You("drop %ld gold piece%s.",  251.  				   amount, plur(amount)); 252. 			if(u.uswallow) 253. 				(u.ustuck)->mgold += amount; 254. 			else { 255. 				mkgold(amount, u.ux, u.uy); 256. 				if(Invisible) newsym(u.ux, u.uy); 257. 			}  258.  		}  259.  		free((genericptr_t) obj); 260. 		return(1); 261. 	}  262.  	if(!canletgo(obj,"drop")) 263. 		return(0); 264. 	if(obj == uwep) { 265. 		if(welded(uwep)) { 266. 			weldmsg(obj, FALSE); 267. 			return(0); 268. 		}  269.  		setuwep((struct obj *)0); 270. 		if(uwep) return 0; /* lifesaved and rewielded */ 271. 	}  272.  #ifdef SINKS 273. 	if((obj->olet == RING_SYM) && IS_SINK(levl[u.ux][u.uy].typ)  274.  							&& !u.uswallow) { 275. 		dosinkring(obj); 276. 		return(1); 277. 	}  278.  #endif 279. #ifdef ALTARS 280. 	if (IS_ALTAR(levl[u.ux][u.uy].typ) && !u.uswallow) { 281. 		/* turn water into [(un)holy] water */ 282. 		if (obj->otyp == POT_WATER) { 283. 			obj->blessed = !!(levl[u.ux][u.uy].altarmask & A_LAW); 284. 			obj->cursed = !!(levl[u.ux][u.uy].altarmask & A_CHAOS); 285. 		}  286.  		doaltarobj(obj);	/* set bknown */ 287. 	} else 288. #endif 289. 	if(flags.verbose) You("drop %s.", doname(obj)); 290. 	dropx(obj); 291. 	return(1); 292. }  293.   294.  /* Called in several places - should not produce texts */ 295. void 296. dropx(obj) 297. register struct obj *obj; 298. {  299.  	freeinv(obj); 300. 	dropy(obj); 301. }  302.   303.  void 304. dropy(obj) 305. register struct obj *obj; 306. {  307.  	if (flooreffects(obj,u.ux,u.uy)) return; 308. #ifdef WORM 309. 	if(obj->otyp == CRYSKNIFE) 310. 		obj->otyp = WORM_TOOTH; 311. #endif 312. 	/* uswallow check done by GAN 01/29/87 */ 313. 	if(u.uswallow) 314. 		mpickobj(u.ustuck,obj); 315. 	else  { 316. 		obj->ox = u.ux; 317. 		obj->oy = u.uy; 318. 		obj->nobj = fobj; 319. 		fobj = obj; 320. 		levl[u.ux][u.uy].omask = 1; 321. 		if(Invisible) newsym(u.ux,u.uy); 322. 		subfrombill(obj); 323. 		stackobj(obj); 324. 	}  325.  }  326.   327.  /* drop several things */ 328. int 329. doddrop { 330. 	return(ggetobj("drop", drop, 0)); 331. }  332.   333.  #ifdef STRONGHOLD 334. static boolean at_ladder = FALSE;	/* on a ladder, used in goto_level */ 335. #endif 336.  337.  int 338. dodown 339. {  340.  	struct trap *trap = 0; 341. #ifdef STRONGHOLD 342. 	if((u.ux != xdnstair || u.uy != ydnstair) &&  343.  	   (!xdnladder || u.ux != xdnladder || u.uy != ydnladder)) { 344. #else 345. 	if(u.ux != xdnstair || u.uy != ydnstair) { 346. #endif /* STRONGHOLD /**/ 347. 		if (!(trap = t_at(u.ux,u.uy)) || trap->ttyp != TRAPDOOR  348.  							|| !trap->tseen) { 349. 			You("can't go down here."); 350. 			return(0); 351. 		}  352.  	}  353.  	if(u.ustuck) { 354. 		You("are being held, and cannot go down."); 355. 		return(1); 356. 	}  357.  	if(Levitation) { 358. #ifdef STRONGHOLD 359. 		pline("You're floating high above the %s.",  360.  		      levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder"); 361. #else 362. 		pline("You're floating high above the stairs."); 363. #endif /* STRONGHOLD /**/ 364. 		return(0); 365. 	}  366.   367.  #ifdef WALKIES 368. 	if(!next_to_u) { 369. 		You("are held back by your pet!"); 370. 		return(0); 371. 	} else { 372. #endif 373. 		unsee; 374. #ifdef STRONGHOLD 375. 		if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE; 376. #endif 377. 		if (trap) 378. 			pline("You jump into the trapdoor..."); 379. 		goto_level(dlevel+1, !trap); 380. #ifdef STRONGHOLD 381. 		at_ladder = FALSE; 382. #endif 383. #ifdef WALKIES 384. 	}  385.  #endif 386. 	return(1); 387. }  388.   389.  int 390. doup 391. {  392.  #ifdef STRONGHOLD 393. 	if((u.ux != xupstair || u.uy != yupstair) &&  394.  	   (!xupladder || u.ux != xupladder || u.uy != yupladder)) { 395. #else 396. 	if(u.ux != xupstair || u.uy != yupstair) { 397. #endif /* STRONGHOLD /**/ 398. 		You("can't go up here."); 399. 		return(0); 400. 	}  401.  	if(u.ustuck) { 402. 		You("are being held, and cannot go up."); 403. 		return(1); 404. 	}  405.  	if(inv_weight + 5 > 0) { 406. 		/* No levitation check; inv_weight already allows for it */ 407. #ifdef STRONGHOLD 408. 		Your("load is too heavy to climb the %s.",  409.  		      levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder"); 410. #else 411. 		Your("load is too heavy to climb the stairs."); 412. #endif /* STRONGHOLD /**/ 413. 		return(1); 414. 	}  415.   416.  #ifdef ENDGAME 417. 	if (dlevel == 1) { 418. 		pline("Beware, there will be no return!  Still climb? "); 419. 		if (yn != 'y') return(0); 420. 		else more; 421. 	}  422.  #endif 423. #ifdef WALKIES 424. 	if(!next_to_u) { 425. 		You("are held back by your pet!"); 426. 		return(0); 427. 	} else { 428. #endif 429. 		unsee; 430. #ifdef STRONGHOLD 431. 		if (levl[u.ux][u.uy].typ == LADDER) at_ladder = TRUE; 432. 		goto_level(dlevel-1,  433.  		    (dlevel-1 < stronghold_level || (at_ladder &&  434.  		       dlevel-1 >= tower_level && dlevel-1 < tower_level+2))); 435. 		at_ladder = FALSE; 436. #else 437. 		goto_level(dlevel-1, (dlevel-1 <= medusa_level)); 438. #endif 439. #ifdef WALKIES 440. 	}  441.  #endif 442. 	return(1); 443. }  444.   445.  void 446. goto_level(newlevel, at_stairs) 447. register int newlevel; 448. register boolean at_stairs; 449. {  450.  	register int fd; 451. 	register boolean up = (newlevel < dlevel); 452.  453.  #ifdef ENDGAME 454. 	if(dlevel == ENDLEVEL) return;	/* To be on the safe side.. */ 455.  #endif 456. 	if(newlevel > MAXLEVEL) newlevel = MAXLEVEL; 457. 	if(newlevel <= 0) 458. #ifdef ENDGAME 459. 	    if(u.uhave_amulet) 460. 		newlevel = ENDLEVEL;	/* Endgame Level !!! */ 461.  	    else 462. #endif 463. 		done("escaped");    /* in fact < 0 is impossible */ 464.  465.  /*	If you have the amulet and are trying to get out of Hell, going 466.  *	up a set of stairs sometimes does some very strange things! 467.  */  468.  #ifdef HARD 469. 	if(Inhell && up && at_stairs  &&  470.  	   (dlevel < MAXLEVEL-3) && u.uhave_amulet) { 471. 	    newlevel = (rn2(5) ? newlevel :  472.  /* neutral */	     !u.ualigntyp ? (rn2(2) ? dlevel : dlevel + (rnd(5) - 2)) : 473.  /* lawful */	     (u.ualigntyp == U_LAWFUL) ? dlevel + (rnd(5) - 2) :  474.  /* chaotic */	     dlevel); 475. 	    pline("A mysterious force surrounds you..."); 476. 	    if(newlevel < 1) newlevel = dlevel; 477. 	    if(newlevel == dlevel) (void) dotele; 478. 		  479.  	}  480.  #endif /* HARD /* */ 481. 	if(newlevel == dlevel) return;	      /* this can happen */ 482. #ifdef STRONGHOLD 483. 	/* In Nethack 3.0, Hell starts after the stronghold. Moreover, 484. 	 * there are traps in the stronghold, that can send the player 485. 	 * to hell (gnark, gnark)! So we have to test here: 486. 	 */  487.  	if(!Inhell && newlevel > stronghold_level && !up && !at_ladder  488.  # ifdef ENDGAME  489.  	&& newlevel < ENDLEVEL  490.  # endif  491.  	) { 492. #else 493. 	if(!Inhell && newlevel >= HELLLEVEL && !up) { 494. #endif /* STRONGHOLD /**/ 495. 	    You("arrive at the center of the earth..."); 496. 	    pline("Unfortunately, it is here that hell is located."); 497. #ifdef MSDOS 498. 	    (void) fflush(stdout); 499. #endif 500. 	    if(Fire_resistance) { 501. 		pline("But the fire doesn't seem to harm you."); 502. 	    } else { 503. 		int save_dlevel = dlevel; 504.  505.  		You("burn to a crisp."); 506. 		You("die..."); 507. 		dlevel = maxdlevel = newlevel; 508. 		killer = "visit to hell"; 509. 		done("burned"); 510. 		dlevel = newlevel = save_dlevel; /* in case they survive */ 511. 	    }  512.  	}  513.   514.  	glo(dlevel); 515. #ifdef MSDOS 516. 	/* Use O_TRUNC to force the file to be shortened if it already 517. 	 * exists and is currently longer. 518. 	 */  519.  	fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); 520. #else 521. 	fd = creat(lock, FCMASK); 522. #endif 523. 	if(fd < 0) { 524. 		/*  525.  		 * This is not quite impossible: e.g., we may have 526. 		 * exceeded our quota. If that is the case then we 527. * cannot leave this level, and cannot save either. 528. 		 * Another possibility is that the directory was not 529. 		 * writable. 530. 		 */  531.  #ifdef DGK 532. 		pline("Cannot create level file '%s'.", lock); 533. #else 534. 		pline("A mysterious force prevents you from going %s.",  535.  			up ? "up" : "down"); 536. #endif 537. 		return; 538. 	}  539.   540.  #ifdef DGK 541. 	if (!savelev(fd, dlevel, COUNT)) { 542. # ifdef ZEROCOMP 543. 		bflush(fd); 544. # endif 545. 		(void) close(fd); 546. 		(void) unlink(lock); 547. 		pline("NetHack is out of disk space for making levels!"); 548. 		You("can save, quit, or continue playing."); 549. 		return; 550. 	}  551.  #endif 552. 	if(Punished) unplacebc; 553. 	u.utrap = 0;				/* needed in level_tele */ 554. 	u.ustuck = 0;				/* idem */ 555. 	keepdogs; 556. 	seeoff(1); 557. 	if(u.uswallow)				/* idem */ 558. 		u.uswldtim = u.uswallow = 0; 559. 	flags.nscrinh = 1; 560. 	u.ux = FAR;				/* hack */ 561. 	(void) inshop;			/* probably was a trapdoor */ 562.  563.  #ifdef DGK 564. # ifdef ZEROCOMP 565. 	bflush(fd);	/* forget buffer */ 566. # endif 567. 	savelev(fd,dlevel, WRITE); 568. #else 569. 	savelev(fd,dlevel); 570. #endif 571. #ifdef ZEROCOMP 572. 	bflush(fd);	/* flush buffer */ 573. #endif 574. 	(void) close(fd); 575. #ifdef REINCARNATION 576. 	if (newlevel == rogue_level || dlevel == rogue_level) { 577. 		/* No graphics characters on Rogue levels */ 578. 		if (dlevel != rogue_level) { 579. 			savesyms = showsyms; 580. 			showsyms = defsyms; 581. 		}  582.  		if (newlevel != rogue_level) 583. 			showsyms = savesyms; 584. 	}  585.  #endif 586. 	dlevel = newlevel; 587. 	if(maxdlevel < dlevel) 588. 		maxdlevel = dlevel; 589. 	glo(dlevel); 590. 	if(  591.  # ifdef ENDGAME  592.  	   dlevel == ENDLEVEL ||  593.  # endif  594.  #if defined(DGK) && !defined(TOS)  595.  	/* If the level has no .where yet, it hasn't been made */  596.  	   !fileinfo[dlevel].where) 597. #else 598. 	   !level_exists[dlevel])  599.  #endif  600.  		mklev;  601.  	else {  602.  #if defined(DGK) && !defined(TOS)  603.  		/* If not currently accessible, swap it in. */  604.  		if (fileinfo[dlevel].where != ACTIVE)  605.  			swapin_file(dlevel);  606.  #endif  607.  #if defined(MSDOS) && !defined(TOS)  608.  		if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {  609.  #else  610.  		if((fd = open(lock,0)) < 0) {  611.  #endif  612.  			pline("Cannot open %s .", lock);  613.  			pline("Probably someone removed it.");  614.  			done("tricked");  615.  		}  616.  #ifdef ZEROCOMP  617.  		minit;  618.  #endif  619.  		getlev(fd, hackpid, dlevel, FALSE);  620.  		(void) close(fd);  621.  	}  622.   623.  #ifdef ENDGAME  624.  	if(dlevel != ENDLEVEL)  625.  #endif  626.  	if(at_stairs) {  627.  	    if(up) {  628.  #ifdef STRONGHOLD  629.  		if (!at_ladder) {  630.  #endif  631.  		    u.ux = xdnstair; 632. 		    u.uy = ydnstair; 633. #ifdef STRONGHOLD 634. 		} else { 635. 		    u.ux = xdnladder; 636. 		    u.uy = ydnladder; 637. 		}  638.  #endif 639. /* Remove bug which crashes with levitation/punishment  KAA */ 640. 		if(Punished) { 641. 		    if(!Levitation) 642. #ifdef STRONGHOLD 643. 			pline("With great effort you climb the %s.",  644.  			      !at_ladder ? "stairs" : "ladder"); 645. #else 646. 			pline("With great effort you climb the stairs."); 647. #endif 648. 		    placebc(1); 649. 		}  650.  	    } else { 651. #ifdef STRONGHOLD 652. 		if (!at_ladder) { 653. #endif 654. 		    u.ux = xupstair; 655. 		    u.uy = yupstair; 656. #ifdef STRONGHOLD 657. 		} else { 658. 		    u.ux = xupladder; 659. 		    u.uy = yupladder; 660. 		}  661.  #endif 662. 		if(inv_weight + 5 > 0 || Punished || Fumbling) { 663. #ifdef STRONGHOLD 664. 			You("fall down the %s.",  665.  			      !at_ladder ? "stairs" : "ladder"); 666. #else 667. 			You("fall down the stairs."); 668. #endif 669. 			losehp(rnd(3), "fall"); 670. 			if(Punished) { 671. 			    if(uwep != uball && rn2(3)) { 672. 				pline("... and are hit by the iron ball."); 673. 				losehp(rnd(20), "iron ball"); 674. 			    }  675.  			    placebc(1); 676. 			}  677.  			selftouch("Falling, you"); 678. 		}  679.  	    }  680.  	} else {	/* trapdoor or level_tele */ 681. 	    register int tryct = 0; 682. 	    do { 683. #ifdef STRONGHOLD 684. 		/* Prevent teleport-landing inside the castle */ 685. 		if(dlevel == stronghold_level) { 686. 			if(up) u.ux = (COLNO - rnd(8)); 687. 			else u.ux = rnd(6); 688. 		}  689.  		else 690. 		/* Prevent teleport-landing inside Vlad's tower */ 691. 		if(dlevel >= tower_level && dlevel <= tower_level+2) { 692. 			do { 693. 			    u.ux = rnd(COLNO-1); 694. 			} while (u.ux > 29 && u.ux < 47); 695. 		}  696.  		else 697. #endif 698. 		u.ux = rnd(COLNO-1); 699. 		u.uy = rn2(ROWNO); 700. 	    } while(tryct++ < 100 && (levl[u.ux][u.uy].typ != ROOM && 701. 		     levl[u.ux][u.uy].typ != CORR) || levl[u.ux][u.uy].mmask); 702. 	    if(tryct >= 100) 703. 		panic("goto_level: could not relocate player!"); 704. 	    if(Punished){ 705. 		if(uwep != uball && !up /* %% */ && rn2(5)){ 706. 			pline("The iron ball falls on your %s.",  707.  				body_part(HEAD)); 708. 			if (uarmh) 709. 				Your("helmet doesn't help too much..."); 710. 			losehp(rnd(25), "iron ball"); 711. 		}  712.  		placebc(1); 713. 	    }  714.  	    selftouch("Falling, you"); 715. 	}  716.  	(void) inshop; 717. 	initrack; 718.  719.  	losedogs; 720. 	if(levl[u.ux][u.uy].mmask) mnexto(m_at(u.ux, u.uy)); 721. 	flags.nscrinh = 0; 722. 	setsee; 723. 	seeobjs;	/* make old cadavers disappear - riv05!a3 */ 724. 	docrt; 725. 	if(!flags.nopick && (levl[u.ux][u.uy].omask || levl[u.ux][u.uy].gmask)) 726. 	    pickup(1); 727. 	else read_engr_at(u.ux,u.uy); 728. #ifdef HARD 729. 	/* Final confrontation */ 730. 	if (dlevel == 1 && u.uhave_amulet && flags.no_of_wizards == 0) 731. 	    resurrect; 732. #endif 733. }  734.   735.  int 736. donull { 737. 	return(1);	/* Do nothing, but let other things happen */ 738. }  739.   740.  static 741. int 742. wipeoff { 743. 	if(u.ucreamed < 4)	u.ucreamed = 0; 744. 	else			u.ucreamed -= 4; 745. 	if (Blinded < 4)	Blinded = 0; 746. 	else			Blinded -= 4; 747. 	if (!Blinded) { 748. 		pline("You've got the glop off."); 749. 		u.ucreamed = 0; 750. 		make_blinded(0L,TRUE); 751. 		return(0); 752. 	} else if (!u.ucreamed) { 753. 		Your("%s feels clean now.", body_part(FACE)); 754. 		return(0); 755. 	}  756.  	return(1);		/* still busy */ 757. }  758.   759.  int 760. dowipe 761. {  762.  	if(u.ucreamed)  { 763. 		static char buf[39]; 764.  765.  		Sprintf(buf, "wiping off your %s", body_part(FACE)); 766. 		set_occupation(wipeoff, buf, 0); 767. 		/* Not totally correct; what if they change back after now 768. 		 * but before they're finished wiping? 769. 		 */  770.  		return(1); 771. 	}  772.  	Your("%s is already clean.", body_part(FACE)); 773. 	return(1); 774. }  775.   776.  /* split obj so that it gets size num */ 777. /* remainder is put in the object structure delivered by this call */ 778. struct obj * 779. splitobj(obj, num) register struct obj *obj; register int num; { 780. register struct obj *otmp; 781. 	otmp = newobj(0); 782. 	*otmp = *obj;		/* copies whole structure */ 783. 	otmp->o_id = flags.ident++; 784. 	otmp->onamelth = 0; 785. 	obj->quan = num; 786. 	obj->owt = weight(obj); 787. 	otmp->quan -= num; 788. 	otmp->owt = weight(otmp);	/* -= obj->owt ? */ 789.  	obj->nobj = otmp; 790. 	if(obj->unpaid) splitbill(obj,otmp); 791. 	return(otmp); 792. }  793.   794.  void 795. set_wounded_legs(side, timex) 796. register long side; 797. register int timex; 798. {  799.  	if(!Wounded_legs) ATEMP(A_DEX)--; 800.  801.  	if(!Wounded_legs || (Wounded_legs & TIMEOUT)) 802. 		Wounded_legs |= side + timex; 803. 	else 804. 		Wounded_legs |= side; 805. }  806.   807.  void 808. heal_legs 809. {  810.  	if(Wounded_legs) { 811. 		if (ATEMP(A_DEX) < 0) ATEMP(A_DEX)++; 812.  813.  		if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES) { 814. 			Your("%s feel somewhat better.",  815.  				makeplural(body_part(LEG))); 816. 		} else { 817. 			Your("%s feels somewhat better.",  818.  				body_part(LEG)); 819. 		}  820.  		Wounded_legs = 0; 821. 	}  822.  }