Source:NetHack 2.2a/do.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to do.c from the source code of NetHack 2.2a. To link to a particular line, write [[NetHack 2.2a/do.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.    /*	SCCS Id: @(#)do.c	2.0	87/09/15
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    /* Contains code for 'd', 'D' (drop), '>', '<' (up, down) and 't' (throw) */
5.    
6.    #include "hack.h"
7.    
8.    extern struct obj *splitobj(), *addinv();
9.    extern boolean hmon();
10.   extern boolean level_exists[];
11.   extern struct monst youmonst;
12.   extern char *Doname();
13.   extern char *nomovemsg;
14.   int	identify();
15.   #ifdef KAA
16.   extern char *xname();
17.   #endif
18.   
19.   dodrop() {
20.   	if(u.ugold)	return(drop(getobj("0$#", "drop")));
21.   	else		return(drop(getobj("0#", "drop")));
22.   }
23.   
24.   static
25.   drop(obj) register struct obj *obj; {
26.   	if(!obj) return(0);
27.   	if(obj->olet == GOLD_SYM) {		/* pseudo object */
28.   		register long amount = OGOLD(obj);
29.   
30.   		if(amount == 0)
31.   			pline("You didn't drop any gold pieces.");
32.   /* Fix bug with dropping huge amounts of gold read as negative    KAA */
33.   		else if(amount < 0) {
34.   			u.ugold += amount;
35.   	pline("The LRS would be very interested to know you have that much.");
36.   		} else {
37.   			/* uswallow test added by GAN 01/29/87 */
38.   			pline("You dropped %ld gold piece%s.",
39.   				 amount, plur(amount));
40.   			if(u.uswallow)
41.   				(u.ustuck)->mgold += amount;
42.   			else {
43.   				mkgold(amount, u.ux, u.uy);
44.   				if(Invisible) newsym(u.ux, u.uy);
45.   			}
46.   		}
47.   		free((char *) obj);
48.   		return(1);
49.   	}
50.   	if(obj->owornmask & (W_ARMOR | W_RING)){
51.   		pline("You cannot drop something you are wearing.");
52.   		return(0);
53.   	}
54.   	if(obj == uwep) {
55.   		if(uwep->cursed) {
56.   			pline("Your weapon is welded to your hand!");
57.   			return(0);
58.   		}
59.   		setuwep((struct obj *) 0);
60.   	}
61.   #ifdef WALKIES
62.           if (obj->otyp == LEASH) {
63.               register struct monst *mtmp = fmon;
64.               while (mtmp && !mtmp->mleashed) mtmp = mtmp->nmon;
65.               if (mtmp) {
66.                   pline ("Your leash is tied around your hand.");
67.                   return (0);
68.               }
69.           }
70.   #endif
71.   	pline("You dropped %s.", doname(obj));
72.   	dropx(obj);
73.   	return(1);
74.   }
75.   
76.   /* Called in several places - should not produce texts */
77.   dropx(obj)
78.   register struct obj *obj;
79.   {
80.   	freeinv(obj);
81.   	dropy(obj);
82.   }
83.   
84.   dropy(obj)
85.   register struct obj *obj;
86.   {
87.   	if(obj->otyp == CRYSKNIFE)
88.   		obj->otyp = WORM_TOOTH;
89.   	/* uswallow check done by GAN 01/29/87 */
90.   	if(u.uswallow)
91.   		mpickobj(u.ustuck,obj);
92.   	else  {
93.   		obj->ox = u.ux;
94.   		obj->oy = u.uy;
95.   		/* Blind check added by GAN 02/18/87 */
96.   		if(Blind)  {
97.   #ifdef KAA
98.   			if(obj->olet != ')')
99.   #endif
100.  			    obj->dknown = index("/=!?*",obj->olet) ? 0 : 1;
101.  			obj->known = 0;
102.  		}
103.  		obj->nobj = fobj;
104.  		fobj = obj;
105.  		if(Invisible) newsym(u.ux,u.uy);
106.  		subfrombill(obj);
107.  		stackobj(obj);
108.  	}
109.  }
110.  
111.  /* drop several things */
112.  doddrop() {
113.  	return(ggetobj("drop", drop, 0));
114.  }
115.  
116.  dodown()
117.  {
118.  	if(u.ux != xdnstair || u.uy != ydnstair) {
119.  		pline("You can't go down here.");
120.  		return(0);
121.  	}
122.  	if(u.ustuck) {
123.  		pline("You are being held, and cannot go down.");
124.  		return(1);
125.  	}
126.  	if(Levitation) {
127.  		pline("Your floating high above the stairs.");
128.  		return(0);
129.  	}
130.  
131.  	goto_level(dlevel+1, TRUE);
132.  	return(1);
133.  }
134.  
135.  doup()
136.  {
137.  	if(u.ux != xupstair || u.uy != yupstair) {
138.  		pline("You can't go up here.");
139.  		return(0);
140.  	}
141.  	if(u.ustuck) {
142.  		pline("You are being held, and cannot go up.");
143.  		return(1);
144.  	}
145.  	if(!Levitation && inv_weight() + 5 > 0) {
146.  		pline("Your load is too heavy to climb the stairs.");
147.  		return(1);
148.  	}
149.  
150.  	goto_level(dlevel-1, TRUE);
151.  	return(1);
152.  }
153.  
154.  goto_level(newlevel, at_stairs)
155.  register int newlevel;
156.  register boolean at_stairs;
157.  {
158.  	register fd;
159.  	register boolean up = (newlevel < dlevel);
160.  
161.  	if(newlevel <= 0) done("escaped");    /* in fact < 0 is impossible */
162.  	if(newlevel > MAXLEVEL) newlevel = MAXLEVEL;	/* strange ... */
163.  	if(newlevel == dlevel) return;	      /* this can happen */
164.  
165.  	glo(dlevel);
166.  #ifdef DGK
167.  	/* Use O_TRUNC to force the file to be shortened if it already
168.  	 * exists and is currently longer.
169.  	 */
170.  	fd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK);
171.  #else
172.  	fd = creat(lock, FMASK);
173.  #endif
174.  	if(fd < 0) {
175.  		/*
176.  		 * This is not quite impossible: e.g., we may have
177.  		 * exceeded our quota. If that is the case then we
178.  		 * cannot leave this level, and cannot save either.
179.  		 * Another possibility is that the directory was not
180.  		 * writable.
181.  		 */
182.  #ifdef DGK
183.  		pline("Cannot create level file '%s'.", lock);
184.  #else
185.  		pline("A mysterious force prevents you from going %s.",
186.  			up ? "up" : "down");
187.  #endif
188.  		return;
189.  	}
190.  
191.  #ifdef DGK
192.  	if (!savelev(fd, dlevel, COUNT)) {
193.  		(void) close(fd);
194.  		(void) unlink(lock);
195.  		pline("HACK is out of disk space for making levels!");
196.  		pline("You can save, quit, or continue playing.");
197.  		return;
198.  	}
199.  #endif
200.  	if(Punished) unplacebc();
201.  	u.utrap = 0;				/* needed in level_tele */
202.  	u.ustuck = 0;				/* idem */
203.  	keepdogs();
204.  	seeoff(1);
205.  	if(u.uswallow)				/* idem */
206.  		u.uswldtim = u.uswallow = 0;
207.  	flags.nscrinh = 1;
208.  	u.ux = FAR;				/* hack */
209.  	(void) inshop();			/* probably was a trapdoor */
210.  
211.  #ifdef DGK
212.  	savelev(fd,dlevel, WRITE);
213.  #else
214.  	savelev(fd,dlevel);
215.  #endif
216.  	(void) close(fd);
217.  
218.  	dlevel = newlevel;
219.  	if(maxdlevel < dlevel)
220.  		maxdlevel = dlevel;
221.  	glo(dlevel);
222.  #ifdef MSDOS
223.  	/* If the level has no where yet, it hasn't been made
224.  	 */
225.  	if(!fileinfo[dlevel].where)
226.  #else
227.  	if(!level_exists[dlevel])
228.  #endif
229.  		mklev();
230.  	else {
231.  		extern int hackpid;
232.  #ifdef DGK
233.  		/* If not currently accessible, swap it in.
234.  		 */
235.  		if (fileinfo[dlevel].where != ACTIVE)
236.  			swapin_file(dlevel);
237.  
238.  		if((fd = open(lock, O_RDONLY | O_BINARY)) < 0) {
239.  #else
240.  		if((fd = open(lock,0)) < 0) {
241.  #endif
242.  			pline("Cannot open %s .", lock);
243.  			pline("Probably someone removed it.");
244.  			done("tricked");
245.  		}
246.  		getlev(fd, hackpid, dlevel);
247.  		(void) close(fd);
248.  	}
249.  
250.  	if(at_stairs) {
251.  	    if(up) {
252.  		u.ux = xdnstair;
253.  		u.uy = ydnstair;
254.  		if(!u.ux) {		/* entering a maze from below? */
255.  		    u.ux = xupstair;	/* this will confuse the player! */
256.  		    u.uy = yupstair;
257.  		}
258.  /* Remove bug which crashes with levitation/punishment  KAA */
259.  		if(Punished) {
260.  		    if(!Levitation) 
261.  			pline("With great effort you climb the stairs.");
262.  		    placebc(1);
263.  		}
264.  	    } else {
265.  		u.ux = xupstair;
266.  		u.uy = yupstair;
267.  		if(inv_weight() + 5 > 0 || Punished){
268.  			pline("You fall down the stairs.");	/* %% */
269.  			losehp(rnd(3), "fall");
270.  			if(Punished) {
271.  			    if(uwep != uball && rn2(3)){
272.  				pline("... and are hit by the iron ball.");
273.  				losehp(rnd(20), "iron ball");
274.  			    }
275.  			    placebc(1);
276.  			}
277.  			selftouch("Falling, you");
278.  		}
279.  	    }
280.  	    { register struct monst *mtmp = m_at(u.ux, u.uy);
281.  	      if(mtmp)
282.  		mnexto(mtmp);
283.  	    }
284.  	} else {	/* trapdoor or level_tele */
285.  	    do {
286.  		u.ux = rnd(COLNO-1);
287.  		u.uy = rn2(ROWNO);
288.  	    } while(levl[u.ux][u.uy].typ != ROOM ||
289.  			m_at(u.ux,u.uy));
290.  	    if(Punished){
291.  		if(uwep != uball && !up /* %% */ && rn2(5)){
292.  			pline("The iron ball falls on your head.");
293.  			losehp(rnd(25), "iron ball");
294.  		}
295.  		placebc(1);
296.  	    }
297.  	    selftouch("Falling, you");
298.  	}
299.  	(void) inshop();
300.  	initrack();
301.  
302.  	losedogs();
303.  	{ register struct monst *mtmp;
304.  	  if(mtmp = m_at(u.ux, u.uy)) mnexto(mtmp);	/* riv05!a3 */
305.  	}
306.  	flags.nscrinh = 0;
307.  	setsee();
308.  	seeobjs();	/* make old cadavers disappear - riv05!a3 */
309.  	docrt();
310.  	pickup(1);
311.  	read_engr_at(u.ux,u.uy);
312.  }
313.  
314.  donull() {
315.  	return(1);	/* Do nothing, but let other things happen */
316.  }
317.  
318.  #if defined(KAA) && defined(KOPS)
319.  wipeoff()
320.  {
321.  	if(u.ucreamed < 4)	u.ucreamed = 0;
322.  	else			u.ucreamed -= 4;
323.  	if(u.ucreamed > 0)  {
324.  		Blinded -= 4;
325.  		if(Blind <= 1) {
326.  			pline("You've got the glop off.");
327.  			u.ucreamed = 0;
328.  			Blinded = 1;
329.  			return(0);
330.  		}
331.  		return(1);		/* still busy */
332.  	}
333.  	pline("Your face feels clean now.");
334.  	u.ucreamed = 0;
335.  	return(0);
336.  }
337.  	
338.  dowipe()
339.  {
340.  	if(u.ucreamed)  {
341.  #ifdef DGKMOD
342.  		set_occupation(wipeoff, "wiping off your face", 0);
343.  #else
344.  		occupation = wipeoff;
345.  		occtxt = "wiping off your face";
346.  #endif
347.  		return(1);
348.  	}
349.  	pline("Your face is already clean.");
350.  	return(1);
351.  }
352.  #endif
353.  
354.  /* split obj so that it gets size num */
355.  /* remainder is put in the object structure delivered by this call */
356.  struct obj *
357.  splitobj(obj, num) register struct obj *obj; register int num; {
358.  register struct obj *otmp;
359.  	otmp = newobj(0);
360.  	*otmp = *obj;		/* copies whole structure */
361.  	otmp->o_id = flags.ident++;
362.  	otmp->onamelth = 0;
363.  	obj->quan = num;
364.  	obj->owt = weight(obj);
365.  	otmp->quan -= num;
366.  	otmp->owt = weight(otmp);	/* -= obj->owt ? */
367.  	obj->nobj = otmp;
368.  	if(obj->unpaid) splitbill(obj,otmp);
369.  	return(otmp);
370.  }
371.  
372.  more_experienced(exp,rexp)
373.  register int exp, rexp;
374.  {
375.  	extern char pl_character[];
376.  
377.  	u.uexp += exp;
378.  	u.urexp += 4*exp + rexp;
379.  	if(exp) flags.botl = 1;
380.  	if(u.urexp >= ((pl_character[0] == 'W') ? 1000 : 2000))
381.  		flags.beginner = 0;
382.  }
383.  
384.  set_wounded_legs(side, timex)
385.  register long side;
386.  register int timex;
387.  {
388.  	if(!Wounded_legs || (Wounded_legs & TIMEOUT))
389.  		Wounded_legs |= side + timex;
390.  	else
391.  		Wounded_legs |= side;
392.  }
393.  
394.  heal_legs()
395.  {
396.  	if(Wounded_legs) {
397.  		if((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
398.  			pline("Your legs feel somewhat better.");
399.  		else
400.  			pline("Your leg feels somewhat better.");
401.  		Wounded_legs = 0;
402.  	}
403.  }