Source:NetHack 3.1.0/hack.c

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

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

1.   /*	SCCS Id: @(#)hack.c	3.1	92/12/04	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6. 7.   STATIC_DCL int NDECL(moverock); 8.   #ifdef POLYSELF 9.   STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P)); 10.  #endif 11.  #ifdef SINKS 12.  STATIC_DCL void NDECL(dosinkfall); 13.  #endif 14.  STATIC_DCL boolean FDECL(bad_rock,(XCHAR_P,XCHAR_P)); 15.  STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int)); 16.   17.   static void FDECL(move_update, (BOOLEAN_P)); 18.   19.   #define IS_SHOP(x)	(rooms[x].rtype >= SHOPBASE) 20.   21.   #ifdef OVL2 22.   23.   boolean 24.  revive_nasty(x, y, msg) 25.  int x,y; 26.  const char *msg; 27.  {  28.       register struct obj *otmp, *otmp2; 29.      struct monst *mtmp; 30.      coord cc; 31.      boolean revived = FALSE; 32.   33.       /* prevent freeobj of revivable corpses */ 34.      for(otmp = level.objects[x][y]; otmp; otmp = otmp2) { 35.  	otmp2 = otmp->nexthere; 36.  	if (otmp->otyp == CORPSE &&  37.   	    (is_rider(&mons[otmp->corpsenm]) || 38.  	     otmp->corpsenm == PM_WIZARD_OF_YENDOR)) { 39.  	    /* move any living monster already at that location */ 40.  	    if((mtmp = m_at(x,y)) && enexto(&cc, x, y, mtmp->data)) 41.  		rloc_to(mtmp, cc.x, cc.y); 42.  	    if(msg) Norep("%s", msg); 43.  	    revive_corpse(otmp, 0, FALSE); 44.  	    revived = MON_AT(x,y); 45.  	}  46.       }  47.    48.       /* this location might not be safe, if not, move revived monster */ 49.      if (revived) { 50.  	mtmp = m_at(x,y); 51.  	if (mtmp && !goodpos(x, y, mtmp, mtmp->data) &&  52.   	    enexto(&cc, x, y, mtmp->data)) { 53.  	    rloc_to(mtmp, cc.x, cc.y); 54.  	}  55.   	/* else impossible? */ 56.       }  57.    58.       return (revived); 59.  }  60.    61.   STATIC_OVL int 62.  moverock 63.  {  64.       register xchar rx, ry; 65.      register struct obj *otmp, *otmp2; 66.      register struct trap *ttmp; 67.      register struct monst *mtmp; 68.   69.       while ((otmp = sobj_at(BOULDER, u.ux+u.dx, u.uy+u.dy)) != 0) { 70.  	rx = u.ux+2*u.dx; 71.  	ry = u.uy+2*u.dy; 72.  	nomul(0); 73.  	if (Levitation || Is_airlevel(&u.uz)) { 74.  	    if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 75.  	    You("don't have enough leverage to push %s.", the(xname(otmp))); 76.  	    /* Give them a chance to climb over it? */ 77.   	    return -1; 78.  	}  79.   #ifdef POLYSELF 80.  	if (verysmall(uasmon)) { 81.  	    if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 82.  	    pline("You're too small to push that %s.", xname(otmp)); 83.  	    goto cannot_push; 84.  	}  85.   #endif 86.  	if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&  87.   	    (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (  88.   #ifdef REINCARNATION  89.   		!Is_rogue_level(&u.uz) &&  90.   #endif  91.   		(levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) &&  92.   	    !sobj_at(BOULDER, rx, ry)) { 93.  	    ttmp = t_at(rx, ry); 94.  	    mtmp = m_at(rx, ry); 95.   96.   	    if (revive_nasty(rx, ry, "You sense movement on the other side.")) 97.  		return (-1); 98.   99.   	    if (mtmp && (!mtmp->mtrapped || 100. 			 !(ttmp && ((ttmp->ttyp == PIT) || 101. 				    (ttmp->ttyp == SPIKED_PIT))))) { 102. 		if (canseemon(mtmp)) 103. 		    pline("There's %s on the other side.", mon_nam(mtmp)); 104. 		else { 105. 		    if (Blind) feel_location(u.ux+u.dx,u.uy+u.dy); 106. 		    You("hear a monster behind %s.", the(xname(otmp))); 107. 		}  108.  		if (flags.verbose) 109. 		    pline("Perhaps that's why you cannot move it."); 110. 		goto cannot_push; 111. 	    }  112.   113.  	    if (ttmp) 114. 		switch(ttmp->ttyp) { 115. 		case SPIKED_PIT: 116. 		case PIT: 117. 		    freeobj(otmp); 118. 		    if (!flooreffects(otmp, rx, ry, "fall")) { 119. 			place_object(otmp, rx, ry); 120. 			otmp->nobj = fobj; 121. 			fobj = otmp; 122. 		    }  123.  		    continue; 124. 		case TRAPDOOR: 125. 		    pline("%s falls into and plugs a hole in the ground!",  126.  			  The(xname(otmp))); 127. 		    deltrap(ttmp); 128. 		    delobj(otmp); 129. 		    delallobj(rx, ry); 130. 		    if (cansee(rx,ry)) newsym(rx,ry); 131. 		    continue; 132. 		case LEVEL_TELEP: 133. 		case TELEP_TRAP: 134. 		    You("push %s and suddenly it disappears!",  135.  			the(xname(otmp))); 136. 		    rloco(otmp); 137. 		    continue; 138. 		}  139.  	    if (closed_door(rx, ry)) 140. 		goto nopushmsg; 141. 	    if (boulder_hits_pool(otmp, rx, ry, TRUE)) 142. 		continue; 143. 	    /*  144.  	     * Re-link at top of fobj chain so that pile order is preserved 145. 	     * when level is restored. 146. 	     */  147.  	    if (otmp != fobj) { 148. 		otmp2 = fobj; 149. 		while (otmp2->nobj && otmp2->nobj != otmp) 150. 		    otmp2 = otmp2->nobj; 151. 		if (!otmp2->nobj) { 152. 		    impossible("moverock: error in fobj chain"); 153. 		} else { 154. 		    otmp2->nobj = otmp->nobj; 155. 		    otmp->nobj = fobj; 156. 		    fobj = otmp; 157. 		}  158.  	    }  159.   160.  	    {  161.  #ifdef LINT /* static long lastmovetime; */ 162. 		long lastmovetime; 163. 		lastmovetime = 0; 164. #else 165. 		static long NEARDATA lastmovetime; 166. #endif 167. 		/* note: this var contains garbage initially and 168. 		   after a restore */ 169. 		if (moves > lastmovetime+2 || moves < lastmovetime) 170. 		    pline("With great effort you move %s.", the(xname(otmp))); 171. 		exercise(A_STR, TRUE); 172. 		lastmovetime = moves; 173. 	    }  174.   175.  	    /* Move the boulder *after* the message. */ 176.  	    move_object(otmp, rx, ry); 177. 	    if (Blind) { 178. 		feel_location(rx,ry); 179. 		feel_location(u.ux+u.dx, u.uy+u.dy); 180. 	    } else { 181. 		newsym(rx,ry); 182. 		newsym(u.ux+u.dx, u.uy+u.dy); 183. 	    }  184.  	} else { 185. 	nopushmsg: 186. 	    You("try to move %s, but in vain.", the(xname(otmp))); 187. 	    if (Blind) feel_location(u.ux+u.dx, u.uy+u.dy); 188. 	cannot_push: 189. #ifdef POLYSELF 190. 	    if (throws_rocks(uasmon)) { 191. 		if (!flags.pickup) 192. 		    pline("However, you easily can push it aside."); 193. 		else 194. 		    pline("However, you easily can pick it up."); 195. 		break; 196. 	    }  197.  #endif 198. 	    if (((!invent || inv_weight <= -850) && 199. 		 (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ) 200. 				     && IS_ROCK(levl[u.ux+u.dx][u.uy].typ))))  201.  #ifdef POLYSELF  202.  		|| verysmall(uasmon)  203.  #endif  204.  		) { 205. 		pline("However, you can squeeze yourself into a small opening."); 206. 		break; 207. 	    } else 208. 		return (-1); 209. 	}  210.      }  211.      return (0); 212. }  213.   214.  #ifdef POLYSELF 215. /*  216.   *  still_chewing 217.  *   218.   *  Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE 219.  *  when done. 220.  */  221.  STATIC_OVL int 222. still_chewing(x,y) 223.     xchar x, y;  224. { 225.      struct rm *lev      = &(levl[x][y]); 226.     struct obj *boulder = sobj_at(BOULDER,x,y); 227.  228.      if (dig_pos.x != x || dig_pos.y != y ||  229.  				!on_level(&dig_level, &u.uz) || dig_down) { 230. 	if (!boulder && (lev->diggable & W_NONDIGGABLE)) 231. 	    You("hurt your teeth on the hard stone."); 232. 	else { 233. 	    dig_down = FALSE; 234. 	    dig_pos.x = x;  235. dig_pos.y = y; 236. assign_level(&dig_level, &u.uz); 237. 	    dig_effort = IS_ROCK(lev->typ) ? 30 : 60; /* rock takes more time */ 238. 	    if (boulder) 239. 		You("start chewing on a boulder."); 240. 	    else 241. 		You("start chewing a hole in the %s.",  242.  					IS_ROCK(lev->typ) ? "rock" : "door"); 243. 	}  244.  	return 1; 245.     } else if ((dig_effort += 30) < 100)  { 246. 	if (flags.verbose) 247. 	    You("continue chewing on the %s.", boulder ? "boulder" :  248.  					(IS_ROCK(lev->typ) ? "rock" : "door")); 249. 	return 1; 250.     }  251.   252.      if (boulder) { 253. 	You("eat the boulder.");	/* yum */ 254. 	delobj(boulder);		/* boulder goes bye-bye */ 255.  256.  	/*  257.  	 *  The location could still block because of  258. * 	1. More than one boulder 259. 	 *  	2. Boulder stuck in a wall/stone/door. 260. 	 *  261.  	 *  [perhaps use does_block below (from vision.c)] 262. 	 */  263.  	if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) { 264. 	    block_point(x,y);	/* delobj will unblock the point */ 265. 	    dig_pos.x = 0;	/* reset dig messages */ 266. 	    return 1; 267. 	}  268.  	  269.      } else if (IS_WALL(lev->typ)) { 270. 	You("chew a hole in the wall."); 271. 	if (level.flags.is_maze_lev) { 272. 	    lev->typ = ROOM; 273. 	} else if (level.flags.is_cavernous_lev) { 274. 	    lev->typ = CORR; 275. 	} else { 276. 	    lev->typ = DOOR; 277. 	    lev->doormask = D_NODOOR; 278. 	}  279.      } else if (lev->typ == SDOOR) { 280. 	if (lev->doormask & D_TRAPPED) { 281. 	    b_trapped("secret door"); 282. 	    lev->doormask = D_NODOOR; 283. 	} else { 284. 	    You("chew through the secret door."); 285. 	    lev->doormask = D_BROKEN; 286. 	}  287.  	lev->typ = DOOR; 288.  289.      } else if (IS_DOOR(lev->typ)) { 290. 	if (lev->doormask & D_TRAPPED) { 291. 	    b_trapped("door"); 292. 	    lev->doormask = D_NODOOR; 293. 	} else { 294. 	    You("chew through the door."); 295. 	    lev->doormask = D_BROKEN; 296. 	}  297.   298.      } else { /* STONE or SCORR */ 299. 	You("chew a passage through the rock."); 300. 	lev->typ = CORR; 301.     }  302.   303.      unblock_point(x, y);	/* vision */ 304.     newsym(x, y); 305.     dig_level.dnum = 0; 306.     dig_level.dlevel = -1; 307.     return 0; 308. }  309.  #endif /* POLYSELF */ 310.  311.  #endif /* OVL2 */ 312. #ifdef OVLB 313.  314.  void 315. movobj(obj, ox, oy) 316. register struct obj *obj; 317. register xchar ox, oy; 318. {  319.  	remove_object(obj); 320. 	newsym(obj->ox, obj->oy); 321. 	place_object(obj, ox, oy); 322. 	newsym(ox, oy); 323. }  324.   325.  #ifdef SINKS 326. STATIC_OVL void 327. dosinkfall 328. {  329.  	register struct obj *obj; 330.  331.  # ifdef POLYSELF 332. 	if (is_floater(uasmon)) { 333. 		You("wobble unsteadily for a moment."); 334. 	} else { 335. # endif 336. 		You("crash to the floor!"); 337. 		losehp((rn1(10, 20 - (int)ACURR(A_CON))),  338.  			"fell onto a sink", NO_KILLER_PREFIX); 339. 		exercise(A_DEX, FALSE); 340. 		for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 341. 		    if(obj->oclass == WEAPON_CLASS) { 342. 			You("fell on %s.",doname(obj)); 343. 			losehp(rn2(3),"fell onto a sink", NO_KILLER_PREFIX); 344. 			exercise(A_CON, FALSE); 345. 		    }  346.  # ifdef POLYSELF 347. 	}  348.  # endif 349.  350.  	HLevitation = (HLevitation & ~TIMEOUT) + 1; 351. 	if(uleft && uleft->otyp == RIN_LEVITATION) { 352. 	    obj = uleft; 353. 	    Ring_off(obj); 354. 	    off_msg(obj); 355. 	}  356.  	if(uright && uright->otyp == RIN_LEVITATION) { 357. 	    obj = uright; 358. 	    Ring_off(obj); 359. 	    off_msg(obj); 360. 	}  361.  	if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 362. 	    obj = uarmf; 363. 	    (void)Boots_off; 364. 	    off_msg(obj); 365. 	}  366.  	HLevitation--; 367. }  368.  #endif 369.  370.  #endif /* OVLB */ 371.  372.  #ifdef OVLB 373.  374.  boolean 375. may_dig(x,y) 376. register xchar x,y; 377. /* intended to be called only on ROCKs */ 378. {  379.  return (!(IS_STWALL(levl[x][y].typ) && (levl[x][y].diggable & W_NONDIGGABLE))); 380. }  381.   382.  #endif /* OVLB */ 383. #ifdef OVL1 384.  385.  STATIC_OVL boolean 386. bad_rock(x,y) 387. register xchar x,y; 388. {  389.  	return(IS_ROCK(levl[x][y].typ)  390.  #ifdef POLYSELF  391.  		    && !passes_walls(uasmon)  392.  		    && (!tunnels(uasmon) || needspick(uasmon) || !may_dig(x,y))  393.  #endif  394.  	); 395. }  396.   397.  boolean 398. invocation_pos(x, y)  399. xchar x, y; 400. { 401.          return(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y); 402. }  403.   404.  #endif /* OVL1 */ 405. #ifdef OVL3 406.  407.  void 408. domove 409. {  410.  	register struct monst *mtmp; 411. 	register struct rm *tmpr,*ust; 412. 	register xchar x,y; 413. 	struct trap *trap; 414. 	int wtcap; 415. 	boolean on_ice; 416. 	xchar chainx, chainy, ballx, bally;	/* ball&chain new positions */ 417. 	int bc_control;				/* control for ball&chain */ 418.  419.  	u_wipe_engr(rnd(5)); 420.  421.  	if(((wtcap = near_capacity) >= OVERLOADED 422. 	    || (wtcap > SLT_ENCUMBER && (u.uhp < 10 && u.uhp != u.uhpmax)))  423.  	   && !Is_airlevel(&u.uz)) { 424. 	    if(wtcap < OVERLOADED) { 425. 		You("don't have enough stamina to move."); 426. 	        exercise(A_CON, FALSE); 427. 	    } else 428. 		You("collapse under your load."); 429. 	    nomul(0); 430. 	    return; 431. 	}  432.  	if(u.uswallow) { 433. 		u.dx = u.dy = 0; 434. 		u.ux = x = u.ustuck->mx; 435. 		u.uy = y = u.ustuck->my; 436. 		mtmp = u.ustuck; 437. 	} else { 438. 		if(Is_airlevel(&u.uz) && rn2(4) && !Levitation  439.  #ifdef POLYSELF  440.  		   && !is_flyer(uasmon)  441.  #endif  442.  		   ) { 443. 		    switch(rn2(3)) { 444. 		    case 0: 445. 			You("tumble in place."); 446. 			exercise(A_DEX, FALSE); 447. 			break; 448. 		    case 1: 449. 			You("can't control your movements very well."); break; 450. 		    case 2: 451. 			pline("It's hard to walk in thin air."); 452. 			exercise(A_DEX, TRUE); 453. 			break; 454. 		    }  455.  		    return; 456. 		}  457.   458.  		/* check slippery ice */ 459. 		on_ice = !Levitation && is_ice(u.ux, u.uy); 460. 		if (on_ice) { 461. 		    static int skates = 0; 462. 		    if (!skates) skates = find_skates; 463. 		    if ((uarmf && uarmf->otyp == skates)  464.  #ifdef POLYSELF  465.  			|| resists_cold(uasmon) || is_flyer(uasmon)  466.  			|| is_floater(uasmon) || is_clinger(uasmon)  467.  			|| is_whirly(uasmon)  468.  #endif  469.  		       ) on_ice = FALSE; 470. 		    else if (!rn2(Cold_resistance ? 3 : 2)) { 471.  			Fumbling |= FROMOUTSIDE; 472. 			if (!(Fumbling & TIMEOUT)) Fumbling += rnd(20); 473. 		    }  474.  		}  475.  		if (!on_ice && (Fumbling & FROMOUTSIDE)) { 476. 		    Fumbling &= ~FROMOUTSIDE; 477. 		    if (!(Fumbling & ~TIMEOUT)) Fumbling = 0; 478. 		}  479.   480.  		x = u.ux + u.dx; 481. 		y = u.uy + u.dy; 482. 		if(Stunned || (Confusion && !rn2(5))) { 483. 			register int tries = 0; 484.  485.  			do { 486. 				if(tries++ > 50) { 487. 					nomul(0); 488. 					return; 489. 				}  490.  				confdir; 491. 				x = u.ux + u.dx; 492. 				y = u.uy + u.dy; 493. 			} while(!isok(x, y) || bad_rock(x, y)); 494. 		}  495.  		if(!isok(x, y)) { 496. 			nomul(0); 497. 			return; 498. 		}  499.  		if((trap = t_at(x, y)) && trap->tseen) { 500. 			if(flags.run >= 2) { 501. 				nomul(0); 502. 				flags.move = 0; 503. 				return; 504. 			} else 505. 				nomul(0); 506. 		}  507.  			  508.  		if(u.ustuck && (x != u.ustuck->mx || 509. 				y != u.ustuck->my)) { 510. 			if (distu(u.ustuck->mx, u.ustuck->my) > 2) { 511. 			/* perhaps it fled (or was teleported or ... ) */ 512. 				u.ustuck = 0; 513. 			} else { 514. #ifdef POLYSELF 515. 				/* If polymorphed into a sticking monster, 516. 				 * u.ustuck means it's stuck to you, not you 517. 				 * to it. 518. 				 */  519.  				if (sticks(uasmon)) { 520. 					You("release %s.", mon_nam(u.ustuck)); 521. 					u.ustuck = 0; 522. 				} else { 523. #endif 524. 					You("cannot escape from %s!",  525.  					    mon_nam(u.ustuck)); 526. 					nomul(0); 527. 					return; 528. #ifdef POLYSELF 529. 				}  530.  #endif 531. 			}  532.  		}  533.  		mtmp = m_at(x,y); 534. 		if (mtmp) { 535. 			/* Don't attack if you're running, and can see it */ 536. 			if (flags.run &&  537.  			    ((!Blind && mon_visible(mtmp) &&  538.  			      ((mtmp->m_ap_type != M_AP_FURNITURE &&  539.  				mtmp->m_ap_type != M_AP_OBJECT) || 540. 			       Protection_from_shape_changers)) || 541. 			     sensemon(mtmp))) { 542. 				nomul(0); 543. 				flags.move = 0; 544. 				return; 545. 			}  546.  		}  547.  	}  548.   549.  	u.ux0 = u.ux; 550. 	u.uy0 = u.uy; 551. 	bhitpos.x = x;  552. bhitpos.y = y; 553. tmpr = &levl[x][y]; 554.  555.  	/* attack monster */ 556. 	if(mtmp) { 557. 	    nomul(0); 558. 	    /* only attack if we know it's there */ 559. 	    /* or if it hides_under, in which case we call attack to print 560. 	     * the Wait! message. 561. 	     * This is different from ceiling hiders, who aren't handled in  562. * attack. 563. 	     */  564.  	    if(!mtmp->mundetected || sensemon(mtmp) ||  565.  			(hides_under(mtmp->data) && !is_safepet(mtmp))){ 566. 		gethungry; 567. 		if(wtcap >= HVY_ENCUMBER && moves%3) { 568. 		    if(u.uhp > 1) 569. 			u.uhp--; 570. 		    else { 571. 			pline("You pass out from exertion!"); 572. 			exercise(A_CON, FALSE); 573. 			nomul(-10); 574. 			u.usleep = 1; 575. 		    }  576.  		}  577.  		if(multi < 0) return;	/* we just fainted */ 578.  579.  		/* try to attack; note that it might evade */ 580. 		/* also, we don't attack tame when _safepet_ */ 581. 		if(attack(mtmp)) return; 582. 	    }  583.  	}  584.   585.  	/* not attacking an animal, so we try to move */ 586. #ifdef POLYSELF 587. 	if(!uasmon->mmove) { 588. 		You("are rooted %s.",  589.  		    Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?  590.  		    "in place" : "to the ground"); 591. 		nomul(0); 592. 		return; 593. 	}  594.  #endif 595. 	if(u.utrap) { 596. 		if(u.utraptype == TT_PIT) { 597. 		    if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) { 598. 			Your("%s gets stuck in a crevice.", body_part(LEG)); 599. 			display_nhwindow(WIN_MESSAGE, FALSE); 600. 			clear_nhwindow(WIN_MESSAGE); 601. 			You("free your %s.", body_part(LEG)); 602. 		    } else if (!(--u.utrap)) { 603. 			You("crawl to the edge of the pit."); 604. 			fill_pit(u.ux, u.uy); 605. 			vision_full_recalc = 1;	/* vision limits change */ 606. 		    } else if (flags.verbose) 607. 			Norep( (Hallucination && !rn2(5)) ?  608.  				"You've fallen, and you can't get up." :  609.  				"You are still in a pit." ); 610. 		} else if (u.utraptype == TT_LAVA) { 611. 		    if(flags.verbose) 612. 		    	Norep("You are stuck in the lava."); 613. 		    if(!is_lava(x,y)) { 614. 			u.utrap--; 615. 			if((u.utrap & 0xff) == 0) { 616. 			    You("pull yourself to the edge of the lava."); 617. 			    u.utrap = 0; 618. 			}  619.  		    }  620.  		    u.umoved = TRUE; 621. 		} else if (u.utraptype == TT_WEB) { 622. 		    if(--u.utrap) { 623. 			if(flags.verbose) 624. 			    Norep("You are stuck to the web."); 625. 		    } else You("disentangle yourself."); 626. 		} else if (u.utraptype == TT_INFLOOR) { 627. 		    if(--u.utrap) { 628. 			if(flags.verbose) 629. 			    Norep("You are stuck in the floor."); 630. 		    } else You("finally wiggle free."); 631. 		} else { 632. 		    if(flags.verbose) 633. 			Norep("You are caught in a bear trap."); 634. 		    if((u.dx && u.dy) || !rn2(5)) u.utrap--; 635. 		}  636.  		return; 637. 	}  638.   639.   640.  	/*  641.  	 *  Check for physical obstacles. First, the place we are going. 642. 	 */  643.  	if (IS_ROCK(tmpr->typ)) { 644. 	    if (Blind) feel_location(x,y); 645. #ifdef POLYSELF 646. 	    if (passes_walls(uasmon)) { 647. 		;	/* do nothing */ 648. 	    } else if (tunnels(uasmon) && !needspick(uasmon)) { 649. 		/* Eat the rock. */ 650.  		if (still_chewing(x,y)) return; 651. 	    } else { 652. #endif 653. 		if (Is_stronghold(&u.uz) && is_db_wall(x,y)) 654. 		    pline("The drawbridge is up!"); 655. 		flags.move = 0; 656. 		nomul(0); 657. 		return; 658. #ifdef POLYSELF 659. 	    }  660.  #endif 661. 	} else if (IS_DOOR(tmpr->typ)) { 662. 	    if (closed_door(x,y)) { 663. 		if (Blind) feel_location(x,y); 664. #ifdef POLYSELF 665. 		if (passes_walls(uasmon)) 666. 		    ;	/* do nothing */ 667. 		else if (amorphous(uasmon)) 668. 		    You("ooze under the door."); 669. 		else if (tunnels(uasmon) && !needspick(uasmon)) { 670. 		    /* Eat the door. */ 671.  		    if (still_chewing(x,y)) return; 672. 		} else { 673. #endif 674. 		    flags.move = 0; 675. 		    if (x == u.ux || y == u.uy) { 676. 			if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { 677. 			    pline("Ouch!  You bump into a door."); 678. 			    exercise(A_DEX, FALSE); 679. 			} else pline("That door is closed."); 680. 		    }  681.  		    nomul(0); 682. 		    return; 683. #ifdef POLYSELF 684. 		}  685.  #endif 686. 	    } else if (u.dx && u.dy  687.  #ifdef POLYSELF  688.  			&& !passes_walls(uasmon)  689.  #endif  690.  			&& ((tmpr->doormask & ~D_BROKEN) 691. #ifdef REINCARNATION 692. 					|| Is_rogue_level(&u.uz) 693. #endif 694. 					|| block_door(x,y))) { 695. 		/* Diagonal moves into a door are not allowed. */ 696.  		if (Blind) feel_location(x,y);	/* ?? */ 697.  		flags.move = 0; 698. 		nomul(0); 699. 		return; 700. 	    }  701.  	}  702.  	if (u.dx && u.dy && bad_rock(u.ux,y) && bad_rock(x,u.uy)) { 703. 	    /* Move at a diagonal. */ 704.  #ifdef POLYSELF 705. 	    if (bigmonst(uasmon)) { 706. 		Your("body is too large to fit through."); 707. 		nomul(0); 708. 		return; 709. 	    }  710.  #endif 711. 	    if (invent && inv_weight > -400) { 712. 		You("are carrying too much to get through."); 713. 		nomul(0); 714. 		return; 715. 	    }  716.  	}  717.   718.  	ust = &levl[u.ux][u.uy]; 719.  720.  	/* Now see if other things block our way. . */ 721.  	if (u.dx && u.dy  722.  #ifdef POLYSELF  723.  			 && !passes_walls(uasmon)  724.  #endif  725.  			 && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN)  726.  #ifdef REINCARNATION  727.  				 || Is_rogue_level(&u.uz)  728.  #endif  729.  				 || block_entry(x, y)) 730. 			     )) {  731.  	    /* Can't move at a diagonal out of a doorway with door. */ 732.  	    flags.move = 0; 733. 	    nomul(0); 734. 	    return; 735. 	}  736.   737.  	if (sobj_at(BOULDER,x,y)  738.  #ifdef POLYSELF  739.  				&& !passes_walls(uasmon)  740.  #endif  741.  							) { 742. 	    if (!(Blind || Hallucination) && (flags.run >= 2)) { 743. 		nomul(0); 744. 		flags.move = 0; 745. 		return; 746. 	    }  747.  #ifdef POLYSELF 748. 	    /* tunneling monsters will chew before pushing */ 749. 	    if (tunnels(uasmon) && !needspick(uasmon)) { 750. 		if (still_chewing(x,y)) return; 751. 	    } else 752. #endif 753. 		if (moverock < 0) return; 754. 	}  755.   756.  	/* OK, it is a legal place to move. */ 757.   758.  	/* Move ball and chain. */ 759.  	if (Punished) 760. 	    if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy)) 761. 		return; 762.  763.  	/* now move the hero */ 764. 	mtmp = m_at(x, y); 765. 	if (u.uinwater) water_friction; 766. 	u.ux += u.dx; 767. 	u.uy += u.dy; 768. 	/* if safepet at destination then move the pet to the hero's  769. * previous location using the same conditions as in attack. 770. 	 * there are special extenuating circumstances: 771. 	 * (1) if the pet dies then your god angers, 772. 	 * (2) if the pet gets trapped then your god may disapprove, 773. 	 * (3) if the pet was already trapped and you attempt to free it  774. * not only do you encounter the trap but you may frighten your 775. 	 * pet causing it to go wild! moral: don't abuse this privilege. 776. 	 */  777.  	/* Ceiling-hiding pets are skipped by this section of code, to  778. * be caught by the normal falling-monster code. 779. 	 */  780.  	if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) { 781. 		int swap_result; 782.  783.  		/* if trapped, there's a chance the pet goes wild */ 784. 		if (mtmp->mtrapped && !rn2(4)) { 785. 		    pline ("%s suddenly goes wild!",  786.  			   mtmp->mnamelth ? NAME(mtmp) : Monnam(mtmp)); 787. 		    mtmp->mtame = mtmp->mpeaceful = mtmp->msleep = 0; 788. 		}  789.   790.  		mtmp->mtrapped = 0; 791. 		mtmp->mundetected = 0; 792. 		remove_monster(x, y); 793. 		place_monster(mtmp, u.ux0, u.uy0); 794.  795.  		/* check first to see if monster drowned. 796. 		 * then check for traps. 797. 		 */  798.  		if (minwater(mtmp)) { 799. 		    swap_result = 2; 800. 		} else swap_result = mintrap(mtmp); 801.  802.  		switch (swap_result) { 803. 		case 0: 804. 		    You("%s %s.", mtmp->mtame ? "displaced" : "frightened",  805.  			    mtmp->mnamelth ? NAME(mtmp) : mon_nam(mtmp)); 806. 		    break; 807. 		case 1:	/* trapped */ 808. 		case 3: /* changed levels */ 809. 		    /* there's already been a trap message, reinforce it */ 810. 		    pline("Trapping your pet was a selfish move."); 811. 		    if (!rn2(4)) { 812. 			pline("You'll pay!"); 813. 			adjalign(-5); 814. 		    }  815.  		    break; 816. 		case 2: 817. 		    /* it may have drowned or died. that's no way to 818. * treat a pet! your god gets angry and complains. 819. 		     */  820.  		    if (rn2(4)) { 821. 			pline ("%s complains in a booming voice:", u_gname); 822. 			verbalize("Losing your pet like this was a mistake!"); 823. 			u.ugangr++ ; 824. 			adjalign(-15); 825. 		    }  826.  		    break; 827. 		default: 828. 		    pline("that's strange, unknown mintrap result!"); 829. 		    break; 830. 		}  831.  	}  832.   833.  	reset_occupations; 834. 	if(flags.run) { 835. 		if(IS_DOOR(tmpr->typ) ||  836.  #ifdef POLYSELF  837.  		(IS_ROCK(tmpr->typ)) ||  838.  #endif  839.  		(xupstair == u.ux && yupstair == u.uy) ||  840.  		(xdnstair == u.ux && ydnstair == u.uy)  841.  		|| (sstairs.sx == u.ux && sstairs.sy == u.uy)  842.  		|| (xupladder == u.ux && yupladder == u.uy)  843.  		|| (xdnladder == u.ux && ydnladder == u.uy)  844.  		|| IS_FOUNTAIN(tmpr->typ)  845.  		|| IS_THRONE(tmpr->typ)  846.  #ifdef SINKS  847.  		|| IS_SINK(tmpr->typ)  848.  #endif  849.  		|| IS_ALTAR(tmpr->typ)  850.  		) 851. 			nomul(0); 852. 	}  853.  #ifdef POLYSELF 854. 	if (hides_under(uasmon)) 855. 	    u.uundetected = OBJ_AT(u.ux, u.uy); 856. 	else if (u.dx || u.dy) { /* piercer */ 857. 	    if (u.usym == S_MIMIC_DEF) 858. 		u.usym = S_MIMIC; 859. 	    u.uundetected = 0; 860. 	}  861.  #endif 862.  863.  #ifdef WALKIES 864. 	check_leash(u.ux0,u.uy0); 865. #endif 866. 	if(u.ux0 != u.ux || u.uy0 != u.uy) { 867. 	    u.umoved = TRUE; 868. 	    /* Clean old position -- vision_recalc will print our new one. */ 869.  	    newsym(u.ux0,u.uy0); 870. 	    /* Since the hero has moved, adjust what can be seen/unseen. */ 871.  	    vision_recalc(1);	/* Do the work now in the recover time. */ 872.   873.  	    /* a special clue-msg when on the Invocation position */ 874. 	    if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) { 875. 	        register struct obj *otmp; 876.  877.  	        You("feel a strange vibration under your %s.",  878.  			makeplural(body_part(FOOT))); 879.  880.  		for(otmp = invent; otmp; otmp = otmp->nobj) { 881. 	            if(otmp->otyp == CANDELABRUM_OF_INVOCATION &&  882.  		       otmp->spe == 7 && otmp->lamplit) { 883. 	                  pline("%s glows with a strange light!",  884.  				The(xname(otmp))); 885. 			  break; 886. 		       }  887.  	        }  888.  		  889.  	    }  890.  	}  891.   892.  	if (Punished)				/* put back ball and chain */ 893. 	    move_bc(0,bc_control,ballx,bally,chainx,chainy); 894.  895.  	spoteffects; 896. }  897.   898.  #endif /* OVL3 */ 899. #ifdef OVL2 900.  901.  void 902. spoteffects 903. {  904.  	register struct trap *trap; 905. 	register struct monst *mtmp; 906.  907.  	if(u.uinwater) { 908. 		int was_underwater; 909.  910.  		if (!is_pool(u.ux,u.uy)) { 911. 			if (Is_waterlevel(&u.uz)) 912. 				You("pop into an air bubble."); 913. 			else 914. 				You("are on solid ground again."); 915. 		}  916.  		else if (Is_waterlevel(&u.uz)) 917. 			goto stillinwater; 918. 		else if (Levitation || is_floater(uasmon)) 919. 			You("pop out of the water like a cork!"); 920. 		else if (is_flyer(uasmon)) 921. 			You("fly out of the water."); 922. 		else if (Wwalking) 923. 			You("slowly rise above the surface."); 924. 		else 925. 			goto stillinwater; 926. 		was_underwater = Underwater && !Is_waterlevel(&u.uz); 927. 		u.uinwater = 0;		/* leave the water */ 928. 		if (was_underwater) {	/* restore vision */ 929. 			docrt; 930. 			vision_full_recalc = 1; 931. 		}  932.  	}  933.  stillinwater:; 934. 	if(!Levitation && !u.ustuck  935.  #ifdef POLYSELF  936.  	   && !is_flyer(uasmon)  937.  #endif  938.  	   ) { 939. 	    /* limit recursive calls through teleds */ 940. 	    if(is_lava(u.ux,u.uy) && lava_effects) 941. 		    return; 942. 	    if(is_pool(u.ux,u.uy) && !Wwalking && drown) 943. 		    return; 944. 	}  945.  	check_special_room(FALSE); 946. #ifdef SINKS 947. 	if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 948. 		dosinkfall; 949. #endif 950. 	if(!flags.nopick && OBJ_AT(u.ux, u.uy) &&  951.  	   (!is_pool(u.ux,u.uy) || Underwater)) 952. 		pickup(1); 953. 	else read_engr_at(u.ux,u.uy); 954. 	if(trap = t_at(u.ux,u.uy)) 955. 		dotrap(trap);	/* fall into pit, arrow trap, etc. */ 956. 	if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) { 957. 		mtmp->mundetected = 0; 958. 		switch(mtmp->data->mlet) { 959. 		    case S_PIERCER: 960. 			pline("%s suddenly drops from the ceiling!",  961.  			      Amonnam(mtmp)); 962. 			if(mtmp->mtame) /* jumps to greet you, not attack */ 963. 			    ;  964.  			else if(uarmh) 965. 			    pline("Its blow glances off your helmet."); 966. 			else if (u.uac + 3 <= rnd(20)) 967. 			    You("are almost hit by %s!",  968.  				x_monnam(mtmp, 2, "falling", 1)); 969. 			else { 970. 			    int dmg; 971. 			    You("are hit by %s!",  972.  				x_monnam(mtmp, 2, "falling", 1)); 973. 			    dmg = d(4,6); 974. 			    if(Half_physical_damage) dmg = (dmg+1) / 2; 975. 			    mdamageu(mtmp, dmg); 976. 			}  977.  			break; 978. 		    default:	/* monster surprises you. */ 979.  			if(mtmp->mtame) 980. 			    pline("%s jumps near you from the ceiling.",  981.  					Amonnam(mtmp)); 982. 			else if(mtmp->mpeaceful) { 983. 				You("surprise %s!",  984.  				    Blind && !sensemon(mtmp) ?  985.  				    "something" : a_monnam(mtmp)); 986. 				mtmp->mpeaceful = 0; 987. 			} else 988. 			    pline("%s attacks you by surprise!",  989.  					Amonnam(mtmp)); 990. 			break; 991. 		}  992.  		mnexto(mtmp); /* have to move the monster */ 993. 	}  994.  }  995.   996.  STATIC_OVL boolean 997. monstinroom(mdat,roomno) 998. struct permonst *mdat; 999. int roomno; 1000. { 1001. 	register struct monst *mtmp; 1002. 1003. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1004. 		if(mtmp->data == mdat && 1005. 		   index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET)) 1006. 			return(TRUE); 1007. 	return(FALSE); 1008. } 1009.  1010. char * 1011. in_rooms(x, y, typewanted) 1012. register xchar x, y; 1013. register int typewanted; 1014. { 1015. 	static char buf[5]; 1016. 	char rno, *ptr = &buf[4]; 1017. 	int typefound, min_x, min_y, max_x, max_y_offset, step; 1018. 	register struct rm *lev; 1019. 1020. #define goodtype(rno) (!typewanted || \  1021. 	     ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \  1022. 	     ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \ 1023. 1024. 	switch (rno = levl[x][y].roomno) { 1025. 		case NO_ROOM: 1026. 			return(ptr); 1027. 		case SHARED: 1028. 			step = 2; 1029. 			break; 1030. 		case SHARED_PLUS: 1031. 			step = 1; 1032. 			break; 1033. 		default:			/* i.e. a regular room # */ 1034. 			if (goodtype(rno)) 1035. 				*(--ptr) = rno; 1036. 			return(ptr); 1037. 	} 1038.  1039. 	min_x = x - 1; 1040. 	max_x = x + 1; 1041. 	if (x < 0) 1042. 		min_x += step; 1043. 	else 1044. 	if (x >= COLNO) 1045. 		max_x -= step; 1046. 1047. 	min_y = y - 1; 1048. 	max_y_offset = 2; 1049. 	if (min_y < 0) { 1050. 		min_y += step; 1051. 		max_y_offset -= step; 1052. 	} else 1053. 	if ((min_y + max_y_offset) >= ROWNO) 1054. 		max_y_offset -= step; 1055. 1056. 	for (x = min_x; x <= max_x; x += step) { 1057. 		lev = &levl[x][min_y]; 1058. 		y = 0; 1059. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1060. 		    !index(ptr, rno) && goodtype(rno)) 1061. 			*(--ptr) = rno; 1062. 		y += step; 1063. 		if (y > max_y_offset) 1064. 			continue; 1065. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1066. 	     	    !index(ptr, rno) && goodtype(rno)) 1067. 			*(--ptr) = rno; 1068. 		y += step; 1069. 		if (y > max_y_offset) 1070. 			continue; 1071. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1072. 		    !index(ptr, rno) && goodtype(rno)) 1073. 			*(--ptr) = rno; 1074. 	} 1075. 	return(ptr); 1076. } 1077.  1078. static void 1079. move_update(newlev) 1080. register boolean newlev; 1081. { 1082. 	char *ptr1, *ptr2, *ptr3, *ptr4; 1083. 1084. 	Strcpy(u.urooms0, u.urooms); 1085. 	Strcpy(u.ushops0, u.ushops); 1086. 	if (newlev) { 1087. 		u.urooms[0] = '\0'; 1088. 		u.uentered[0] = '\0'; 1089. 		u.ushops[0] = '\0'; 1090. 		u.ushops_entered[0] = '\0'; 1091. 		Strcpy(u.ushops_left, u.ushops0); 1092. 		return; 1093. 	} 1094. 	Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0)); 1095. 1096. 	for (ptr1 = &u.urooms[0],  1097. 	     ptr2 = &u.uentered[0],  1098. 	     ptr3 = &u.ushops[0],  1099. 	     ptr4 = &u.ushops_entered[0];  1100. 	     *ptr1; ptr1++) { 1101. 		if (!index(u.urooms0, *ptr1)) 1102. 			*(ptr2++) = *ptr1; 1103. 		if (IS_SHOP(*ptr1 - ROOMOFFSET)) { 1104. 			*(ptr3++) = *ptr1; 1105. 			if (!index(u.ushops0, *ptr1)) 1106. 				*(ptr4++) = *ptr1; 1107. 		} 1108. 	}  1109. 	*ptr2 = '\0'; 1110. 	*ptr3 = '\0'; 1111. 	*ptr4 = '\0'; 1112. 1113. 	/* filter u.ushops0 -> u.ushops_left */ 1114. 	for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++) 1115. 		if (!index(u.ushops, *ptr1)) 1116. 			*(ptr2++) = *ptr1; 1117. 	*ptr2 = '\0'; 1118. } 1119.  1120. void 1121. check_special_room(newlev) 1122. register boolean newlev; 1123. { 1124. 	register struct monst *mtmp; 1125. 	char *ptr; 1126. 1127. 	move_update(newlev); 1128. 1129. 	if (*u.ushops0) 1130. 	   u_left_shop(u.ushops_left, newlev); 1131. 1132. 	if (!*u.uentered && !*u.ushops_entered) 1133. 	   return;		/* no entrance messages necessary */ 1134. 1135. 	/* Did we just enter a shop? */ 1136. 	if (*u.ushops_entered) 1137.            u_entered_shop(u.ushops_entered); 1138. 1139. 	for (ptr = &u.uentered[0]; *ptr; ptr++) { 1140. 	   register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype; 1141. 1142. 	    /* Did we just enter some other special room? */ 1143. 	    /* vault.c insists that a vault remain a VAULT, 1144. 	    * and temples should remain TEMPLEs, 1145. 	    * but everything else gives a message only the first time */ 1146. 	   if(!newlev) 1147. 	  	switch (rt) { 1148. 		   case ZOO: 1149. 		  	pline("Welcome to David's treasure zoo!"); 1150. 		   	break; 1151. 		   case SWAMP: 1152. 		   	pline("It %s rather %s down here.",  1153. 	    		      Blind ? "feels" : "looks",  1154. 	    		      Blind ? "humid" : "muddy"); 1155. 		   	break; 1156. 		   case COURT: 1157. 			You("enter an opulent throne room!"); 1158. 		   	break; 1159. 		   case MORGUE: 1160. 		   	if(midnight) 1161. 			   pline("Run away!  Run away!"); 1162. 		   	else 1163. 			   You("have an uncanny feeling..."); 1164. 		   	break; 1165. 		   case BEEHIVE: 1166. 		   	You("enter a giant beehive!"); 1167. 		   	break; 1168. #ifdef ARMY 1169. 		   case BARRACKS: 1170. 		   	if(monstinroom(&mons[PM_SOLDIER], roomno) ||  1171. 			    monstinroom(&mons[PM_SERGEANT], roomno) ||  1172. 			    monstinroom(&mons[PM_LIEUTENANT], roomno) ||  1173. 			    monstinroom(&mons[PM_CAPTAIN], roomno)) 1174. 		   	    You("enter a military barracks!"); 1175. 		   	else 1176. 			   You("enter an abandoned barracks."); 1177. 		   	break; 1178. #endif 1179. 		   case DELPHI: 1180. 		   	if(monstinroom(&mons[PM_ORACLE], roomno)) 1181. 			   verbalize("Hello, %s, welcome to Delphi!", plname); 1182. 		   	break; 1183. 		   case TEMPLE: 1184. 			intemple(roomno + ROOMOFFSET); 1185. 		   	/* fall through */ 1186. 		   default: 1187. 		   	rt = 0; 1188. 	   	}  1189. 	    else 1190. 		rt = 0; 1191. 1192. 	    if(rt != 0) { 1193. 		rooms[roomno].rtype = OROOM; 1194. 		if (!search_special(rt)) { 1195. 			/* No more room of that type */ 1196. 			switch(rt) { 1197. 			   case COURT: 1198. 				level.flags.has_court = 0; 1199. 				break; 1200. 			   case SWAMP: 1201. 				level.flags.has_swamp = 0; 1202. 				break; 1203. 			   case MORGUE: 1204. 				level.flags.has_morgue = 0; 1205. 				break; 1206. 			   case ZOO: 1207. 				level.flags.has_zoo = 0; 1208. 				break; 1209. #ifdef ARMY 1210. 			   case BARRACKS: 1211. 				level.flags.has_barracks = 0; 1212. 				break; 1213. #endif 1214. 			   case TEMPLE: 1215. 				level.flags.has_temple = 0; 1216. 				break; 1217. 			   case BEEHIVE: 1218. 				level.flags.has_beehive = 0; 1219. 				break; 1220. 			} 1221. 		}  1222. 		if(rt==COURT || rt==SWAMP || rt==MORGUE || rt==ZOO) 1223. 			for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1224. 				if(!Stealth && !rn2(3)) 1225. 					mtmp->msleep = 0; 1226. 	   }  1227. 	}  1228.  1229. 	return; 1230. } 1231.  1232. #endif /* OVL2 */ 1233. #ifdef OVLB 1234. 1235. int 1236. dopickup 1237. { 1238. 	int count; 1239. 	/* awful kludge to work around parse's pre-decrement */ 1240. 	count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0; 1241. 	multi = 0;	/* always reset */ 1242. 	/* uswallow case added by GAN 01/29/87 */ 1243. 	if(u.uswallow) { 1244. 		if (is_animal(u.ustuck->data)) { 1245. 		   You("pick up %s tongue.",  1246. 			            s_suffix(mon_nam(u.ustuck))); 1247. 		   pline("But it's kind of slimy, so you drop it."); 1248. 		} else 1249. 		   You("don't %s anything in here to pick up.",  1250. 			  Blind ? "feel" : "see"); 1251. 		return(1); 1252. 	} 1253. 	if(!OBJ_AT(u.ux, u.uy)) { 1254. 		pline("There is nothing here to pick up."); 1255. 		return(0); 1256. 	} 1257. 	if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 1258. 		You("cannot reach the floor."); 1259. 		return(1); 1260. 	} 1261. 	if(is_pool(u.ux, u.uy)) { 1262. 		if(Wwalking 1263. #ifdef POLYSELF  1264. 		   || is_flyer(uasmon) || is_clinger(uasmon)  1265. #endif  1266. 		   ) { 1267. 			You("cannot dive into the water to pick things up."); 1268. 			return(1); 1269. 		} 1270. 		else if(!Underwater) { 1271. 			You("can't even see the bottom, let alone pick up something."); 1272. 			return(1); 1273. 		} 1274. 	}  1275. 	pickup(-count); 1276. 	return(1); 1277. } 1278.  1279. #endif /* OVLB */ 1280. #ifdef OVL2 1281. 1282. /* stop running if we see something interesting */ 1283. /* turn around a corner if that is the only way we can proceed */ 1284. /* do not turn left or right twice */ 1285. void 1286. lookaround 1287. { 1288.     register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9; 1289.    register int corrct = 0, noturn = 0; 1290.    register struct monst *mtmp; 1291.    register struct trap *trap; 1292. 1293. #ifdef POLYSELF 1294. 	/* Grid bugs stop if trying to move diagonal, even if blind. Maybe */ 1295. 	/* they polymorphed while in the middle of a long move. */ 1296. 	if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) { 1297. 		nomul(0); 1298. 		return; 1299. 	} 1300. #endif 1301. 	if(Blind || flags.run == 0) return; 1302. 	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 1303. 		if(!isok(x,y)) continue; 1304. #ifdef POLYSELF 1305. 	if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue; 1306. #endif 1307. 	if(x == u.ux && y == u.uy) continue; 1308. 1309. 	if((mtmp = m_at(x,y)) &&  1310. 		    mtmp->m_ap_type != M_AP_FURNITURE &&  1311. 		    mtmp->m_ap_type != M_AP_OBJECT &&  1312. 		    (!mtmp->minvis || See_invisible) && !mtmp->mundetected) { 1313. 	   if((flags.run != 1 && !mtmp->mtame)  1314. 					|| (x == u.ux+u.dx && y == u.uy+u.dy)) 1315. 		goto stop; 1316. 	} 1317.  1318. 	if (levl[x][y].typ == STONE) continue; 1319. 	if (x == u.ux-u.dx && y == u.uy-u.dy) continue; 1320. 1321. 	if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) ||  1322. 	    IS_AIR(levl[x][y].typ)) 1323. 	   continue; 1324. 	else if (closed_door(x,y)) { 1325. 	   if(x != u.ux && y != u.uy) continue; 1326. 	   if(flags.run != 1) goto stop; 1327. 	   goto bcorr; 1328. 	} else if (levl[x][y].typ == CORR) { 1329. bcorr: 1330. 	   if(levl[u.ux][u.uy].typ != ROOM) { 1331. 		if(flags.run == 1 || flags.run == 3) { 1332. 		   i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 1333. 		   if(i > 2) continue; 1334. 		   if(corrct == 1 && dist2(x,y,x0,y0) != 1) 1335. 			noturn = 1; 1336. 		   if(i < i0) { 1337. 			i0 = i; 1338. x0 = x; 1339. y0 = y; 1340. m0 = mtmp ? 1 : 0; 1341. 		    }  1342. 		}  1343. 		corrct++; 1344. 	   }  1345. 	    continue; 1346. 	} else if ((trap = t_at(x,y)) && trap->tseen) { 1347. 	   if(flags.run == 1) goto bcorr;	/* if you must */ 1348. 	   if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1349. 	   continue; 1350. 	} else if (is_pool(x,y) || is_lava(x,y)) { 1351. 	   /* water and lava only stop you if directly in front, and stop 1352. 	    * you even if you are running 1353. 	    */  1354. 	    if(!Levitation &&  1355. #ifdef POLYSELF  1356. 			!is_flyer(uasmon) && !is_clinger(uasmon) &&  1357. #endif  1358. 			/* No Wwalking check; otherwise they'd be able  1359. 			 * to test boots by trying to SHIFT-direction  1360. 			 * into a pool and seeing if the game allowed it  1361. 			 */  1362. 			x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1363. 	   continue; 1364. 	} else {		/* e.g. objects or trap or stairs */ 1365. 	   if(flags.run == 1) goto bcorr; 1366. 	   if(mtmp) continue;		/* d */ 1367. 	   if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) ||  1368. 	       ((y == u.uy - u.dy) && (x != u.ux + u.dx))) 1369. 	      continue; 1370. 	} 1371. stop: 1372. 	nomul(0); 1373. 	return; 1374.    } /* end for loops */ 1375. 1376.     if(corrct > 1 && flags.run == 2) goto stop; 1377.    if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&  1378. 				(corrct == 1 || (corrct == 2 && i0 == 1))) { 1379. 	/* make sure that we do not turn too far */ 1380. 	if(i0 == 2) { 1381. 	   if(u.dx == y0-u.uy && u.dy == u.ux-x0) 1382. 		i = 2;		/* straight turn right */ 1383. 	   else 1384. 		i = -2;		/* straight turn left */ 1385. 	} else if(u.dx && u.dy) { 1386. 	   if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy)) 1387. 		i = -1;		/* half turn left */ 1388. 	   else 1389. 		i = 1;		/* half turn right */ 1390. 	} else { 1391. 	   if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy)) 1392. 		i = 1;		/* half turn right */ 1393. 	   else 1394. 		i = -1;		/* half turn left */ 1395. 	} 1396.  1397. 	i += u.last_str_turn; 1398. 	if(i <= 2 && i >= -2) { 1399. 	   u.last_str_turn = i;  1400. u.dx = x0-u.ux; 1401. 	   u.dy = y0-u.uy; 1402. 	} 1403.     }  1404. }  1405.  1406. /* something like lookaround, but we are not running */ 1407. /* react only to monsters that might hit us */ 1408. int 1409. monster_nearby 1410. { 1411. 	register int x,y; 1412. 	register struct monst *mtmp; 1413. 1414. 	if(!Blind) 1415. 	for(x = u.ux-1; x <= u.ux+1; x++) 1416. 	   for(y = u.uy-1; y <= u.uy+1; y++) { 1417. 		if(!isok(x,y)) continue; 1418. 		if(x == u.ux && y == u.uy) continue; 1419. 		if((mtmp = m_at(x,y)) && 1420. 		   mtmp->m_ap_type != M_AP_FURNITURE &&  1421. 		   mtmp->m_ap_type != M_AP_OBJECT &&  1422. 		   !mtmp->mpeaceful &&  1423. 		   (!is_hider(mtmp->data) || !mtmp->mundetected) &&  1424. 		   !noattacks(mtmp->data) &&  1425. 		   mtmp->mcanmove && !mtmp->msleep &&  /* aplvax!jcn */  1426. 		   (!mtmp->minvis || See_invisible) &&  1427. 		   !onscary(u.ux, u.uy, mtmp)) 1428. 			return(1); 1429. 	} 1430. 	return(0); 1431. } 1432.  1433. void 1434. nomul(nval) 1435. 	register int nval; 1436. { 1437. 	if(multi < nval) return;	/* This is a bug fix by ab@unido */ 1438. 	u.uinvulnerable = FALSE;	/* Kludge to avoid ctrl-C bug -dlc */ 1439. 	u.usleep = 0; 1440. 	multi = nval; 1441. 	flags.mv = flags.run = 0; 1442. } 1443.  1444. #endif /* OVL2 */ 1445. #ifdef OVL1 1446. 1447. void 1448. losehp(n, knam, k_format) 1449. register int n; 1450. register const char *knam; 1451. boolean k_format; 1452. { 1453. #ifdef POLYSELF 1454. 	if (u.mtimedone) { 1455. 		u.mh -= n; 1456. if (u.mhmax < u.mh) u.mhmax = u.mh; 1457. 		flags.botl = 1; 1458. 		if (u.mh < 1) rehumanize; 1459. 		return; 1460. 	} 1461. #endif 1462. 	u.uhp -= n; 1463. if(u.uhp > u.uhpmax) 1464. 		u.uhpmax = u.uhp;	/* perhaps n was negative */ 1465. 	flags.botl = 1; 1466. 	if(u.uhp < 1) { 1467. 		killer_format = k_format; 1468. 		killer = knam;		/* the thing that killed you */ 1469. 		You("die..."); 1470. 		done(DIED); 1471. 	} else if(u.uhp*10 < u.uhpmax && moves-wailmsg > 50 && n > 0){ 1472. 		wailmsg = moves; 1473. 		if(index("WEV", pl_character[0])) { 1474. 			if (u.uhp == 1) 1475. 				pline("%s is about to die.", pl_character); 1476. 			else if (4 <= (!!(HTeleportation & INTRINSIC)) + 1477. 				    (!!(HSee_invisible & INTRINSIC)) +  1478. 				    (!!(HPoison_resistance & INTRINSIC)) +  1479. 				    (!!(HCold_resistance & INTRINSIC)) +  1480. 				    (!!(HShock_resistance & INTRINSIC)) +  1481. 				    (!!(HFire_resistance & INTRINSIC)) +  1482. 				    (!!(HSleep_resistance & INTRINSIC)) +  1483. 				    (!!(HDisint_resistance & INTRINSIC)) +  1484. 				    (!!(HTeleport_control & INTRINSIC)) +  1485. 				    (!!(Stealth & INTRINSIC)) +  1486. 				    (!!(Fast & INTRINSIC)) +  1487. 				    (!!(HInvis & INTRINSIC))) 1488. 				pline("%s, all your powers will be lost...", 1489. 					pl_character); 1490. 			else 1491. 				pline("%s, your life force is running out.", 1492. 					pl_character); 1493. 		} else { 1494. 			if(u.uhp == 1) 1495. 				You("hear the wailing of the Banshee..."); 1496. 			else 1497. 				You("hear the howling of the CwnAnnwn..."); 1498. 		} 1499. 	}  1500. }  1501.  1502. int 1503. weight_cap 1504. { 1505. 	register long carrcap; 1506. 1507. 	carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50; 1508. #ifdef POLYSELF 1509. 	if (u.mtimedone) { 1510. 		/* consistent with can_carry in mon.c */ 1511. 		if (u.usym == S_NYMPH) 1512. 		       carrcap = MAX_CARR_CAP; 1513. 		else if (!uasmon->cwt) 1514. 			carrcap = (carrcap * (long)uasmon->msize) / MZ_HUMAN; 1515. 		else if (!strongmonst(uasmon) 1516. 			|| (strongmonst(uasmon) && (uasmon->cwt > WT_HUMAN))) 1517. 			carrcap = (carrcap * (long)uasmon->cwt / WT_HUMAN); 1518. 	} 1519. #endif 1520. 	if(Levitation || Is_airlevel(&u.uz))	/* pugh@cornell */ 1521. 		carrcap = MAX_CARR_CAP; 1522. 	else { 1523. 		if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1524. 		if(Wounded_legs & LEFT_SIDE) carrcap -= 100; 1525. 		if(Wounded_legs & RIGHT_SIDE) carrcap -= 100; 1526. 	} 1527. 	return((int) carrcap); 1528. } 1529.  1530. /* returns how far beyond the normal capacity the player is currently. */ 1531. /* inv_weight is negative if the player is below normal capacity. */ 1532. int 1533. inv_weight 1534. { 1535. 	register struct obj *otmp = invent; 1536. #ifdef LINT	/* long to int conversion */ 1537. 	register int wt = 0; 1538. #else 1539. 	register int wt = (int)((u.ugold + 50L)/100L); 1540. #endif /* LINT */ 1541. 	while(otmp){ 1542. #ifdef POLYSELF 1543. 		if (otmp->otyp != BOULDER || !throws_rocks(uasmon)) 1544. #endif 1545. 			wt += otmp->owt; 1546. 		otmp = otmp->nobj; 1547. 	} 1548. 	return(wt - weight_cap); 1549. } 1550.  1551. /*  1552.  * Returns 0 if below normal capacity, or the number of "capacity units" 1553. * over the normal capacity the player is loaded. Max is 5. 1554. */  1555. int 1556. near_capacity 1557. { 1558.     int cap, wt = inv_weight; 1559. 1560.     if (wt < 0) return UNENCUMBERED; 1561.    cap = (wt / (weight_cap/2)) + 1; 1562.    return min(cap, OVERLOADED); 1563. } 1564.  1565. int 1566. max_capacity 1567. { 1568.     return(inv_weight - (2 * weight_cap)); 1569. } 1570.  1571. boolean 1572. check_capacity(str) 1573. const char *str; 1574. { 1575.     if(near_capacity >= EXT_ENCUMBER) { 1576. 	if(str) 1577. 	   pline(str); 1578. 	else 1579. 	   You("can't do that while carrying so much stuff."); 1580. 	return 1; 1581.    }  1582.     return 0; 1583. } 1584.  1585. #endif /* OVL1 */ 1586. #ifdef OVLB 1587. 1588. int 1589. inv_cnt 1590. { 1591. 	register struct obj *otmp = invent; 1592. 	register int ct = 0; 1593. 1594. 	while(otmp){ 1595. 		ct++; 1596. 		otmp = otmp->nobj; 1597. 	} 1598. 	return(ct); 1599. } 1600.  1601. int 1602. identify(otmp)		/* also called by newmail */ 1603. 	register struct obj *otmp; 1604. { 1605. 	makeknown(otmp->otyp); 1606. 	otmp->known = otmp->dknown = otmp->bknown = otmp->rknown = 1; 1607. 	prinv(NULL, otmp, 0L); 1608. 	return(1); 1609. } 1610.  1611. #endif /* OVLB */ 1612. 1613. /*hack.c*/