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