Source:NetHack 3.4.0/do.c

Below is the full text to do.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2001/11/29	*/ 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.    #include "lev.h"  9. 10.  #include   11. #ifdef _MSC_VER	/* MSC 6.0 defines errno quite differently */ 12.  # if (_MSC_VER >= 600) 13.  #  define SKIP_ERRNO 14.  # endif 15.  #endif 16.  #ifndef SKIP_ERRNO 17.  #ifdef _DCC 18.  const 19.  #endif 20.  extern int errno; 21.  #endif 22.   23.   #ifdef SINKS 24.  # ifdef OVLB 25.  STATIC_DCL void FDECL(trycall, (struct obj *)); 26.  # endif /* OVLB */ 27.  STATIC_DCL void FDECL(dosinkring, (struct obj *)); 28.  #endif /* SINKS */ 29.   30.   STATIC_PTR int FDECL(drop, (struct obj *)); 31.  STATIC_PTR int NDECL(wipeoff); 32.   33.   #ifdef OVL0 34.  STATIC_DCL int FDECL(menu_drop, (int)); 35.  #endif 36.  #ifdef OVL2 37.  STATIC_DCL int NDECL(currentlevel_rewrite); 38.  STATIC_DCL void NDECL(final_level); 39.  /* static boolean FDECL(badspot, (XCHAR_P,XCHAR_P)); */ 40.  #endif 41.   42.   #ifdef OVLB 43.   44.   static NEARDATA const char drop_types[] = 45.  	{ ALLOW_COUNT, GOLD_CLASS, ALL_CLASSES, 0 }; 46.   47.   /* 'd' command: drop one inventory item */ 48.  int 49.  dodrop 50.  {  51.   #ifndef GOLDOBJ 52.  	int result, i = (invent || u.ugold) ? 0 : (SIZE(drop_types) - 1); 53.  #else 54.  	int result, i = (invent) ? 0 : (SIZE(drop_types) - 1); 55.  #endif 56.   57.   	if (*u.ushops) sellobj_state(SELL_DELIBERATE); 58.  	result = drop(getobj(&drop_types[i], "drop")); 59.  	if (*u.ushops) sellobj_state(SELL_NORMAL); 60.  	reset_occupations; 61.   62.   	return result; 63.  }  64.    65.   #endif /* OVLB */ 66.  #ifdef OVL0 67.   68.   /* Called when a boulder is dropped, thrown, or pushed. If it ends up 69. * in a pool, it either fills the pool up or sinks away. In either case, 70.   * it's gone for good...  If the destination is not a pool, returns FALSE. 71.   */  72.   boolean 73.  boulder_hits_pool(otmp, rx, ry, pushing) 74.  struct obj *otmp; 75.  register int rx, ry; 76.  boolean pushing; 77.  {  78.   	if (!otmp || otmp->otyp != BOULDER) 79.  	    impossible("Not a boulder?"); 80.  	else if (!Is_waterlevel(&u.uz) && (is_pool(rx,ry) || is_lava(rx,ry))) { 81.  	    boolean lava = is_lava(rx,ry), fills_up; 82.  	    const char *what = lava ? "lava" : "water"; 83.  	    schar ltyp = levl[rx][ry].typ; 84.  	    int chance = rn2(10);		/* water: 90%; lava: 10% */ 85.  	    fills_up = lava ? chance == 0 : chance != 0; 86.   87.   	    if (fills_up) { 88.  		if (ltyp == DRAWBRIDGE_UP) { 89.  		    levl[rx][ry].drawbridgemask &= ~DB_UNDER; /* clear lava */ 90.  		    levl[rx][ry].drawbridgemask |= DB_FLOOR; 91.  		} else 92.  		    levl[rx][ry].typ = ROOM; 93.   94.   		bury_objs(rx, ry); 95.  		newsym(rx,ry); 96.  		if (pushing) { 97.  		    You("push %s into the %s.", the(xname(otmp)), what); 98.  		    if (flags.verbose && !Blind) 99.  			pline("Now you can cross it!"); 100. 		    /* no splashing in this case */ 101. 		}  102.  	    }  103.  	    if (!fills_up || !pushing) {	/* splashing occurs */ 104. 		if (!u.uinwater) { 105. 		    if (pushing ? !Blind : cansee(rx,ry)) { 106. 			boolean moat = (ltyp != WATER) && 107. 			    !Is_medusa_level(&u.uz) && !Is_waterlevel(&u.uz); 108.  109.  			There("is a large splash as %s %s the %s.",  110.  			      the(xname(otmp)), fills_up? "fills":"falls into",  111.  			      lava ? "lava" : ltyp==POOL ? "pool" :  112.  			      moat ? "moat" : "water"); 113. 		    } else if (flags.soundok) 114. 			You_hear("a%s splash.", lava ? " sizzling" : ""); 115. 		    wake_nearto(rx, ry, 40); 116. 		}  117.   118.  		if (fills_up && u.uinwater && distu(rx,ry) == 0) { 119. 		    u.uinwater = 0; 120. 		    docrt; 121. 		    vision_full_recalc = 1; 122. 		    You("find yourself on dry land again!"); 123. 		} else if (lava && distu(rx,ry) <= 2) { 124. 		    You("are hit by molten lava%c",  125.  			Fire_resistance ? '.' : '!'); 126. 			burn_away_slime; 127. 		    losehp(d((Fire_resistance ? 1 : 3), 6),  128.  			   "molten lava", KILLED_BY); 129. 		} else if (!fills_up && flags.verbose &&  130.  			   (pushing ? !Blind : cansee(rx,ry))) 131. 		    pline("It sinks without a trace!"); 132. 	    }  133.   134.  	    /* boulder is now gone */ 135. 	    if (pushing) delobj(otmp); 136. 	    else obfree(otmp, (struct obj *)0); 137. 	    return TRUE; 138. 	}  139.  	return FALSE; 140. }  141.   142.  /* Used for objects which sometimes do special things when dropped; must be  143. * called with the object not in any chain. Returns TRUE if the object goes 144.  * away. 145.  */  146.  boolean 147. flooreffects(obj,x,y,verb) 148. struct obj *obj; 149. int x,y; 150. const char *verb; 151. {  152.  	struct trap *t; 153. 	struct monst *mtmp; 154.  155.  	if (obj->where != OBJ_FREE) 156. 	    panic("flooreffects: obj not free"); 157.  158.  	/* make sure things like water_damage have no pointers to follow */ 159. 	obj->nobj = obj->nexthere = (struct obj *)0; 160.  161.  	if (obj->otyp == BOULDER && boulder_hits_pool(obj, x, y, FALSE)) 162. 		return TRUE; 163. 	else if (obj->otyp == BOULDER && (t = t_at(x,y)) != 0 &&  164.  		 (t->ttyp==PIT || t->ttyp==SPIKED_PIT 165. 			|| t->ttyp==TRAPDOOR || t->ttyp==HOLE)) { 166. 		if (((mtmp = m_at(x, y)) && mtmp->mtrapped) ||  167.  			(u.utrap && u.ux == x && u.uy == y)) { 168. 		    if (*verb) 169. 			pline_The("boulder %s into the pit%s.",  170.  				vtense((const char *)0, verb),  171.  				(mtmp) ? "" : " with you"); 172. 		    if (mtmp) { 173. 			if (!passes_walls(mtmp->data) &&  174.  				!throws_rocks(mtmp->data)) { 175. 			    if (hmon(mtmp, obj, TRUE) && !is_whirly(mtmp->data)) 176. 				return FALSE;	/* still alive */ 177. 			}  178.  			mtmp->mtrapped = 0; 179. 		    } else { 180. 			if (!Passes_walls && !throws_rocks(youmonst.data)) { 181. 			    losehp(rnd(15), "squished under a boulder",  182.  				   NO_KILLER_PREFIX); 183. 			    return FALSE;	/* player remains trapped */ 184. 			} else u.utrap = 0; 185. 		    }  186.  		}  187.  		if (*verb) { 188. 			if (Blind) { 189. 				if ((x == u.ux) && (y == u.uy)) 190. 					You_hear("a CRASH! beneath you."); 191. 				else 192. 					You_hear("the boulder %s.", verb); 193. 			} else if (cansee(x, y)) { 194. 				pline_The("boulder %s%s.",  195.  				    t->tseen ? "" : "triggers and ",  196.  				    t->ttyp == TRAPDOOR ? "plugs a trap door" :  197.  				    t->ttyp == HOLE ? "plugs a hole" :  198.  				    "fills a pit"); 199. 			}  200.  		}  201.  		deltrap(t); 202. 		obfree(obj, (struct obj *)0); 203. 		bury_objs(x, y); 204. 		newsym(x,y); 205. 		return TRUE; 206. 	} else if (is_lava(x, y)) { 207. 		return fire_damage(obj, FALSE, FALSE, x, y); 208. 	} else if (is_pool(x, y)) { 209. 		water_damage(obj, FALSE, FALSE); 210. 	}  211.  	return FALSE; 212. }  213.   214.  #endif /* OVL0 */ 215. #ifdef OVLB 216.  217.  void 218. doaltarobj(obj)  /* obj is an object dropped on an altar */ 219. 	register struct obj *obj; 220. {  221.  	if (Blind || obj->oclass == GOLD_CLASS) 222. 		return; 223.  224.  	/* KMH, conduct */ 225. 	u.uconduct.gnostic++; 226.  227.  	if (obj->blessed || obj->cursed) { 228. 		There("is %s flash as %s %s the altar.",  229.  			an(hcolor(obj->blessed ? amber : Black)),  230.  			doname(obj), otense(obj, "hit")); 231. 		if (!Hallucination) obj->bknown = 1; 232. 	} else { 233. 		pline("%s %s on the altar.", Doname2(obj),  234.  			otense(obj, "land")); 235. 		obj->bknown = 1; 236. 	}  237.  }  238.   239.  #ifdef SINKS 240. STATIC_OVL 241. void 242. trycall(obj) 243. register struct obj *obj; 244. {  245.  	if(!objects[obj->otyp].oc_name_known &&  246.  	   !objects[obj->otyp].oc_uname) 247. 	   docall(obj); 248. }  249.   250.  STATIC_OVL 251. void 252. dosinkring(obj)  /* obj is a ring being dropped over a kitchen sink */ 253. register struct obj *obj; 254. {  255.  	register struct obj *otmp,*otmp2; 256. 	register boolean ideed = TRUE; 257.  258.  	You("drop %s down the drain.", doname(obj)); 259. 	obj->in_use = TRUE;	/* block free identification via interrupt */ 260. 	switch(obj->otyp) {	/* effects that can be noticed without eyes */ 261. 	    case RIN_SEARCHING: 262. 		You("thought your %s got lost in the sink, but there it is!",  263.  			xname(obj)); 264. 		goto giveback; 265. 	    case RIN_SLOW_DIGESTION: 266. 		pline_The("ring is regurgitated!"); 267. giveback: 268. 		obj->in_use = FALSE; 269. 		dropx(obj); 270. 		trycall(obj); 271. 		return; 272. 	    case RIN_LEVITATION: 273. 		pline_The("sink quivers upward for a moment."); 274. 		break; 275. 	    case RIN_POISON_RESISTANCE: 276. 		You("smell rotten %s.", makeplural(pl_fruit)); 277. 		break; 278. 	    case RIN_AGGRAVATE_MONSTER: 279. 		pline("Several flies buzz angrily around the sink."); 280. 		break; 281. 	    case RIN_SHOCK_RESISTANCE: 282. 		pline("Static electricity surrounds the sink."); 283. 		break; 284. 	    case RIN_CONFLICT: 285. 		You_hear("loud noises coming from the drain."); 286. 		break; 287. 	    case RIN_SUSTAIN_ABILITY:	/* KMH */ 288. 		pline_The("water flow seems fixed."); 289. 		break; 290. 	    case RIN_GAIN_STRENGTH: 291. 		pline_The("water flow seems %ser now.",  292.  			(obj->spe<0) ? "weak" : "strong"); 293. 		break; 294. 	    case RIN_GAIN_CONSTITUTION: 295. 		pline_The("water flow seems %ser now.",  296.  			(obj->spe<0) ? "less" : "great"); 297. 		break; 298. 	    case RIN_INCREASE_ACCURACY:	/* KMH */ 299. 		pline_The("water flow %s the drain.",  300.  			(obj->spe<0) ? "misses" : "hits"); 301. 		break; 302. 	    case RIN_INCREASE_DAMAGE: 303. 		pline_The("water's force seems %ser now.",  304.  			(obj->spe<0) ? "small" : "great"); 305. 		break; 306. 	    case RIN_HUNGER: 307. 		ideed = FALSE; 308. 		for(otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp2) { 309. 		    otmp2 = otmp->nexthere; 310. 		    if (otmp != uball && otmp != uchain &&  311.  			    !obj_resists(otmp, 1, 99)) { 312. 			if (!Blind) { 313. 			    pline("Suddenly, %s %s from the sink!",  314.  				  doname(otmp), otense(otmp, "vanish")); 315. 			    ideed = TRUE; 316. 			}  317.  			delobj(otmp); 318. 		    }  319.  		}  320.  		break; 321. 	    case MEAT_RING: 322. 		/* Not the same as aggravate monster; besides, it's obvious. */ 323.  		pline("Several flies buzz around the sink."); 324. 		break; 325. 	    default: 326. 		ideed = FALSE; 327. 		break; 328. 	}  329.  	if(!Blind && !ideed && obj->otyp != RIN_HUNGER) { 330. 	    ideed = TRUE; 331. 	    switch(obj->otyp) {		/* effects that need eyes */ 332. 		case RIN_ADORNMENT: 333. 		    pline_The("faucets flash brightly for a moment."); 334. 		    break; 335. 		case RIN_REGENERATION: 336. 		    pline_The("sink looks as good as new."); 337. 		    break; 338. 		case RIN_INVISIBILITY: 339. 		    You("don't see anything happen to the sink."); 340. 		    break; 341. 		case RIN_FREE_ACTION: 342. 		    You("see the ring slide right down the drain!"); 343. 		    break; 344. 		case RIN_SEE_INVISIBLE: 345. 		    You("see some air in the sink."); 346. 		    break; 347. 		case RIN_STEALTH: 348. 		pline_The("sink seems to blend into the floor for a moment."); 349. 		    break; 350. 		case RIN_FIRE_RESISTANCE: 351. 		pline_The("hot water faucet flashes brightly for a moment."); 352. 		    break; 353. 		case RIN_COLD_RESISTANCE: 354. 		pline_The("cold water faucet flashes brightly for a moment."); 355. 		    break; 356. 		case RIN_PROTECTION_FROM_SHAPE_CHAN: 357. 		    pline_The("sink looks nothing like a fountain."); 358. 		    break; 359. 		case RIN_PROTECTION: 360. 		    pline_The("sink glows %s for a moment.",  361.  			    hcolor((obj->spe<0) ? Black : silver)); 362. 		    break; 363. 		case RIN_WARNING: 364. 		    pline_The("sink glows %s for a moment.", hcolor(White)); 365. 		    break; 366. 		case RIN_TELEPORTATION: 367. 		    pline_The("sink momentarily vanishes."); 368. 		    break; 369. 		case RIN_TELEPORT_CONTROL: 370. 	    pline_The("sink looks like it is being beamed aboard somewhere."); 371. 		    break; 372. 		case RIN_POLYMORPH: 373. 		    pline_The("sink momentarily looks like a fountain."); 374. 		    break; 375. 		case RIN_POLYMORPH_CONTROL: 376. 	pline_The("sink momentarily looks like a regularly erupting geyser."); 377. 		    break; 378. 	    }  379.  	}  380.  	if(ideed) 381. 	    trycall(obj); 382. 	else 383. 	    You_hear("the ring bouncing down the drainpipe."); 384. 	if (!rn2(20)) { 385. 		pline_The("sink backs up, leaving %s.", doname(obj)); 386. 		obj->in_use = FALSE; 387. 		dropx(obj); 388. 	} else 389. 		useup(obj); 390. }  391.  #endif 392.  393.  #endif /* OVLB */ 394. #ifdef OVL0 395.  396.  /* some common tests when trying to drop or throw items */ 397. boolean 398. canletgo(obj,word) 399. register struct obj *obj; 400. register const char *word; 401. {  402.  	if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)){ 403. 		if (*word) 404. 			Norep("You cannot %s %s you are wearing.",word,  405.  				something); 406. 		return(FALSE); 407. 	}  408.  	if (obj->otyp == LOADSTONE && obj->cursed) { 409. 		if (*word) 410. 			pline("For some reason, you cannot %s the stone%s!",  411.  				word, plur(obj->quan)); 412. 		/* Kludge -- see invent.c */ 413. 		if (obj->corpsenm) { 414. 			struct obj *otmp; 415.  416.  			otmp = obj; 417. 			obj = obj->nobj; 418. 			obj->quan += otmp->quan; 419. 			obj->owt = weight(obj); 420. 			freeinv(otmp); 421. 			obfree(otmp, obj); 422. 		}  423.  		obj->bknown = 1; 424. 		return(FALSE); 425. 	}  426.  	if (obj->otyp == LEASH && obj->leashmon != 0) { 427. 		if (*word) 428. 			pline_The("leash is tied around your %s.",  429.  					body_part(HAND)); 430. 		return(FALSE); 431. 	}  432.  #ifdef STEED 433. 	if (obj->owornmask & W_SADDLE) { 434. 		if (*word) 435. 			You("cannot %s %s you are sitting on.", word,  436.  				something); 437. 		return (FALSE); 438. 	}  439.  #endif 440. 	return(TRUE); 441. }  442.   443.  STATIC_PTR 444. int 445. drop(obj) 446. register struct obj *obj; 447. {  448.  	if(!obj) return(0); 449. 	if(!canletgo(obj,"drop")) 450. 		return(0); 451. 	if(obj == uwep) { 452. 		if(welded(uwep)) { 453. 			weldmsg(obj); 454. 			return(0); 455. 		}  456.  		setuwep((struct obj *)0); 457. 	}  458.  	if(obj == uquiver) { 459. 		setuqwep((struct obj *)0); 460. 	}  461.  	if (obj == uswapwep) { 462. 		setuswapwep((struct obj *)0); 463. 	}  464.   465.  	if (u.uswallow) { 466. 		/* barrier between you and the floor */ 467. 		if(flags.verbose) 468. 		{  469.  			char buf[BUFSZ]; 470.  471.  			/* doname can call s_suffix, reusing its buffer */ 472. 			Strcpy(buf, s_suffix(mon_nam(u.ustuck))); 473. 			You("drop %s into %s %s.", doname(obj), buf,  474.  				mbodypart(u.ustuck, STOMACH)); 475. 		}  476.  	} else { 477. #ifdef SINKS 478. 	    if((obj->oclass == RING_CLASS || obj->otyp == MEAT_RING) &&  479.  			IS_SINK(levl[u.ux][u.uy].typ)) { 480. 		dosinkring(obj); 481. 		return(1); 482. 	    }  483.  #endif 484. 	    if (!can_reach_floor) { 485. 		if(flags.verbose) You("drop %s.", doname(obj)); 486. 		if (obj->oclass != GOLD_CLASS || obj == invent) freeinv(obj); 487. 		hitfloor(obj); 488. 		return(1); 489. 	    }  490.  	    if (IS_ALTAR(levl[u.ux][u.uy].typ)) { 491. 		doaltarobj(obj);	/* set bknown */ 492. 	    } else 493. 		if(flags.verbose) You("drop %s.", doname(obj)); 494. 	}  495.  	dropx(obj); 496. 	return(1); 497. }  498.   499.  /* Called in several places - should not produce texts */ 500. /* ship_object _can_ produce texts--is that comment still correct? */ 501.  void 502. dropx(obj) 503. register struct obj *obj; 504. {  505.  #ifndef GOLDOBJ 506. 	if (obj->oclass != GOLD_CLASS || obj == invent) freeinv(obj); 507. #else 508.         /* Ensure update when we drop gold objects */ 509.         if (obj->oclass == GOLD_CLASS) flags.botl = 1; 510. 	/* Money is usually not in our inventory */ 511. 	/*if (obj->oclass != GOLD_CLASS || obj == invent)*/ 512.         /* !!!! make sure we don't drop "created" gold not in inventory any more,*/ 513.         /* or this will crash !!!! */ 514.          freeinv(obj); 515. #endif 516. 	if (!u.uswallow && ship_object(obj, u.ux, u.uy, FALSE)) return; 517. 	dropy(obj); 518. }  519.   520.  void 521. dropy(obj) 522. register struct obj *obj; 523. {  524.  	if (obj == uwep) setuwep((struct obj *)0); 525. 	if (obj == uquiver) setuqwep((struct obj *)0); 526. 	if (obj == uswapwep) setuswapwep((struct obj *)0); 527.  528.  	if (!u.uswallow && flooreffects(obj,u.ux,u.uy,"drop")) return; 529. 	/* uswallow check done by GAN 01/29/87 */ 530. 	if(u.uswallow) { 531. 	    boolean could_petrify; 532. 	    if (obj != uball) {		/* mon doesn't pick up ball */ 533. 		could_petrify = obj->otyp == CORPSE && 534. 		    touch_petrifies(&mons[obj->corpsenm]); 535. 		(void) mpickobj(u.ustuck,obj); 536. 		if (could_petrify && is_animal(u.ustuck->data)) { 537. 		    minstapetrify(u.ustuck, TRUE); 538. 		    /* Don't leave a cockatrice corpse available in a statue */ 539. 		    if (!u.uswallow) delobj(obj); 540. 		}  541.  	    }  542.  	} else  { 543. 	    place_object(obj, u.ux, u.uy); 544. 	    if (obj == uball) 545. 		drop_ball(u.ux,u.uy); 546. 	    else 547. 		sellobj(obj, u.ux, u.uy); 548. 	    stackobj(obj); 549. 	    if(Blind && Levitation) 550. 		map_object(obj, 0); 551. 	    newsym(u.ux,u.uy);	/* remap location under self */ 552. 	}  553.  }  554.   555.  /* things that must change when not held; recurse into containers. 556.    Called for both player and monsters */ 557. void 558. obj_no_longer_held(obj) 559. struct obj *obj; 560. {  561.  	if (!obj) { 562. 	    return; 563. 	} else if ((Is_container(obj) || obj->otyp == STATUE) && obj->cobj) { 564. 	    struct obj *contents; 565. 	    for(contents=obj->cobj; contents; contents=contents->nobj) 566. 		obj_no_longer_held(contents); 567. 	}  568.  	switch(obj->otyp) { 569. 	case CRYSKNIFE: 570. 	    /* KMH -- Fixed crysknives have only 10% chance of reverting */ 571. 	    /* only changes when not held by player or monster */ 572. 	    if (!obj->oerodeproof || !rn2(10)) { 573. 		obj->otyp = WORM_TOOTH; 574. 		obj->oerodeproof = 0; 575. 	    }  576.  	    break; 577. 	}  578.  }  579.   580.  /* 'D' command: drop several things */ 581. int 582. doddrop 583. {  584.  	int result = 0; 585.  586.  	add_valid_menu_class(0); /* clear any classes already there */ 587. 	if (*u.ushops) sellobj_state(SELL_DELIBERATE); 588. 	if (flags.menu_style != MENU_TRADITIONAL ||  589.  		(result = ggetobj("drop", drop, 0, FALSE, (unsigned *)0)) < -1) 590. 	    result = menu_drop(result); 591. 	if (*u.ushops) sellobj_state(SELL_NORMAL); 592. 	reset_occupations; 593.  594.  	return result; 595. }  596.   597.  /* Drop things from the hero's inventory, using a menu. */ 598.  STATIC_OVL int 599. menu_drop(retry) 600. int retry; 601. {  602.      int n, i, n_dropped = 0; 603.     long cnt; 604.     struct obj *otmp, *otmp2; 605. #ifndef GOLDOBJ 606.     struct obj *u_gold = 0; 607. #endif 608.     menu_item *pick_list; 609.     boolean all_categories = TRUE; 610.     boolean drop_everything = FALSE; 611.  612.  #ifndef GOLDOBJ 613.     if (u.ugold) { 614. 	/* Hack: gold is not in the inventory, so make a gold object 615. 	   and put it at the head of the inventory list. */ 616.  	u_gold = mkgoldobj(u.ugold);	/* removes from u.ugold */ 617. 	u.ugold = u_gold->quan;		/* put the gold back */ 618. 	assigninvlet(u_gold);		/* might end up as NOINVSYM */ 619. 	u_gold->nobj = invent; 620. 	invent = u_gold; 621.     }  622.  #endif 623.     if (retry) { 624. 	all_categories = (retry == -2); 625.     } else if (flags.menu_style == MENU_FULL) { 626. 	all_categories = FALSE; 627. 	n = query_category("Drop what type of items?",  628.  			invent,  629.  			UNPAID_TYPES | ALL_TYPES | CHOOSE_ALL |  630.  			BUC_BLESSED | BUC_CURSED | BUC_UNCURSED | BUC_UNKNOWN,  631.  			&pick_list, PICK_ANY); 632. 	if (!n) goto drop_done; 633. 	for (i = 0; i < n; i++) { 634. 	    if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) 635. 		all_categories = TRUE; 636. 	    else if (pick_list[i].item.a_int == 'A') 637. 		drop_everything = TRUE; 638. 	    else 639. 		add_valid_menu_class(pick_list[i].item.a_int); 640. 	}  641.  	free((genericptr_t) pick_list); 642.     } else if (flags.menu_style == MENU_COMBINATION) { 643. 	unsigned ggoresults = 0; 644. 	all_categories = FALSE; 645. 	/* Gather valid classes via traditional NetHack method */ 646. 	i = ggetobj("drop", drop, 0, TRUE, &ggoresults); 647. 	if (i == -2) all_categories = TRUE; 648. 	if (ggoresults & ALL_FINISHED) { 649. 		n_dropped = i;  650. goto drop_done; 651. 	}  652.      }  653.   654.      if (drop_everything) { 655. 	for(otmp = invent; otmp; otmp = otmp2) { 656. 	    otmp2 = otmp->nobj; 657. 	    n_dropped += drop(otmp); 658. 	}  659.      } else { 660. 	/* should coordinate with perm invent, maybe not show worn items */ 661. 	n = query_objlist("What would you like to drop?", invent,  662.  			USE_INVLET|INVORDER_SORT, &pick_list,  663.  			PICK_ANY, all_categories ? allow_all : allow_category); 664. 	if (n > 0) { 665. 	    for (i = 0; i < n; i++) { 666. 		otmp = pick_list[i].item.a_obj; 667. 		cnt = pick_list[i].count; 668. 		if (cnt < otmp->quan && !welded(otmp) &&  669.  			(!otmp->cursed || otmp->otyp != LOADSTONE)) { 670. #ifndef GOLDOBJ 671. 		    if (otmp->oclass == GOLD_CLASS) 672. 			(void) splitobj(otmp, otmp->quan - cnt); 673. 		    else 674. #endif 675. 		    otmp = splitobj(otmp, cnt); 676. 		}  677.  		n_dropped += drop(otmp); 678. 	    }  679.  	    free((genericptr_t) pick_list); 680. 	}  681.      }  682.   683.   drop_done: 684. #ifndef GOLDOBJ 685.     if (u_gold && invent && invent->oclass == GOLD_CLASS) { 686. 	/* didn't drop [all of] it */ 687. 	u_gold = invent; 688. 	invent = u_gold->nobj; 689. 	dealloc_obj(u_gold); 690. 	update_inventory; 691.     }  692.  #endif 693.     return n_dropped; 694. }  695.   696.  #endif /* OVL0 */ 697. #ifdef OVL2 698.  699.  /* on a ladder, used in goto_level */ 700. static NEARDATA boolean at_ladder = FALSE; 701.  702.  int 703. dodown 704. {  705.  	struct trap *trap = 0; 706. 	boolean stairs_down = ((u.ux == xdnstair && u.uy == ydnstair) ||  707.  		    (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)), 708. 		ladder_down = (u.ux == xdnladder && u.uy == ydnladder); 709.  710.  #ifdef STEED 711. 	if (u.usteed && !u.usteed->mcanmove) { 712. 		pline("%s won't move!", Monnam(u.usteed)); 713. 		return(0); 714. 	} else if (u.usteed && u.usteed->meating) { 715. 		pline("%s is still eating.", Monnam(u.usteed)); 716. 		return(0); 717. 	} else 718. #endif 719. 	if (Levitation) { 720. 	    if ((HLevitation & I_SPECIAL) || (ELevitation & W_ARTI)) { 721. 		/* end controlled levitation */ 722. 		if (ELevitation & W_ARTI) { 723. 		    struct obj *obj; 724.  725.  		    for(obj = invent; obj; obj = obj->nobj) { 726. 			if (obj->oartifact &&  727.  					artifact_has_invprop(obj,LEVITATION)) { 728. 			    if (obj->age < monstermoves) 729. 				obj->age = monstermoves + rnz(100); 730. 			    else 731. 				obj->age += rnz(100); 732. 			}  733.  		    }  734.  		}  735.  		if (float_down(I_SPECIAL|TIMEOUT, W_ARTI)) 736. 		    return (1);   /* came down, so moved */ 737. 	    }  738.  	    floating_above(stairs_down ? "stairs" : ladder_down ?  739.  			   "ladder" : surface(u.ux, u.uy)); 740. 	    return (0);   /* didn't move */ 741. 	}  742.  	if (!stairs_down && !ladder_down) { 743. 		if (!(trap = t_at(u.ux,u.uy)) ||  744.  			(trap->ttyp != TRAPDOOR && trap->ttyp != HOLE)  745.  			|| !Can_fall_thru(&u.uz) || !trap->tseen) { 746. 			You_cant("go down here."); 747. 			return(0); 748. 		}  749.  	}  750.  	if(u.ustuck) { 751. 		You("are %s, and cannot go down.",  752.  			!u.uswallow ? "being held" : is_animal(u.ustuck->data) ?  753.  			"swallowed" : "engulfed"); 754. 		return(1); 755. 	}  756.  	if (on_level(&valley_level, &u.uz) && !u.uevent.gehennom_entered) { 757. 		You("are standing at the gate to Gehennom."); 758. 		pline("Unspeakable cruelty and harm lurk down there."); 759. 		if (yn("Are you sure you want to enter?") != 'y') 760. 			return(0); 761. 		else pline("So be it."); 762. 		u.uevent.gehennom_entered = 1;	/* don't ask again */ 763. 	}  764.   765.  	if(!next_to_u) { 766. 		You("are held back by your pet!"); 767. 		return(0); 768. 	}  769.   770.  	if (trap) 771. 	    You("%s %s.", locomotion(youmonst.data, "jump"),  772.  		trap->ttyp == HOLE ? "down the hole" : "through the trap door"); 773.  774.  	if (trap && Is_stronghold(&u.uz)) { 775. 		goto_hell(TRUE, TRUE); 776. 	} else { 777. 		at_ladder = (boolean) (levl[u.ux][u.uy].typ == LADDER); 778. 		next_level(!trap); 779. 		at_ladder = FALSE; 780. 	}  781.  	return(1); 782. }  783.   784.  int 785. doup 786. {  787.  	if( (u.ux != xupstair || u.uy != yupstair)  788.  	     && (!xupladder || u.ux != xupladder || u.uy != yupladder)  789.  	     && (!sstairs.sx || u.ux != sstairs.sx || u.uy != sstairs.sy  790. || !sstairs.up) 791.  	  ) { 792. 		You_cant("go up here."); 793. 		return(0); 794. 	}  795.  #ifdef STEED 796. 	if (u.usteed && !u.usteed->mcanmove) { 797. 		pline("%s won't move!", Monnam(u.usteed)); 798. 		return(0); 799. 	} else if (u.usteed && u.usteed->meating) { 800. 		pline("%s is still eating.", Monnam(u.usteed)); 801. 		return(0); 802. 	} else 803. #endif 804. 	if(u.ustuck) { 805. 		You("are %s, and cannot go up.",  806.  			!u.uswallow ? "being held" : is_animal(u.ustuck->data) ?  807.  			"swallowed" : "engulfed"); 808. 		return(1); 809. 	}  810.  	if(near_capacity > SLT_ENCUMBER) { 811. 		/* No levitation check; inv_weight already allows for it */ 812. 		Your("load is too heavy to climb the %s.",  813.  			levl[u.ux][u.uy].typ == STAIRS ? "stairs" : "ladder"); 814. 		return(1); 815. 	}  816.  	if(ledger_no(&u.uz) == 1) { 817. 		if (yn("Beware, there will be no return! Still climb?") != 'y') 818. 			return(0); 819. 	}  820.  	if(!next_to_u) { 821. 		You("are held back by your pet!"); 822. 		return(0); 823. 	}  824.  	at_ladder = (boolean) (levl[u.ux][u.uy].typ == LADDER); 825. 	prev_level(TRUE); 826. 	at_ladder = FALSE; 827. 	return(1); 828. }  829.   830.  d_level save_dlevel = {0, 0}; 831.  832.  /* check that we can write out the current level */ 833. STATIC_OVL int 834. currentlevel_rewrite 835. {  836.  	register int fd; 837.  838.  	/* since level change might be a bit slow, flush any buffered screen 839. 	 *  output (like "you fall through a trap door") */ 840. 	mark_synch; 841.  842.  	fd = create_levelfile(ledger_no(&u.uz)); 843.  844.  	if(fd < 0) { 845. 		/*  846.  		 * This is not quite impossible: e.g., we may have 847. 		 * exceeded our quota. If that is the case then we 848. * cannot leave this level, and cannot save either. 849. 		 * Another possibility is that the directory was not 850. 		 * writable. 851. 		 */  852.  		pline("Cannot create level file for level %d.",  853.  						ledger_no(&u.uz)); 854. 		return -1; 855. 	}  856.   857.  #ifdef MFLOPPY 858. 	if (!savelev(fd, ledger_no(&u.uz), COUNT_SAVE)) { 859. 		(void) close(fd); 860. 		delete_levelfile(ledger_no(&u.uz)); 861. 		pline("NetHack is out of disk space for making levels!"); 862. 		You("can save, quit, or continue playing."); 863. 		return -1; 864. 	}  865.  #endif 866. 	return fd; 867. }  868.   869.  #ifdef INSURANCE 870. void 871. save_currentstate 872. {  873.  	int fd; 874.  875.  	if (flags.ins_chkpt) { 876. 		/* write out just-attained level, with pets and everything */ 877. 		fd = currentlevel_rewrite; 878. 		if(fd < 0) return; 879. 		bufon(fd); 880. 		savelev(fd,ledger_no(&u.uz), WRITE_SAVE); 881. 		bclose(fd); 882. 	}  883.   884.  	/* write out non-level state */ 885. 	savestateinlock; 886. }  887.  #endif 888.  889.  /*  890.  static boolean 891. badspot(x, y)  892. register xchar x, y; 893. { 894.  	return((levl[x][y].typ != ROOM && levl[x][y].typ != AIR && 895. 			 levl[x][y].typ != CORR) || MON_AT(x, y)); 896. }  897.  */  898.   899.  void 900. goto_level(newlevel, at_stairs, falling, portal) 901. d_level *newlevel; 902. boolean at_stairs, falling, portal; 903. {  904.  	int fd, l_idx; 905. 	xchar new_ledger; 906. 	boolean cant_go_back, 907. 		up = (depth(newlevel) < depth(&u.uz)), 908. 		newdungeon = (u.uz.dnum != newlevel->dnum), 909. 		was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz), 910. 		familiar = FALSE; 911. 	boolean new = FALSE;	/* made a new level? */ 912.  	struct monst *mtmp; 913.  914.  	if (dunlev(newlevel) > dunlevs_in_dungeon(newlevel)) 915. 		newlevel->dlevel = dunlevs_in_dungeon(newlevel); 916. 	if (newdungeon && In_endgame(newlevel)) { /* 1st Endgame Level !!! */ 917.  		if (u.uhave.amulet) 918. 		    assign_level(newlevel, &earth_level); 919. 		else return; 920. 	}  921.  	new_ledger = ledger_no(newlevel); 922. 	if (new_ledger <= 0) 923. 		done(ESCAPED);	/* in fact < 0 is impossible */ 924.  925.  	/* If you have the amulet and are trying to get out of Gehennom, going 926. 	 * up a set of stairs sometimes does some very strange things! 927. 	 * Biased against law and towards chaos, but not nearly as strongly 928. 	 * as it used to be (prior to 3.2.0). 929. 	 * Odds:	    old				    new 930. 	 *	"up"    L      N      C		"up"    L      N      C  931. *	 +1  75.0   75.0   75.0	 +1   75.0   75.0   75.0  932.  	 *	  0    0.0   12.5   25.0	  0    6.25   8.33  12.5  933.  	 *	 -1    8.33   4.17   0.0	 -1    6.25   8.33  12.5  934.  	 *	 -2    8.33   4.17   0.0	 -2    6.25   8.33   0.0  935.  	 *	 -3    8.33   4.17   0.0	 -3    6.25   0.0    0.0  936.  	 */  937.  	if (Inhell && up && u.uhave.amulet && !newdungeon && !portal &&  938.  				(dunlev(&u.uz) < dunlevs_in_dungeon(&u.uz)-3)) { 939. 		if (!rn2(4)) { 940. 		    int odds = 3 + (int)u.ualign.type,		/* 2..4 */ 941. 			diff = odds <= 1 ? 0 : rn2(odds);	/* paranoia */ 942.  943.  		    if (diff != 0) { 944. 			assign_rnd_level(newlevel, &u.uz, diff); 945. 			/* if inside the tower, stay inside */ 946. 			if (was_in_W_tower &&  947.  			    !On_W_tower_level(newlevel)) diff = 0; 948. 		    }  949.  		    if (diff == 0) 950. 			assign_level(newlevel, &u.uz); 951.  952.  		    new_ledger = ledger_no(newlevel); 953.  954.  		    pline("A mysterious force momentarily surrounds you..."); 955. 		    if (on_level(newlevel, &u.uz)) { 956. 			(void) safe_teleds; 957. 			(void) next_to_u; 958. 			return; 959. 		    } else 960. 			at_stairs = at_ladder = FALSE; 961. 		}  962.  	}  963.   964.  	/* Prevent the player from going past the first quest level unless 965. 	 * (s)he has been given the go-ahead by the leader. 966. 	 */  967.  	if (on_level(&u.uz, &qstart_level) && !newdungeon && !ok_to_quest) { 968. 		pline("A mysterious force prevents you from descending."); 969. 		return; 970. 	}  971.   972.  	if (on_level(newlevel, &u.uz)) return;		/* this can happen */ 973.  974.  	fd = currentlevel_rewrite; 975. 	if (fd < 0) return; 976.  977.  	if (falling) /* assuming this is only trap door or hole */ 978. 	    impact_drop((struct obj *)0, u.ux, u.uy, newlevel->dlevel); 979.  980.  	check_special_room(TRUE);		/* probably was a trap door */ 981. 	if (Punished) unplacebc; 982. 	u.utrap = 0;				/* needed in level_tele */ 983. 	fill_pit(u.ux, u.uy); 984. 	u.ustuck = 0;				/* idem */ 985. 	u.uinwater = 0; 986. 	keepdogs(FALSE); 987. 	if (u.uswallow)				/* idem */ 988. 		u.uswldtim = u.uswallow = 0; 989. 	/*  990.  	 *  We no longer see anything on the level. Make sure that this 991. 	 *  follows u.uswallow set to null since uswallow overrides all 992. 	 *  normal vision. 993. 	 */  994.  	vision_recalc(2); 995.  996.  	/*  997.  	 * Save the level we're leaving. If we're entering the endgame, 998. 	 * we can get rid of all existing levels because they cannot be  999. * reached any more. We still need to use savelev's cleanup 1000. 	 * for the level being left, to recover dynamic memory in use and 1001. 	 * to avoid dangling timers and light sources. 1002. 	 */ 1003. 	cant_go_back = (newdungeon && In_endgame(newlevel)); 1004. 	if (!cant_go_back) { 1005. 	   update_mlstmv;	/* current monsters are becoming inactive */ 1006. 	   bufon(fd);		/* use buffered output */ 1007. 	} 1008. 	savelev(fd, ledger_no(&u.uz),  1009. 		cant_go_back ? FREE_SAVE : (WRITE_SAVE | FREE_SAVE)); 1010. 	bclose(fd); 1011. 	if (cant_go_back) { 1012. 	   /* discard unreachable levels; keep #0 */ 1013. 	   for (l_idx = maxledgerno; l_idx > 0; --l_idx) 1014. 		delete_levelfile(l_idx); 1015. 	} 1016.  1017. #ifdef REINCARNATION 1018. 	if (Is_rogue_level(newlevel) || Is_rogue_level(&u.uz)) 1019. 		assign_rogue_graphics(Is_rogue_level(newlevel)); 1020. #endif 1021. #ifdef USE_TILES 1022. 	substitute_tiles(newlevel); 1023. #endif 1024. 	assign_level(&u.uz0, &u.uz); 1025. 	assign_level(&u.uz, newlevel); 1026. 	assign_level(&u.utolev, newlevel); 1027. 	u.utotype = 0; 1028. 	if (dunlev_reached(&u.uz) < dunlev(&u.uz)) 1029. 		dunlev_reached(&u.uz) = dunlev(&u.uz); 1030. 	reset_rndmonst(NON_PM);  /* u.uz change affects monster generation */ 1031. 1032. 	/* set default level change destination areas */ 1033. 	/* the special level code may override these */ 1034. 	(void) memset((genericptr_t) &updest, 0, sizeof updest); 1035. 	(void) memset((genericptr_t) &dndest, 0, sizeof dndest); 1036. 1037. 	if (!(level_info[new_ledger].flags & LFILE_EXISTS)) { 1038. 		/* entering this level for first time; make it now */ 1039. 		if (level_info[new_ledger].flags & (FORGOTTEN|VISITED)) { 1040. 		   impossible("goto_level: returning to discarded level?"); 1041. 		   level_info[new_ledger].flags &= ~(FORGOTTEN|VISITED); 1042. 		} 1043. 		mklev; 1044. 		new = TRUE;	/* made the level */ 1045. 	} else { 1046. 		/* returning to previously visited level; reload it */ 1047. 		fd = open_levelfile(new_ledger); 1048. 		if (fd < 0) { 1049. 			pline("Cannot open file (#%d) for level %d (errno %d).", 1050. 					(int) new_ledger, depth(&u.uz), errno); 1051. 			pline("Probably someone removed it."); 1052. 			done(TRICKED); 1053. 		} 1054. 		minit;	/* ZEROCOMP */ 1055. 		getlev(fd, hackpid, new_ledger, FALSE); 1056. 		(void) close(fd); 1057. 	} 1058. 	/* do this prior to level-change pline messages */ 1059. 	vision_reset;		/* clear old level's line-of-sight */ 1060. 	vision_full_recalc = 0;	/* don't let that reenable vision yet */ 1061. 1062. 	if (portal && !In_endgame(&u.uz)) { 1063. 	   /* find the portal on the new level */ 1064. 	   register struct trap *ttrap; 1065. 1066. 	    for (ttrap = ftrap; ttrap; ttrap = ttrap->ntrap) 1067. 		if (ttrap->ttyp == MAGIC_PORTAL) break; 1068. 1069. 	    if (!ttrap) panic("goto_level: no corresponding portal!"); 1070. 	   seetrap(ttrap); 1071. 	   u_on_newpos(ttrap->tx, ttrap->ty); 1072. 	} else if (at_stairs && !In_endgame(&u.uz)) { 1073. 	   if (up) { 1074. 		if (at_ladder) { 1075. 		   u_on_newpos(xdnladder, ydnladder); 1076. 		} else { 1077. 		   if (newdungeon) { 1078. 			if (Is_stronghold(&u.uz)) { 1079. 			   register xchar x, y;  1080. 1081. 			   do { 1082. 				x = (COLNO - 2 - rnd(5)); 1083. 				y = rn1(ROWNO - 4, 3); 1084. 			   } while(occupied(x, y) ||  1085. 				    IS_WALL(levl[x][y].typ)); 1086. 			   u_on_newpos(x, y); 1087. 			} else u_on_sstairs; 1088. 		   } else u_on_dnstairs; 1089. 		} 1090. 		/* Remove bug which crashes with levitation/punishment  KAA */ 1091. 		if (Punished && !Levitation) { 1092. 			pline("With great effort you climb the %s.", 1093. 				at_ladder ? "ladder" : "stairs"); 1094. 		} else if (at_ladder) 1095. 		   You("climb up the ladder."); 1096. 	   } else {	/* down */ 1097. 		if (at_ladder) { 1098. 		   u_on_newpos(xupladder, yupladder); 1099. 		} else { 1100. 		   if (newdungeon) u_on_sstairs; 1101. 		   else u_on_upstairs; 1102. 		} 1103. 		if (u.dz && Flying) 1104. 		   You("fly down along the %s.",  1105. 			at_ladder ? "ladder" : "stairs"); 1106. 		else if (u.dz && 1107. 		    (near_capacity > UNENCUMBERED || Punished || Fumbling)) { 1108. 		   You("fall down the %s.", at_ladder ? "ladder" : "stairs"); 1109. 		   if (Punished) { 1110. 			drag_down; 1111. 			if (carried(uball)) { 1112. 			   if (uwep == uball) 1113. 				setuwep((struct obj *)0); 1114. 			   if (uswapwep == uball) 1115. 				setuswapwep((struct obj *)0); 1116. 			   if (uquiver == uball) 1117. 				setuqwep((struct obj *)0); 1118. 			   freeinv(uball); 1119. 			} 1120. 		    }  1121. 		    losehp(rnd(3), "falling downstairs", KILLED_BY); 1122. #ifdef STEED 1123. 		   if (u.usteed) { 1124. 			dismount_steed(DISMOUNT_FELL); 1125. 			if (Punished) unplacebc; 1126. 		   }  1127. #endif 1128. 		   selftouch("Falling, you"); 1129. 		} else if (u.dz && at_ladder) 1130. 		   You("climb down the ladder."); 1131. 	   }  1132. 	} else {	/* trap door or level_tele or In_endgame */ 1133. 	   if (was_in_W_tower && On_W_tower_level(&u.uz)) 1134. 		/* Stay inside the Wizard's tower when feasible. */ 1135. 		/* Note: up vs down doesn't really matter in this case. */ 1136. 		place_lregion(dndest.nlx, dndest.nly,  1137. 				dndest.nhx, dndest.nhy,  1138. 				0,0, 0,0, LR_DOWNTELE, (d_level *) 0); 1139. 	   else if (up) 1140. 		place_lregion(updest.lx, updest.ly, 1141. 				updest.hx, updest.hy,  1142. 				updest.nlx, updest.nly,  1143. 				updest.nhx, updest.nhy,  1144. 				LR_UPTELE, (d_level *) 0); 1145. 	   else 1146. 		place_lregion(dndest.lx, dndest.ly, 1147. 				dndest.hx, dndest.hy,  1148. 				dndest.nlx, dndest.nly,  1149. 				dndest.nhx, dndest.nhy,  1150. 				LR_DOWNTELE, (d_level *) 0); 1151. 	   if (falling) { 1152. 		if (Punished) ballfall; 1153. 		selftouch("Falling, you"); 1154. 	   }  1155. 	}  1156.  1157. 	if (Punished) placebc; 1158. 	obj_delivery;		/* before killing geno'd monsters' eggs */ 1159. 	losedogs; 1160. 	kill_genocided_monsters; /* for those wiped out while in limbo */ 1161. 	/* 1162. 	 * Expire all timers that have gone off while away. Must be 1163. * after migrating monsters and objects are delivered 1164. 	 * (losedogs and obj_delivery). 1165. 	 */ 1166. 	run_timers; 1167. 1168. 	initrack; 1169. 1170. 	if ((mtmp = m_at(u.ux, u.uy)) != 0  1171. #ifdef STEED  1172. 		&& mtmp != u.usteed  1173. #endif  1174. 		) { 1175. 	   /* There's a monster at your target destination; it might be one 1176. 	      which accompanied you--see mon_arrive(dogmove.c)--or perhaps 1177. 	      it was already here. Randomly move you to an adjacent spot 1178. 	      or else the monster to any nearby location. Prior to 3.3.0 1179. 	      the latter was done unconditionally. */ 1180. 	    coord cc; 1181. 1182. 	    if (!rn2(2) &&  1183. 		    enexto(&cc, u.ux, u.uy, youmonst.data) &&  1184. 		    distu(cc.x, cc.y) <= 2) 1185. 		u_on_newpos(cc.x, cc.y);	/*[maybe give message here?]*/ 1186. 	   else 1187. 		mnexto(mtmp); 1188. 1189. 	    if ((mtmp = m_at(u.ux, u.uy)) != 0) { 1190. 		impossible("mnexto failed (do.c)?"); 1191. 		rloc(mtmp); 1192. 	   }  1193. 	}  1194.  1195. 	/* initial movement of bubbles just before vision_recalc */ 1196. 	if (Is_waterlevel(&u.uz)) 1197. 		movebubbles; 1198. 1199. 	if (level_info[new_ledger].flags & FORGOTTEN) { 1200. 	   forget_map(ALL_MAP);	/* forget the map */ 1201. 	   forget_traps;		/* forget all traps too */ 1202. 	   familiar = TRUE; 1203. 	   level_info[new_ledger].flags &= ~FORGOTTEN; 1204. 	} 1205.  1206. 	/* Reset the screen. */ 1207. 	vision_reset;		/* reset the blockages */ 1208. 	docrt;		/* does a full vision recalc */ 1209. 	flush_screen(1); 1210. 1211. 	/*  1212. 	 *  Move all plines beyond the screen reset. 1213. 	 */ 1214.  1215. 	/* give room entrance message, if any */ 1216. 	check_special_room(FALSE); 1217. 1218. 	/* Check whether we just entered Gehennom. */ 1219. 	if (!In_hell(&u.uz0) && Inhell) { 1220. 	   if (Is_valley(&u.uz)) { 1221. 		You("arrive at the Valley of the Dead..."); 1222. 		pline_The("odor of burnt flesh and decay pervades the air."); 1223. #ifdef MICRO 1224. 		display_nhwindow(WIN_MESSAGE, FALSE); 1225. #endif 1226. 		You_hear("groans and moans everywhere."); 1227. 	   } else pline("It is hot here.  You smell smoke..."); 1228. 	} 1229.  1230. 	if (familiar) { 1231. 	   static const char *fam_msgs[4] = { 1232. 		"You have a sense of deja vu.", 1233. 		"You feel like you've been here before.", 1234. 		"This place %s familiar...", 1235. 		0	/* no message */ 1236. 	   };  1237. 	    static const char *halu_fam_msgs[4] = { 1238. 		"Whoa! Everything %s different.", 1239. 		"You are surrounded by twisty little passages, all alike.", 1240. 		"Gee, this %s like uncle Conan's place...", 1241. 		0	/* no message */ 1242. 	   };  1243. 	    const char *mesg; 1244. 	   char buf[BUFSZ]; 1245. 	   int which = rn2(4); 1246. 1247. 	    if (Hallucination) 1248. 		mesg = halu_fam_msgs[which]; 1249. 	   else 1250. 		mesg = fam_msgs[which]; 1251. 	   if (mesg && index(mesg, '%')) { 1252. 		Sprintf(buf, mesg, !Blind ? "looks" : "seems"); 1253. 		mesg = buf; 1254. 	   }  1255. 	    if (mesg) pline(mesg); 1256. 	} 1257.  1258. #ifdef REINCARNATION 1259. 	if (new && Is_rogue_level(&u.uz)) 1260. 	   You("enter what seems to be an older, more primitive world."); 1261. #endif 1262. 	/* Final confrontation */ 1263. 	if (In_endgame(&u.uz) && newdungeon && u.uhave.amulet) 1264. 		resurrect; 1265. 	if (newdungeon && In_V_tower(&u.uz) && In_hell(&u.uz0)) 1266. 		pline_The("heat and smoke are gone."); 1267. 1268. 	/* the message from your quest leader */ 1269. 	if (!In_quest(&u.uz0) && at_dgn_entrance("The Quest") && 1270. 		!(u.uevent.qexpelled || u.uevent.qcompleted || quest_status.leader_is_dead)) { 1271. 1272. 		if (u.uevent.qcalled) { 1273. 			com_pager(Role_if(PM_ROGUE) ? 4 : 3); 1274. 		} else { 1275. 			com_pager(2); 1276. 			u.uevent.qcalled = TRUE; 1277. 		} 1278. 	}  1279.  1280. 	/* once Croesus is dead, his alarm doesn't work any more */ 1281. 	if (Is_knox(&u.uz) && (new || !mvitals[PM_CROESUS].died)) { 1282. 		You("penetrated a high security area!"); 1283. 		pline("An alarm sounds!"); 1284. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1285. 		   if (!DEADMONSTER(mtmp) && mtmp->msleeping) mtmp->msleeping = 0; 1286. 	} 1287.  1288. 	if (on_level(&u.uz, &astral_level)) 1289. 	   final_level; 1290. 	else 1291. 	   onquest; 1292. 	assign_level(&u.uz0, &u.uz); /* reset u.uz0 */ 1293. 1294. #ifdef INSURANCE 1295. 	save_currentstate; 1296. #endif 1297. 1298. 	(void) pickup(1); 1299. } 1300.  1301. STATIC_OVL void 1302. final_level 1303. { 1304. 	struct monst *mtmp; 1305. 	struct obj *otmp; 1306. 	coord mm; 1307. 	int i; 1308. 1309. 	/* reset monster hostility relative to player */ 1310. 	for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1311. 	   if (!DEADMONSTER(mtmp)) reset_hostility(mtmp); 1312. 1313. 	/* create some player-monsters */ 1314. 	create_mplayers(rn1(4, 3), TRUE); 1315. 1316. 	/* create a guardian angel next to player, if worthy */ 1317. 	if (Conflict) { 1318. 	   pline(  1319. 	     "A voice booms: \"Thy desire for conflict shall be fulfilled!\""); 1320. 	   for (i = rnd(4); i > 0; --i) { 1321. 		mm.x = u.ux; 1322. 		mm.y = u.uy; 1323. 		if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) 1324. 		   (void) mk_roamer(&mons[PM_ANGEL], u.ualign.type,  1325. 				     mm.x, mm.y, FALSE); 1326. 	   }  1327.  1328. 	} else if (u.ualign.record > 8) {	/* fervent */ 1329. 	   pline("A voice whispers: \"Thou hast been worthy of me!\""); 1330. 	   mm.x = u.ux; 1331. 	   mm.y = u.uy; 1332. 	   if (enexto(&mm, mm.x, mm.y, &mons[PM_ANGEL])) { 1333. 		if ((mtmp = mk_roamer(&mons[PM_ANGEL], u.ualign.type, 1334. 				      mm.x, mm.y, TRUE)) != 0) { 1335. 		   if (!Blind) 1336. 			pline("An angel appears near you."); 1337. 		   else 1338. 			You_feel("the presence of a friendly angel near you."); 1339. 		   /* guardian angel -- the one case mtame doesn't  1340. * imply an edog structure, so we don't want to 1341. * call tamedog. 1342. 		    */  1343. 		    mtmp->mtame = 10; 1344. 		   /* make him strong enough vs. endgame foes */ 1345. 		   mtmp->m_lev = rn1(8,15); 1346. 		   mtmp->mhp = mtmp->mhpmax = 1347. 					d((int)mtmp->m_lev,10) + 30 + rnd(30); 1348. 		   if ((otmp = select_hwep(mtmp)) == 0) { 1349. 			otmp = mksobj(SILVER_SABER, FALSE, FALSE); 1350. 			if (mpickobj(mtmp, otmp)) 1351. 			   panic("merged weapon?"); 1352. 		   }  1353. 		    bless(otmp); 1354. 		   if (otmp->spe < 4) otmp->spe += rnd(4); 1355. 		   if ((otmp = which_armor(mtmp, W_ARMS)) == 0 ||  1356. 			    otmp->otyp != SHIELD_OF_REFLECTION) { 1357. 			(void) mongets(mtmp, AMULET_OF_REFLECTION); 1358. 			m_dowear(mtmp, TRUE); 1359. 		   }  1360. 		}  1361. 	    }  1362. 	}  1363. }  1364.  1365. static char *dfr_pre_msg = 0,	/* pline before level change */ 1366. 	   *dfr_post_msg = 0;	/* pline after level change */ 1367. 1368. /* change levels at the end of this turn, after monsters finish moving */ 1369. void 1370. schedule_goto(tolev, at_stairs, falling, portal_flag, pre_msg, post_msg) 1371. d_level *tolev; 1372. boolean at_stairs, falling; 1373. int portal_flag; 1374. const char *pre_msg, *post_msg; 1375. { 1376. 	int typmask = 0100;		/* non-zero triggers `deferred_goto' */ 1377. 1378. 	/* destination flags (`goto_level' args) */ 1379. 	if (at_stairs)	 typmask |= 1; 1380. 	if (falling)	 typmask |= 2; 1381. 	if (portal_flag) typmask |= 4; 1382. 	if (portal_flag < 0) typmask |= 0200;	/* flag for portal removal */ 1383. 	u.utotype = typmask; 1384. 	/* destination level */ 1385. 	assign_level(&u.utolev, tolev); 1386. 1387. 	if (pre_msg) 1388. 	   dfr_pre_msg = strcpy((char *)alloc(strlen(pre_msg) + 1), pre_msg); 1389. 	if (post_msg) 1390. 	   dfr_post_msg = strcpy((char *)alloc(strlen(post_msg)+1), post_msg); 1391. } 1392.  1393. /* handle something like portal ejection */ 1394. void 1395. deferred_goto 1396. { 1397. 	if (!on_level(&u.uz, &u.utolev)) { 1398. 	   d_level dest; 1399. 	   int typmask = u.utotype; /* save it; goto_level zeroes u.utotype */ 1400. 1401. 	    assign_level(&dest, &u.utolev); 1402. 	   if (dfr_pre_msg) pline(dfr_pre_msg); 1403. 	   goto_level(&dest, !!(typmask&1), !!(typmask&2), !!(typmask&4)); 1404. 	   if (typmask & 0200) {	/* remove portal */ 1405. 		struct trap *t = t_at(u.ux, u.uy); 1406. 1407. 		if (t) { 1408. 		   deltrap(t); 1409. 		   newsym(u.ux, u.uy); 1410. 		} 1411. 	    }  1412. 	    if (dfr_post_msg) pline(dfr_post_msg); 1413. 	} 1414. 	u.utotype = 0;		/* our caller keys off of this */ 1415. 	if (dfr_pre_msg) 1416. 	   free((genericptr_t)dfr_pre_msg),  dfr_pre_msg = 0; 1417. 	if (dfr_post_msg) 1418. 	   free((genericptr_t)dfr_post_msg),  dfr_post_msg = 0; 1419. } 1420.  1421. #endif /* OVL2 */ 1422. #ifdef OVL3 1423. 1424. /*  1425.  * Return TRUE if we created a monster for the corpse. If successful, the 1426. * corpse is gone. 1427. */  1428. boolean 1429. revive_corpse(corpse) 1430. struct obj *corpse; 1431. { 1432.     struct monst *mtmp, *mcarry; 1433.    boolean is_uwep, chewed; 1434.    xchar where; 1435.    char *cname, cname_buf[BUFSZ]; 1436.    struct obj *container = (struct obj *)0; 1437.    int container_where = 0; 1438.     1439.     where = corpse->where; 1440.    is_uwep = corpse == uwep; 1441.    cname = eos(strcpy(cname_buf, "bite-covered ")); 1442.    Strcpy(cname, corpse_xname(corpse, TRUE)); 1443.    mcarry = (where == OBJ_MINVENT) ? corpse->ocarry : 0; 1444. 1445.     if (where == OBJ_CONTAINED) { 1446.    	struct monst *mtmp2 = (struct monst *)0; 1447. 	container = corpse->ocontainer; 1448.    	mtmp2 = get_container_location(container, &container_where, (int *)0); 1449. 	/* container_where is the outermost container's location even if nested */ 1450. 	if (container_where == OBJ_MINVENT && mtmp2) mcarry = mtmp2; 1451.    }  1452.     mtmp = revive(corpse);	/* corpse is gone if successful */ 1453. 1454.     if (mtmp) { 1455. 	chewed = (mtmp->mhp < mtmp->mhpmax); 1456. 	if (chewed) cname = cname_buf;	/* include "bite-covered" prefix */ 1457. 	switch (where) { 1458. 	   case OBJ_INVENT: 1459. 		if (is_uwep) 1460. 		   pline_The("%s writhes out of your grasp!", cname); 1461. 		else 1462. 		   You_feel("squirming in your backpack!"); 1463. 		break; 1464. 1465. 	    case OBJ_FLOOR: 1466. 		if (cansee(mtmp->mx, mtmp->my)) 1467. 		   pline("%s rises from the dead!", chewed ?  1468. 			  Adjmonnam(mtmp, "bite-covered") : Monnam(mtmp)); 1469. 		break; 1470. 1471. 	    case OBJ_MINVENT:		/* probably a nymph's */ 1472. 		if (cansee(mtmp->mx, mtmp->my)) { 1473. 		   if (canseemon(mcarry)) 1474. 			pline("Startled, %s drops %s as it revives!", 1475. 			      mon_nam(mcarry), an(cname)); 1476. 		   else 1477. 			pline("%s suddenly appears!", chewed ? 1478. 			      Adjmonnam(mtmp, "bite-covered") : Monnam(mtmp)); 1479. 		} 1480. 		break; 1481. 	  case OBJ_CONTAINED: 1482. 	  	if (container_where == OBJ_MINVENT && cansee(mtmp->mx, mtmp->my) &&  1483. 		    mcarry && canseemon(mcarry) && container) { 1484. 		       char sackname[BUFSZ]; 1485. 		       Sprintf(sackname, "%s %s", s_suffix(mon_nam(mcarry)),  1486. 				xname(container)); 1487. 	  		pline("%s writhes out of %s!", Amonnam(mtmp), sackname); 1488. 	  	} else if (container_where == OBJ_INVENT && container) { 1489. 		       char sackname[BUFSZ]; 1490. 		       Strcpy(sackname, an(xname(container))); 1491. 	  		pline("%s %s out of %s in your pack!",  1492. 	   			Blind ? Something : Amonnam(mtmp),  1493. 				locomotion(mtmp->data,"writhes"),  1494. 	   			sackname); 1495. 	  	} else if (container_where == OBJ_FLOOR && container &&  1496. 		            cansee(mtmp->mx, mtmp->my)) { 1497. 		       char sackname[BUFSZ]; 1498. 		       Strcpy(sackname, an(xname(container))); 1499. 			pline("%s escapes from %s!", Amonnam(mtmp), sackname); 1500. 		} 1501. 		break; 1502. 	   default: 1503. 		/* we should be able to handle the other cases... */ 1504. 		impossible("revive_corpse: lost corpse @ %d", where); 1505. 		break; 1506. 	} 1507. 	return TRUE; 1508.    }  1509.     return FALSE; 1510. } 1511.  1512. /* Revive the corpse via a timeout. */ 1513. /*ARGSUSED*/ 1514. void 1515. revive_mon(arg, timeout) 1516. genericptr_t arg; 1517. long timeout; 1518. { 1519.     struct obj *body = (struct obj *) arg; 1520. 1521.     /* if we succeed, the corpse is gone, otherwise, rot it away */ 1522.    if (!revive_corpse(body)) { 1523. 	if (is_rider(&mons[body->corpsenm])) 1524. 	   You_feel("less hassled."); 1525. 	(void) start_timer(250L - (monstermoves-body->age), 1526. 					TIMER_OBJECT, ROT_CORPSE, arg); 1527.    }  1528. }  1529.  1530. int 1531. donull 1532. { 1533. 	return(1);	/* Do nothing, but let other things happen */ 1534. } 1535.  1536. #endif /* OVL3 */ 1537. #ifdef OVLB 1538. 1539. STATIC_PTR int 1540. wipeoff 1541. { 1542. 	if(u.ucreamed < 4)	u.ucreamed = 0; 1543. 	else			u.ucreamed -= 4; 1544. 	if (Blinded < 4)	Blinded = 0; 1545. 	else			Blinded -= 4; 1546. 	if (!Blinded) { 1547. 		pline("You've got the glop off."); 1548. 		u.ucreamed = 0; 1549. 		Blinded = 1; 1550. 		make_blinded(0L,TRUE); 1551. 		return(0); 1552. 	} else if (!u.ucreamed) { 1553. 		Your("%s feels clean now.", body_part(FACE)); 1554. 		return(0); 1555. 	} 1556. 	return(1);		/* still busy */ 1557. } 1558.  1559. int 1560. dowipe 1561. { 1562. 	if(u.ucreamed)  { 1563. 		static NEARDATA char buf[39]; 1564. 1565. 		Sprintf(buf, "wiping off your %s", body_part(FACE)); 1566. 		set_occupation(wipeoff, buf, 0); 1567. 		/* Not totally correct; what if they change back after now 1568. 		 * but before they're finished wiping? 1569. 		 */ 1570. 		return(1); 1571. 	} 1572. 	Your("%s is already clean.", body_part(FACE)); 1573. 	return(1); 1574. } 1575.  1576. void 1577. set_wounded_legs(side, timex) 1578. register long side; 1579. register int timex; 1580. { 1581. 	/* KMH -- STEED 1582. 	 * If you are riding, your steed gets the wounded legs instead. 1583. 	 * You still call this function, but don't lose hp. 1584. 	 * Caller is also responsible for adjusting messages. 1585. 	 */ 1586.  1587. 	if(!Wounded_legs) { 1588. 		ATEMP(A_DEX)--; 1589. 		flags.botl = 1; 1590. 	} 1591.  1592. 	if(!Wounded_legs || (HWounded_legs & TIMEOUT)) 1593. 		HWounded_legs = timex; 1594. 	EWounded_legs = side; 1595. 	(void)encumber_msg; 1596. } 1597.  1598. void 1599. heal_legs 1600. { 1601. 	if(Wounded_legs) { 1602. 		if (ATEMP(A_DEX) < 0) { 1603. 			ATEMP(A_DEX)++; 1604. 			flags.botl = 1; 1605. 		} 1606.  1607. #ifdef STEED 1608. 		if (!u.usteed) 1609. #endif 1610. 		{ 1611. 			/* KMH, intrinsics patch */ 1612. 			if((EWounded_legs & BOTH_SIDES) == BOTH_SIDES) { 1613. 			Your("%s feel somewhat better.", 1614. 				makeplural(body_part(LEG))); 1615. 		} else { 1616. 			Your("%s feels somewhat better.", 1617. 				body_part(LEG)); 1618. 		} 1619. 		}  1620. 		HWounded_legs = EWounded_legs = 0; 1621. 	} 1622. 	(void)encumber_msg; 1623. } 1624.  1625. #endif /* OVLB */ 1626. 1627. /*do.c*/