Source:NetHack 1.4f/do.c

From NetHackWiki
Jump to: navigation, search

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