Source:NetHack 2.3e/hack.c

From NetHackWiki
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2.    
3.    #include <stdio.h>
4.    #include "hack.h"
5.    #ifdef UNIX
6.    static	char	SCCS_Id[] = "@(#)hack.c	2.3\t88/02/18";
7.    #endif
8.    extern char news0();
9.    extern char *nomovemsg;
10.   extern char *exclam();
11.   extern struct obj *addinv();
12.   extern boolean hmon();
13.   
14.   /* called on movement:
15.   	1. when throwing ball+chain far away
16.   	2. when teleporting
17.   	3. when walking out of a lit room
18.    */
19.   unsee() {
20.   	register x,y;
21.   	register struct rm *lev;
22.   
23.   /*
24.   	if(u.udispl){
25.   		u.udispl = 0;
26.   		newsym(u.udisx, u.udisy);
27.   	}
28.   */
29.   #ifndef QUEST
30.   	if(seehx){
31.   		seehx = 0;
32.   	} else
33.   #endif
34.   	for(x = u.ux-1; x < u.ux+2; x++)
35.   	  for(y = u.uy-1; y < u.uy+2; y++) {
36.   		if(!isok(x, y)) continue;
37.   		lev = &levl[x][y];
38.   		if(!lev->lit && lev->scrsym == ROOM_SYM) {
39.   			lev->scrsym = STONE_SYM;
40.   			lev->new = 1;
41.   			on_scr(x,y);
42.   		}
43.   	}
44.   }
45.   
46.   /* called:
47.   	in apply.c:  seeoff(0)	- when taking a picture of yourself
48.   				- when donning a blindfold
49.   	in do.c:     seeoff(0)	- blind after drinking potion
50.   	in do.c:     seeoff(1)	- go up or down the stairs
51.   	in eat.c:    seeoff(0)	- blind after eating rotten food
52.   	in mhitu.c:  seeoff(0)	- blinded by a yellow light
53.   	in mon.c:    seeoff(1)	- swallowed
54.   	in potion.c: seeoff(0)	- quaffing or sniffing a potion of blindness
55.   	in spell.c:  seeoff(0)	- due to a cursed spellbook
56.   	in trap.c:   seeoff(1)	- fall through trapdoor
57.   	in wizard.c: seeoff(0)	- hit by a cream pie.
58.    */
59.   seeoff(mode)	/* 1 to redo @, 0 to leave them */
60.   {	/* 1 means misc movement, 0 means blindness */
61.   	register x,y;
62.   	register struct rm *lev;
63.   
64.   	if(u.udispl && mode){
65.   		u.udispl = 0;
66.   		levl[u.udisx][u.udisy].scrsym = news0(u.udisx,u.udisy);
67.   	}
68.   #ifndef QUEST
69.   	if(seehx) {
70.   		seehx = 0;
71.   	} else
72.   #endif
73.   	if(!mode) {
74.   		for(x = u.ux-1; x < u.ux+2; x++)
75.   			for(y = u.uy-1; y < u.uy+2; y++) {
76.   				if(!isok(x, y)) continue;
77.   				lev = &levl[x][y];
78.   				if(!lev->lit && lev->scrsym == ROOM_SYM)
79.   					lev->seen = 0;
80.   			}
81.   	}
82.   }
83.   
84.   static
85.   moverock() {
86.   	register xchar rx, ry;
87.   	register struct obj *otmp;
88.   	register struct trap *ttmp;
89.   	register struct	monst *mtmp;
90.   	struct monst *m_at();
91.   
92.   	while(otmp = sobj_at(ENORMOUS_ROCK, u.ux+u.dx, u.uy+u.dy)) {
93.   		rx = u.ux+2*u.dx;
94.   		ry = u.uy+2*u.dy;
95.   		nomul(0);
96.   		if(isok(rx,ry) && !IS_ROCK(levl[rx][ry].typ) &&
97.   		    (levl[rx][ry].typ != DOOR || !(u.dx && u.dy)) &&
98.   		    !sobj_at(ENORMOUS_ROCK, rx, ry)) {
99.   			if((mtmp = m_at(rx,ry))) {
100.  			    if(canseemon(mtmp))
101.  				pline("There's %s on the other side.", monnam(mtmp));
102.  			    else
103.  				pline("You hear a monster behind the rock.");
104.  			    pline("Perhaps that's why you cannot move it.");
105.  			    goto cannot_push;
106.  			}
107.  			if(ttmp = t_at(rx,ry))
108.  			    switch(ttmp->ttyp) {
109.  			    case PIT:
110.  				pline("You push the rock into a pit!");
111.  				deltrap(ttmp);
112.  				delobj(otmp);
113.  				pline("It completely fills the pit!");
114.  				continue;
115.  			    case TELEP_TRAP:
116.  				pline("You push the rock and suddenly it disappears!");
117.  				delobj(otmp);
118.  				continue;
119.  			    }
120.  			if(levl[rx][ry].typ == POOL) {
121.  				levl[rx][ry].typ = ROOM;
122.  				mnewsym(rx,ry);
123.  				prl(rx,ry);
124.  				pline("You push the rock into the water.");
125.  				pline("Now you can cross the water!");
126.  				delobj(otmp);
127.  				continue;
128.  			}
129.  			otmp->ox = rx;
130.  			otmp->oy = ry;
131.  			/* pobj(otmp); */
132.  			if(cansee(rx,ry)) atl(rx,ry,otmp->olet);
133.  			if(Invisible) newsym(u.ux+u.dx, u.uy+u.dy);
134.  
135.  			{ static long lastmovetime;
136.  			/* note: this var contains garbage initially and
137.  			   after a restore */
138.  			if(moves > lastmovetime+2 || moves < lastmovetime)
139.  			pline("With great effort you move the enormous rock.");
140.  			lastmovetime = moves;
141.  			}
142.  		} else {
143.  		    pline("You try to move the enormous rock, but in vain.");
144.  	    cannot_push:
145.  #ifdef KAA
146.  		    if (u.usym=='9') {
147.  # ifdef DGKMOD
148.  			if(!flags.pickup)
149.  				pline("You easily can push it aside.");
150.  			else
151.  # endif
152.  				pline("However, you easily can pick it up.");
153.  			break;
154.  		    }
155.  #endif
156.  		    if((!invent || inv_weight()+90 <= 0) &&
157.  			(!u.dx || !u.dy || (IS_ROCK(levl[u.ux][u.uy+u.dy].typ)
158.  					&& IS_ROCK(levl[u.ux+u.dx][u.uy].typ)))){
159.  			pline("However, you can squeeze yourself into a small opening.");
160.  			break;
161.  		    } else
162.  			return (-1);
163.  		}
164.  	}
165.  	return (0);
166.  }
167.  
168.  domove()
169.  {
170.  	register struct monst *mtmp;
171.  	register struct rm *tmpr,*ust;
172.  	struct trap *trap;
173.  
174.  	u_wipe_engr(rnd(5));
175.  
176.  	if(inv_weight() > 0){
177.  		pline("You collapse under your load.");
178.  		nomul(0);
179.  		return;
180.  	}
181.  	if(u.uswallow) {
182.  		u.dx = u.dy = 0;
183.  		u.ux = u.ustuck->mx;
184.  		u.uy = u.ustuck->my;
185.  	} else {
186.  		if(Confusion) {
187.  			do {
188.  				confdir();
189.  			} while(!isok(u.ux+u.dx, u.uy+u.dy) ||
190.  			    IS_ROCK(levl[u.ux+u.dx][u.uy+u.dy].typ));
191.  		}
192.  		if(!isok(u.ux+u.dx, u.uy+u.dy)){
193.  			nomul(0);
194.  			return;
195.  		}
196.  	}
197.  
198.  	ust = &levl[u.ux][u.uy];
199.  	u.ux0 = u.ux;
200.  	u.uy0 = u.uy;
201.  	if(!u.uswallow && (trap = t_at(u.ux+u.dx, u.uy+u.dy)) && trap->tseen)
202.  		nomul(0);
203.  	if(u.ustuck && !u.uswallow && (u.ux+u.dx != u.ustuck->mx ||
204.  		u.uy+u.dy != u.ustuck->my)) {
205.  		if(dist(u.ustuck->mx, u.ustuck->my) > 2){
206.  			/* perhaps it fled (or was teleported or ... ) */
207.  			u.ustuck = 0;
208.  		} else {
209.  			if(Blind) pline("You cannot escape from it!");
210.  			else pline("You cannot escape from %s!",
211.  				monnam(u.ustuck));
212.  			nomul(0);
213.  			return;
214.  		}
215.  	}
216.  	if(u.uswallow || (mtmp = m_at(u.ux+u.dx,u.uy+u.dy))) {
217.  	/* attack monster */
218.  
219.  #ifdef SAFE_ATTACK
220.  		/* Don't attack if you're running */
221.  		if (flags.run && !mtmp->mimic
222.  		&& (Blind ? Telepat : (!mtmp->minvis || See_invisible))) {
223.  			nomul(0);
224.  			flags.move = 0;
225.  			return;
226.  		}
227.  #endif
228.  		nomul(0);
229.  		gethungry();
230.  		if(multi < 0) return;	/* we just fainted */
231.  
232.  		/* try to attack; note that it might evade */
233.  		if(attack(u.uswallow ? u.ustuck : mtmp))
234.  			return;
235.  	}
236.  	/* not attacking an animal, so we try to move */
237.  	if(u.utrap) {
238.  		if(u.utraptype == TT_PIT) {
239.  			pline("You are still in a pit.");
240.  			u.utrap--;
241.  #ifdef SPIDERS
242.  		} else if (u.utraptype == TT_WEB) {
243.  		    	pline("You are stuck to the web.");
244.  			u.utrap--;
245.  #endif
246.  		} else {
247.  			pline("You are caught in a bear trap.");
248.  			if((u.dx && u.dy) || !rn2(5)) u.utrap--;
249.  		}
250.  		return;
251.  	}
252.  	tmpr = &levl[u.ux+u.dx][u.uy+u.dy];
253.  	if(IS_ROCK(tmpr->typ) ||
254.  	   (u.dx && u.dy && (tmpr->typ == DOOR || ust->typ == DOOR))){
255.  		flags.move = 0;
256.  		nomul(0);
257.  		return;
258.  	}
259.  	if(moverock() < 0) return;
260.  	if(u.dx && u.dy && IS_ROCK(levl[u.ux][u.uy+u.dy].typ) &&
261.  		IS_ROCK(levl[u.ux+u.dx][u.uy].typ) &&
262.  		invent && inv_weight()+40 > 0) {
263.  		pline("You are carrying too much to get through.");
264.  		nomul(0);
265.  		return;
266.  	}
267.  	if(Punished &&
268.  	   DIST(u.ux+u.dx, u.uy+u.dy, uchain->ox, uchain->oy) > 2){
269.  		if(carried(uball)) {
270.  			movobj(uchain, u.ux, u.uy);
271.  			goto nodrag;
272.  		}
273.  
274.  		if(DIST(u.ux+u.dx, u.uy+u.dy, uball->ox, uball->oy) < 3){
275.  			/* leave ball, move chain under/over ball */
276.  			movobj(uchain, uball->ox, uball->oy);
277.  			goto nodrag;
278.  		}
279.  
280.  		if(inv_weight() + (int) uball->owt/2 > 0) {
281.  			pline("You cannot %sdrag the heavy iron ball.",
282.  			invent ? "carry all that and also " : "");
283.  			nomul(0);
284.  			return;
285.  		}
286.  
287.  		movobj(uball, uchain->ox, uchain->oy);
288.  		unpobj(uball);		/* BAH %% */
289.  		uchain->ox = u.ux;
290.  		uchain->oy = u.uy;
291.  		nomul(-2);
292.  		nomovemsg = "";
293.  	nodrag:	;
294.  	}
295.  	u.ux += u.dx;
296.  	u.uy += u.dy;
297.  	if(flags.run) {
298.  		if(tmpr->typ == DOOR ||
299.  		(xupstair == u.ux && yupstair == u.uy) ||
300.  		(xdnstair == u.ux && ydnstair == u.uy)
301.  #ifdef FOUNTAINS
302.  		|| IS_FOUNTAIN(levl[u.ux][u.uy].typ)
303.  #endif
304.  #ifdef NEWCLASS
305.  		|| IS_THRONE(levl[u.ux][u.uy].typ)
306.  #endif
307.  #ifdef SINKS
308.  		|| IS_SINK(levl[u.ux][u.uy].typ)
309.  #endif
310.  		)
311.  			nomul(0);
312.  	}
313.  
314.  #ifdef SINKS
315.  	if(IS_SINK(levl[u.ux][u.uy].typ) && Levitation)
316.  		dosinkfall();
317.  #endif
318.  	if(tmpr->typ == POOL && !Levitation)
319.  		drown();	/* not necessarily fatal */
320.  
321.  /*
322.  	if(u.udispl) {
323.  		u.udispl = 0;
324.  		newsym(u.ux0,u.uy0);
325.  	}
326.  */
327.  	if(!Blind) {
328.  #ifdef QUEST
329.  		setsee();
330.  #else
331.  		if(ust->lit) {
332.  			if(tmpr->lit) {
333.  				if(tmpr->typ == DOOR)
334.  					prl1(u.ux+u.dx,u.uy+u.dy);
335.  				else if(ust->typ == DOOR)
336.  					nose1(u.ux0-u.dx,u.uy0-u.dy);
337.  			} else {
338.  				unsee();
339.  				prl1(u.ux+u.dx,u.uy+u.dy);
340.  			}
341.  		} else {
342.  			if(tmpr->lit) setsee();
343.  			else {
344.  				prl1(u.ux+u.dx,u.uy+u.dy);
345.  				if(tmpr->typ == DOOR) {
346.  					if(u.dy) {
347.  						prl(u.ux-1,u.uy);
348.  						prl(u.ux+1,u.uy);
349.  					} else {
350.  						prl(u.ux,u.uy-1);
351.  						prl(u.ux,u.uy+1);
352.  					}
353.  				}
354.  			}
355.  			nose1(u.ux0-u.dx,u.uy0-u.dy);
356.  		}
357.  #endif /* QUEST /**/
358.  	} else {
359.  		pru();
360.  	}
361.  	if(!flags.nopick) pickup(1);
362.  	if(trap) dotrap(trap);		/* fall into pit, arrow trap, etc. */
363.  	(void) inshop();
364.  	if(!Blind) read_engr_at(u.ux,u.uy);
365.  }
366.  
367.  movobj(obj, ox, oy)
368.  register struct obj *obj;
369.  register int ox, oy;
370.  {
371.  	/* Some dirty programming to get display right */
372.  	freeobj(obj);
373.  	unpobj(obj);
374.  	obj->nobj = fobj;
375.  	fobj = obj;
376.  	obj->ox = ox;
377.  	obj->oy = oy;
378.  }
379.  
380.  dopickup(){
381.  	/* uswallow case added by GAN 01/29/87 */
382.  	if(u.uswallow)  {
383.  		pline("You pick up %s's tongue.",monnam(u.ustuck));
384.  		pline("But it's kind of slimy, so you drop it.");
385.  		return(1);
386.  	}
387.  	if(!g_at(u.ux,u.uy) && !o_at(u.ux,u.uy)) {
388.  		pline("There is nothing here to pick up.");
389.  		return(0);
390.  	}
391.  	if(Levitation) {
392.  		pline("You cannot reach the floor.");
393.  		return(1);
394.  	}
395.  	pickup(0);
396.  	return(1);
397.  }
398.  
399.  pickup(all)
400.  {
401.  	register struct gold *gold;
402.  	register struct obj *obj, *obj2;
403.  	register int wt;
404.  	char buf[BUFSZ];
405.  	register char *ip;
406.  	register char sym;
407.  	register int oletct = 0, iletct = 0;
408.  	char olets[20], ilets[20];
409.  
410.  	if(Levitation) return;
411.  #ifdef DGKMOD
412.  	if (all && !flags.pickup) {
413.  		int ct = 0;
414.  
415.  		for (obj = fobj; obj; obj = obj->nobj)
416.  			if (obj->ox == u.ux && obj->oy == u.uy)
417.  				if (!Punished || obj != uchain)
418.  					ct++;
419.  		/* If gold is the only thing here, pick it up.
420.  		 */
421.  		if (!ct && g_at(u.ux, u.uy)) {
422.  			if (flags.run) nomul(0);
423.  			while (gold = g_at(u.ux,u.uy)) {
424.  				pline("%ld gold piece%s.", gold->amount,
425.  					plur(gold->amount));
426.  				u.ugold += gold->amount;
427.  				flags.botl = 1;
428.  				freegold(gold);
429.  			}
430.  			if (Invisible) newsym(u.ux,u.uy);
431.  		}
432.  
433.  		/* If there are objects here, take a look.
434.  		 */
435.  		if (ct) {
436.  			if (flags.run)
437.  				nomul(0);
438.  			nscr();
439.  			if (ct < 5)
440.  				dolook();
441.  			else
442.  				pline("There are several objects here.");
443.  		}
444.  		return;
445.  	}
446.  #endif
447.  	while(gold = g_at(u.ux,u.uy)) {
448.  		pline("%ld gold piece%s.", gold->amount, plur(gold->amount));
449.  		u.ugold += gold->amount;
450.  		flags.botl = 1;
451.  		freegold(gold);
452.  		if(flags.run) nomul(0);
453.  		if(Invisible) newsym(u.ux,u.uy);
454.  	}
455.  	/* check for more than one object */
456.  	if(!all) {
457.  		register int ct = 0;
458.  
459.  		for(obj = fobj; obj; obj = obj->nobj)
460.  			if(obj->ox == u.ux && obj->oy == u.uy) ct++;
461.  		if(g_at(u.ux,u.uy))
462.  			ct++;
463.  		if(ct < 2)
464.  			all++;
465.  		else
466.  			pline("There are several objects here.");
467.  	}
468.  
469.  	/* added by GAN 10/24/86 to allow selective picking up */
470.  	if(!all)  {
471.  		register struct obj *otmp = fobj;
472.  
473.  		if(g_at(u.ux,u.uy)) ilets[iletct++] = GOLD_SYM;
474.  		ilets[iletct] = 0;
475.  		while(otmp) {
476.  			if(!index(ilets, otmp->olet) &&
477.  			   otmp->ox == u.ux && otmp->oy == u.uy)  {
478.  				ilets[iletct++] = otmp->olet;
479.  				ilets[iletct] = 0;
480.  			}
481.  			otmp = otmp->nobj;
482.  		}        
483.  		if(iletct == 1)
484.  			strcpy(buf,ilets);
485.  		else  {
486.  			ilets[iletct++] = ' ';
487.  			ilets[iletct++] = 'a';
488.  			ilets[iletct++] = 'A';
489.  			ilets[iletct] = 0;
490.  
491.  			if(iletct = 3)    
492.  			pline("What kinds of thing do you want to pick up? [%s] ", ilets);
493.  			getlin(buf);
494.  			if(buf[0] == '\033') {
495.  				clrlin();
496.  				return;
497.  			}
498.  #ifdef KJSMODS
499.  			else if(!buf[0]) strcpy(buf,"A");
500.  #endif
501.  		}
502.  		ip = buf;
503.  		olets[0] = 0;
504.  		while(sym = *ip++){
505.  			/* new A function (selective all) added by
506.  			 * GAN 01/09/87
507.  			 */
508.  			if(sym == 'A')  {
509.  				for(oletct = 0; ilets[oletct] != ' '; oletct++)
510.  					olets[oletct] = ilets[oletct];
511.  				olets[oletct] = 0;
512.  				break;
513.  			}
514.  			if(sym == ' ') continue;
515.  			if(sym == 'a') all++; else
516.  			if(index(ilets, sym)){
517.  				if(!index(olets, sym)){
518.  					olets[oletct++] = sym;
519.  					olets[oletct] = 0;
520.  				}
521.  			}
522.  			else pline("There are no %c's here.", sym);
523.  		}        
524.  	}
525.  
526.  	if(all || index(olets, GOLD_SYM))
527.  		while(gold = g_at(u.ux,u.uy)) {
528.  			pline("%ld gold piece%s.", gold->amount,
529.  			   plur(gold->amount));
530.  			u.ugold += gold->amount;
531.  			flags.botl = 1;
532.  			freegold(gold);
533.  			if(flags.run) nomul(0);
534.  			if(Invis) newsym(u.ux,u.uy);
535.  	}
536.  
537.  
538.  	for(obj = fobj; obj; obj = obj2) {
539.  	    obj2 = obj->nobj;   /* perhaps obj will be picked up */
540.  	    if(obj->ox == u.ux && obj->oy == u.uy) {
541.  		if(flags.run) nomul(0);
542.  
543.  		if(!all)  {
544.  			char c;
545.  		       
546.  			if(!index(olets,obj->olet)) continue;
547.   
548.  			pline("Pick up %s ? [ynaq]", doname(obj));
549.  			while(!index("ynaq ", (c = readchar())))
550.  				bell();
551.  			if(c == 'q') return;
552.  			if(c == 'n') continue;
553.  			if(c == 'a') all = 1;
554.  		}
555.   
556.  		if(obj->otyp == DEAD_COCKATRICE && !uarmg && u.usym != 'c') {
557.  		    pline("Touching the dead cockatrice is a fatal mistake.");
558.  		    pline("You turn to stone.");
559.  		    pline("You die...");
560.  		    killer = "cockatrice cadaver";
561.  		    done("died");
562.  		}        
563.   
564.  		if(obj->otyp == SCR_SCARE_MONSTER){
565.  		  if(!obj->spe) obj->spe = 1;
566.  		  else {
567.  		    /* Note: perhaps the 1st pickup failed: you cannot
568.  			carry anymore, and so we never dropped it -
569.  			lets assume that treading on it twice also
570.  			destroys the scroll */
571.  		    pline("The scroll turns to dust as you pick it up.");
572.  #ifdef KAA
573.  			if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
574.  			   !(objects[SCR_SCARE_MONSTER].oc_uname))
575.  				docall(obj);
576.  #endif
577.  		    delobj(obj);
578.  		    continue;
579.  		  }
580.  		}
581.  		   
582.  		/* do not pick up uchain */
583.  		if(Punished && obj == uchain)
584.  			continue;
585.  
586.  				  
587.  		wt = inv_weight() + obj->owt;
588.  		if(wt > 0) {
589.  			if(obj->quan > 1) {
590.  				/* see how many we can lift */
591.  				extern struct obj *splitobj();
592.  				int savequan = obj->quan;
593.  				int iw = inv_weight();
594.  				int qq;
595.  				for(qq = 1; qq < savequan; qq++){
596.  					obj->quan = qq;
597.  					if(iw + weight(obj) > 0)
598.  						break;
599.  				}
600.  				obj->quan = savequan;
601.  				qq--;
602.  				/* we can carry qq of them */
603.  				if(!qq) goto too_heavy;
604.  			pline("You can only carry %s of the %s lying here.",
605.  					(qq == 1) ? "one" : "some",
606.  					doname(obj));
607.  				{
608.  				register struct obj *obj3;
609.  
610.  				obj3 = splitobj(obj, qq);
611.  				if(obj3->otyp == SCR_SCARE_MONSTER)
612.  					if(obj3->spe) obj->spe = 0;
613.  				}
614.  				/* note: obj2 is set already, so well never
615.  				 * encounter the other half; if it should be
616.  				 * otherwise then write
617.  				 *      obj2 = splitobj(obj,qq);
618.  				 */
619.  				goto lift_some;
620.  			}          
621.  		too_heavy:
622.  			pline("There %s %s here, but %s.",
623.  				(obj->quan == 1) ? "is" : "are",
624.  				doname(obj),
625.  				!invent ? "it is too heavy for you to lift"
626.  				/* There is no such word as "anymore". KAA */
627.  					: "you cannot carry any more");
628.  				if(obj->otyp == SCR_SCARE_MONSTER)
629.  					if(obj->spe) obj->spe = 0;
630.  			break;
631.  		}
632.  	lift_some:
633.  		if(inv_cnt() >= 52) {
634.  		    pline("Your knapsack cannot accommodate any more items.");
635.  				if(obj->otyp == SCR_SCARE_MONSTER)
636.  					if(obj->spe) obj->spe = 0;
637.  		    break;
638.  		}
639.  		freeobj(obj);
640.  		if(Invisible) newsym(u.ux,u.uy);
641.  		addtobill(obj);       /* sets obj->unpaid if necessary */
642.  		if(wt > -5) pline("You have a little trouble lifting");
643.  		{ int pickquan = obj->quan;
644.  		  int mergquan;
645.  #ifdef KAA
646.  		if(!Blind) if(obj->olet != WEAPON_SYM) obj->dknown = 1;
647.  #else
648.  		if(!Blind) obj->dknown = 1;     /* this is done by prinv(),
649.  				 but addinv() needs it already for merging */
650.  #endif
651.  		obj = addinv(obj);    /* might merge it with other objects */
652.  		  mergquan = obj->quan;
653.  		  obj->quan = pickquan; /* to fool prinv() */
654.  		prinv(obj);
655.  		  obj->quan = mergquan;
656.  		}
657.  	    }
658.  	}
659.  }
660.  
661.  /* stop running if we see something interesting */
662.  /* turn around a corner if that is the only way we can proceed */
663.  /* do not turn left or right twice */
664.  lookaround(){
665.  register x,y,i,x0,y0,m0,i0 = 9;
666.  register int corrct = 0, noturn = 0;
667.  register struct monst *mtmp;
668.  #ifdef LINT
669.  	/* suppress "used before set" message */
670.  	x0 = y0 = 0;
671.  #endif
672.  	if(Blind || flags.run == 0) return;
673.  	if(flags.run == 1 && levl[u.ux][u.uy].typ == ROOM) return;
674.  #ifdef QUEST
675.  	if(u.ux0 == u.ux+u.dx && u.uy0 == u.uy+u.dy) goto stop;
676.  #endif
677.  	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
678.  		if(x == u.ux && y == u.uy) continue;
679.  		if(!levl[x][y].typ) continue;
680.  		if((mtmp = m_at(x,y)) && !mtmp->mimic &&
681.  		    (!mtmp->minvis || See_invisible)){
682.  			if(!mtmp->mtame || (x == u.ux+u.dx && y == u.uy+u.dy))
683.  				goto stop;
684.  		} else mtmp = 0; /* invisible M cannot influence us */
685.  		if(x == u.ux-u.dx && y == u.uy-u.dy) continue;
686.  		{
687.  		register uchar sym = levl[x][y].scrsym;
688.  
689.  		if (sym == VWALL_SYM || sym == HWALL_SYM
690.  		    || sym == ROOM_SYM || sym == STONE_SYM
691.  		    || IS_CORNER(sym))
692.  			continue;
693.  		else if (sym == DOOR_SYM) {
694.  			if(x != u.ux && y != u.uy) continue;
695.  			if(flags.run != 1) goto stop;
696.  			goto corr;
697.  		} else if (sym == CORR_SYM) {
698.  		corr:
699.  			if(flags.run == 1 || flags.run == 3) {
700.  				i = DIST(x,y,u.ux+u.dx,u.uy+u.dy);
701.  				if(i > 2) continue;
702.  				if(corrct == 1 && DIST(x,y,x0,y0) != 1)
703.  					noturn = 1;
704.  				if(i < i0) {
705.  					i0 = i;
706.  					x0 = x;
707.  					y0 = y;
708.  					m0 = mtmp ? 1 : 0;
709.  				}
710.  			}
711.  			corrct++;
712.  			continue;
713.  		} else if (sym == TRAP_SYM) {
714.  			if(flags.run == 1) goto corr;	/* if you must */
715.  			if(x == u.ux+u.dx && y == u.uy+u.dy) goto stop;
716.  			continue;
717.  		} else {		/* e.g. objects or trap or stairs */
718.  			if(flags.run == 1) goto corr;
719.  			if(mtmp) continue;		/* d */
720.  		}
721.  		stop:
722.  			nomul(0);
723.  			return;
724.  		}
725.  	}
726.  #ifdef QUEST
727.  	if(corrct > 0 && (flags.run == 4 || flags.run == 5)) goto stop;
728.  #endif
729.  	if(corrct > 1 && flags.run == 2) goto stop;
730.  	if((flags.run == 1 || flags.run == 3) && !noturn && !m0 && i0 &&
731.  		(corrct == 1 || (corrct == 2 && i0 == 1))) {
732.  		/* make sure that we do not turn too far */
733.  		if(i0 == 2) {
734.  		    if(u.dx == y0-u.uy && u.dy == u.ux-x0)
735.  			i = 2;		/* straight turn right */
736.  		    else
737.  			i = -2;		/* straight turn left */
738.  		} else if(u.dx && u.dy) {
739.  		    if((u.dx == u.dy && y0 == u.uy) ||
740.  			(u.dx != u.dy && y0 != u.uy))
741.  			i = -1;		/* half turn left */
742.  		    else
743.  			i = 1;		/* half turn right */
744.  		} else {
745.  		    if((x0-u.ux == y0-u.uy && !u.dy) ||
746.  			(x0-u.ux != y0-u.uy && u.dy))
747.  			i = 1;		/* half turn right */
748.  		    else
749.  			i = -1;		/* half turn left */
750.  		}
751.  		i += u.last_str_turn;
752.  		if(i <= 2 && i >= -2) {
753.  			u.last_str_turn = i;
754.  			u.dx = x0-u.ux, u.dy = y0-u.uy;
755.  		}
756.  	}
757.  }
758.  
759.  /* something like lookaround, but we are not running */
760.  /* react only to monsters that might hit us */
761.  monster_nearby() {
762.  register int x,y;
763.  register struct monst *mtmp;
764.  	if(!Blind)
765.  	for(x = u.ux-1; x <= u.ux+1; x++) for(y = u.uy-1; y <= u.uy+1; y++){
766.  		if(x == u.ux && y == u.uy) continue;
767.  		if((mtmp = m_at(x,y)) && !mtmp->mimic && !mtmp->mtame &&
768.  			!mtmp->mpeaceful && !index("Ea", mtmp->data->mlet) &&
769.  			!mtmp->mfroz && !mtmp->msleep &&  /* aplvax!jcn */
770.  			(!mtmp->minvis || See_invisible))
771.  			return(1);
772.  	}
773.  	return(0);
774.  }
775.  
776.  #ifdef QUEST
777.  cansee(x,y) xchar x,y; {
778.  register int dx,dy,adx,ady,sdx,sdy,dmax,d;
779.  	if(Blind) return(0);
780.  	if(!isok(x,y)) return(0);
781.  	d = dist(x,y);
782.  	if(d < 3) return(1);
783.  	if(d > u.uhorizon*u.uhorizon) return(0);
784.  	if(!levl[x][y].lit)
785.  		return(0);
786.  	dx = x - u.ux;	adx = abs(dx);	sdx = sgn(dx);
787.  	dy = y - u.uy;  ady = abs(dy);	sdy = sgn(dy);
788.  	if(dx == 0 || dy == 0 || adx == ady){
789.  		dmax = (dx == 0) ? ady : adx;
790.  		for(d = 1; d <= dmax; d++)
791.  			if(!rroom(sdx*d,sdy*d))
792.  				return(0);
793.  		return(1);
794.  	} else if(ady > adx){
795.  		for(d = 1; d <= ady; d++){
796.  			if(!rroom(sdx*( (d*adx)/ady ), sdy*d) ||
797.  			   !rroom(sdx*( (d*adx-1)/ady+1 ), sdy*d))
798.  				return(0);
799.  		}
800.  		return(1);
801.  	} else {
802.  		for(d = 1; d <= adx; d++){
803.  			if(!rroom(sdx*d, sdy*( (d*ady)/adx )) ||
804.  			   !rroom(sdx*d, sdy*( (d*ady-1)/adx+1 )))
805.  				return(0);
806.  		}
807.  		return(1);
808.  	}
809.  }
810.  
811.  rroom(x,y) register int x,y; {
812.  	return(IS_ROOM(levl[u.ux+x][u.uy+y].typ));
813.  }
814.  
815.  #else
816.  
817.  cansee(x,y) xchar x,y; {
818.  	if(Blind || u.uswallow) return(0);
819.  	if(dist(x,y) < 3) return(1);
820.  	if(levl[x][y].lit && seelx <= x && x <= seehx && seely <= y &&
821.  		y <= seehy) return(1);
822.  	return(0);
823.  }
824.  #endif /* QUEST /**/
825.  
826.  sgn(a) register int a; {
827.  	return((a > 0) ? 1 : (a == 0) ? 0 : -1);
828.  }
829.  
830.  #ifdef QUEST
831.  setsee()
832.  {
833.  	register x,y;
834.  
835.  	if(Blind) {
836.  		pru();
837.  		return;
838.  	}
839.  	for(y = u.uy-u.uhorizon; y <= u.uy+u.uhorizon; y++)
840.  		for(x = u.ux-u.uhorizon; x <= u.ux+u.uhorizon; x++) {
841.  			if(cansee(x,y))
842.  				prl(x,y);
843.  	}
844.  }
845.  
846.  #else
847.  
848.  setsee()
849.  {
850.  	register x,y;
851.  
852.  	if(Blind) {
853.  		pru();
854.  		return;
855.  	}
856.  	if(!levl[u.ux][u.uy].lit) {
857.  		seelx = u.ux-1;
858.  		seehx = u.ux+1;
859.  		seely = u.uy-1;
860.  		seehy = u.uy+1;
861.  	} else {
862.  		for(seelx = u.ux; levl[seelx-1][u.uy].lit; seelx--);
863.  		for(seehx = u.ux; levl[seehx+1][u.uy].lit; seehx++);
864.  		for(seely = u.uy; levl[u.ux][seely-1].lit; seely--);
865.  		for(seehy = u.uy; levl[u.ux][seehy+1].lit; seehy++);
866.  	}
867.  	for(y = seely; y <= seehy; y++)
868.  		for(x = seelx; x <= seehx; x++) {
869.  			prl(x,y);
870.  	}
871.  	if(!levl[u.ux][u.uy].lit) seehx = 0; /* seems necessary elsewhere */
872.  	else {
873.  	    if(seely == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seely-1);
874.  	    if(seehy == u.uy) for(x = u.ux-1; x <= u.ux+1; x++) prl(x,seehy+1);
875.  	    if(seelx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seelx-1,y);
876.  	    if(seehx == u.ux) for(y = u.uy-1; y <= u.uy+1; y++) prl(seehx+1,y);
877.  	}
878.  }
879.  #endif /* QUEST /**/
880.  
881.  nomul(nval)
882.  register nval;
883.  {
884.  #ifdef DGKMOD
885.  	if(multi < nval) return;	/* This is a bug fix by ab@unido */
886.  #else
887.  	if(multi < 0) return;
888.  #endif
889.  	multi = nval;
890.  	flags.mv = flags.run = 0;
891.  }
892.  
893.  abon()
894.  {
895.  #ifdef KAA
896.  	if (u.usym != '@') return(mons[u.umonnum].mlevel-3);
897.  #endif
898.  	if(u.ustr == 3) return(-3);
899.  	else if(u.ustr < 6) return(-2);
900.  	else if(u.ustr < 8) return(-1);
901.  	else if(u.ustr < 17) return(0);
902.  	else if(u.ustr < 69) return(1);	/* up to 18/50 */
903.  	else if(u.ustr < 118) return(2);
904.  	else return(3);
905.  }
906.  
907.  dbon()
908.  {
909.  	if (u.usym != '@') return(0);
910.  
911.  	if(u.ustr < 6) return(-1);
912.  	else if(u.ustr < 16) return(0);
913.  	else if(u.ustr < 18) return(1);
914.  	else if(u.ustr == 18) return(2);	/* up to 18 */
915.  	else if(u.ustr < 94) return(3);		/* up to 18/75 */
916.  	else if(u.ustr < 109) return(4);	/* up to 18/90 */
917.  	else if(u.ustr < 118) return(5);	/* up to 18/99 */
918.  	else return(6);
919.  }
920.  
921.  losestr(num)	/* may kill you; cause may be poison or monster like 'A' */
922.  register num;
923.  {
924.  	u.ustr -= num;
925.  	while(u.ustr < 3) {
926.  		u.ustr++;
927.  		u.uhp -= 6;
928.  		u.uhpmax -= 6;
929.  	}
930.  	flags.botl = 1;
931.  }
932.  
933.  losehp(n,knam)
934.  register n;
935.  register char *knam;
936.  {
937.  #ifdef KAA
938.  	if (u.mtimedone) {
939.  		u.mh -= n;
940.  		if (u.mhmax < u.mh) u.mhmax = u.mh;
941.  		flags.botl = 1;
942.  		if (u.mh < 1) rehumanize();
943.  		return;
944.  	}
945.  #endif
946.  	u.uhp -= n;
947.  	if(u.uhp > u.uhpmax)
948.  		u.uhpmax = u.uhp;	/* perhaps n was negative */
949.  	flags.botl = 1;
950.  	if(u.uhp < 1) {
951.  		killer = knam;	/* the thing that killed you */
952.  		pline("You die...");
953.  		done("died");
954.  	}
955.  }
956.  
957.  losehp_m(n,mtmp)
958.  register n;
959.  register struct monst *mtmp;
960.  {
961.  #ifdef KAA
962.  	if (u.mtimedone) {
963.  		u.mh -= n;
964.  		flags.botl = 1;
965.  		if (u.mh < 1) rehumanize();
966.  		return;
967.  	}
968.  #endif
969.  	u.uhp -= n;
970.  	flags.botl = 1;
971.  	if(u.uhp < 1)
972.  		done_in_by(mtmp);
973.  }
974.  
975.  losexp()	/* hit by V or W */
976.  {
977.  	register num;
978.  	extern long newuexp();
979.  
980.  	if (u.usym == 'V' || u.usym=='W') return;
981.  
982.  	if(u.ulevel > 1)
983.  		pline("Goodbye level %u.", u.ulevel--);
984.  	else
985.  		u.uhp = -1;
986.  	num = rnd(10);
987.  	u.uhp -= num;
988.  	u.uhpmax -= num;
989.  #ifdef SPELLS
990.  	num = rnd(u.ulevel/2+1) + 1;		/* M. Stephenson */
991.  	u.uen -= num;
992.  	if (u.uen < 0)		u.uen = 0;
993.  	u.uenmax -= num;
994.  	if (u.uenmax < 0)	u.uenmax = 0;
995.  #endif
996.  	u.uexp = newuexp();
997.  	flags.botl = 1;
998.  }
999.  
1000. inv_weight(){
1001. register struct obj *otmp = invent;
1002. register int wt = (u.ugold + 500)/1000;
1003. register int carrcap;
1004. #ifdef KAA
1005. 	if (u.mtimedone) {
1006. 		if (u.usym == '9') carrcap = MAX_CARR_CAP * 4;
1007. 		else if (u.usym == 'N') carrcap = MAX_CARR_CAP;
1008. 		else if (mons[u.umonnum].mlevel <= 3)
1009. 			carrcap = 5*mons[u.umonnum].mlevel + 30;
1010. 		else carrcap = 5*mons[u.umonnum].mlevel + 100;
1011. 	}
1012. #endif
1013. 	if(Levitation)			/* pugh@cornell */
1014. 		carrcap = MAX_CARR_CAP;
1015. 	else {
1016. #ifdef HARD
1017. 		carrcap = 5*(((u.ustr > 18) ? 20 : u.ustr) + u.ulevel);
1018. #else
1019. 	        carrcap = 5*u.ulevel;      /* New strength stewr 870807 */
1020. 		if (u.ustr < 19) carrcap += 5*u.ustr;
1021. 		if (u.ustr > 18) carrcap += u.ustr - 18 + 90;
1022. 		if (u.ustr > 68) carrcap += u.ustr - 68;
1023. 		if (u.ustr > 93) carrcap += u.ustr - 93;
1024. 		if (u.ustr > 108) carrcap += 2*(u.ustr - 108);
1025. 		if (u.ustr > 113) carrcap += 5*(u.ustr - 113);
1026. 		if (u.ustr == 118) carrcap += 100;
1027. #endif
1028. 		if(carrcap > MAX_CARR_CAP) carrcap = MAX_CARR_CAP;
1029. 		if(Wounded_legs & LEFT_SIDE) carrcap -= 10;
1030. 		if(Wounded_legs & RIGHT_SIDE) carrcap -= 10;
1031. 	}
1032. 	while(otmp){
1033. 		wt += otmp->owt;
1034. 		otmp = otmp->nobj;
1035. 	}
1036. 	return(wt - carrcap);
1037. }
1038. 
1039. inv_cnt(){
1040. register struct obj *otmp = invent;
1041. register int ct = 0;
1042. 	while(otmp){
1043. 		ct++;
1044. 		otmp = otmp->nobj;
1045. 	}
1046. 	return(ct);
1047. }
1048. 
1049. long
1050. newuexp()
1051. {
1052. 	return(10*(1L << (u.ulevel-1)));
1053. }
1054. 
1055. change_luck(n)
1056. 	register schar n;
1057. {
1058. 	u.uluck += n;
1059. 	if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN;
1060. 	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX;
1061. }
1062. 
1063. #ifdef SINKS
1064. dosinkfall() {
1065. register struct obj *obj;
1066. 	pline("You crash to the floor!");
1067. 	losehp(rn2(15) + 3*u.ulevel,"fall onto a sink");
1068. 	for(obj=fobj; obj; obj=obj->nobj)
1069. 	    if(obj->ox == u.ux && obj->oy == u.uy && obj->olet == WEAPON_SYM) {
1070. 		pline("You fell on %s.",doname(obj));
1071. 		losehp(rn2(3),"fall onto a sink");
1072. 	    }
1073. 
1074. 	Levitation += 1;
1075. 	if(uleft && uleft->otyp == RIN_LEVITATION) {
1076. 	    obj = uleft;
1077. 	    ringoff(obj);
1078. 	    off_msg(obj);
1079. 	}
1080. 	if(uright && uright->otyp == RIN_LEVITATION) {
1081. 	    obj = uright;
1082. 	    ringoff(obj);
1083. 	    off_msg(obj);
1084. 	}
1085. 	Levitation = 0;
1086. }
1087. #endif