abstract
| - Below is the full text to pickup.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.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.1 93/01/04 */ 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. static void FDECL(unsplitobj, (struct obj *,struct obj *,long)); 12. static void FDECL(simple_look, (struct obj *,BOOLEAN_P)); 13. static boolean FDECL(query_classes, (char *,boolean *,boolean *, 14. const char *,struct obj *,BOOLEAN_P,BOOLEAN_P)); 15. static boolean FDECL(pickup_object, (struct obj *,struct obj *)); 16. static boolean FDECL(mbag_explodes, (struct obj *,int)); 17. STATIC_PTR int FDECL(in_container,(struct obj *)); 18. STATIC_PTR int FDECL(ck_bag,(struct obj *)); 19. STATIC_PTR int FDECL(out_container,(struct obj *)); 20. 21. /* 22. * How much the weight of the given container will change when the given 23. * object is removed from it. This calculation must match the one used 24. * by weight() in mkobj.c. 25. */ 26. #define DELTA_CWT(cont,obj) \ 27. ((cont)->cursed ? (obj)->owt * 2 : \ 28. 1 + ((obj)->owt / ((cont)->blessed ? 4 : 2))) 29. 30. static const char moderateloadmsg[] = "You have a little trouble lifting"; 31. static const char nearloadmsg[] = "You have much trouble lifting"; 32. 33. static void 34. unsplitobj(obj_block, obj_chip, resplit) 35. register struct obj *obj_block, *obj_chip; 36. long resplit; /* non-zero => shift the quantities */ 37. { 38. if (obj_block->nobj != obj_chip) { 39. impossible("can't unsplit objects"); 40. } else if (resplit) { /* 1st object should be reduced to 'resplit' */ 41. obj_chip->quan += (obj_block->quan - resplit); 42. obj_block->quan = resplit; 43. obj_block->owt = weight(obj_block); 44. obj_chip->owt = weight(obj_chip); 45. } else { /* 2nd obj should be merged back into 1st, then destroyed */ 46. obj_block->nobj = obj_chip->nobj; 47. obj_block->nexthere = obj_chip->nexthere; 48. obj_block->quan += obj_chip->quan; 49. obj_block->owt = weight(obj_block); 50. /* no need to worry about 'unsplitbill'; unsplit only occurs 51. when unable to pick something up, hence we're not dealing 52. with billable objects here (I hope!) 53. */ 54. dealloc_obj(obj_chip); 55. } 56. } 57. 58. /* much simpler version of the look-here code; used by query_classes() */ 59. static void 60. simple_look(otmp, here) 61. struct obj *otmp; /* list of objects */ 62. boolean here; /* flag for type of obj list linkage */ 63. { 64. /* Neither of the first two cases is expected to happen, since 65. * we're only called after multiple classes of objects have been 66. * detected, hence multiple objects must be present. 67. */ 68. if (!otmp) { 69. impossible("simple_look(NULL)"); 70. } else if (!(here ? otmp->nexthere : otmp->nobj)) { 71. pline("%s", doname(otmp)); 72. } else { 73. winid tmpwin = create_nhwindow(NHW_MENU); 74. putstr(tmpwin, 0, ""); 75. do { 76. putstr(tmpwin, 0, doname(otmp)); 77. otmp = here ? otmp->nexthere : otmp->nobj; 78. } while (otmp); 79. display_nhwindow(tmpwin, TRUE); 80. destroy_nhwindow(tmpwin); 81. } 82. } 83. 84. int 85. collect_obj_classes(ilets, otmp, here, incl_gold) 86. char ilets[]; 87. register struct obj *otmp; 88. boolean here, incl_gold; 89. { 90. register int iletct = 0; 91. register char c, last_c = '\0'; 92. 93. if (incl_gold) 94. ilets[iletct++] = def_oc_syms[GOLD_CLASS]; 95. ilets[iletct] = '\0'; /* terminate ilets so that index() will work */ 96. while (otmp) { 97. c = def_oc_syms[(int)otmp->oclass]; 98. if (c != last_c && !index(ilets, (last_c = c))) 99. ilets[iletct++] = c, ilets[iletct] = '\0'; 100. otmp = here ? otmp->nexthere : otmp->nobj; 101. } 102. 103. return iletct; 104. } 105. 106. static boolean 107. query_classes(olets, one_at_a_time, everything, action, objs, here, incl_gold) 108. char olets[]; 109. boolean *one_at_a_time, *everything; 110. const char *action; 111. struct obj *objs; 112. boolean here, incl_gold; 113. { 114. char ilets[20], inbuf[BUFSZ]; 115. int iletct, oletct; 116. char qbuf[QBUFSZ]; 117. 118. olets[oletct = 0] = '\0'; 119. *one_at_a_time = *everything = FALSE; 120. iletct = collect_obj_classes(ilets, objs, here, incl_gold); 121. if (iletct == 0) { 122. return FALSE; 123. } else if (iletct == 1) { 124. olets[0] = def_char_to_objclass(ilets[0]); 125. olets[1] = '\0'; 126. } else { /* more than one choice available */ 127. const char *where = 0; 128. register char sym, oc_of_sym, *p; 129. /* additional choices */ 130. ilets[iletct++] = ' '; 131. ilets[iletct++] = 'a'; 132. ilets[iletct++] = 'A'; 133. ilets[iletct++] = (objs == invent ? 'i' : ':'); 134. ilets[iletct] = '\0'; 135. ask_again: 136. olets[oletct = 0] = '\0'; 137. *one_at_a_time = *everything = FALSE; 138. Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]", 139. action, ilets); 140. getlin(qbuf,inbuf); 141. if (*inbuf == '\033') { 142. clear_nhwindow(WIN_MESSAGE); 143. return FALSE; 144. } 145. for (p = inbuf; (sym = *p++); ) { 146. /* new A function (selective all) added by GAN 01/09/87 */ 147. if (sym == ' ') continue; 148. else if (sym == 'A') *one_at_a_time = TRUE; 149. else if (sym == 'a') *everything = TRUE; 150. else if (sym == ':') { 151. simple_look(objs, here); /* dumb if objs==invent */ 152. goto ask_again; 153. } else if (sym == 'i') { 154. (void) display_inventory(NULL, FALSE); 155. goto ask_again; 156. } else { 157. oc_of_sym = def_char_to_objclass(sym); 158. if (index(ilets,sym)) { 159. olets[oletct++] = oc_of_sym; 160. olets[oletct] = '\0'; 161. } else { 162. if (!where) 163. where = !strcmp(action,"pick up") ? "here" : 164. !strcmp(action,"take out") ? 165. "inside" : ""; 166. if (*where) 167. pline("There are no %c's %s.", sym, where); 168. else 169. You("have no %c's.", sym); 170. } 171. } 172. } 173. if (!oletct && !*everything) *one_at_a_time = TRUE; 174. } 175. return TRUE; 176. } 177. 178. void 179. pickup(all) 180. int all; /* all >= 0 => yes/no; < 0 => -count */ 181. { 182. register struct obj *obj; 183. struct obj *obj2, *objx; 184. boolean all_of_a_type = FALSE, selective = FALSE; 185. char olets[20]; 186. long count; 187. 188. count = (all < 0) ? (-1L * all) : 0L; 189. if (count) all = 0; 190. 191. if(Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 192. if ((multi && !flags.run) || (all && !flags.pickup)) 193. read_engr_at(u.ux,u.uy); 194. return; 195. } 196. 197. /* multi && !flags.run means they are in the middle of some other 198. * action, or possibly paralyzed, sleeping, etc.... and they just 199. * teleported onto the object. They shouldn't pick it up. 200. */ 201. if ((multi && !flags.run) || (all && !flags.pickup)) { 202. int ct = 0; 203. 204. for (obj = level.objects[u.ux][u.uy]; obj; 205. obj = obj->nexthere) 206. if(obj != uchain) 207. ct++; 208. 209. /* If there are objects here, take a look. 210. */ 211. if (ct) { 212. if (flags.run) 213. nomul(0); 214. flush_screen(1); 215. if (ct < 5) 216. (void) dolook(); 217. else { 218. read_engr_at(u.ux,u.uy); 219. pline("There are several objects here."); 220. } 221. } else read_engr_at(u.ux,u.uy); 222. return; 223. } 224. 225. /* check for more than one object */ 226. if(!all) { 227. register int ct = 0; 228. 229. for(obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 230. ct++; 231. if(ct < 2) 232. all++; 233. else { 234. pline("There are several objects here."); 235. count = 0; 236. } 237. } 238. 239. #ifdef POLYSELF 240. if (nolimbs(uasmon)) { 241. You("cannot pick things up without limbs."); 242. return; 243. } 244. #endif 245. 246. /* added by GAN 10/24/86 to allow selective picking up */ 247. if (!all) { 248. if (!query_classes(olets, &selective, &all_of_a_type, 249. "pick up", level.objects[u.ux][u.uy], TRUE, FALSE)) 250. return; 251. } 252. if(all_of_a_type && !olets[0]) all = TRUE; 253. 254. for(obj = level.objects[u.ux][u.uy]; obj; obj = obj2) { 255. obj2 = obj->nexthere; /* perhaps obj will be picked up */ 256. objx = 0; 257. if(flags.run) nomul(0); 258. 259. if(!all) { 260. if(!selective && !index(olets,obj->oclass)) continue; 261. 262. if (!all_of_a_type) { 263. char qbuf[QBUFSZ]; 264. Sprintf(qbuf,"Pick up %s?", doname(obj)); 265. switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) { 266. case 'q': return; 267. case 'n': continue; 268. case 'a': 269. all_of_a_type = TRUE; 270. if (selective) { 271. selective = FALSE; 272. olets[0] = obj->oclass; 273. olets[1] = '\0'; 274. } 275. break; 276. case '#': /* count was entered */ 277. if (!yn_number) continue; /* 0 count => No */ 278. else count = yn_number; 279. /* fall thru :-} */ 280. default: /* 'y' */ 281. break; 282. } 283. } 284. } 285. 286. if (count) { 287. /* Pickup a specific number of items; split the object 288. unless count corresponds to full quantity. 1 special 289. case: cursed loadstones will remain as merged unit. 290. */ 291. if (count < obj->quan && 292. (!obj->cursed || obj->otyp != LOADSTONE)) { 293. objx = splitobj(obj, count); 294. if (!objx || objx->nexthere != obj2) 295. impossible("bad object split in pickup"); 296. } 297. count = 0; /* reset */ 298. } 299. if (pickup_object(obj, objx)) break; 300. } 301. 302. /* 303. * Re-map what is at the hero's location after the pickup so the 304. * map is correct. 305. */ 306. newsym(u.ux,u.uy); 307. } 308. 309. /* 310. * Pick up an object from the ground or out of a container and add it to 311. * the inventory. Returns true if pickup() should break out of its loop. 312. */ 313. static boolean 314. pickup_object(obj, objx) 315. struct obj *obj, *objx; 316. { 317. int wt, nearload; 318. long pickquan; 319. 320. if (obj == uchain) { /* do not pick up attached chain */ 321. return FALSE; 322. } else if (obj->oartifact && !touch_artifact(obj,&youmonst)) { 323. return FALSE; 324. } else if (obj->otyp == GOLD_PIECE) { 325. /* 326. * Special consideration for gold pieces... 327. */ 328. long iw = (long)max_capacity() - ((u.ugold + 50L) / 100L); 329. long gold_capacity = ((-iw) * 100L) - 50L + 99L - u.ugold; 330. 331. if (gold_capacity <= 0L) { 332. if (objx) unsplitobj(obj, objx, 0L); 333. pline("There %s %ld gold piece%s here, but you cannot carry any more.", 334. (obj->quan == 1L) ? "is" : "are", 335. obj->quan, plur(obj->quan)); 336. return FALSE; 337. } else if (gold_capacity < obj->quan) { 338. if (objx) unsplitobj(obj, objx, 0L); 339. You("can only carry %s of the %ld gold pieces lying here.", 340. gold_capacity == 1L ? "one" : "some", obj->quan); 341. pline("%s %ld gold piece%s.", 342. nearloadmsg, gold_capacity, plur(gold_capacity)); 343. u.ugold += gold_capacity; 344. obj->quan -= gold_capacity; 345. costly_gold(obj->ox, obj->oy, gold_capacity); 346. } else { 347. u.ugold += obj->quan; 348. if ((nearload = near_capacity()) != 0) 349. pline("%s %ld gold piece%s.", 350. nearload < MOD_ENCUMBER ? 351. moderateloadmsg : nearloadmsg, 352. obj->quan, plur(obj->quan)); 353. else 354. prinv(NULL, obj, 0L); 355. costly_gold(obj->ox, obj->oy, obj->quan); 356. delobj(obj); 357. } 358. flags.botl = 1; 359. if (flags.run) nomul(0); 360. return FALSE; 361. } else if (obj->otyp == CORPSE) { 362. 363. if (obj->corpsenm == PM_COCKATRICE && !uarmg 364. #ifdef POLYSELF 365. && !resists_ston(uasmon) 366. #endif 367. ) { 368. #ifdef POLYSELF 369. if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 370. display_nhwindow(WIN_MESSAGE, FALSE); 371. else 372. #endif 373. { 374. pline("Touching the cockatrice corpse is a fatal mistake."); 375. You("turn to stone."); 376. You("die..."); 377. killer_format = KILLED_BY_AN; 378. killer = "cockatrice corpse"; 379. done(STONING); 380. } 381. } else if (is_rider(&mons[obj->corpsenm])) { 382. pline("At your touch, the corpse suddenly moves..."); 383. revive_corpse(obj, 1, FALSE); 384. exercise(A_WIS, FALSE); 385. return FALSE; 386. } 387. 388. } else if (obj->otyp == SCR_SCARE_MONSTER) { 389. if (obj->blessed) obj->blessed = 0; 390. else if (!obj->spe && !obj->cursed) obj->spe = 1; 391. else { 392. pline("The scroll%s turn%s to dust as you pick %s up.", 393. plur(obj->quan), (obj->quan == 1L) ? "s" : "", 394. (obj->quan == 1L) ? "it" : "them"); 395. if (!(objects[SCR_SCARE_MONSTER].oc_name_known) && 396. !(objects[SCR_SCARE_MONSTER].oc_uname)) 397. docall(obj); 398. useupf(obj); 399. return FALSE; 400. } 401. } 402. 403. wt = max_capacity() + (int)obj->owt; 404. if (obj->otyp == LOADSTONE) 405. goto lift_some; /* pick it up even if too heavy */ 406. #ifdef POLYSELF 407. if (obj->otyp == BOULDER && throws_rocks(uasmon)) { 408. goto lift_some; 409. } 410. #endif 411. if (wt > 0) { 412. if (obj->quan > 1L) { 413. /* see how many we can lift */ 414. long qq, savequan = obj->quan; 415. int iw = max_capacity(); 416. /* This is correct only because containers */ 417. /* don't merge. -dean */ 418. for (qq = 1; qq < savequan; qq++) { 419. obj->quan = qq; 420. if (iw + weight(obj) > 0) 421. break; 422. } 423. obj->quan = savequan; 424. qq--; 425. /* we can carry qq of them */ 426. if (qq) { 427. if (objx) { /* temporarily unsplit */ 428. savequan = obj->quan; 429. obj->quan += objx->quan; 430. } 431. You("can only carry %s of the %s lying here.", 432. (qq == 1L) ? "one" : "some", doname(obj)); 433. if (objx) { /* re-do the prior split */ 434. obj->quan = savequan; 435. unsplitobj(obj, objx, qq); 436. } else { /* split into two groups */ 437. objx = splitobj(obj, qq); 438. if (objx->otyp == SCR_SCARE_MONSTER) objx->spe = 0; 439. } 440. goto lift_some; 441. } 442. } 443. if (objx) unsplitobj(obj, objx, 0L); 444. pline("There %s %s here, but %s.", 445. (obj->quan == 1L) ? "is" : "are", doname(obj), 446. !invent ? (obj->quan == 1L ? 447. "it is too heavy for you to lift" : 448. "they are too heavy for you to lift") : 449. "you cannot carry any more"); 450. if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0; 451. return TRUE; 452. } 453. 454. lift_some: 455. if (inv_cnt() >= 52) { 456. if (objx) unsplitobj(obj, objx, 0L); 457. Your("knapsack cannot accommodate any more items."); 458. if (obj->otyp == SCR_SCARE_MONSTER) obj->spe = 0; 459. return TRUE; 460. } 461. 462. pickquan = obj->quan; /* save number picked up */ 463. obj = pick_obj(obj); 464. 465. if (!Blind) obj->dknown = 1; 466. if (uwep && uwep == obj) mrg_to_wielded = TRUE; 467. nearload = near_capacity(); 468. prinv(nearload > SLT_ENCUMBER ? nearloadmsg : 469. nearload > UNENCUMBERED ? moderateloadmsg : NULL, 470. obj, pickquan); 471. mrg_to_wielded = FALSE; 472. return FALSE; 473. } 474. 475. /* Gold never reaches this routine. */ 476. struct obj * 477. pick_obj(otmp) 478. register struct obj *otmp; 479. { 480. freeobj(otmp); 481. if (*u.ushops && costly_spot(u.ux, u.uy) && 482. otmp != uball) /* don't charge for this - kd, 1/17/90 */ 483. /* sets obj->unpaid if necessary */ 484. addtobill(otmp, TRUE, FALSE, FALSE); 485. if(Invisible) newsym(u.ux,u.uy); 486. return(addinv(otmp)); /* might merge it with other objects */ 487. } 488. 489. /* 490. * prints a message if encumbrance changed since the last check and 491. * returns the new encumbrance value (from near_capacity()). 492. */ 493. int 494. encumber_msg() 495. { 496. static int oldcap = UNENCUMBERED; 497. int newcap = near_capacity(); 498. 499. if(oldcap < newcap) { 500. switch(newcap) { 501. case 1: Your("movements are slowed slightly because of your load."); 502. break; 503. case 2: You("rebalance your load. Movement is difficult."); 504. break; 505. case 3: You("stagger under your heavy load. Movement is very hard."); 506. break; 507. default: You("can barely move a handspan with this load!"); 508. break; 509. } 510. flags.botl = 1; 511. } else if(oldcap > newcap) { 512. switch(newcap) { 513. case 0: Your("movements are now unencumbered."); 514. break; 515. case 1: Your("movements are only slowed slightly by your load."); 516. break; 517. case 2: You("rebalance your load. Movement is still difficult."); 518. break; 519. case 3: You("stagger under your load. Movement is still very hard."); 520. break; 521. } 522. flags.botl = 1; 523. } 524. 525. oldcap = newcap; 526. return (newcap); 527. } 528. 529. int 530. doloot() /* loot a container on the floor. */ 531. { 532. register struct obj *cobj, *nobj; 533. register int c; 534. int timepassed = 0; 535. 536. if (Levitation && !Is_airlevel(&u.uz) && !Is_waterlevel(&u.uz)) { 537. You("cannot reach the floor."); 538. return(0); 539. } 540. if(is_pool(u.ux, u.uy)) { 541. You("cannot loot things that are deep in the water."); 542. return(0); 543. } 544. 545. #ifdef POLYSELF 546. if(nolimbs(uasmon)) { 547. You("cannot loot things without limbs."); 548. return(0); 549. } 550. #endif 551. 552. for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) { 553. nobj = cobj->nexthere; 554. 555. if(Is_container(cobj)) { 556. char qbuf[QBUFSZ]; 557. 558. Sprintf(qbuf, "There is %s here, loot it?", doname(cobj)); 559. c = ynq(qbuf); 560. if(c == 'q') return (timepassed); 561. if(c == 'n') continue; 562. 563. if(cobj->olocked) { 564. pline("Hmmm, it seems to be locked."); 565. continue; 566. } 567. if(cobj->otyp == BAG_OF_TRICKS) { 568. You("carefully open the bag..."); 569. pline("It develops a huge set of teeth and bites you!"); 570. c = rnd(10); 571. if(Half_physical_damage) c = (c+1) / 2; 572. losehp(c, "carnivorous bag", KILLED_BY_AN); 573. makeknown(BAG_OF_TRICKS); 574. timepassed = 1; 575. continue; 576. } 577. 578. You("carefully open %s...", the(xname(cobj))); 579. if (cobj->otrapped && chest_trap(cobj, FINGER, FALSE)) { 580. timepassed = 1; 581. continue; /* explosion destroyed cobj */ 582. } 583. if(multi < 0) return (1); /* a paralysis trap */ 584. 585. timepassed |= use_container(cobj, 0); 586. } 587. } 588. return (timepassed); 589. } 590. 591. /* 592. * Decide whether an object being placed into a magic bag will cause 593. * it to explode. If the object is a bag itself, check recursively. 594. */ 595. static boolean 596. mbag_explodes(obj, depthin) 597. struct obj *obj; 598. int depthin; 599. { 600. /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */ 601. if ((Is_mbag(obj) || (obj->otyp == WAN_CANCELLATION && obj->spe > 0)) && 602. (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin)) 603. return TRUE; 604. else if (Is_container(obj)) { 605. struct obj *otmp; 606. 607. for (otmp = obj->cobj; otmp; otmp = otmp->nobj) 608. if (mbag_explodes(otmp, depthin+1)) return TRUE; 609. } 610. return FALSE; 611. } 612. 613. /* A variable set in use_container(), to be used by the callback routines */ 614. /* chk_bg(), in_container(), and out_container() from askchain(). */ 615. static struct obj NEARDATA *current_container; 616. #define Icebox (current_container->otyp == ICE_BOX) 617. 618. STATIC_PTR int 619. in_container(obj) 620. register struct obj *obj; 621. { 622. register struct obj *gold; 623. boolean is_gold = (obj->otyp == GOLD_PIECE); 624. boolean floor_container = !carried(current_container); 625. char buf[BUFSZ]; 626. 627. if (!current_container) { 628. impossible(" no current_container?"); 629. return 0; 630. } else if (obj == uball || obj == uchain) { 631. You("must be kidding."); 632. return 0; 633. } else if (obj == current_container) { 634. pline("That would be an interesting topological exercise."); 635. return 0; 636. } else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) { 637. Norep("You cannot %s something you are wearing.", 638. Icebox ? "refrigerate" : "stash"); 639. return 0; 640. } else if ((obj->otyp == LOADSTONE) && obj->cursed) { 641. obj->bknown = 1; 642. pline("The stone%s won't leave your person.", plur(obj->quan)); 643. return 0; 644. } else if (obj->otyp == AMULET_OF_YENDOR || 645. obj->otyp == CANDELABRUM_OF_INVOCATION || 646. obj->otyp == BELL_OF_OPENING || 647. obj->otyp == SPE_BOOK_OF_THE_DEAD) { 648. /* Prohibit Amulets in containers; if you allow it, monsters can't 649. * steal them. It also becomes a pain to check to see if someone 650. * has the Amulet. Ditto for the Candelabrum, the Bell and the Book. 651. */ 652. pline("%s cannot be confined in such trappings.", The(xname(obj))); 653. return 0; 654. } 655. #ifdef WALKIES 656. else if (obj->otyp == LEASH && obj->leashmon != 0) { 657. pline("%s is attached to your pet.", The(xname(obj))); 658. return 0; 659. } 660. #endif 661. else if (obj == uwep) { 662. if (welded(obj)) { 663. weldmsg(obj, FALSE); 664. return 0; 665. } 666. setuwep((struct obj *) 0); 667. if (uwep) return 0; /* unwielded, died, rewielded */ 668. } 669. 670. /* boxes can't fit into any container */ 671. if (obj->otyp == ICE_BOX || Is_box(obj)) { 672. /* 673. * xname() uses a static result array. Save obj's name 674. * before current_container's name is computed. Don't 675. * use the result of strcpy() within You() --- the order 676. * of evaluation of the parameters is undefined. 677. */ 678. Strcpy(buf, the(xname(obj))); 679. You("cannot fit %s into %s.", buf, 680. the(xname(current_container))); 681. return 0; 682. } 683. 684. freeinv(obj); 685. 686. if (is_gold) { /* look for other gold within the container */ 687. for (gold = current_container->cobj; gold; gold = gold->nobj) 688. if (gold->otyp == GOLD_PIECE) break; 689. } else 690. gold = 0; 691. 692. if (gold) { 693. gold->quan += obj->quan; 694. } else { 695. obj->nobj = current_container->cobj; 696. current_container->cobj = obj; 697. } 698. 699. current_container->owt = weight(current_container); 700. 701. Strcpy(buf, the(xname(current_container))); 702. You("put %s into %s.", doname(obj), buf); 703. 704. if (floor_container && costly_spot(u.ux, u.uy)) { 705. sellobj_state(TRUE); 706. sellobj(obj, u.ux, u.uy); 707. sellobj_state(FALSE); 708. } 709. (void) snuff_candle(obj); /* must follow the "put" msg */ 710. if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN 711. && !Is_candle(obj)) 712. obj->age = monstermoves - obj->age; /* actual age */ 713. 714. else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) { 715. You("are blasted by a magical explosion!"); 716. 717. /* the !floor_container case is taken care of */ 718. if(*u.ushops && costly_spot(u.ux, u.uy) && floor_container) { 719. register struct monst *shkp; 720. 721. if ((shkp = shop_keeper(*u.ushops)) != 0) 722. (void)stolen_value(current_container, u.ux, u.uy, 723. (boolean)shkp->mpeaceful, FALSE); 724. } 725. delete_contents(current_container); 726. if (!floor_container) 727. useup(current_container); 728. else if (obj_here(current_container, u.ux, u.uy)) 729. useupf(current_container); 730. else 731. panic("in_container: bag not found."); 732. 733. losehp(d(6,6),"magical explosion", KILLED_BY_AN); 734. current_container = 0; /* baggone = TRUE; */ 735. } 736. 737. if (is_gold) { 738. if (gold) dealloc_obj(obj); 739. bot(); /* update character's gold piece count immediately */ 740. } 741. 742. return(current_container ? 1 : -1); 743. } 744. 745. STATIC_PTR int 746. ck_bag(obj) 747. struct obj *obj; 748. { 749. return current_container && obj != current_container; 750. } 751. 752. STATIC_PTR int 753. out_container(obj) 754. register struct obj *obj; 755. { 756. register struct obj *otmp, *ootmp; 757. boolean is_gold = (obj->otyp == GOLD_PIECE); 758. int loadlev; 759. long quan; 760. 761. if (!current_container) { 762. impossible(" no current_container?"); 763. return -1; 764. } else if (is_gold) { 765. obj->owt = weight(obj); 766. } else if (inv_cnt() >= 52) { 767. You("have no room to hold anything else."); 768. return -1; /* skips gold too; oh well */ 769. } 770. 771. if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0; 772. 773. if(obj->otyp != LOADSTONE && max_capacity() + (int)obj->owt - 774. (carried(current_container) ? 775. (current_container->otyp == BAG_OF_HOLDING ? 776. (int)DELTA_CWT(current_container,obj) : (int)obj->owt) : 0) > 0) { 777. char buf[BUFSZ]; 778. 779. Strcpy(buf, doname(obj)); 780. pline("There %s %s in %s, but %s.", 781. obj->quan==1 ? "is" : "are", 782. buf, the(xname(current_container)), 783. invent ? "you cannot carry any more" 784. : "it is too heavy for you to carry"); 785. /* "too heavy for you to lift" is not right if you're carrying 786. the container... */ 787. return(0); 788. } 789. /* Remove the object from the list. */ 790. if (obj == current_container->cobj) 791. current_container->cobj = obj->nobj; 792. else { 793. for(otmp = current_container->cobj; otmp->nobj != obj; 794. otmp = otmp->nobj) 795. if(!otmp->nobj) panic("out_container"); 796. otmp->nobj = obj->nobj; 797. } 798. 799. current_container->owt = weight(current_container); 800. 801. if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN 802. && !Is_candle(obj)) 803. obj->age = monstermoves - obj->age; 804. /* simulated point of time */ 805. 806. if(!obj->unpaid && !carried(current_container) && 807. costly_spot(current_container->ox, current_container->oy)) { 808. 809. addtobill(obj, FALSE, FALSE, FALSE); 810. } 811. 812. quan = obj->quan; 813. ootmp = addinv(obj); 814. loadlev = near_capacity(); 815. prinv(loadlev ? 816. (loadlev < MOD_ENCUMBER ? 817. "You have a little trouble removing" : 818. "You have much trouble removing") : NULL, 819. ootmp, quan); 820. 821. if (is_gold) { 822. dealloc_obj(obj); 823. bot(); /* update character's gold piece count immediately */ 824. } 825. return 1; 826. } 827. 828. /* for getobj: allow counts, allow all types, expect food */ 829. static const char NEARDATA frozen_food[] = 830. { ALLOW_COUNT, ALL_CLASSES, FOOD_CLASS, 0 }; 831. 832. int 833. use_container(obj, held) 834. register struct obj *obj; 835. register int held; 836. { 837. register int cnt = 0; 838. register struct obj *curr, *prev, *otmp; 839. boolean one_by_one, allflag; 840. char select[MAXOCLASSES+1]; 841. char qbuf[QBUFSZ]; 842. int used = 0, lcnt = 0; 843. long loss = 0L; 844. register struct monst *shkp; 845. 846. current_container = obj; /* for use by in/out_container */ 847. if (current_container->olocked) { 848. pline("%s seems to be locked.", The(xname(current_container))); 849. if (held) You("must put it down to unlock."); 850. return 0; 851. } 852. /* Count the number of contained objects. Sometimes toss objects if */ 853. /* a cursed magic bag. */ 854. for(curr = obj->cobj, prev = (struct obj *) 0; curr; 855. prev = curr, curr = otmp) { 856. otmp = curr->nobj; 857. if (Is_mbag(obj) && obj->cursed && !rn2(13)) { 858. if (curr->known) 859. pline("%s to have vanished!", The(aobjnam(curr,"seem"))); 860. else 861. You("%s %s disappear.", Blind ? "notice" : "see", 862. doname(curr)); 863. if (prev) 864. prev->nobj = otmp; 865. else 866. obj->cobj = otmp; 867. 868. if(*u.ushops && (shkp = shop_keeper(*u.ushops))) { 869. if(held) { 870. if(curr->unpaid) 871. loss += stolen_value(curr, u.ux, u.uy, 872. (boolean)shkp->mpeaceful, TRUE); 873. lcnt++; 874. } else if(costly_spot(u.ux, u.uy)) { 875. loss += stolen_value(curr, u.ux, u.uy, 876. (boolean)shkp->mpeaceful, TRUE); 877. lcnt++; 878. } 879. } 880. /* obfree() will free all contained objects */ 881. obfree(curr, (struct obj *) 0); 882. } else 883. cnt++; 884. } 885. 886. if (cnt && loss) 887. You("owe %ld zorkmids for lost item%s.", 888. loss, lcnt > 1 ? "s" : ""); 889. 890. current_container->owt = weight(current_container); 891. 892. if(!cnt) 893. pline("%s %s is empty.", (held) ? "Your" : "The", xname(obj)); 894. else { 895. Sprintf(qbuf, "Do you want to take something out of %s?", 896. the(xname(obj))); 897. ask_again: 898. switch (yn_function(qbuf, ":ynq", 'n')) { 899. case ':': 900. container_contents(current_container, FALSE, FALSE); 901. goto ask_again; 902. case 'y': 903. if (query_classes(select, &one_by_one, &allflag, "take out", 904. current_container->cobj, FALSE, FALSE)) { 905. if (askchain((struct obj **)¤t_container->cobj, 906. (one_by_one ? (char *)0 : select), allflag, 907. out_container, (int (*)())0, 0, "nodot")) 908. used = 1; 909. } 910. /*FALLTHRU*/ 911. case 'n': 912. break; 913. case 'q': 914. default: 915. return 0; 916. } 917. } 918. 919. if (!invent && (u.ugold == 0 || Icebox)) return used; 920. if (yn_function("Do you wish to put something in?", ynqchars, 'n') 921. != 'y') return used; 922. if (Icebox && current_container->dknown) { 923. otmp = getobj(frozen_food, "put in"); 924. if(!otmp || !in_container(otmp)) 925. flags.move = multi = 0; 926. } else { 927. if (query_classes(select, &one_by_one, &allflag, "put in", 928. invent, FALSE, (u.ugold != 0L))) { 929. struct obj *u_gold = (struct obj *)0; 930. if (u.ugold && (one_by_one || (allflag && !*select) 931. || index(select, GOLD_CLASS))) { 932. /* make gold object & insert at head of inventory */ 933. u_gold = mkgoldobj(u.ugold); /*(removes gold too)*/ 934. u.ugold = u_gold->quan; /* put the gold back */ 935. u_gold->nobj = invent; 936. invent = u_gold; 937. } 938. used = (askchain((struct obj **)&invent, 939. (one_by_one ? (char *)0 : select), allflag, 940. in_container, ck_bag, 0, "nodot") > 0); 941. if (u_gold && invent && invent->otyp == GOLD_PIECE) { 942. /* didn't stash [all of] it */ 943. u_gold = invent; 944. invent = u_gold->nobj; 945. dealloc_obj(u_gold); 946. } 947. } 948. } 949. 950. return used; 951. } 952. 953. /*pickup.c*/
|