Source:NetHack 3.0.0/pickup.c

From NetHackWiki
Revision as of 05:15, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/pickup.c moved to Source:NetHack 3.0.0/pickup.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Below is the full text to pickup.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/pickup.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: @(#)pickup.c	3.0	88/07/12
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    /*
6.     *	Contains code for picking objects up, and container use.
7.     */
8.    
9.    #include	"hack.h"
10.   
11.   void explode_bag();
12.   
13.   void
14.   pickup(all)
15.   int all;
16.   {
17.   	register struct gold *gold = g_at(u.ux, u.uy);
18.   	register struct obj *obj, *obj2;
19.   	register int wt;
20.   	char buf[BUFSZ];
21.   	register char *ip;
22.   	register char sym;
23.   	register int oletct = 0, iletct = 0;
24.   	boolean all_of_a_type = FALSE, selective = FALSE;
25.   	char olets[20], ilets[20];
26.   	struct obj dummygold;
27.   
28.   	dummygold.ox = u.ux;
29.   	dummygold.oy = u.uy;
30.   	dummygold.olet = GOLD_SYM;
31.   	dummygold.nobj = fobj;
32.   	dummygold.cobj = 0;
33.   
34.   	if(Levitation) return;
35.   	if (all && !flags.pickup) {
36.   		int ct = 0;
37.   
38.   		for (obj = fobj; obj; obj = obj->nobj)
39.   			if(obj->ox == u.ux && obj->oy == u.uy)
40.   			    if(!obj->cobj)
41.   				if (obj != uchain)
42.   					ct++;
43.   
44.   		/* Stop on a zorkmid */
45.   		if (gold) ct++;
46.   
47.   		/* If there are objects here, take a look.
48.   		 */
49.   		if (ct) {
50.   			if (flags.run)
51.   				nomul(0);
52.   			nscr();
53.   			if (ct < 5)
54.   				(void) dolook();
55.   			else {
56.   				read_engr_at(u.ux,u.uy);
57.   				pline("There are several objects here.");
58.   			}
59.   		} else read_engr_at(u.ux,u.uy);
60.   		return;
61.   	}
62.   
63.   	/* check for more than one object */
64.   	if(!all) {
65.   		register int ct = 0;
66.   
67.   		if (gold) ct++;
68.   		for(obj = fobj; obj; obj = obj->nobj)
69.   		    if(obj->ox == u.ux && obj->oy == u.uy)
70.   			if(!obj->cobj) ct++;
71.   		if(ct < 2)
72.   			all++;
73.   		else
74.   			pline("There are several objects here.");
75.   	}
76.   
77.   	/* added by GAN 10/24/86 to allow selective picking up */
78.   	if(!all)  {
79.   		register struct obj *otmp = fobj;
80.   
81.   		ilets[iletct] = 0;
82.   		if(gold) {
83.   			ilets[iletct++] = GOLD_SYM;
84.   			ilets[iletct] = 0;
85.   		}
86.   		while(otmp) {
87.   			if(!index(ilets, otmp->olet) && !otmp->cobj &&
88.   			   otmp->ox == u.ux && otmp->oy == u.uy)  {
89.   				ilets[iletct++] = otmp->olet;
90.   				ilets[iletct] = 0;
91.   			}
92.   			otmp = otmp->nobj;
93.   		}
94.   		if(iletct == 1)
95.   			Strcpy(buf,ilets);
96.   		else  {
97.   			ilets[iletct++] = ' ';
98.   			ilets[iletct++] = 'a';
99.   			ilets[iletct++] = 'A';
100.  			ilets[iletct] = 0;
101.  
102.  			pline("What kinds of thing do you want to pick up? [%s] ", ilets);
103.  			getlin(buf);
104.  			if(buf[0] == '\033') {
105.  				clrlin();
106.  				return;
107.  			}
108.  			else if(!buf[0]) selective = TRUE;
109.  		}
110.  		ip = buf;
111.  		olets[0] = 0;
112.  		while(sym = *ip++){
113.  			/* new A function (selective all) added by
114.  			 * GAN 01/09/87
115.  			 */
116.  			if(sym == ' ') continue;
117.  			if(sym == 'A') selective = TRUE;
118.  			else if(sym == 'a') all_of_a_type = TRUE;
119.  			else if(index(ilets, sym)){
120.  				if(!index(olets, sym)){
121.  					olets[oletct++] = sym;
122.  					olets[oletct] = 0;
123.  				}
124.  			}
125.  			else pline("There are no %c's here.", sym);
126.  		}
127.  	}
128.  	if(all_of_a_type && !olets[0]) all = TRUE;
129.  
130.  	for(obj = (gold ? &dummygold : fobj); obj; obj = obj2) {
131.  	    obj2 = obj->nobj;   /* perhaps obj will be picked up */
132.  	    if(!obj->cobj && obj->ox == u.ux && obj->oy == u.uy) {
133.  		if(flags.run) nomul(0);
134.  
135.  		if(!all)  {
136.  			char c;
137.  
138.  			if(!selective && !index(olets,obj->olet)) continue;
139.  
140.  			if (!all_of_a_type) {
141.  				if (obj == &dummygold)
142.  					pline("Pick up %ld gold piece%s? ",
143.  					    gold->amount, plur(gold->amount));
144.  				else pline("Pick up %s? ", doname(obj));
145.  				if((c = ynaq()) == 'q') return;
146.  				if(c == 'n') continue;
147.  				if(c == 'a') {
148.  					all_of_a_type = TRUE;
149.  					if (selective) {
150.  						selective = FALSE;
151.  						olets[0] = obj->olet;
152.  						olets[1] = 0;
153.  						/* oletct = 1; */
154.  					}
155.  				}
156.  			}
157.  		}
158.  
159.  		if(obj == &dummygold) {
160.  		    int iw = inv_weight();
161.  		    long gold_capacity;
162.  
163.  #ifndef lint /* long/int conversion */
164.  		    iw -= (int)((u.ugold + 500)/1000);
165.  #endif
166.  		    gold_capacity = ((-iw) * 1000L) - 500 + 999 - u.ugold;
167.  		    if (gold_capacity <= 0L) {
168.  	 pline("There %s %ld gold piece%s here, but you cannot carry any more.",
169.  				(gold->amount == 1) ? "is" : "are",
170.  				gold->amount, plur(gold->amount));
171.  			continue;
172.  		    }
173.  		    if (gold_capacity >= gold->amount) {
174.  			pline("%ld gold piece%s.",
175.  				gold->amount, plur(gold->amount));
176.  			u.ugold += gold->amount;
177.  			freegold(gold);
178.  			if(Invisible) newsym(u.ux,u.uy);
179.  		    } else {
180.  	pline("You can only carry %s of the %ld gold pieces lying here.",
181.  			    gold_capacity == 1L ? "one" : "some", gold->amount);
182.  			pline("%ld gold piece%s.",
183.  				 gold_capacity, plur(gold_capacity));
184.  			u.ugold += gold_capacity;
185.  			gold->amount -= gold_capacity;
186.  		    }
187.  		    flags.botl = 1;
188.  		    if(flags.run) nomul(0);
189.  		    continue;
190.  		}
191.  
192.  		if((obj->otyp == CORPSE && obj->corpsenm == PM_COCKATRICE) &&
193.  		   !uarmg
194.  #ifdef POLYSELF
195.  			&& !resists_ston(uasmon)
196.  #endif
197.  						) {
198.  		    pline("Touching the dead cockatrice is a fatal mistake.");
199.  		    You("turn to stone.");
200.  		    You("die...");
201.  		    killer = "cockatrice cadaver";
202.  		    done("stoned");
203.  		}
204.  
205.  		if(obj->otyp == SCR_SCARE_MONSTER){
206.  		  if(!obj->spe) obj->spe = 1;
207.  		  else {
208.  		    pline("The scroll turns to dust as you pick it up.");
209.  			if(!(objects[SCR_SCARE_MONSTER].oc_name_known) &&
210.  			   !(objects[SCR_SCARE_MONSTER].oc_uname))
211.  				docall(obj);
212.  		    delobj(obj);
213.  		    continue;
214.  		  }
215.  		}
216.  
217.  		/* do not pick up uchain */
218.  		if(obj == uchain)
219.  			continue;
220.  
221.  		wt = inv_weight() + obj->owt;
222.  		if (obj->otyp == LOADSTONE)
223.  			goto lift_some; /* pick it up even if too heavy */
224.  #ifdef POLYSELF
225.  		if (obj->otyp == BOULDER && throws_rocks(uasmon)) {
226.  			wt = inv_weight();
227.  			goto lift_some;
228.  		}
229.  #endif
230.  		if(wt > 0) {
231.  			if(obj->quan > 1) {
232.  				/* see how many we can lift */
233.  				int savequan = obj->quan;
234.  				int iw = inv_weight();
235.  				int qq;
236.  				for(qq = 1; qq < savequan; qq++){
237.  					obj->quan = qq;
238.  					if(iw + weight(obj) > 0)
239.  						break;
240.  				}
241.  				obj->quan = savequan;
242.  				qq--;
243.  				/* we can carry qq of them */
244.  				if(!qq) goto too_heavy;
245.  			You("can only carry %s of the %s lying here.",
246.  					(qq == 1) ? "one" : "some",
247.  					doname(obj));
248.  				{
249.  				register struct obj *obj3;
250.  
251.  				obj3 = splitobj(obj, qq);
252.  				if(obj3->otyp == SCR_SCARE_MONSTER)
253.  					if(obj3->spe) obj->spe = 0;
254.  				}
255.  				goto lift_some;
256.  			}
257.  		too_heavy:
258.  			pline("There %s %s here, but %s.",
259.  				(obj->quan == 1) ? "is" : "are",
260.  				doname(obj),
261.  				!invent ? "it is too heavy for you to lift"
262.  					: "you cannot carry any more");
263.  				if(obj->otyp == SCR_SCARE_MONSTER)
264.  					if(obj->spe) obj->spe = 0;
265.  			break;
266.  		}
267.  	lift_some:
268.  		if(inv_cnt() >= 52) {
269.  		    Your("knapsack cannot accommodate any more items.");
270.  				if(obj->otyp == SCR_SCARE_MONSTER)
271.  					if(obj->spe) obj->spe = 0;
272.  		    break;
273.  		}
274.  		freeobj(obj);
275.  		if(Invisible) newsym(u.ux,u.uy);
276.  		addtobill(obj, TRUE);       /* sets obj->unpaid if necessary */
277.  		if(wt > -5) You("have a little trouble lifting");
278.  		{ int pickquan = obj->quan;
279.  		  int mergquan;
280.  		if(!Blind) obj->dknown = 1;
281.  		obj = addinv(obj);    /* might merge it with other objects */
282.  		  mergquan = obj->quan;
283.  		  obj->quan = pickquan; /* to fool prinv() */
284.  		prinv(obj);
285.  		  obj->quan = mergquan;
286.  		}
287.  	    }
288.  	}
289.  	set_omask(u.ux, u.uy);
290.  }
291.  
292.  int
293.  doloot() {	/* loot a container on the floor. */
294.  
295.  	register struct obj *cobj;
296.  	register int c;
297.  
298.  	if (Levitation) {
299.  		pline("You cannot reach the floor.");
300.  		return(0);
301.  	}
302.  	if(levl[u.ux][u.uy].omask)
303.  	for(cobj = fobj; cobj; cobj = cobj->nobj) {
304.  
305.  	    if(cobj->ox == u.ux && cobj->oy == u.uy)
306.  		if(Is_container(cobj)) {
307.  
308.  		    pline("There is %s here, loot it? ", doname(cobj));
309.  		    c = ynq();
310.  		    if(c == 'q') return 0;
311.  		    if(c == 'n') continue;
312.  
313.  		    if(cobj->olocked) {
314.  
315.  			pline("Hmmm, it seems to be locked.");
316.  			continue;
317.  		    }
318.  		    if(cobj->otyp == BAG_OF_TRICKS) {
319.  
320.  			You("carefully open the bag...");
321.  			pline("It develops a huge set of teeth and bites you!");
322.  			losehp(rnd(10), "carnivorous bag");
323.  			makeknown(BAG_OF_TRICKS);
324.  			continue;
325.  		    }
326.  
327.  		    You("carefully open the %s...", xname(cobj));
328.  		    if(cobj->otrapped) chest_trap(cobj, FINGER);
329.  
330.  		    use_container(cobj, 0);
331.  		}
332.  	}
333.  	return 0;
334.  }
335.  
336.  static
337.  struct obj *current_container;	/* a local variable of use_container, to be
338.  				used by its local procedures in/ck_container */
339.  #define Icebox (current_container->otyp == ICE_BOX)
340.  int baggone;	/* used in askchain so bag isn't used after explosion */
341.  
342.  void
343.  inc_cwt(cobj, obj)
344.  register struct obj *cobj, *obj;
345.  {
346.  	if (cobj->otyp == BAG_OF_HOLDING)
347.  		cobj->owt += (obj->owt/2 + 1);
348.  	else	cobj->owt += obj->owt;
349.  }
350.  
351.  static int
352.  in_container(obj)
353.  register struct obj *obj;
354.  {
355.  	if(obj == uball || obj == uchain) {
356.  		You("must be kidding.");
357.  		return(0);
358.  	}
359.  	if(obj == current_container) {
360.  		pline("That would be an interesting topological exercise.");
361.  		return(0);
362.  	}
363.  	if(obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) {
364.  		You("cannot %s something you are wearing.",
365.  			Icebox ? "refrigerate" : "stash");
366.  		return(0);
367.  	}
368.  	if((obj->otyp == LOADSTONE) && obj->cursed) {
369.  		obj->bknown = 1;
370.  		pline("The stone%s won't leave your person.",
371.  			obj->quan==1 ? "" : "s");
372.  		return(0);
373.  	}
374.  	/* Prohibit Amulets in containers; if you allow it, monsters can't
375.  	 * steal them.  It also becomes a pain to check to see if someone
376.  	 * has the Amulet.
377.  	 */
378.  	if(obj->otyp == AMULET_OF_YENDOR && !obj->spe) {
379.  	    pline("The Amulet of Yendor cannot be confined in such trappings.");
380.  	    return(0);
381.  	}
382.  	/* no nested containers - they do not save/restore properly. */
383.  	/* magic bag -> magic bag will self destruct later on. */
384.  	if(Is_container(obj) && Is_container(current_container) &&
385.  	    (!Is_mbag(obj) || !Is_mbag(current_container))) {
386.  		pline("It won't go in.");
387.  		return(1);	/* be careful! */
388.  	}
389.  	if(obj == uwep) {
390.  		if(welded(obj)) {
391.  			weldmsg(obj, FALSE);
392.  			return(0);
393.  		}
394.  		setuwep((struct obj *) 0);
395.  		if (uwep) return(0); /* unwielded, died, rewielded */
396.  	}
397.  #ifdef WALKIES
398.  	if(obj->otyp == LEASH && obj->leashmon != 0) {
399.  		pline("It is attached to your pet.");
400.  		return(0);
401.  	}
402.  #endif
403.  	inc_cwt(current_container, obj);
404.  	freeinv(obj);
405.  
406.  	obj->cobj = current_container;
407.  	obj->nobj = fcobj;
408.  	fcobj = obj;
409.  
410.  	if(Icebox)	obj->age = moves - obj->age;	/* actual age */
411.  
412.  	else if(Is_mbag(obj->cobj) &&
413.  		(Is_mbag(obj) ||
414.  		 (obj->otyp == WAN_CANCELLATION && (obj->spe > 0)) )) {
415.  		explode_bag(obj);
416.  		You("are blasted by a magical explosion!");
417.  		losehp(d(6,6),"magical explosion");
418.  		baggone = 1;
419.  	}
420.  	return(1);
421.  }
422.  
423.  static int
424.  ck_container(obj)
425.  register struct obj *obj;
426.  {
427.  	return(obj->cobj == current_container);
428.  }
429.  
430.  static int
431.  ck_bag()
432.  {
433.  	return(!baggone);
434.  }
435.  
436.  static int
437.  out_container(obj)
438.  register struct obj *obj;
439.  {
440.  	register struct obj *otmp;
441.  
442.  	if(inv_cnt() >= 52) {
443.  		pline("You have no room to hold anything else.");
444.  		return(0);
445.  	}
446.  	if(obj == fcobj) fcobj = fcobj->nobj;
447.  	else {
448.  		for(otmp = fcobj; otmp->nobj != obj; otmp = otmp->nobj)
449.  			if(!otmp->nobj) panic("out_container");
450.  		otmp->nobj = obj->nobj;
451.  	}
452.  	dec_cwt(current_container, obj);
453.  	obj->cobj = (struct obj *) 0;
454.  
455.  	if (Icebox)
456.  		obj->age = moves - obj->age;	/* simulated point of time */
457.  
458.  	(void) addinv(obj);
459.  	return 0;
460.  }
461.  
462.  void
463.  get_all_from_box() {
464.  	register struct obj *otmp, *cobj, *ootmp, *nxobj;
465.  
466.  	for(otmp = invent; otmp; otmp = otmp->nobj) {
467.  	    cobj = otmp;
468.  	    if(Is_container(otmp))
469.  		for(ootmp=fcobj,nxobj=(fcobj ? fcobj->nobj : 0); ootmp;
470.  			    ootmp=nxobj,nxobj=(ootmp ? ootmp->nobj : 0) )
471.  		    if(ootmp->cobj == cobj)
472.  			(void)out_container(ootmp);
473.  	}
474.  	return;
475.  }
476.  
477.  /* for getobj: 0: allow cnt; #: allow all types; %: expect food */
478.  static const char frozen_food[] = { '0', '#', FOOD_SYM, 0 };
479.  
480.  void
481.  use_container(obj, held)
482.  register struct obj *obj;
483.  register int held;
484.  {
485.  	register int cnt = 0;
486.  	register struct obj *otmp;
487.  	register struct obj *backobj;
488.  
489.  	current_container = obj;	/* for use by in/out_container */
490.  	if(current_container->olocked) {
491.  		pline("The %s seems to be locked.", xname(current_container));
492.  		return;
493.  	}
494.  	for(otmp = fcobj, backobj = (struct obj *) 0; otmp;
495.  	    backobj = otmp, otmp = otmp->nobj)
496.  		if(otmp->cobj == obj)
497.  		    if(Is_mbag(obj) && obj->cursed && !rn2(13)) {
498.  			if (otmp->known)
499.  				pline("The %s to have vanished!",
500.  							aobjnam(otmp,"seem"));
501.  			else You("%s %s disappear.",
502.  				Blind ? "notice" : "see",
503.  				doname(otmp));
504.  			if(!backobj) {
505.  			    fcobj = otmp->nobj;
506.  			    dec_cwt(current_container, otmp);
507.  			    obfree(otmp, (struct obj *) 0);
508.  			    otmp = fcobj;
509.  			} else {
510.  			    backobj->nobj = otmp->nobj;
511.  			    dec_cwt(current_container, otmp);
512.  			    obfree(otmp, (struct obj *) 0);
513.  			    otmp = backobj->nobj;
514.  			}
515.  			if (!otmp) break;
516.  			if(otmp->cobj == obj) cnt++;
517.  		    } else cnt++;
518.  	if(!cnt)
519.  	    pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj));
520.  	else if (inv_cnt() < 52) {
521.  	    pline("Do you want to take something out of the %s? ",
522.  		  xname(obj));
523.  	    if(yn() != 'n')
524.  		if(askchain(fcobj, FALSE, NULL, 0, out_container, ck_container, 0, "nodot"))
525.  		    return;
526.  	}
527.  	if(!invent) return;
528.  	pline("Do you wish to put something in? ");
529.  	if(yn() != 'y') return;
530.  	if (Icebox && current_container->dknown) {
531.  		otmp = getobj(frozen_food, "put in");
532.  		if(!otmp || !in_container(otmp))
533.  			flags.move = multi = 0;
534.  	} else {
535.  		baggone = 0; /* might be set by in_container */
536.  		if(askchain(invent, TRUE, NULL, 0, in_container, ck_bag, 0, "nodot"))
537.  		  return;
538.  	}
539.  	return;
540.  }
541.  
542.  void
543.  delete_contents(obj)
544.  register struct obj *obj;
545.  {
546.  	register struct obj *otmp, *notmp;
547.  
548.  	while (fcobj && fcobj->cobj == obj) {
549.  		otmp = fcobj;
550.  		fcobj = fcobj->nobj;
551.  		obfree(otmp,(struct obj *)0);
552.  	}
553.  	if (fcobj) {
554.  		otmp = fcobj;
555.  		while(otmp->nobj)
556.  			if (otmp->nobj->cobj == obj) {
557.  				notmp = otmp->nobj;
558.  				otmp->nobj = notmp->nobj;
559.  				obfree(notmp,(struct obj *)0);
560.  			} else
561.  				otmp = otmp->nobj;
562.  	}
563.  }
564.  
565.  void
566.  explode_bag(obj)
567.  struct obj *obj;
568.  {
569.  	struct obj *otmp, *cobj;
570.  
571.  	cobj = obj->cobj;
572.  	delete_contents(cobj);
573.  
574.  	for (otmp = invent; otmp; otmp = otmp->nobj)
575.  		if (otmp == cobj) break;
576.  
577.  	if (otmp) {
578.  		You("see your %s blow apart!", xname(otmp));
579.  		useup(otmp);
580.  		/*return(0);*/
581.  	} else	panic("explode_bag: bag not in invent.");
582.  }
583.  
584.  void
585.  dec_cwt(cobj, obj)
586.  register struct obj *cobj, *obj;
587.  {
588.  	if (Is_mbag(cobj))
589.  		cobj->owt -= (obj->owt/2 + 1);
590.  	else	cobj->owt -= obj->owt;
591.  
592.  	if(cobj->owt < objects[cobj->otyp].oc_weight)
593.  		cobj->owt = objects[cobj->otyp].oc_weight;
594.  }