Source:NetHack 3.0.0/pickup.c

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

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. }