Source:NetHack 3.2.0/hack.c

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