Source:NetHack 3.1.0/hack.c

From NetHackWiki
Jump to navigation Jump to search

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

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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