Source:NetHack 3.4.0/hack.c

Below is the full text to hack.c from the source code of NetHack 3.4.0. To link to a particular line, write [[NetHack 3.4.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.4	2002/03/09	*/ 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.   #ifdef OVL1 8.   STATIC_DCL void NDECL(maybe_wail); 9.   #endif /*OVL1*/ 10.  STATIC_DCL int NDECL(moverock); 11.  STATIC_DCL int FDECL(still_chewing,(XCHAR_P,XCHAR_P)); 12.  #ifdef SINKS 13.  STATIC_DCL void NDECL(dosinkfall); 14.  #endif 15.  STATIC_DCL void NDECL(findtravelpath); 16.  STATIC_DCL boolean FDECL(monstinroom, (struct permonst *,int)); 17.   18.   STATIC_DCL void FDECL(move_update, (BOOLEAN_P)); 19.   20.   #define IS_SHOP(x)	(rooms[x].rtype >= SHOPBASE) 21.   22.   #ifdef OVL2 23.   24.   boolean 25.  revive_nasty(x, y, msg) 26.  int x,y; 27.  const char *msg; 28.  {  29.       register struct obj *otmp, *otmp2; 30.      struct monst *mtmp; 31.      coord cc; 32.      boolean revived = FALSE; 33.   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.  	    revived = revive_corpse(otmp); 44.  	}  45.       }  46.    47.       /* this location might not be safe, if not, move revived monster */ 48.      if (revived) { 49.  	mtmp = m_at(x,y); 50.  	if (mtmp && !goodpos(x, y, mtmp) &&  51.   	    enexto(&cc, x, y, mtmp->data)) { 52.  	    rloc_to(mtmp, cc.x, cc.y); 53.  	}  54.   	/* else impossible? */ 55.       }  56.    57.       return (revived); 58.  }  59.    60.   STATIC_OVL int 61.  moverock 62.  {  63.       register xchar rx, ry, sx, sy; 64.      register struct obj *otmp; 65.      register struct trap *ttmp; 66.      register struct monst *mtmp; 67.   68.       sx = u.ux + u.dx,  sy = u.uy + u.dy;	/* boulder starting position */ 69.      while ((otmp = sobj_at(BOULDER, sx, sy)) != 0) { 70.  	/* make sure that this boulder is visible as the top object */ 71.  	if (otmp != level.objects[sx][sy]) movobj(otmp, sx, sy); 72.   73.   	rx = u.ux + 2 * u.dx;	/* boulder destination position */ 74.  	ry = u.uy + 2 * u.dy; 75.  	nomul(0); 76.  	if (Levitation || Is_airlevel(&u.uz)) { 77.  	    if (Blind) feel_location(sx, sy); 78.  	    You("don't have enough leverage to push %s.", the(xname(otmp))); 79.  	    /* Give them a chance to climb over it? */ 80.   	    return -1; 81.  	}  82.   	if (verysmall(youmonst.data)  83.   #ifdef STEED  84.   		 && !u.usteed  85.   #endif  86.   				    ) { 87.  	    if (Blind) feel_location(sx, sy); 88.  	    pline("You're too small to push that %s.", xname(otmp)); 89.  	    goto cannot_push; 90.  	}  91.   	if (isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&  92.   	    (!IS_DOOR(levl[rx][ry].typ) || !(u.dx && u.dy) || (  93.   #ifdef REINCARNATION  94.   		!Is_rogue_level(&u.uz) &&  95.   #endif  96.   		(levl[rx][ry].doormask & ~D_BROKEN) == D_NODOOR)) &&  97.   	    !sobj_at(BOULDER, rx, ry)) { 98.  	    ttmp = t_at(rx, ry); 99.  	    mtmp = m_at(rx, ry); 100.  101.  		/* KMH -- Sokoban doesn't let you push boulders diagonally */ 102. 	    if (In_sokoban(&u.uz) && u.dx && u.dy) { 103. 	    	if (Blind) feel_location(sx,sy); 104. 	    	pline("%s won't roll diagonally on this %s.",  105.  	        		The(xname(otmp)), surface(sx, sy)); 106. 	    	goto cannot_push; 107. 	    }  108.   109.  	    if (revive_nasty(rx, ry, "You sense movement on the other side.")) 110. 		return (-1); 111.  112.  	    if (mtmp && !noncorporeal(mtmp->data) &&  113.  		    (!mtmp->mtrapped || 114. 			 !(ttmp && ((ttmp->ttyp == PIT) || 115. 				    (ttmp->ttyp == SPIKED_PIT))))) { 116. 		if (canspotmon(mtmp)) 117. 		    pline("There's %s on the other side.", mon_nam(mtmp)); 118. 		else { 119. 		    if (Blind) feel_location(sx, sy); 120. 		    You_hear("a monster behind %s.", the(xname(otmp))); 121. 		    map_invisible(rx, ry); 122. 		}  123.  		if (flags.verbose) 124. 		    pline("Perhaps that's why %s cannot move it.",  125.  #ifdef STEED  126.  				u.usteed ? mon_nam(u.usteed) :  127.  #endif  128.  				"you"); 129. 		goto cannot_push; 130. 	    }  131.   132.  	    if (ttmp) 133. 		switch(ttmp->ttyp) { 134. 		case LANDMINE: 135. 		    if (rn2(10)) { 136. 			pline("KAABLAMM!!!  %s %s land mine.",  137.  				Tobjnam(otmp, "trigger"),  138.  				ttmp->madeby_u ? "your" : "a"); 139. 			obj_extract_self(otmp); 140. 			place_object(otmp, rx, ry); 141. 			blow_up_landmine(ttmp); 142. 			/* if the boulder remains, it should fill the pit */ 143. 			fill_pit(u.ux, u.uy); 144. 			if (cansee(rx,ry)) newsym(rx,ry); 145. 			continue; 146. 		    }  147.  		    break; 148. 		case SPIKED_PIT: 149. 		case PIT: 150. 		    obj_extract_self(otmp); 151. 		    /* vision kludge to get messages right; 152. 		       the pit will temporarily be seen even 153. 		       if this is one among multiple boulders */ 154. 		    if (!Blind) viz_array[ry][rx] |= IN_SIGHT; 155. 		    if (!flooreffects(otmp, rx, ry, "fall")) { 156. 			place_object(otmp, rx, ry); 157. 		    }  158.  		    if (mtmp && !Blind) newsym(rx, ry); 159. 		    continue; 160. 		case HOLE: 161. 		case TRAPDOOR: 162. 		    if (Blind) 163. 			pline("Kerplunk!  You no longer feel %s.",  164.  				the(xname(otmp))); 165. 		    else 166. 			pline("%s%s and %s a %s in the %s!",  167.  			  Tobjnam(otmp, 168. 			   (ttmp->ttyp == TRAPDOOR) ? "trigger" : "fall"), 169.  			  (ttmp->ttyp == TRAPDOOR) ? nul : " into",  170.  			  otense(otmp, "plug"),  171.  			  (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole",  172.  			  surface(rx, ry)); 173. 		    deltrap(ttmp); 174. 		    delobj(otmp); 175. 		    bury_objs(rx, ry); 176. 		    if (cansee(rx,ry)) newsym(rx,ry); 177. 		    continue; 178. 		case LEVEL_TELEP: 179. 		case TELEP_TRAP: 180. #ifdef STEED 181. 		    if (u.usteed) 182. 			pline("%s pushes %s and suddenly it disappears!",  183.  				Monnam(u.usteed), the(xname(otmp))); 184. 		    else 185. #endif 186. 		    You("push %s and suddenly it disappears!",  187.  			the(xname(otmp))); 188. 		    if (ttmp->ttyp == TELEP_TRAP) 189. 			rloco(otmp); 190. 		    else { 191. 			int newlev = random_teleport_level; 192. 			d_level dest; 193.  194.  			if (newlev == depth(&u.uz) || In_endgame(&u.uz)) 195. 			    continue; 196. 			obj_extract_self(otmp); 197. 			add_to_migration(otmp); 198. 			get_level(&dest, newlev); 199. 			otmp->ox = dest.dnum; 200. 			otmp->oy = dest.dlevel; 201. 			otmp->owornmask = (long)MIGR_RANDOM; 202. 		    }  203.  		    seetrap(ttmp); 204. 		    continue; 205. 		}  206.  	    if (closed_door(rx, ry)) 207. 		goto nopushmsg; 208. 	    if (boulder_hits_pool(otmp, rx, ry, TRUE)) 209. 		continue; 210. 	    /*  211.  	     * Re-link at top of fobj chain so that pile order is preserved 212. 	     * when level is restored. 213. 	     */  214.  	    if (otmp != fobj) { 215. 		remove_object(otmp); 216. 		place_object(otmp, otmp->ox, otmp->oy); 217. 	    }  218.   219.  	    {  220.  #ifdef LINT /* static long lastmovetime; */ 221. 		long lastmovetime; 222. 		lastmovetime = 0; 223. #else 224. 		static NEARDATA long lastmovetime; 225. #endif 226. 		/* note: this var contains garbage initially and 227. 		   after a restore */ 228. #ifdef STEED 229. 		if (!u.usteed) { 230. #endif 231. 		  if (moves > lastmovetime+2 || moves < lastmovetime) 232. 		    pline("With %s effort you move %s.",  233.  			  throws_rocks(youmonst.data) ? "little" : "great",  234.  			  the(xname(otmp))); 235. 		  exercise(A_STR, TRUE); 236. #ifdef STEED 237. 		} else 238. 		    pline("%s moves %s.", Monnam(u.usteed), the(xname(otmp))); 239. #endif 240. 		lastmovetime = moves; 241. 	    }  242.   243.  	    /* Move the boulder *after* the message. */ 244.  	    if (glyph_is_invisible(levl[rx][ry].glyph)) 245. 		unmap_object(rx, ry); 246. 	    movobj(otmp, rx, ry);	/* does newsym(rx,ry) */ 247. 	    if (Blind) { 248. 		feel_location(rx,ry); 249. 		feel_location(sx, sy); 250. 	    } else { 251. 		newsym(sx, sy); 252. 	    }  253.  	} else { 254. 	nopushmsg: 255. #ifdef STEED 256. 	  if (u.usteed) 257. 	    pline("%s tries to move %s, but cannot.",  258.  		  	Monnam(u.usteed), the(xname(otmp))); 259. 	  else 260. #endif 261. 	    You("try to move %s, but in vain.", the(xname(otmp))); 262. 	    if (Blind) feel_location(sx, sy); 263. 	cannot_push: 264. 	    if (throws_rocks(youmonst.data)) { 265. #ifdef STEED 266. 		if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) { 267. 		    You("aren't skilled enough to %s %s from %s.",  268.  			(flags.pickup && !In_sokoban(&u.uz))  269.  			    ? "pick up" : "push aside",  270.  			the(xname(otmp)), mon_nam(u.usteed)); 271. 		} else 272. #endif 273. 		{  274.  		    pline("However, you can easily %s.",  275.  			(flags.pickup && !In_sokoban(&u.uz))  276.  			    ? "pick it up" : "push it aside"); 277. 		    if (In_sokoban(&u.uz)) 278. 			change_luck(-1);	/* Sokoban guilt */ 279. 		    break; 280. 		}  281.  		break; 282. 	    }  283.   284.  	    if (  285.  #ifdef STEED  286.  		!u.usteed &&  287.  #endif	     288.  		(((!invent || inv_weight <= -850) &&  289.  		 (!u.dx || !u.dy || (IS_ROCK(levl[u.ux][sy].typ)  290.  				     && IS_ROCK(levl[sx][u.uy].typ)))) 291. 		|| verysmall(youmonst.data))) { 292. 		pline("However, you can squeeze yourself into a small opening."); 293. 		if (In_sokoban(&u.uz)) 294. 		    change_luck(-1);	/* Sokoban guilt */ 295. 		break; 296. 	    } else 297. 		return (-1); 298. 	}  299.      }  300.      return (0); 301. }  302.   303.  /*  304.   *  still_chewing 305.  *  306.   *  Chew on a wall, door, or boulder. Returns TRUE if still eating, FALSE 307.  *  when done. 308.  */  309.  STATIC_OVL int 310. still_chewing(x,y) 311.     xchar x, y;  312. { 313.      struct rm *lev = &levl[x][y]; 314.     struct obj *boulder = sobj_at(BOULDER,x,y); 315.     const char *digtxt = (char *)0, *dmgtxt = (char *)0; 316.  317.      if (digging.down)		/* not continuing previous dig (w/ pick-axe) */ 318. 	(void) memset((genericptr_t)&digging, 0, sizeof digging); 319.  320.      if (!boulder && IS_ROCK(lev->typ) && !may_dig(x,y)) { 321. 	You("hurt your teeth on the %s.",  322.  	    IS_TREE(lev->typ) ? "tree" : "hard stone"); 323. 	nomul(0); 324. 	return 1; 325.     } else if (digging.pos.x != x || digging.pos.y != y ||  326.  		!on_level(&digging.level, &u.uz)) { 327. 	digging.down = FALSE; 328. 	digging.chew = TRUE; 329. 	digging.warned = FALSE; 330. 	digging.pos.x = x;  331. digging.pos.y = y; 332. assign_level(&digging.level, &u.uz); 333. 	/* solid rock takes more work & time to dig through */ 334. 	digging.effort = 335. 	    (IS_ROCK(lev->typ) && !IS_TREE(lev->typ) ? 30 : 60) + u.udaminc; 336. 	You("start chewing %s %s.",  337.  	    (boulder || IS_TREE(lev->typ)) ? "on a" : "a hole in the",  338.  	    boulder ? "boulder" :  339.  	    IS_TREE(lev->typ) ? "tree" : IS_ROCK(lev->typ) ? "rock" : "door"); 340. 	watch_dig((struct monst *)0, x, y, FALSE); 341. 	return 1; 342.     } else if ((digging.effort += (30 + u.udaminc)) <= 100)  { 343. 	if (flags.verbose) 344. 	    You("%s chewing on the %s.",  345.  		digging.chew ? "continue" : "begin",  346.  		boulder ? "boulder" :  347.  		IS_TREE(lev->typ) ? "tree" :  348.  		IS_ROCK(lev->typ) ? "rock" : "door"); 349. 	digging.chew = TRUE; 350. 	watch_dig((struct monst *)0, x, y, FALSE); 351. 	return 1; 352.     }  353.   354.      /* Okay, you've chewed through something */ 355.     u.uconduct.food++; 356.     u.uhunger += rnd(20); 357.  358.      if (boulder) { 359. 	delobj(boulder);		/* boulder goes bye-bye */ 360. 	You("eat the boulder.");	/* yum */ 361.  362.  	/*  363.  	 *  The location could still block because of  364. *	1. More than one boulder 365. 	 *	2. Boulder stuck in a wall/stone/door. 366. 	 *  367.  	 *  [perhaps use does_block below (from vision.c)] 368. 	 */  369.  	if (IS_ROCK(lev->typ) || closed_door(x,y) || sobj_at(BOULDER,x,y)) { 370. 	    block_point(x,y);	/* delobj will unblock the point */ 371. 	    /* reset dig state */ 372. 	    (void) memset((genericptr_t)&digging, 0, sizeof digging); 373. 	    return 1; 374. 	}  375.   376.      } else if (IS_WALL(lev->typ)) { 377. 	if (*in_rooms(x, y, SHOPBASE)) { 378. 	    add_damage(x, y, 10L * ACURRSTR); 379. 	    dmgtxt = "damage"; 380. 	}  381.  	digtxt = "chew a hole in the wall."; 382. 	if (level.flags.is_maze_lev) { 383. 	    lev->typ = ROOM; 384. 	} else if (level.flags.is_cavernous_lev) { 385. 	    lev->typ = CORR; 386. 	} else { 387. 	    lev->typ = DOOR; 388. 	    lev->doormask = D_NODOOR; 389. 	}  390.      } else if (lev->typ == SDOOR) { 391. 	if (lev->doormask & D_TRAPPED) { 392. 	    lev->doormask = D_NODOOR; 393. 	    b_trapped("secret door", 0); 394. 	} else { 395. 	    digtxt = "chew through the secret door."; 396. 	    lev->doormask = D_BROKEN; 397. 	}  398.  	lev->typ = DOOR; 399.  400.      } else if (IS_DOOR(lev->typ)) { 401. 	if (*in_rooms(x, y, SHOPBASE)) { 402. 	    add_damage(x, y, 400L); 403. 	    dmgtxt = "break"; 404. 	}  405.  	if (lev->doormask & D_TRAPPED) { 406. 	    lev->doormask = D_NODOOR; 407. 	    b_trapped("door", 0); 408. 	} else { 409. 	    digtxt = "chew through the door."; 410. 	    lev->doormask = D_BROKEN; 411. 	}  412.   413.      } else { /* STONE or SCORR */ 414. 	digtxt = "chew a passage through the rock."; 415. 	lev->typ = CORR; 416.     }  417.   418.      unblock_point(x, y);	/* vision */ 419.     newsym(x, y); 420.     if (digtxt) You(digtxt);	/* after newsym */ 421.     if (dmgtxt) pay_for_damage(dmgtxt); 422.     (void) memset((genericptr_t)&digging, 0, sizeof digging); 423.     return 0; 424. }  425.   426.  #endif /* OVL2 */ 427. #ifdef OVLB 428.  429.  void 430. movobj(obj, ox, oy) 431. register struct obj *obj; 432. register xchar ox, oy; 433. {  434.  	/* optimize by leaving on the fobj chain? */ 435.  	remove_object(obj); 436. 	newsym(obj->ox, obj->oy); 437. 	place_object(obj, ox, oy); 438. 	newsym(ox, oy); 439. }  440.   441.  #ifdef SINKS 442. static NEARDATA const char fell_on_sink[] = "fell onto a sink"; 443.  444.  STATIC_OVL void 445. dosinkfall 446. {  447.  	register struct obj *obj; 448.  449.  	if (is_floater(youmonst.data) || (HLevitation & FROMOUTSIDE)) { 450. 	    You("wobble unsteadily for a moment."); 451. 	} else { 452. 	    You("crash to the floor!"); 453. 	    losehp(rn1(8, 25 - (int)ACURR(A_CON)),  454.  		   fell_on_sink, NO_KILLER_PREFIX); 455. 	    exercise(A_DEX, FALSE); 456. 	    selftouch("Falling, you"); 457. 	    for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 458. 		if (obj->oclass == WEAPON_CLASS || is_weptool(obj)) { 459. 		    You("fell on %s.", doname(obj)); 460. 		    losehp(rnd(3), fell_on_sink, NO_KILLER_PREFIX); 461. 		    exercise(A_CON, FALSE); 462. 		}  463.  	}  464.   465.  	ELevitation &= ~W_ARTI; 466. 	HLevitation &= ~(I_SPECIAL|TIMEOUT); 467. 	HLevitation++; 468. 	if(uleft && uleft->otyp == RIN_LEVITATION) { 469. 	    obj = uleft; 470. 	    Ring_off(obj); 471. 	    off_msg(obj); 472. 	}  473.  	if(uright && uright->otyp == RIN_LEVITATION) { 474. 	    obj = uright; 475. 	    Ring_off(obj); 476. 	    off_msg(obj); 477. 	}  478.  	if(uarmf && uarmf->otyp == LEVITATION_BOOTS) { 479. 	    obj = uarmf; 480. 	    (void)Boots_off; 481. 	    off_msg(obj); 482. 	}  483.  	HLevitation--; 484. }  485.  #endif 486.  487.  boolean 488. may_dig(x,y) 489. register xchar x,y; 490. /* intended to be called only on ROCKs */ 491. {  492.      return (boolean)(!(IS_STWALL(levl[x][y].typ) && 493. 			(levl[x][y].wall_info & W_NONDIGGABLE))); 494. }  495.   496.  boolean 497. may_passwall(x,y) 498. register xchar x,y; 499. {  500.     return (boolean)(!(IS_STWALL(levl[x][y].typ) && 501. 			(levl[x][y].wall_info & W_NONPASSWALL))); 502. }  503.   504.  #endif /* OVLB */ 505. #ifdef OVL1 506.  507.  boolean 508. bad_rock(mdat,x,y) 509. struct permonst *mdat; 510. register xchar x,y; 511. {  512.  	return((boolean) ((In_sokoban(&u.uz) && sobj_at(BOULDER,x,y)) || 513. 	       (IS_ROCK(levl[x][y].typ)  514.  		    && (!tunnels(mdat) || needspick(mdat) || !may_dig(x,y))  515.  		    && !(passes_walls(mdat) && may_passwall(x,y))))); 516. }  517.   518.  boolean 519. invocation_pos(x, y)  520. xchar x, y; 521. { 522.  	return((boolean)(Invocation_lev(&u.uz) && x == inv_pos.x && y == inv_pos.y)); 523. }  524.   525.  #endif /* OVL1 */ 526. #ifdef OVL3 527.  528.  /* return TRUE if (dx,dy) is an OK place to move */ 529. boolean 530. test_move(ux, uy, dx, dy, test_only) 531. int ux, uy, dx, dy; 532. boolean test_only; 533. {  534.      int x = ux+dx; 535.     int y = uy+dy; 536.     register struct rm *tmpr = &levl[x][y]; 537.     register struct rm *ust; 538.  539.      /*  540.       *  Check for physical obstacles. First, the place we are going. 541.      */  542.      if (IS_ROCK(tmpr->typ) || tmpr->typ == IRONBARS) { 543. 	if (Blind && !test_only) feel_location(x,y); 544. 	if (Passes_walls && may_passwall(x,y)) { 545. 	    ;	/* do nothing */ 546. 	} else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { 547. 	    /* Eat the rock. */ 548.  	    if (!test_only && still_chewing(x,y)) return FALSE; 549. 	} else if (flags.autodig && !flags.run && !flags.nopick &&  550.  		   uwep && is_pick(uwep)) { 551. 	/* MRKR: Automatic digging when wielding the appropriate tool */ 552. 	    if (!test_only) 553. 		(void) use_pick_axe2(uwep); 554. 	    return FALSE; 555. 	} else { 556. 	    if ( !test_only ) { 557. 		if (Is_stronghold(&u.uz) && is_db_wall(x,y)) 558. 		    pline_The("drawbridge is up!"); 559. 		if (Passes_walls && !may_passwall(x,y) && In_sokoban(&u.uz)) 560. 	    		pline_The("Sokoban walls resist your ability."); 561. 	    }  562.  	    return FALSE; 563. 	}  564.      } else if (IS_DOOR(tmpr->typ)) { 565. 	if (closed_door(x,y)) { 566. 	    if (Blind && !test_only) feel_location(x,y); 567. 	    if (Passes_walls) 568. 		;	/* do nothing */ 569. 	    else if (can_ooze(&youmonst)) { 570. 		if ( !test_only ) You("ooze under the door."); 571. 	    } else if (tunnels(youmonst.data) && !needspick(youmonst.data)) { 572. 		/* Eat the door. */ 573.  		if (!test_only && still_chewing(x,y)) return FALSE; 574. 	    } else { 575. 		if ( !test_only ) { 576. 		    if (amorphous(youmonst.data)) 577. 			You("try to ooze under the door, but can't squeeze your possessions through."); 578. 		    else if (x == ux || y == uy) { 579. 			if (Blind || Stunned || ACURR(A_DEX) < 10 || Fumbling) { 580. #ifdef STEED 581. 			    if (u.usteed) 582. 				You_cant("lead %s through that closed door.",  583.  				      x_monnam(u.usteed, 584. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 585. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)); 586. 		 	    else { 587. #else 588. 			        pline("Ouch!  You bump into a door."); 589. 			        exercise(A_DEX, FALSE); 590. #endif 591. #ifdef STEED 592. 			    }  593.  #endif 594. 			} else pline("That door is closed."); 595. 		    }  596.  		}  597.  		return FALSE; 598. 	    }  599.  	} else if (dx && dy && !Passes_walls  600.  		    && ((tmpr->doormask & ~D_BROKEN) 601. #ifdef REINCARNATION 602. 				    || Is_rogue_level(&u.uz) 603. #endif 604. 				    || block_door(x,y))) { 605. 	    /* Diagonal moves into a door are not allowed. */ 606.  	    if ( Blind && !test_only ) 607. 		feel_location(x,y); 608. 	    return FALSE; 609. 	}  610.      }  611.      if (dx && dy  612.  	    && bad_rock(youmonst.data,ux,y) && bad_rock(youmonst.data,x,uy)) { 613. 	/* Move at a diagonal. */ 614.  	if (In_sokoban(&u.uz)) { 615. 	    if ( !test_only ) 616. 		You("cannot pass that way."); 617. 	    return FALSE; 618. 	}  619.  	if (bigmonst(youmonst.data)) { 620. 	    if ( !test_only ) 621. 		Your("body is too large to fit through."); 622. 	    return FALSE; 623. 	}  624.  	if (invent && (inv_weight + weight_cap > 600)) { 625. 	    if ( !test_only ) 626. 		You("are carrying too much to get through."); 627. 	    return FALSE; 628. 	}  629.      }  630.   631.      ust = &levl[ux][uy]; 632.  633.      /* Now see if other things block our way. . */ 634.      if (dx && dy && !Passes_walls  635.  		     && (IS_DOOR(ust->typ) && ((ust->doormask & ~D_BROKEN)  636.  #ifdef REINCARNATION  637.  			     || Is_rogue_level(&u.uz)  638.  #endif  639.  			     || block_entry(x, y)) 640. 			 )) {  641.  	/* Can't move at a diagonal out of a doorway with door. */ 642.  	return FALSE; 643.     }  644.   645.      if (sobj_at(BOULDER,x,y) && (In_sokoban(&u.uz) || !Passes_walls)) { 646. 	if (!(Blind || Hallucination) && (flags.run >= 2)) 647. 	    return FALSE; 648. 	if (!test_only) { 649. 	    /* tunneling monsters will chew before pushing */ 650. 	    if (tunnels(youmonst.data) && !needspick(youmonst.data) &&  651.  		!In_sokoban(&u.uz)) { 652. 		if (still_chewing(x,y)) return FALSE; 653. 	    } else 654. 		if (moverock < 0) return FALSE; 655. 	}  656.  	/* test_only will assume you'll be able to push it when you get there... */ 657.      }  658.   659.      /* OK, it is a legal place to move. */ 660.      return TRUE; 661. }  662.   663.  static void findtravelpath 664. {  665.      if ( u.tx != u.ux || u.ty != u.uy ) { 666. 	xchar travel[COLNO][ROWNO]; 667. 	xchar travelstepx[2][COLNO*ROWNO]; 668. 	xchar travelstepy[2][COLNO*ROWNO]; 669. 	int n=1; 670. 	int set=0; 671. 	int dia=1; 672.  673.  	(void) memset((genericptr_t)travel,0,sizeof(travel)); 674.  675.  	travelstepx[0][0] = u.tx; 676. 	travelstepy[0][0] = u.ty; 677. 	while ( n ) { 678. 	    int i;  679. int nn=0; 680. 	    for (i=0; i<n; i++) { 681. 		int dir; 682. 		int x = travelstepx[set][i]; 683. 		int y = travelstepy[set][i]; 684. 		static int ordered[] = { 0, 2, 4, 6, 1, 3, 5, 7 }; 685. 		for (dir=0; dir<8; dir++) { 686. 		    int nx = x+xdir[ordered[dir]]; 687. 		    int ny = y+ydir[ordered[dir]]; 688.     /*printf("try %d,%d\n",nx,ny);*/ 689. 		    if ( isok(nx,ny) && test_move( x, y, nx-x, ny-y, 1 ) ) { 690. 			if ( nx == u.ux && ny == u.uy ) { 691. 			    u.dx = x-u.ux; 692. 			    u.dy = y-u.uy; 693. 	/*printf("found\n");*/ 694. 	/*printf("findtravelpath %d,%d -> %d,%d by %d,%d\n",u.ux,u.uy,u.tx,u.ty,u.dx,u.dy); 695. 	*/  696.  			    return; 697. 			} else { 698. 	/*printf("%d %d %d",isok(nx,ny), !travel[nx][ny], ACCESSIBLE(levl[nx][ny].typ));*/ 699. 			    if ( !travel[nx][ny] ) { 700. 				travelstepx[1-set][nn]=nx; 701. 				travelstepy[1-set][nn]=ny; 702. 				travel[nx][ny]=dia; 703. 				nn++; 704. 			    }  705.  			}  706.  		    }  707.  		}  708.  	    }  709.  	    n = nn; 710. 	    set = 1-set; 711. 	    dia++; 712. 	}  713.   714.  	/* give up */ 715.     }  716.   717.      u.dx = 0; 718.     u.dy = 0; 719.     nomul(0); 720. }  721.   722.  void 723. domove 724. {  725.  	register struct monst *mtmp; 726. 	register struct rm *tmpr; 727. 	register xchar x,y; 728. 	struct trap *trap; 729. 	int wtcap; 730. 	boolean on_ice; 731. 	xchar chainx, chainy, ballx, bally;	/* ball&chain new positions */ 732. 	int bc_control;				/* control for ball&chain */ 733. 	boolean cause_delay = FALSE;	/* dragging ball will skip a move */ 734.  735.  	u_wipe_engr(rnd(5)); 736.  737.  	if ( flags.travel ) 738. 	    findtravelpath; 739.  740.  	if(((wtcap = near_capacity) >= OVERLOADED 741. 	    || (wtcap > SLT_ENCUMBER &&  742.  		(Upolyd ? (u.mh < 5 && u.mh != u.mhmax) 743. 			: (u.uhp < 10 && u.uhp != u.uhpmax))))  744.  	   && !Is_airlevel(&u.uz)) { 745. 	    if(wtcap < OVERLOADED) { 746. 		You("don't have enough stamina to move."); 747. 		exercise(A_CON, FALSE); 748. 	    } else 749. 		You("collapse under your load."); 750. 	    nomul(0); 751. 	    return; 752. 	}  753.  	if(u.uswallow) { 754. 		u.dx = u.dy = 0; 755. 		u.ux = x = u.ustuck->mx; 756. 		u.uy = y = u.ustuck->my; 757. 		mtmp = u.ustuck; 758. 	} else { 759. 		if (Is_airlevel(&u.uz) && rn2(4) &&  760.  			!Levitation && !Flying) { 761. 		    switch(rn2(3)) { 762. 		    case 0: 763. 			You("tumble in place."); 764. 			exercise(A_DEX, FALSE); 765. 			break; 766. 		    case 1: 767. 			You_cant("control your movements very well."); break; 768. 		    case 2: 769. 			pline("It's hard to walk in thin air."); 770. 			exercise(A_DEX, TRUE); 771. 			break; 772. 		    }  773.  		    return; 774. 		}  775.   776.  		/* check slippery ice */ 777. 		on_ice = !Levitation && is_ice(u.ux, u.uy); 778. 		if (on_ice) { 779. 		    static int skates = 0; 780. 		    if (!skates) skates = find_skates; 781. 		    if ((uarmf && uarmf->otyp == skates)  782.  			    || resists_cold(&youmonst) || Flying  783.  			    || is_floater(youmonst.data) || is_clinger(youmonst.data)  784.  			    || is_whirly(youmonst.data)) 785. 			on_ice = FALSE; 786. 		    else if (!rn2(Cold_resistance ? 3 : 2)) { 787.  			HFumbling |= FROMOUTSIDE; 788. 			HFumbling &= ~TIMEOUT; 789. 			HFumbling += 1;  /* slip on next move */ 790. 		    }  791.  		}  792.  		if (!on_ice && (HFumbling & FROMOUTSIDE)) 793. 		    HFumbling &= ~FROMOUTSIDE; 794.  795.  		x = u.ux + u.dx; 796. 		y = u.uy + u.dy; 797. 		if(Stunned || (Confusion && !rn2(5))) { 798. 			register int tries = 0; 799.  800.  			do { 801. 				if(tries++ > 50) { 802. 					nomul(0); 803. 					return; 804. 				}  805.  				confdir; 806. 				x = u.ux + u.dx; 807. 				y = u.uy + u.dy; 808. 			} while(!isok(x, y) || bad_rock(youmonst.data, x, y)); 809. 		}  810.  		/* turbulence might alter your actual destination */ 811. 		if (u.uinwater) { 812. 			water_friction; 813. 			if (!u.dx && !u.dy) { 814. 				nomul(0); 815. 				return; 816. 			}  817.  			x = u.ux + u.dx; 818. 			y = u.uy + u.dy; 819. 		}  820.  		if(!isok(x, y)) { 821. 			nomul(0); 822. 			return; 823. 		}  824.  		if((trap = t_at(x, y)) && trap->tseen) { 825. 			if(flags.run >= 2) { 826. 				nomul(0); 827. 				flags.move = 0; 828. 				return; 829. 			} else 830. 				nomul(0); 831. 		}  832.   833.  		if (u.ustuck && (x != u.ustuck->mx || y != u.ustuck->my)) { 834. 		    if (distu(u.ustuck->mx, u.ustuck->my) > 2) { 835. 			/* perhaps it fled (or was teleported or ... ) */ 836. 			u.ustuck = 0; 837. 		    } else if (sticks(youmonst.data)) { 838. 			/* When polymorphed into a sticking monster, 839. 			 * u.ustuck means it's stuck to you, not you to it. 840. 			 */  841.  			You("release %s.", mon_nam(u.ustuck)); 842. 			u.ustuck = 0; 843. 		    } else { 844. 			/* If holder is asleep or paralyzed: 845. 			 *	37.5% chance of getting away, 846. 			 *	12.5% chance of waking/releasing it; 847. 			 * otherwise: 848. 			 *	 7.5% chance of getting away. 849. 			 * [strength ought to be a factor] 850. 			 * If holder is tame and there is no conflict, 851. 			 * guaranteed escape. 852. 			 */  853.  			switch (rn2(!u.ustuck->mcanmove ? 8 : 40)) { 854.  			case 0: case 1: case 2: 855. 			pull_free: 856. 			    You("pull free from %s.", mon_nam(u.ustuck)); 857. 			    u.ustuck = 0; 858. 			    break; 859. 			case 3: 860. 			    if (!u.ustuck->mcanmove) { 861. 				/* it's free to move on next turn */ 862. 				u.ustuck->mfrozen = 1; 863. 				u.ustuck->msleeping = 0; 864. 			    }  865.  			    /*FALLTHRU*/ 866. 			default: 867. 			    if (u.ustuck->mtame &&  868.  				!Conflict && !u.ustuck->mconf) 869. 				goto pull_free; 870. 			    You("cannot escape from %s!", mon_nam(u.ustuck)); 871. 			    nomul(0); 872. 			    return; 873. 			}  874.  		    }  875.  		}  876.   877.  		mtmp = m_at(x,y); 878. 		if (mtmp) { 879. 			/* Don't attack if you're running, and can see it */ 880. 			/* We should never get here if forcefight */ 881. 			if (flags.run &&  882.  			    ((!Blind && mon_visible(mtmp) &&  883.  			      ((mtmp->m_ap_type != M_AP_FURNITURE &&  884.  				mtmp->m_ap_type != M_AP_OBJECT) || 885. 			       Protection_from_shape_changers)) || 886. 			     sensemon(mtmp))) { 887. 				nomul(0); 888. 				flags.move = 0; 889. 				return; 890. 			}  891.  		}  892.  	}  893.   894.  	u.ux0 = u.ux; 895. 	u.uy0 = u.uy; 896. 	bhitpos.x = x;  897. bhitpos.y = y; 898. tmpr = &levl[x][y]; 899.  900.  	/* attack monster */ 901. 	if(mtmp) { 902. 	    nomul(0); 903. 	    /* only attack if we know it's there */ 904. 	    /* or if we used the 'F' command to fight blindly */ 905. 	    /* or if it hides_under, in which case we call attack to print 906. 	     * the Wait! message. 907. 	     * This is different from ceiling hiders, who aren't handled in  908. * attack. 909. 	     */  910.   911.  	    /* If they used a 'm' command, trying to move onto a monster 912. 	     * prints the below message and wastes a turn. The exception is 913. * if the monster is unseen and the player doesn't remember an 914. * invisible monster--then, we fall through to attack and 915. 	     * attack_check, which still wastes a turn, but prints a  916. * different message and makes the player remember the monster. */ 917.  	    if(flags.nopick &&  918.  		  (canspotmon(mtmp) || glyph_is_invisible(levl[x][y].glyph))){ 919. 		if(mtmp->m_ap_type && !Protection_from_shape_changers  920.  						    && !sensemon(mtmp)) 921. 		    stumble_onto_mimic(mtmp); 922. 		else if (mtmp->mpeaceful && !Hallucination) 923. 		    pline("Pardon me, %s.", m_monnam(mtmp)); 924. 		else 925. 		    You("move right into %s.", mon_nam(mtmp)); 926. 		return; 927. 	    }  928.  	    if(flags.forcefight || !mtmp->mundetected || sensemon(mtmp) ||  929.  		    ((hides_under(mtmp->data) || mtmp->data->mlet == S_EEL) && 930. 			!is_safepet(mtmp))){ 931. 		gethungry; 932. 		if(wtcap >= HVY_ENCUMBER && moves%3) { 933. 		    if (Upolyd && u.mh > 1) { 934. 			u.mh--; 935. 		    } else if (!Upolyd && u.uhp > 1) { 936. 			u.uhp--; 937. 		    } else { 938. 			You("pass out from exertion!"); 939. 			exercise(A_CON, FALSE); 940. 			fall_asleep(-10, FALSE); 941. 		    }  942.  		}  943.  		if(multi < 0) return;	/* we just fainted */ 944.  945.  		/* try to attack; note that it might evade */ 946. 		/* also, we don't attack tame when _safepet_ */ 947. 		if(attack(mtmp)) return; 948. 	    }  949.  	}  950.   951.  	/* specifying 'F' with no monster wastes a turn */ 952. 	if (flags.forcefight ||  953.  	    /* remembered an 'I' && didn't use a move command */  954.  	    (glyph_is_invisible(levl[x][y].glyph) && !flags.nopick)) { 955. 	    	char buf[BUFSZ]; 956. 		Sprintf(buf,"a vacant spot on the %s", surface(x,y)); 957. 		You("attack %s.",  958.  		    !Underwater ? "thin air" : is_pool(x,y) ? "empty water" : buf); 959. 		unmap_object(x, y); /* known empty -- remove 'I' if present */ 960. 		newsym(x, y); 961. 		nomul(0); 962. 		return; 963. 	}  964.  	if (glyph_is_invisible(levl[x][y].glyph)) { 965. 	    unmap_object(x, y); 966. 	    newsym(x, y); 967. 	}  968.  	/* not attacking an animal, so we try to move */ 969. #ifdef STEED 970. 	if (u.usteed && !u.usteed->mcanmove && (u.dx || u.dy)) { 971. 		pline("%s won't move!",  972.  			upstart(x_monnam(u.usteed,  973.  					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  974.  				 	 (char *)0, SUPPRESS_SADDLE, FALSE))); 975. 		nomul(0); 976. 		return; 977. 	} else 978. #endif 979. 	if(!youmonst.data->mmove) { 980. 		You("are rooted %s.",  981.  		    Levitation || Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) ?  982.  		    "in place" : "to the ground"); 983. 		nomul(0); 984. 		return; 985. 	}  986.  	if(u.utrap) { 987. 		if(u.utraptype == TT_PIT) { 988. 		    if (!rn2(2) && sobj_at(BOULDER, u.ux, u.uy)) { 989. 			Your("%s gets stuck in a crevice.", body_part(LEG)); 990. 			display_nhwindow(WIN_MESSAGE, FALSE); 991. 			clear_nhwindow(WIN_MESSAGE); 992. 			You("free your %s.", body_part(LEG)); 993. 		    } else if (!(--u.utrap)) { 994. 			You("%s to the edge of the pit.",  995.  				(In_sokoban(&u.uz) && Levitation) ?  996.  				"struggle against the air currents and float" :  997.  #ifdef STEED  998.  				u.usteed ? "ride" :  999.  #endif  1000. 				"crawl"); 1001. 			fill_pit(u.ux, u.uy); 1002. 			vision_full_recalc = 1;	/* vision limits change */ 1003. 		   } else if (flags.verbose) { 1004. #ifdef STEED 1005. 			if (u.usteed) 1006. 			   	Norep("%s is still in a pit.",  1007. 				      upstart(x_monnam(u.usteed,  1008. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1009. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE))); 1010. 			else 1011. #endif 1012. 			Norep( (Hallucination && !rn2(5)) ? 1013. 				"You've fallen, and you can't get up." :  1014. 				"You are still in a pit." ); 1015. 		   }  1016. 		} else if (u.utraptype == TT_LAVA) { 1017. 		   if(flags.verbose) { 1018. 			char *predicament = "stuck in the lava"; 1019. #ifdef STEED 1020. 			if (u.usteed) 1021. 			   	Norep("%s is %s.",  1022. 				      upstart(x_monnam(u.usteed,  1023. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1024. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)),  1025. 					 predicament); 1026. 			else 1027. #endif 1028. 			Norep("You are %s.", predicament); 1029. 		   }  1030. 		    if(!is_lava(x,y)) { 1031. 			u.utrap--; 1032. 			if((u.utrap & 0xff) == 0) { 1033. #ifdef STEED 1034. 			   if (u.usteed) 1035. 				You("lead %s to the edge of the lava.", 1036. 				      x_monnam(u.usteed, 1037. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE, 1038. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)); 1039. 			   else 1040. #endif 1041. 			    You("pull yourself to the edge of the lava."); 1042. 			   u.utrap = 0; 1043. 			} 1044. 		    }  1045. 		    u.umoved = TRUE; 1046. 		} else if (u.utraptype == TT_WEB) { 1047. 		   if(uwep && uwep->oartifact == ART_STING) { 1048. 			u.utrap = 0; 1049. 			pline("Sting cuts through the web!"); 1050. 			return; 1051. 		   }  1052. 		    if(--u.utrap) { 1053. 			if(flags.verbose) { 1054. 			   char *predicament = "stuck to the web"; 1055. #ifdef STEED 1056. 			   if (u.usteed) 1057. 			   	Norep("%s is %s.",  1058. 				      upstart(x_monnam(u.usteed,  1059. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1060. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)),  1061. 					 predicament); 1062. 			   else 1063. #endif 1064. 			   Norep("You are %s.", predicament); 1065. 			} 1066. 		    } else { 1067. #ifdef STEED 1068. 			if (u.usteed) 1069. 				pline("%s breaks out of the web.", 1070. 				      upstart(x_monnam(u.usteed,  1071. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1072. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE))); 1073. 			else 1074. #endif 1075. 			You("disentangle yourself."); 1076. 		   }  1077. 		} else if (u.utraptype == TT_INFLOOR) { 1078. 		   if(--u.utrap) { 1079. 			if(flags.verbose) { 1080. 			   char *predicament = "stuck in the"; 1081. #ifdef STEED 1082. 			   if (u.usteed) 1083. 			   	Norep("%s is %s %s.",  1084. 				      upstart(x_monnam(u.usteed,  1085. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1086. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)),  1087. 					 predicament, surface(u.ux, u.uy)); 1088. 			   else 1089. #endif 1090. 			   Norep("You are %s %s.", predicament, surface(u.ux, u.uy)); 1091. 			} 1092. 		    } else { 1093. #ifdef STEED 1094. 			if (u.usteed) 1095. 				pline("%s finally wiggles free.", 1096. 				      upstart(x_monnam(u.usteed,  1097. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1098. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE))); 1099. 			else 1100. #endif 1101. 			You("finally wiggle free."); 1102. 		   }  1103. 		} else { 1104. 		   if(flags.verbose) { 1105. 			char *predicament = "caught in a bear trap"; 1106. #ifdef STEED 1107. 			if (u.usteed) 1108. 			   	Norep("%s is %s.",  1109. 				      upstart(x_monnam(u.usteed,  1110. 					 u.usteed->mnamelth ? ARTICLE_NONE : ARTICLE_THE,  1111. 				 	 (char *)0, SUPPRESS_SADDLE, FALSE)),  1112. 					 predicament); 1113. 			else 1114. #endif 1115. 			Norep("You are %s.", predicament); 1116. 		   }  1117. 		    if((u.dx && u.dy) || !rn2(5)) u.utrap--; 1118. 		} 1119. 		return; 1120. 	} 1121.  1122. 	if ( !test_move( u.ux, u.uy, x-u.ux, y-u.uy, 0 ) ) { 1123. 	   flags.move = 0; 1124. 	   nomul(0); 1125. 	   return; 1126. 	} 1127.  1128. 	/* Move ball and chain. */ 1129. 	if (Punished) 1130. 	   if (!drag_ball(x,y, &bc_control, &ballx, &bally, &chainx, &chainy, 1131. 			&cause_delay)) 1132. 		return; 1133. 1134. 	/* Check regions entering/leaving */ 1135. 	if (!in_out_region(x,y)) 1136. 	   return; 1137. 1138.  	/* now move the hero */ 1139. 	mtmp = m_at(x, y); 1140. 	u.ux += u.dx; 1141. 	u.uy += u.dy; 1142. #ifdef STEED 1143. 	/* Move your steed, too */ 1144. 	if (u.usteed) { 1145. 		u.usteed->mx = u.ux; 1146. 		u.usteed->my = u.uy; 1147. 		exercise_steed; 1148. 	} 1149. #endif 1150. 1151. 	/*  1152. 	 * If safepet at destination then move the pet to the hero's  1153. * previous location using the same conditions as in attack. 1154. 	 * there are special extenuating circumstances: 1155. 	 * (1) if the pet dies then your god angers, 1156. 	 * (2) if the pet gets trapped then your god may disapprove, 1157. 	 * (3) if the pet was already trapped and you attempt to free it 1158. * not only do you encounter the trap but you may frighten your 1159. 	 * pet causing it to go wild! moral: don't abuse this privilege. 1160. 	 * 1161. 	 * Ceiling-hiding pets are skipped by this section of code, to  1162. * be caught by the normal falling-monster code. 1163. 	 */ 1164. 	if (is_safepet(mtmp) && !(is_hider(mtmp->data) && mtmp->mundetected)) { 1165. 	   /* if trapped, there's a chance the pet goes wild */ 1166. 	   if (mtmp->mtrapped) { 1167. 		if (!rn2(mtmp->mtame)) { 1168. 		   mtmp->mtame = mtmp->mpeaceful = mtmp->msleeping = 0; 1169. 		   if (mtmp->mleashed) m_unleash(mtmp, TRUE); 1170. 		   growl(mtmp); 1171. 		} else { 1172. 		   yelp(mtmp); 1173. 		} 1174. 	    }  1175. 	    mtmp->mundetected = 0; 1176. 	   if (mtmp->m_ap_type) seemimic(mtmp); 1177. 	   else if (!mtmp->mtame) newsym(mtmp->mx, mtmp->my); 1178. 1179. 	    if (mtmp->mtrapped &&  1180. 		    (trap = t_at(mtmp->mx, mtmp->my)) != 0 &&  1181. 		    (trap->ttyp == PIT || trap->ttyp == SPIKED_PIT) &&  1182. 		    sobj_at(BOULDER, trap->tx, trap->ty)) { 1183. 		/* can't swap places with pet pinned in a pit by a boulder */ 1184. 		u.ux = u.ux0, u.uy = u.uy0;	/* didn't move after all */ 1185. 	   } else { 1186. 		char pnambuf[BUFSZ]; 1187. 1188. 		/* save its current description in case of polymorph */ 1189. 		Strcpy(pnambuf, y_monnam(mtmp)); 1190. 		mtmp->mtrapped = 0; 1191. 		remove_monster(x, y); 1192. 		place_monster(mtmp, u.ux0, u.uy0); 1193. 1194. 		/* check for displacing it into pools and traps */ 1195. 		switch (minliquid(mtmp) ? 2 : mintrap(mtmp)) { 1196. 		case 0: 1197. 		   You("%s %s.", mtmp->mtame ? "displaced" : "frightened",  1198. 			pnambuf); 1199. 		   break; 1200. 		case 1:		/* trapped */ 1201. 		case 3:		/* changed levels */ 1202. 		   /* there's already been a trap message, reinforce it */ 1203. 		   abuse_dog(mtmp); 1204. 		   adjalign(-3); 1205. 		   break; 1206. 		case 2: 1207. 		   /* it may have drowned or died. that's no way to 1208. * treat a pet! your god gets angry. 1209. 		    */  1210. 		    if (rn2(4)) { 1211. 			You_feel("guilty about losing your pet like this."); 1212. 			u.ugangr++; 1213. 			adjalign(-15); 1214. 		   }  1215.  1216. 		    /* you killed your pet by direct action. 1217. 		    * minliquid and mintrap don't know to do this 1218. 		    */  1219. 		    u.uconduct.killer++; 1220. 		   break; 1221. 		default: 1222. 		   pline("that's strange, unknown mintrap result!"); 1223. 		   break; 1224. 		} 1225. 	    }  1226. 	}  1227.  1228. 	reset_occupations; 1229. 	if (flags.run) { 1230. 	   if ( flags.run < 8 ) 1231. 		if (IS_DOOR(tmpr->typ) || IS_ROCK(tmpr->typ) || 1232. 			IS_FURNITURE(tmpr->typ)) 1233. 		   nomul(0); 1234. 	} 1235.  1236. 	if (hides_under(youmonst.data)) 1237. 	   u.uundetected = OBJ_AT(u.ux, u.uy); 1238. 	else if (youmonst.data->mlet == S_EEL) 1239. 	   u.uundetected = is_pool(u.ux, u.uy) && !Is_waterlevel(&u.uz); 1240. 	else if (u.dx || u.dy) 1241. 	   u.uundetected = 0; 1242. 1243. 	/*  1244. 	 * Mimics (or whatever) become noticeable if they move and are 1245. 	 * imitating something that doesn't move. We could extend this 1246. 	 * to non-moving monsters... 1247. */ 1248. 	if ((u.dx || u.dy) && (youmonst.m_ap_type == M_AP_OBJECT 1249. 				|| youmonst.m_ap_type == M_AP_FURNITURE)) 1250. 	   youmonst.m_ap_type = M_AP_NOTHING; 1251. 1252. 	check_leash(u.ux0,u.uy0); 1253. 1254. 	if(u.ux0 != u.ux || u.uy0 != u.uy) { 1255. 	   u.umoved = TRUE; 1256. 	   /* Clean old position -- vision_recalc will print our new one. */ 1257. 	    newsym(u.ux0,u.uy0); 1258. 	   /* Since the hero has moved, adjust what can be seen/unseen. */ 1259. 	    vision_recalc(1);	/* Do the work now in the recover time. */ 1260. 	    invocation_message; 1261. 	} 1262.  1263. 	if (Punished)				/* put back ball and chain */ 1264. 	   move_bc(0,bc_control,ballx,bally,chainx,chainy); 1265. 1266. 	spoteffects(TRUE); 1267. 1268. 	/* delay next move because of ball dragging */ 1269. 	/* must come after we finished picking up, in spoteffects */ 1270. 	if (cause_delay) { 1271. 	   nomul(-2); 1272. 	   nomovemsg = ""; 1273. 	} 1274. }  1275.  1276. void 1277. invocation_message 1278. { 1279. 	/* a special clue-msg when on the Invocation position */ 1280. 	if(invocation_pos(u.ux, u.uy) && !On_stairs(u.ux, u.uy)) { 1281. 	   struct obj *otmp = carrying(CANDELABRUM_OF_INVOCATION); 1282. 1283. 	    You_feel("a strange vibration under your %s.",  1284. 		    makeplural(body_part(FOOT))); 1285. 	   if (otmp && otmp->spe == 7 && otmp->lamplit) 1286. 		pline("%s %s!", The(xname(otmp)), 1287. 		    Blind ? "throbs palpably" : "glows with a strange light"); 1288. 	} 1289. }  1290.  1291. #endif /* OVL3 */ 1292. #ifdef OVL2 1293. 1294. void 1295. spoteffects(pick) 1296. boolean pick; 1297. { 1298. 	register struct trap *trap; 1299. 	register struct monst *mtmp; 1300. 1301. 	if(u.uinwater) { 1302. 		int was_underwater; 1303. 1304. 		if (!is_pool(u.ux,u.uy)) { 1305. 			if (Is_waterlevel(&u.uz)) 1306. 				You("pop into an air bubble."); 1307. 			else if (is_lava(u.ux, u.uy)) 1308. 				You("leave the water...");	/* oops! */ 1309. 			else 1310. 				You("are on solid %s again.", 1311. 				    is_ice(u.ux, u.uy) ? "ice" : "land"); 1312. 		} 1313. 		else if (Is_waterlevel(&u.uz)) 1314. 			goto stillinwater; 1315. 		else if (Levitation) 1316. 			You("pop out of the water like a cork!"); 1317. 		else if (Flying) 1318. 			You("fly out of the water."); 1319. 		else if (Wwalking) 1320. 			You("slowly rise above the surface."); 1321. 		else 1322. 			goto stillinwater; 1323. 		was_underwater = Underwater && !Is_waterlevel(&u.uz); 1324. 		u.uinwater = 0;		/* leave the water */ 1325. 		if (was_underwater) {	/* restore vision */ 1326. 			docrt; 1327. 			vision_full_recalc = 1; 1328. 		} 1329. 	}  1330. stillinwater:; 1331. 	if (!Levitation && !u.ustuck && !Flying) { 1332. 	   /* limit recursive calls through teleds */ 1333. 	   if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) { 1334. #ifdef STEED 1335. 		if (u.usteed && !is_flyer(u.usteed->data) && 1336. 			!is_floater(u.usteed->data) &&  1337. 			!is_clinger(u.usteed->data)) { 1338. 		   dismount_steed(Underwater ?  1339. 			    DISMOUNT_FELL : DISMOUNT_GENERIC); 1340. 		   /* dismount_steed -> float_down -> pickup */ 1341. 		   if (!Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) 1342. 			pick = FALSE; 1343. 		} else 1344. #endif 1345. 		if (is_lava(u.ux, u.uy)) { 1346. 		   if (lava_effects) return; 1347. 		} else if (!Wwalking && drown) 1348. 		   return; 1349. 	   }  1350. 	}  1351. 	check_special_room(FALSE); 1352. #ifdef SINKS 1353. 	if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation) 1354. 		dosinkfall; 1355. #endif 1356. 	if (pick && !in_steed_dismounting) 1357. 		(void) pickup(1); 1358. 	/* if dismounting, we'll check again later */ 1359. 	if ((trap = t_at(u.ux,u.uy)) != 0 && !in_steed_dismounting) 1360. 		dotrap(trap, 0);	/* fall into pit, arrow trap, etc. */ 1361. 	if((mtmp = m_at(u.ux, u.uy)) && !u.uswallow) { 1362. 		mtmp->mundetected = mtmp->msleeping = 0; 1363. 		switch(mtmp->data->mlet) { 1364. 		   case S_PIERCER: 1365. 			pline("%s suddenly drops from the %s!", 1366. 			      Amonnam(mtmp), ceiling(u.ux,u.uy)); 1367. 			if(mtmp->mtame) /* jumps to greet you, not attack */ 1368. 			   ;  1369. 			else if(uarmh) 1370. 			   pline("Its blow glances off your helmet."); 1371. 			else if (u.uac + 3 <= rnd(20)) 1372. 			   You("are almost hit by %s!",  1373. 				x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE)); 1374. 			else { 1375. 			   int dmg; 1376. 			   You("are hit by %s!",  1377. 				x_monnam(mtmp, ARTICLE_A, "falling", 0, TRUE)); 1378. 			   dmg = d(4,6); 1379. 			   if(Half_physical_damage) dmg = (dmg+1) / 2; 1380. 			   mdamageu(mtmp, dmg); 1381. 			} 1382. 			break; 1383. 		   default:	/* monster surprises you. */ 1384. 			if(mtmp->mtame) 1385. 			   pline("%s jumps near you from the %s.",  1386. 					Amonnam(mtmp), ceiling(u.ux,u.uy)); 1387. 			else if(mtmp->mpeaceful) { 1388. 				You("surprise %s!", 1389. 				    Blind && !sensemon(mtmp) ?  1390. 				    something : a_monnam(mtmp)); 1391. 				mtmp->mpeaceful = 0; 1392. 			} else 1393. 			   pline("%s attacks you by surprise!",  1394. 					Amonnam(mtmp)); 1395. 			break; 1396. 		} 1397. 		mnexto(mtmp); /* have to move the monster */ 1398. 	} 1399. }  1400.  1401. STATIC_OVL boolean 1402. monstinroom(mdat,roomno) 1403. struct permonst *mdat; 1404. int roomno; 1405. { 1406. 	register struct monst *mtmp; 1407. 1408. 	for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1409. 		if(!DEADMONSTER(mtmp) && mtmp->data == mdat && 1410. 		   index(in_rooms(mtmp->mx, mtmp->my, 0), roomno + ROOMOFFSET)) 1411. 			return(TRUE); 1412. 	return(FALSE); 1413. } 1414.  1415. char * 1416. in_rooms(x, y, typewanted) 1417. register xchar x, y; 1418. register int typewanted; 1419. { 1420. 	static char buf[5]; 1421. 	char rno, *ptr = &buf[4]; 1422. 	int typefound, min_x, min_y, max_x, max_y_offset, step; 1423. 	register struct rm *lev; 1424. 1425. #define goodtype(rno) (!typewanted || \  1426. 	     ((typefound = rooms[rno - ROOMOFFSET].rtype) == typewanted) || \  1427. 	     ((typewanted == SHOPBASE) && (typefound > SHOPBASE))) \ 1428. 1429. 	switch (rno = levl[x][y].roomno) { 1430. 		case NO_ROOM: 1431. 			return(ptr); 1432. 		case SHARED: 1433. 			step = 2; 1434. 			break; 1435. 		case SHARED_PLUS: 1436. 			step = 1; 1437. 			break; 1438. 		default:			/* i.e. a regular room # */ 1439. 			if (goodtype(rno)) 1440. 				*(--ptr) = rno; 1441. 			return(ptr); 1442. 	} 1443.  1444. 	min_x = x - 1; 1445. 	max_x = x + 1; 1446. 	if (x < 1) 1447. 		min_x += step; 1448. 	else 1449. 	if (x >= COLNO) 1450. 		max_x -= step; 1451. 1452. 	min_y = y - 1; 1453. 	max_y_offset = 2; 1454. 	if (min_y < 0) { 1455. 		min_y += step; 1456. 		max_y_offset -= step; 1457. 	} else 1458. 	if ((min_y + max_y_offset) >= ROWNO) 1459. 		max_y_offset -= step; 1460. 1461. 	for (x = min_x; x <= max_x; x += step) { 1462. 		lev = &levl[x][min_y]; 1463. 		y = 0; 1464. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1465. 		    !index(ptr, rno) && goodtype(rno)) 1466. 			*(--ptr) = rno; 1467. 		y += step; 1468. 		if (y > max_y_offset) 1469. 			continue; 1470. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1471. 		    !index(ptr, rno) && goodtype(rno)) 1472. 			*(--ptr) = rno; 1473. 		y += step; 1474. 		if (y > max_y_offset) 1475. 			continue; 1476. 		if (((rno = lev[y].roomno) >= ROOMOFFSET) && 1477. 		    !index(ptr, rno) && goodtype(rno)) 1478. 			*(--ptr) = rno; 1479. 	} 1480. 	return(ptr); 1481. } 1482.  1483. STATIC_OVL void 1484. move_update(newlev) 1485. register boolean newlev; 1486. { 1487. 	char *ptr1, *ptr2, *ptr3, *ptr4; 1488. 1489. 	Strcpy(u.urooms0, u.urooms); 1490. 	Strcpy(u.ushops0, u.ushops); 1491. 	if (newlev) { 1492. 		u.urooms[0] = '\0'; 1493. 		u.uentered[0] = '\0'; 1494. 		u.ushops[0] = '\0'; 1495. 		u.ushops_entered[0] = '\0'; 1496. 		Strcpy(u.ushops_left, u.ushops0); 1497. 		return; 1498. 	} 1499. 	Strcpy(u.urooms, in_rooms(u.ux, u.uy, 0)); 1500. 1501. 	for (ptr1 = &u.urooms[0],  1502. 	     ptr2 = &u.uentered[0],  1503. 	     ptr3 = &u.ushops[0],  1504. 	     ptr4 = &u.ushops_entered[0];  1505. 	     *ptr1; ptr1++) { 1506. 		if (!index(u.urooms0, *ptr1)) 1507. 			*(ptr2++) = *ptr1; 1508. 		if (IS_SHOP(*ptr1 - ROOMOFFSET)) { 1509. 			*(ptr3++) = *ptr1; 1510. 			if (!index(u.ushops0, *ptr1)) 1511. 				*(ptr4++) = *ptr1; 1512. 		} 1513. 	}  1514. 	*ptr2 = '\0'; 1515. 	*ptr3 = '\0'; 1516. 	*ptr4 = '\0'; 1517. 1518. 	/* filter u.ushops0 -> u.ushops_left */ 1519. 	for (ptr1 = &u.ushops0[0], ptr2 = &u.ushops_left[0]; *ptr1; ptr1++) 1520. 		if (!index(u.ushops, *ptr1)) 1521. 			*(ptr2++) = *ptr1; 1522. 	*ptr2 = '\0'; 1523. } 1524.  1525. void 1526. check_special_room(newlev) 1527. register boolean newlev; 1528. { 1529. 	register struct monst *mtmp; 1530. 	char *ptr; 1531. 1532. 	move_update(newlev); 1533. 1534. 	if (*u.ushops0) 1535. 	   u_left_shop(u.ushops_left, newlev); 1536. 1537. 	if (!*u.uentered && !*u.ushops_entered)		/* implied by newlev */ 1538. 	   return;		/* no entrance messages necessary */ 1539. 1540. 	/* Did we just enter a shop? */ 1541. 	if (*u.ushops_entered) 1542. 	   u_entered_shop(u.ushops_entered); 1543. 1544. 	for (ptr = &u.uentered[0]; *ptr; ptr++) { 1545. 	   register int roomno = *ptr - ROOMOFFSET, rt = rooms[roomno].rtype; 1546. 1547. 	    /* Did we just enter some other special room? */ 1548. 	    /* vault.c insists that a vault remain a VAULT, 1549. 	    * and temples should remain TEMPLEs, 1550. 	    * but everything else gives a message only the first time */ 1551. 	   switch (rt) { 1552. 		case ZOO: 1553. 		   pline("Welcome to David's treasure zoo!"); 1554. 		   break; 1555. 		case SWAMP: 1556. 		   pline("It %s rather %s down here.",  1557. 			  Blind ? "feels" : "looks",  1558. 			  Blind ? "humid" : "muddy"); 1559. 		   break; 1560. 		case COURT: 1561. 		   You("enter an opulent throne room!"); 1562. 		   break; 1563. 		case LEPREHALL: 1564. 		   You("enter a leprechaun hall!"); 1565. 		   break; 1566. 		case MORGUE: 1567. 		   if(midnight) { 1568. 			const char *run = locomotion(youmonst.data, "Run"); 1569. 			pline("%s away! %s away!", run, run); 1570. 		   } else 1571. 			You("have an uncanny feeling..."); 1572. 		   break; 1573. 		case BEEHIVE: 1574. 		   You("enter a giant beehive!"); 1575. 		   break; 1576. 		case COCKNEST: 1577. 		   You("enter a disgusting nest!"); 1578. 		   break; 1579. 		case ANTHOLE: 1580. 		   You("enter an anthole!"); 1581. 		   break; 1582. 		case BARRACKS: 1583. 		   if(monstinroom(&mons[PM_SOLDIER], roomno) ||  1584. 			monstinroom(&mons[PM_SERGEANT], roomno) ||  1585. 			monstinroom(&mons[PM_LIEUTENANT], roomno) ||  1586. 			monstinroom(&mons[PM_CAPTAIN], roomno)) 1587. 			You("enter a military barracks!"); 1588. 		   else 1589. 			You("enter an abandoned barracks."); 1590. 		   break; 1591. 		case DELPHI: 1592. 		   if(monstinroom(&mons[PM_ORACLE], roomno)) 1593. 			verbalize("%s, %s, welcome to Delphi!", 1594. 					Hello((struct monst *) 0), plname); 1595. 		   break; 1596. 		case TEMPLE: 1597. 		   intemple(roomno + ROOMOFFSET); 1598. 		   /* fall through */ 1599. 		default: 1600. 		   rt = 0; 1601. 	   }  1602.  1603. 	    if (rt != 0) { 1604. 		rooms[roomno].rtype = OROOM; 1605. 		if (!search_special(rt)) { 1606. 			/* No more room of that type */ 1607. 			switch(rt) { 1608. 			   case COURT: 1609. 				level.flags.has_court = 0; 1610. 				break; 1611. 			   case SWAMP: 1612. 				level.flags.has_swamp = 0; 1613. 				break; 1614. 			   case MORGUE: 1615. 				level.flags.has_morgue = 0; 1616. 				break; 1617. 			   case ZOO: 1618. 				level.flags.has_zoo = 0; 1619. 				break; 1620. 			   case BARRACKS: 1621. 				level.flags.has_barracks = 0; 1622. 				break; 1623. 			   case TEMPLE: 1624. 				level.flags.has_temple = 0; 1625. 				break; 1626. 			   case BEEHIVE: 1627. 				level.flags.has_beehive = 0; 1628. 				break; 1629. 			} 1630. 		}  1631. 		if (rt == COURT || rt == SWAMP || rt == MORGUE || rt == ZOO) 1632. 		   for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 1633. 			if (!DEADMONSTER(mtmp) && !Stealth && !rn2(3)) mtmp->msleeping = 0; 1634. 	   }  1635. 	}  1636.  1637. 	return; 1638. } 1639.  1640. #endif /* OVL2 */ 1641. #ifdef OVLB 1642. 1643. int 1644. dopickup 1645. { 1646. 	int count; 1647. 	/* awful kludge to work around parse's pre-decrement */ 1648. 	count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0; 1649. 	multi = 0;	/* always reset */ 1650. 	/* uswallow case added by GAN 01/29/87 */ 1651. 	if(u.uswallow) { 1652. 	   if (!u.ustuck->minvent) { 1653. 		if (is_animal(u.ustuck->data)) { 1654. 		   You("pick up %s tongue.", s_suffix(mon_nam(u.ustuck))); 1655. 		   pline("But it's kind of slimy, so you drop it."); 1656. 		} else 1657. 		   You("don't %s anything in here to pick up.",  1658. 			  Blind ? "feel" : "see"); 1659. 		return(1); 1660. 	   } else { 1661. 	   	int tmpcount = -count; 1662. 		return loot_mon(u.ustuck, &tmpcount, (boolean *)0); 1663. 	   }  1664. 	}  1665. 	if(is_pool(u.ux, u.uy)) { 1666. 	   if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)  1667. 			|| (Flying && !Breathless)) { 1668. 		You("cannot dive into the water to pick things up."); 1669. 		return(0); 1670. 	   } else if (!Underwater) { 1671. 		You_cant("even see the bottom, let alone pick up %s.", 1672. 				something); 1673. 		return(0); 1674. 	   }  1675. 	}  1676. 	if (is_lava(u.ux, u.uy)) { 1677. 	   if (Wwalking || is_floater(youmonst.data) || is_clinger(youmonst.data)  1678. 			|| (Flying && !Breathless)) { 1679. 		You_cant("reach the bottom to pick things up."); 1680. 		return(0); 1681. 	   } else if (!likes_lava(youmonst.data)) { 1682. 		You("would burn to a crisp trying to pick things up."); 1683. 		return(0); 1684. 	   }  1685. 	}  1686. 	if(!OBJ_AT(u.ux, u.uy)) { 1687. 		There("is nothing here to pick up."); 1688. 		return(0); 1689. 	} 1690. 	if (!can_reach_floor) { 1691. #ifdef STEED 1692. 		if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) 1693. 			You("aren't skilled enough to reach from %s.", 1694. 					mon_nam(u.usteed)); 1695. 		else 1696. #endif 1697. 		You("cannot reach the %s.", surface(u.ux,u.uy)); 1698. 		return(0); 1699. 	} 1700. 	return (pickup(-count)); 1701. } 1702.  1703. #endif /* OVLB */ 1704. #ifdef OVL2 1705. 1706. /* stop running if we see something interesting */ 1707. /* turn around a corner if that is the only way we can proceed */ 1708. /* do not turn left or right twice */ 1709. void 1710. lookaround 1711. { 1712.     register int x, y, i, x0 = 0, y0 = 0, m0 = 1, i0 = 9; 1713.    register int corrct = 0, noturn = 0; 1714.    register struct monst *mtmp; 1715.    register struct trap *trap; 1716. 1717.     /* Grid bugs stop if trying to move diagonal, even if blind. Maybe */ 1718.    /* they polymorphed while in the middle of a long move. */ 1719.     if (u.umonnum == PM_GRID_BUG && u.dx && u.dy) { 1720. 	nomul(0); 1721. 	return; 1722.    }  1723.  1724.     if(Blind || flags.run == 0) return; 1725.    for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++) { 1726. 	if(!isok(x,y)) continue; 1727. 1728. 	if(u.umonnum == PM_GRID_BUG && x != u.ux && y != u.uy) continue; 1729. 1730. 	if(x == u.ux && y == u.uy) continue; 1731. 1732. 	if((mtmp = m_at(x,y)) &&  1733. 		    mtmp->m_ap_type != M_AP_FURNITURE &&  1734. 		    mtmp->m_ap_type != M_AP_OBJECT &&  1735. 		    (!mtmp->minvis || See_invisible) && !mtmp->mundetected) { 1736. 	   if((flags.run != 1 && !mtmp->mtame)  1737. 					|| (x == u.ux+u.dx && y == u.uy+u.dy)) 1738. 		goto stop; 1739. 	} 1740.  1741. 	if (levl[x][y].typ == STONE) continue; 1742. 	if (x == u.ux-u.dx && y == u.uy-u.dy) continue; 1743. 1744. 	if (IS_ROCK(levl[x][y].typ) || (levl[x][y].typ == ROOM) ||  1745. 	    IS_AIR(levl[x][y].typ)) 1746. 	   continue; 1747. 	else if (closed_door(x,y)) { 1748. 	   if(x != u.ux && y != u.uy) continue; 1749. 	   if(flags.run != 1) goto stop; 1750. 	   goto bcorr; 1751. 	} else if (levl[x][y].typ == CORR) { 1752. bcorr: 1753. 	   if(levl[u.ux][u.uy].typ != ROOM) { 1754. 		if(flags.run == 1 || flags.run == 3 || flags.run == 8) { 1755. 		   i = dist2(x,y,u.ux+u.dx,u.uy+u.dy); 1756. 		   if(i > 2) continue; 1757. 		   if(corrct == 1 && dist2(x,y,x0,y0) != 1) 1758. 			noturn = 1; 1759. 		   if(i < i0) { 1760. 			i0 = i; 1761. x0 = x; 1762. y0 = y; 1763. m0 = mtmp ? 1 : 0; 1764. 		    }  1765. 		}  1766. 		corrct++; 1767. 	   }  1768. 	    continue; 1769. 	} else if ((trap = t_at(x,y)) && trap->tseen) { 1770. 	   if(flags.run == 1) goto bcorr;	/* if you must */ 1771. 	   if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop; 1772. 	   continue; 1773. 	} else if (is_pool(x,y) || is_lava(x,y)) { 1774. 	   /* water and lava only stop you if directly in front, and stop 1775. 	    * you even if you are running 1776. 	    */  1777. 	    if(!Levitation && !Flying && !is_clinger(youmonst.data) &&  1778. 				x == u.ux+u.dx && y == u.uy+u.dy) 1779. 			/* No Wwalking check; otherwise they'd be able 1780. 			 * to test boots by trying to SHIFT-direction 1781. 			 * into a pool and seeing if the game allowed it 1782. */ 1783. 			goto stop; 1784. 	   continue; 1785. 	} else {		/* e.g. objects or trap or stairs */ 1786. 	   if(flags.run == 1) goto bcorr; 1787. 	   if(flags.run == 8) continue; 1788. 	   if(mtmp) continue;		/* d */ 1789. 	   if(((x == u.ux - u.dx) && (y != u.uy + u.dy)) ||  1790. 	       ((y == u.uy - u.dy) && (x != u.ux + u.dx))) 1791. 	      continue; 1792. 	} 1793. stop: 1794. 	nomul(0); 1795. 	return; 1796.    } /* end for loops */ 1797. 1798.     if(corrct > 1 && flags.run == 2) goto stop; 1799.    if((flags.run == 1 || flags.run == 3 || flags.run == 8) &&  1800. 	!noturn && !m0 && i0 && (corrct == 1 || (corrct == 2 && i0 == 1))) 1801.    {  1802. 	/* make sure that we do not turn too far */ 1803. 	if(i0 == 2) { 1804. 	   if(u.dx == y0-u.uy && u.dy == u.ux-x0) 1805. 		i = 2;		/* straight turn right */ 1806. 	   else 1807. 		i = -2;		/* straight turn left */ 1808. 	} else if(u.dx && u.dy) { 1809. 	   if((u.dx == u.dy && y0 == u.uy) || (u.dx != u.dy && y0 != u.uy)) 1810. 		i = -1;		/* half turn left */ 1811. 	   else 1812. 		i = 1;		/* half turn right */ 1813. 	} else { 1814. 	   if((x0-u.ux == y0-u.uy && !u.dy) || (x0-u.ux != y0-u.uy && u.dy)) 1815. 		i = 1;		/* half turn right */ 1816. 	   else 1817. 		i = -1;		/* half turn left */ 1818. 	} 1819.  1820. 	i += u.last_str_turn; 1821. 	if(i <= 2 && i >= -2) { 1822. 	   u.last_str_turn = i;  1823. u.dx = x0-u.ux; 1824. 	   u.dy = y0-u.uy; 1825. 	} 1826.     }  1827. }  1828.  1829. /* something like lookaround, but we are not running */ 1830. /* react only to monsters that might hit us */ 1831. int 1832. monster_nearby 1833. { 1834. 	register int x,y; 1835. 	register struct monst *mtmp; 1836. 1837. 	/* Also see the similar check in dochugw in monmove.c */ 1838. 	for(x = u.ux-1; x <= u.ux+1; x++) 1839. 	   for(y = u.uy-1; y <= u.uy+1; y++) { 1840. 		if(!isok(x,y)) continue; 1841. 		if(x == u.ux && y == u.uy) continue; 1842. 		if((mtmp = m_at(x,y)) && 1843. 		   mtmp->m_ap_type != M_AP_FURNITURE &&  1844. 		   mtmp->m_ap_type != M_AP_OBJECT &&  1845. 		   (!mtmp->mpeaceful || Hallucination) &&  1846. 		   (!is_hider(mtmp->data) || !mtmp->mundetected) &&  1847. 		   !noattacks(mtmp->data) &&  1848. 		   mtmp->mcanmove && !mtmp->msleeping &&  /* aplvax!jcn */  1849. 		   !onscary(u.ux, u.uy, mtmp) &&  1850. 		   canspotmon(mtmp)) 1851. 			return(1); 1852. 	} 1853. 	return(0); 1854. } 1855.  1856. void 1857. nomul(nval) 1858. 	register int nval; 1859. { 1860. 	if(multi < nval) return;	/* This is a bug fix by ab@unido */ 1861. 	u.uinvulnerable = FALSE;	/* Kludge to avoid ctrl-C bug -dlc */ 1862. 	u.usleep = 0; 1863. 	multi = nval; 1864. 	flags.travel = flags.mv = flags.run = 0; 1865. } 1866.  1867. /* called when a non-movement, multi-turn action has completed */ 1868. void unmul(msg_override) 1869. const char *msg_override; 1870. { 1871. 	multi = 0;	/* caller will usually have done this already */ 1872. 	if (msg_override) nomovemsg = msg_override; 1873. 	else if (!nomovemsg) nomovemsg = You_can_move_again; 1874. 	if (*nomovemsg) pline(nomovemsg); 1875. 	nomovemsg = 0; 1876. 	u.usleep = 0; 1877. 	if (afternmv) (*afternmv); 1878. 	afternmv = 0; 1879. } 1880.  1881. #endif /* OVL2 */ 1882. #ifdef OVL1 1883. 1884. STATIC_OVL void 1885. maybe_wail 1886. { 1887.     static short powers[] = { TELEPORT, SEE_INVIS, POISON_RES, COLD_RES, 1888. 			     SHOCK_RES, FIRE_RES, SLEEP_RES, DISINT_RES, 1889. 			     TELEPORT_CONTROL, STEALTH, FAST, INVIS }; 1890. 1891.     if (moves <= wailmsg + 50) return; 1892. 1893.     wailmsg = moves; 1894.    if (Role_if(PM_WIZARD) || Race_if(PM_ELF) || Role_if(PM_VALKYRIE)) { 1895. 	const char *who; 1896. 	int i, powercnt; 1897. 1898. 	who = (Role_if(PM_WIZARD) || Role_if(PM_VALKYRIE)) ? 1899. 		urole.name.m : "Elf"; 1900. 	if (u.uhp == 1) { 1901. 	   pline("%s is about to die.", who); 1902. 	} else { 1903. 	   for (i = 0, powercnt = 0; i < SIZE(powers); ++i) 1904. 		if (u.uprops[powers[i]].intrinsic & INTRINSIC) ++powercnt; 1905. 1906. 	    pline(powercnt >= 4 ? "%s, all your powers will be lost..."  1907. 				: "%s, your life force is running out.", who); 1908. 	} 1909.     } else { 1910. 	You_hear(u.uhp == 1 ? "the wailing of the Banshee..." 1911. 			    : "the howling of the CwnAnnwn..."); 1912.    }  1913. }  1914.  1915. void 1916. losehp(n, knam, k_format) 1917. register int n; 1918. register const char *knam; 1919. boolean k_format; 1920. { 1921. 	if (Upolyd) { 1922. 		u.mh -= n; 1923. if (u.mhmax < u.mh) u.mhmax = u.mh; 1924. 		flags.botl = 1; 1925. 		if (u.mh < 1) 1926. 		   rehumanize; 1927. 		else if (n > 0 && u.mh*10 < u.mhmax && Unchanging) 1928. 		   maybe_wail; 1929. 		return; 1930. 	} 1931.  1932. 	u.uhp -= n;  1933. if(u.uhp > u.uhpmax) 1934. 		u.uhpmax = u.uhp;	/* perhaps n was negative */ 1935. 	flags.botl = 1; 1936. 	if(u.uhp < 1) { 1937. 		killer_format = k_format; 1938. 		killer = knam;		/* the thing that killed you */ 1939. 		You("die..."); 1940. 		done(DIED); 1941. 	} else if (n > 0 && u.uhp*10 < u.uhpmax) { 1942. 		maybe_wail; 1943. 	} 1944. }  1945.  1946. int 1947. weight_cap 1948. { 1949. 	register long carrcap; 1950. 1951. 	carrcap = (((ACURRSTR + ACURR(A_CON))/2)+1)*50; 1952. 	if (Upolyd) { 1953. 		/* consistent with can_carry in mon.c */ 1954. 		if (youmonst.data->mlet == S_NYMPH) 1955. 			carrcap = MAX_CARR_CAP; 1956. 		else if (!youmonst.data->cwt) 1957. 			carrcap = (carrcap * (long)youmonst.data->msize) / MZ_HUMAN; 1958. 		else if (!strongmonst(youmonst.data) 1959. 			|| (strongmonst(youmonst.data) && (youmonst.data->cwt > WT_HUMAN))) 1960. 			carrcap = (carrcap * (long)youmonst.data->cwt / WT_HUMAN); 1961. 	} 1962.  1963. 	if (Levitation || Is_airlevel(&u.uz)    /* pugh@cornell */  1964. #ifdef STEED  1965. 			|| (u.usteed && strongmonst(u.usteed->data))  1966. #endif  1967. 	) 1968. 		carrcap = MAX_CARR_CAP; 1969. 	else { 1970. 		if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP; 1971. 		if (!Flying) { 1972. 			if(EWounded_legs & LEFT_SIDE) carrcap -= 100; 1973. 			if(EWounded_legs & RIGHT_SIDE) carrcap -= 100; 1974. 		} 1975. 		if (carrcap < 0) carrcap = 0; 1976. 	} 1977. 	return((int) carrcap); 1978. } 1979.  1980. static int wc;	/* current weight_cap; valid after call to inv_weight */ 1981. 1982. /* returns how far beyond the normal capacity the player is currently. */ 1983. /* inv_weight is negative if the player is below normal capacity. */ 1984. int 1985. inv_weight 1986. { 1987. 	register struct obj *otmp = invent; 1988. 	register int wt = 0; 1989. 1990. #ifndef GOLDOBJ 1991. 	/* when putting stuff into containers, gold is inserted at the head 1992. 	  of invent for easier manipulation by askchain & co, but it's also 1993. 	  retained in u.ugold in order to keep the status line accurate; we  1994. mustn't add its weight in twice under that circumstance */ 1995. 	wt = (otmp && otmp->oclass == GOLD_CLASS) ? 0 : 1996. 		(int)((u.ugold + 50L) / 100L); 1997. #endif 1998. 	while (otmp) { 1999. #ifndef GOLDOBJ 2000. 		if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data)) 2001. #else 2002. 		if (otmp->oclass == GOLD_CLASS) 2003. 			wt += (int)(((long)otmp->quan + 50L) / 100L); 2004. 		else if (otmp->otyp != BOULDER || !throws_rocks(youmonst.data)) 2005. #endif 2006. 			wt += otmp->owt; 2007. 		otmp = otmp->nobj; 2008. 	} 2009. 	wc = weight_cap; 2010. 	return (wt - wc); 2011. } 2012.  2013. /*  2014.  * Returns 0 if below normal capacity, or the number of "capacity units" 2015. * over the normal capacity the player is loaded. Max is 5. 2016. */  2017. int 2018. calc_capacity(xtra_wt) 2019. int xtra_wt; 2020. { 2021.     int cap, wt = inv_weight + xtra_wt; 2022. 2023.     if (wt <= 0) return UNENCUMBERED; 2024.    if (wc <= 1) return OVERLOADED; 2025.    cap = (wt*2 / wc) + 1; 2026.    return min(cap, OVERLOADED); 2027. } 2028.  2029. int 2030. near_capacity 2031. { 2032.     return calc_capacity(0); 2033. } 2034.  2035. int 2036. max_capacity 2037. { 2038.     int wt = inv_weight; 2039. 2040.     return (wt - (2 * wc)); 2041. } 2042.  2043. boolean 2044. check_capacity(str) 2045. const char *str; 2046. { 2047.     if(near_capacity >= EXT_ENCUMBER) { 2048. 	if(str) 2049. 	   pline(str); 2050. 	else 2051. 	   You_cant("do that while carrying so much stuff."); 2052. 	return 1; 2053.    }  2054.     return 0; 2055. } 2056.  2057. #endif /* OVL1 */ 2058. #ifdef OVLB 2059. 2060. int 2061. inv_cnt 2062. { 2063. 	register struct obj *otmp = invent; 2064. 	register int ct = 0; 2065. 2066. 	while(otmp){ 2067. 		ct++; 2068. 		otmp = otmp->nobj; 2069. 	} 2070. 	return(ct); 2071. } 2072.  2073. #ifdef GOLDOBJ 2074. /* Counts the money in an object chain. */ 2075. /* Intended use is for your or some monsters inventory, */ 2076. /* now that u.gold/m.gold is gone.*/ 2077. /* Counting money in a container might be possible too. */ 2078. long money_cnt(otmp) 2079. struct obj *otmp; 2080. { 2081.         while(otmp) { 2082. 	       /* Must change when silver & copper is implemented: */ 2083. 	        if (otmp->oclass == GOLD_CLASS) return otmp->quan; 2084.  	        otmp = otmp->nobj; 2085. 	} 2086. 	return 0; 2087. } 2088. #endif 2089. #endif /* OVLB */ 2090. 2091. /*hack.c*/