abstract
| - Below is the full text to pickup.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2 96/03/03 */ 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(simple_look, (struct obj *,BOOLEAN_P)); 12. static boolean FDECL(query_classes, (char *,boolean *,boolean *, 13. const char *,struct obj *,BOOLEAN_P,BOOLEAN_P,int *)); 14. static void FDECL(check_here, (BOOLEAN_P)); 15. static boolean FDECL(n_or_more, (struct obj *)); 16. static boolean FDECL(all_but_uchain, (struct obj *)); 17. #if 0 /* not used */ 18. static boolean FDECL(allow_cat_no_uchain, (struct obj *)); 19. #endif 20. static int FDECL(autopick, (struct obj*, int, menu_item **)); 21. static int FDECL(count_categories, (struct obj *,int)); 22. static long FDECL(carry_count, 23. (struct obj *,struct obj *,long,BOOLEAN_P,int *,int *)); 24. static int FDECL(lift_object, (struct obj *,struct obj *,long *,BOOLEAN_P)); 25. static boolean FDECL(mbag_explodes, (struct obj *,int)); 26. STATIC_PTR int FDECL(in_container,(struct obj *)); 27. STATIC_PTR int FDECL(ck_bag,(struct obj *)); 28. STATIC_PTR int FDECL(out_container,(struct obj *)); 29. static int FDECL(menu_loot, (int, struct obj *, BOOLEAN_P)); 30. static int FDECL(in_or_out_menu, (const char *,struct obj *)); 31. 32. /* define for query_objlist() and autopickup() */ 33. #define FOLLOW(curr, flags) \ 34. (((flags) & BY_NEXTHERE) ? (curr)->nexthere : (curr)->nobj) 35. 36. /* 37. * How much the weight of the given container will change when the given 38. * object is removed from it. This calculation must match the one used 39. * by weight() in mkobj.c. 40. */ 41. #define DELTA_CWT(cont,obj) \ 42. ((cont)->cursed ? (obj)->owt * 2 : \ 43. 1 + ((obj)->owt / ((cont)->blessed ? 4 : 2))) 44. #define GOLD_WT(n) (((n) + 50L) / 100L) 45. /* if you can figure this out, give yourself a hearty pat on the back... */ 46. #define GOLD_CAPACITY(w,n) (((w) * -100L) - ((n) + 50L) - 1L) 47. 48. static const char moderateloadmsg[] = "You have a little trouble lifting"; 49. static const char nearloadmsg[] = "You have much trouble lifting"; 50. static const char overloadmsg[] = "You have extreme difficulty lifting"; 51. 52. /* BUG: this lets you look at cockatrice corpses while blind without 53. touching them */ 54. /* much simpler version of the look-here code; used by query_classes() */ 55. static void 56. simple_look(otmp, here) 57. struct obj *otmp; /* list of objects */ 58. boolean here; /* flag for type of obj list linkage */ 59. { 60. /* Neither of the first two cases is expected to happen, since 61. * we're only called after multiple classes of objects have been 62. * detected, hence multiple objects must be present. 63. */ 64. if (!otmp) { 65. impossible("simple_look(null)"); 66. } else if (!(here ? otmp->nexthere : otmp->nobj)) { 67. pline("%s", doname(otmp)); 68. } else { 69. winid tmpwin = create_nhwindow(NHW_MENU); 70. putstr(tmpwin, 0, ""); 71. do { 72. putstr(tmpwin, 0, doname(otmp)); 73. otmp = here ? otmp->nexthere : otmp->nobj; 74. } while (otmp); 75. display_nhwindow(tmpwin, TRUE); 76. destroy_nhwindow(tmpwin); 77. } 78. } 79. 80. int 81. collect_obj_classes(ilets, otmp, here, incl_gold, filter) 82. char ilets[]; 83. register struct obj *otmp; 84. boolean here, incl_gold; 85. boolean FDECL((*filter),(OBJ_P)); 86. { 87. register int iletct = 0; 88. register char c; 89. 90. if (incl_gold) 91. ilets[iletct++] = def_oc_syms[GOLD_CLASS]; 92. ilets[iletct] = '\0'; /* terminate ilets so that index() will work */ 93. while (otmp) { 94. c = def_oc_syms[(int)otmp->oclass]; 95. if (!index(ilets, c) && (!filter || (*filter)(otmp))) 96. ilets[iletct++] = c, ilets[iletct] = '\0'; 97. otmp = here ? otmp->nexthere : otmp->nobj; 98. } 99. 100. return iletct; 101. } 102. 103. /* 104. * Suppose some '?' and '!' objects are present, but '/' objects aren't: 105. * "a" picks all items without further prompting; 106. * "A" steps through all items, asking one by one; 107. * "?" steps through '?' items, asking, and ignores '!' ones; 108. * "/" becomes 'A', since no '/' present; 109. * "?a" or "a?" picks all '?' without further prompting; 110. * "/a" or "a/" becomes 'A' since there aren't any '/' 111. * (bug fix: 3.1.0 thru 3.1.3 treated it as "a"); 112. * "?/a" or "a?/" or "/a?",&c picks all '?' even though no '/' 113. * (ie, treated as if it had just been "?a"). 114. */ 115. static boolean 116. query_classes(oclasses, one_at_a_time, everything, action, objs, 117. here, incl_gold, menu_on_demand) 118. char oclasses[]; 119. boolean *one_at_a_time, *everything; 120. const char *action; 121. struct obj *objs; 122. boolean here, incl_gold; 123. int *menu_on_demand; 124. { 125. char ilets[20], inbuf[BUFSZ]; 126. int iletct, oclassct; 127. boolean not_everything; 128. char qbuf[QBUFSZ]; 129. boolean m_seen; 130. 131. oclasses[oclassct = 0] = '\0'; 132. *one_at_a_time = *everything = m_seen = FALSE; 133. iletct = collect_obj_classes(ilets, objs, here, incl_gold, 134. (boolean FDECL((*),(OBJ_P))) 0); 135. if (iletct == 0) { 136. return FALSE; 137. } else if (iletct == 1) { 138. oclasses[0] = def_char_to_objclass(ilets[0]); 139. oclasses[1] = '\0'; 140. } else { /* more than one choice available */ 141. const char *where = 0; 142. register char sym, oc_of_sym, *p; 143. /* additional choices */ 144. ilets[iletct++] = ' '; 145. ilets[iletct++] = 'a'; 146. ilets[iletct++] = 'A'; 147. ilets[iletct++] = (objs == invent ? 'i' : ':'); 148. if (menu_on_demand) { 149. ilets[iletct++] = 'm'; 150. *menu_on_demand = 0; 151. } 152. ilets[iletct] = '\0'; 153. ask_again: 154. oclasses[oclassct = 0] = '\0'; 155. *one_at_a_time = *everything = FALSE; 156. not_everything = FALSE; 157. Sprintf(qbuf,"What kinds of thing do you want to %s? [%s]", 158. action, ilets); 159. getlin(qbuf,inbuf); 160. if (*inbuf == '\033') return FALSE; 161. 162. for (p = inbuf; (sym = *p++); ) { 163. /* new A function (selective all) added by GAN 01/09/87 */ 164. if (sym == ' ') continue; 165. else if (sym == 'A') *one_at_a_time = TRUE; 166. else if (sym == 'a') *everything = TRUE; 167. else if (sym == ':') { 168. simple_look(objs, here); /* dumb if objs==invent */ 169. goto ask_again; 170. } else if (sym == 'i') { 171. (void) display_inventory((char *)0, TRUE); 172. goto ask_again; 173. } else if (sym == 'm') { 174. m_seen = TRUE; 175. } else { 176. oc_of_sym = def_char_to_objclass(sym); 177. if (index(ilets,sym)) { 178. add_valid_menu_class(oc_of_sym); 179. oclasses[oclassct++] = oc_of_sym; 180. oclasses[oclassct] = '\0'; 181. } else { 182. if (!where) 183. where = !strcmp(action,"pick up") ? "here" : 184. !strcmp(action,"take out") ? 185. "inside" : ""; 186. if (*where) 187. pline("There are no %c's %s.", sym, where); 188. else 189. You("have no %c's.", sym); 190. not_everything = TRUE; 191. } 192. } 193. } 194. if (m_seen && menu_on_demand) { 195. *menu_on_demand = (*everything || !oclassct) ? -2 : -3; 196. return FALSE; 197. } 198. if (!oclassct && (!*everything || not_everything)) { 199. /* didn't pick anything, 200. or tried to pick something that's not present */ 201. *one_at_a_time = TRUE; /* force 'A' */ 202. *everything = FALSE; /* inhibit 'a' */ 203. } 204. } 205. return TRUE; 206. } 207. 208. /* look at the objects at our location, unless there are too many of them */ 209. static void 210. check_here(picked_some) 211. boolean picked_some; 212. { 213. register struct obj *obj; 214. register int ct = 0; 215. 216. /* count the objects here */ 217. for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) { 218. if (obj != uchain) 219. ct++; 220. } 221. 222. /* If there are objects here, take a look. */ 223. if (ct) { 224. if (flags.run) nomul(0); 225. flush_screen(1); 226. if (ct < 5) { 227. (void) dolook(); 228. } else { 229. read_engr_at(u.ux,u.uy); 230. pline("There are several %sobjects here.", 231. picked_some ? "more " : ""); 232. } 233. } else { 234. read_engr_at(u.ux,u.uy); 235. } 236. } 237. 238. /* Value set by query_objlist() for n_or_more(). */ 239. static long val_for_n_or_more; 240. 241. /* query_objlist callback: return TRUE if obj's count is >= reference value */ 242. static boolean 243. n_or_more(obj) 244. struct obj *obj; 245. { 246. if (obj == uchain) return FALSE; 247. return (obj->quan >= val_for_n_or_more); 248. } 249. 250. /* List of valid menu classes for query_objlist() and allow_category callback */ 251. static char valid_menu_classes[MAXOCLASSES + 2]; 252. 253. void 254. add_valid_menu_class(c) 255. int c; 256. { 257. static int vmc_count = 0; 258. 259. if (c == 0) /* reset */ 260. vmc_count = 0; 261. else 262. valid_menu_classes[vmc_count++] = (char)c; 263. valid_menu_classes[vmc_count] = '\0'; 264. } 265. 266. /* query_objlist callback: return TRUE if not uchain */ 267. static boolean 268. all_but_uchain(obj) 269. struct obj *obj; 270. { 271. return (obj != uchain); 272. } 273. 274. /* query_objlist callback: return TRUE */ 275. /*ARGSUSED*/ 276. boolean 277. allow_all(obj) 278. struct obj *obj; 279. { 280. return TRUE; 281. } 282. 283. boolean 284. allow_category(obj) 285. struct obj *obj; 286. { 287. if (((index(valid_menu_classes,'u') != (char *)0) && obj->unpaid) || 288. (index(valid_menu_classes, obj->oclass) != (char *)0)) 289. return TRUE; 290. else 291. return FALSE; 292. } 293. 294. #if 0 /* not used */ 295. /* query_objlist callback: return TRUE if valid category (class), no uchain */ 296. static boolean 297. allow_cat_no_uchain(obj) 298. struct obj *obj; 299. { 300. if ((obj != uchain) && 301. (((index(valid_menu_classes,'u') != (char *)0) && obj->unpaid) || 302. (index(valid_menu_classes, obj->oclass) != (char *)0))) 303. return TRUE; 304. else 305. return FALSE; 306. } 307. #endif 308. 309. /* query_objlist callback: return TRUE if valid class and worn */ 310. boolean 311. is_worn_by_type(otmp) 312. register struct obj *otmp; 313. { 314. return((boolean)(!!(otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP))) 315. && (index(valid_menu_classes, otmp->oclass) != (char *)0)); 316. } 317. 318. /* 319. * Have the hero pick things from the ground. 320. * 321. * Arg what: 322. * >0 autopickup 323. * =0 interactive 324. * <0 pickup count of something 325. */ 326. void 327. pickup(what) 328. int what; /* should be a long */ 329. { 330. int i, n, res, count, n_picked = 0; 331. menu_item *pick_list = (menu_item *) 0; 332. boolean autopickup = what > 0; 333. 334. if (what < 0) /* pick N of something */ 335. count = -what; 336. else /* pick anything */ 337. count = 0; 338. 339. /* no auto-pick if no-pick move, nothing there, or in a pool */ 340. if (autopickup && (flags.nopick || !OBJ_AT(u.ux, u.uy) || 341. (is_pool(u.ux, u.uy) && !Underwater))) { 342. read_engr_at(u.ux, u.uy); 343. return; 344. } 345. 346. /* no pickup if levitating & not on air or water level */ 347. if (!can_reach_floor()) { 348. if ((multi && !flags.run) || (autopickup && !flags.pickup)) 349. read_engr_at(u.ux, u.uy); 350. return; 351. } 352. 353. /* multi && !flags.run means they are in the middle of some other 354. * action, or possibly paralyzed, sleeping, etc.... and they just 355. * teleported onto the object. They shouldn't pick it up. 356. */ 357. if ((multi && !flags.run) || (autopickup && !flags.pickup)) { 358. check_here(FALSE); 359. return; 360. } 361. 362. /* if there's anything here, stop running */ 363. if (OBJ_AT(u.ux,u.uy) && flags.run && !flags.nopick) nomul(0); 364. 365. add_valid_menu_class(0); /* reset */ 366. /* 367. * Start the actual pickup process. This is split into two main 368. * sections, the newer menu and the older "traditional" methods. 369. * Automatic pickup has been split into its own menu-style routine 370. * to make things less confusing. 371. */ 372. if (autopickup) { 373. n = autopick(level.objects[u.ux][u.uy], BY_NEXTHERE, &pick_list); 374. goto menu_pickup; 375. } 376. 377. if (flags.menu_style != MENU_TRADITIONAL) { 378. /* use menus exclusively */ 379. 380. if (count) { /* looking for N of something */ 381. char buf[QBUFSZ]; 382. Sprintf(buf, "Pick %d of what?", count); 383. val_for_n_or_more = count; /* set up callback selector */ 384. n = query_objlist(buf, level.objects[u.ux][u.uy], 385. BY_NEXTHERE|AUTOSELECT_SINGLE|INVORDER_SORT, 386. &pick_list, PICK_ONE, n_or_more); 387. /* correct counts, if any given */ 388. for (i = 0; i < n; i++) 389. pick_list[i].count = count; 390. } else { 391. n = query_objlist("Pick up what?", level.objects[u.ux][u.uy], 392. BY_NEXTHERE|AUTOSELECT_SINGLE|INVORDER_SORT, 393. &pick_list, PICK_ANY, all_but_uchain); 394. } 395. menu_pickup: 396. for (n_picked = i = 0 ; i < n; i++) { 397. res = pickup_object(pick_list[i].item.a_obj,pick_list[i].count, 398. FALSE); 399. if (res < 0) break; /* can't continue */ 400. n_picked += res; 401. } 402. if (pick_list) free((genericptr_t)pick_list); 403. 404. } else { 405. /* old style interface */ 406. int ct = 0; 407. long lcount; 408. boolean all_of_a_type, selective; 409. char oclasses[MAXOCLASSES]; 410. struct obj *obj, *obj2; 411. 412. oclasses[0] = '\0'; /* types to consider (empty for all) */ 413. all_of_a_type = TRUE; /* take all of considered types */ 414. selective = FALSE; /* ask for each item */ 415. 416. /* check for more than one object */ 417. for (obj = level.objects[u.ux][u.uy]; obj; obj = obj->nexthere) 418. ct++; 419. 420. if (ct == 1 && count) { 421. /* if only one thing, then pick it */ 422. obj = level.objects[u.ux][u.uy]; 423. lcount = min(obj->quan, (long)count); 424. if (pickup_object(obj, lcount, FALSE) > 0) 425. n_picked++; /* picked something */ 426. goto end_query; 427. 428. } else if (ct >= 2) { 429. int via_menu = 0; 430. 431. pline("There are several objects here."); 432. if (!query_classes(oclasses, &selective, &all_of_a_type, 433. "pick up", level.objects[u.ux][u.uy], 434. TRUE, FALSE, &via_menu)) { 435. if (!via_menu) return; 436. n = query_objlist("Pick up what?", 437. level.objects[u.ux][u.uy], 438. BY_NEXTHERE|(selective ? 0 : INVORDER_SORT), 439. &pick_list, PICK_ANY, 440. via_menu == -2 ? allow_all : allow_category); 441. goto menu_pickup; 442. } 443. } 444. 445. for (obj = level.objects[u.ux][u.uy]; obj; obj = obj2) { 446. obj2 = obj->nexthere; /* perhaps obj will be picked up */ 447. lcount = -1L; 448. 449. if (!selective && oclasses[0] && !index(oclasses,obj->oclass)) 450. continue; 451. 452. if (!all_of_a_type) { 453. char qbuf[QBUFSZ]; 454. Sprintf(qbuf, "Pick up %s?", doname(obj)); 455. switch ((obj->quan < 2L) ? ynaq(qbuf) : ynNaq(qbuf)) { 456. case 'q': goto end_query; /* out 2 levels */ 457. case 'n': continue; 458. case 'a': 459. all_of_a_type = TRUE; 460. if (selective) { 461. selective = FALSE; 462. oclasses[0] = obj->oclass; 463. oclasses[1] = '\0'; 464. } 465. break; 466. case '#': /* count was entered */ 467. if (!yn_number) continue; /* 0 count => No */ 468. lcount = (long) yn_number; 469. if (lcount > obj->quan) lcount = obj->quan; 470. /* fall thru */ 471. default: /* 'y' */ 472. break; 473. } 474. } 475. if (lcount == -1L) lcount = obj->quan; 476. 477. if ((res = pickup_object(obj, lcount, FALSE)) < 0) break; 478. n_picked += res; 479. } 480. end_query: 481. ; /* semicolon needed by brain-damaged compilers */ 482. } 483. 484. /* position may need updating (invisible hero) */ 485. if (n_picked) newsym(u.ux,u.uy); 486. 487. /* see whether there's anything else here, after auto-pickup is done */ 488. if (autopickup) check_here(n_picked > 0); 489. } 490. 491. /* 492. * Pick from the given list using flags.pickup_types. Return the number 493. * of items picked (not counts). Create an array that returns pointers 494. * and counts of the items to be picked up. If the number of items 495. * picked is zero, the pickup list is left alone. The caller of this 496. * function must free the pickup list. 497. */ 498. static int 499. autopick(olist, follow, pick_list) 500. struct obj *olist; /* the object list */ 501. int follow; /* how to follow the object list */ 502. menu_item **pick_list; /* list of objects and counts to pick up */ 503. { 504. menu_item *pi; /* pick item */ 505. struct obj *curr; 506. int n; 507. const char *otypes = flags.pickup_types; 508. 509. /* first count the number of eligible items */ 510. for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) 511. if (!*otypes || index(otypes, curr->oclass)) 512. n++; 513. 514. if (n) { 515. *pick_list = pi = (menu_item *) alloc(sizeof(menu_item) * n); 516. for (n = 0, curr = olist; curr; curr = FOLLOW(curr, follow)) 517. if (!*otypes || index(otypes, curr->oclass)) { 518. pi[n].item.a_obj = curr; 519. pi[n].count = curr->quan; 520. n++; 521. } 522. } 523. return n; 524. } 525. 526. 527. /* 528. * Put up a menu using the given object list. Only those objects on the 529. * list that meet the approval of the allow function are displayed. Return 530. * a count of the number of items selected, as well as an allocated array of 531. * menu_items, containing pointers to the objects selected and counts. The 532. * returned counts are guaranteed to be in bounds and non-zero. 533. * 534. * Query flags: 535. * BY_NEXTHERE - Follow object list via nexthere instead of nobj. 536. * AUTOSELECT_SINGLE - Don't ask if only 1 object qualifies - just 537. * use it. 538. * USE_INVLET - Use object's invlet. 539. * INVORDER_SORT - Use hero's pack order. 540. * SIGNAL_NOMENU - Return -1 rather than 0 if nothing passes "allow". 541. */ 542. int 543. query_objlist(qstr, olist, qflags, pick_list, how, allow) 544. const char *qstr; /* query string */ 545. struct obj *olist; /* the list to pick from */ 546. int qflags; /* options to control the query */ 547. menu_item **pick_list; /* return list of items picked */ 548. int how; /* type of query */ 549. boolean FDECL((*allow), (OBJ_P));/* allow function */ 550. { 551. int n; 552. winid win; 553. struct obj *curr, *last; 554. char *pack; 555. anything any; 556. boolean printed_type_name; 557. 558. *pick_list = (menu_item *) 0; 559. if (!olist) return 0; 560. 561. /* count the number of items allowed */ 562. for (n = 0, last = 0, curr = olist; curr; curr = FOLLOW(curr, qflags)) 563. if ((*allow)(curr)) { 564. last = curr; 565. n++; 566. } 567. 568. if (n == 0) /* nothing to pick here */ 569. return (qflags & SIGNAL_NOMENU) ? -1 : 0; 570. 571. if (n == 1 && (qflags & AUTOSELECT_SINGLE)) { 572. *pick_list = (menu_item *) alloc(sizeof(menu_item)); 573. (*pick_list)->item.a_obj = last; 574. (*pick_list)->count = last->quan; 575. return 1; 576. } 577. 578. win = create_nhwindow(NHW_MENU); 579. start_menu(win); 580. any.a_obj = (struct obj *) 0; 581. 582. /* 583. * Run through the list and add the objects to the menu. If 584. * INVORDER_SORT is set, we'll run through the list once for 585. * each type so we can group them. The allow function will only 586. * be called once per object in the list. 587. */ 588. pack = flags.inv_order; 589. do { 590. printed_type_name = FALSE; 591. for (curr = olist; curr; curr = FOLLOW(curr, qflags)) 592. if ((!(qflags & INVORDER_SORT) || curr->oclass == *pack) 593. && (*allow)(curr)) { 594. 595. /* if sorting, print type name (once only) */ 596. if (qflags & INVORDER_SORT && !printed_type_name) { 597. any.a_obj = (struct obj *) 0; 598. add_menu(win, NO_GLYPH, &any, 0, ATR_INVERSE, 599. let_to_name(*pack, FALSE), MENU_UNSELECTED); 600. printed_type_name = TRUE; 601. } 602. 603. any.a_obj = curr; 604. add_menu(win, obj_to_glyph(curr), &any, 605. qflags & USE_INVLET ? curr->invlet : 0, 606. ATR_NONE, doname(curr), MENU_UNSELECTED); 607. } 608. pack++; 609. } while (qflags & INVORDER_SORT && *pack); 610. 611. end_menu(win, qstr); 612. n = select_menu(win, how, pick_list); 613. destroy_nhwindow(win); 614. 615. if (n > 0) { 616. menu_item *mi; 617. int i; 618. 619. /* fix up counts: -1 means no count used => pick all */ 620. for (i = 0, mi = *pick_list; i < n; i++, mi++) 621. if (mi->count == -1L || mi->count > mi->item.a_obj->quan) 622. mi->count = mi->item.a_obj->quan; 623. } else if (n < 0) { 624. n = 0; /* caller's don't expect -1 */ 625. } 626. return n; 627. } 628. 629. /* 630. * allow menu-based category (class) selection (for Drop,take off etc.) 631. * 632. */ 633. int 634. query_category(qstr, olist, qflags, pick_list, how) 635. const char *qstr; /* query string */ 636. struct obj *olist; /* the list to pick from */ 637. int qflags; /* behaviour modification flags */ 638. menu_item **pick_list; /* return list of items picked */ 639. int how; /* type of query */ 640. { 641. int n; 642. winid win; 643. struct obj *curr; 644. char *pack; 645. anything any; 646. boolean collected_type_name; 647. char invlet; 648. int ccount; 649. boolean do_unpaid = FALSE; 650. 651. *pick_list = (menu_item *) 0; 652. if (!olist) return 0; 653. if ((qflags & UNPAID_TYPES) && count_unpaid(olist)) do_unpaid = TRUE; 654. 655. ccount = count_categories(olist, qflags); 656. /* no point in actually showing a menu for a single category */ 657. if (ccount == 1 && !do_unpaid && !(qflags & BILLED_TYPES)) { 658. for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 659. if ((qflags & WORN_TYPES) && 660. !(curr->owornmask & (W_ARMOR|W_RING|W_AMUL|W_TOOL|W_WEP))) 661. continue; 662. break; 663. } 664. if (curr) { 665. *pick_list = (menu_item *) alloc(sizeof(menu_item)); 666. (*pick_list)->item.a_int = curr->oclass; 667. return 1; 668. } else { 669. #ifdef DEBUG 670. impossible("query_category: no single object match"); 671. #endif 672. } 673. return 0; 674. } 675. 676. win = create_nhwindow(NHW_MENU); 677. start_menu(win); 678. pack = flags.inv_order; 679. if ((qflags & ALL_TYPES) && (ccount > 1)) { 680. invlet = 'a'; 681. any.a_void = 0; 682. any.a_int = ALL_TYPES_SELECTED; 683. add_menu(win, NO_GLYPH, &any, invlet, ATR_NONE, 684. (qflags & WORN_TYPES) ? "All worn types" : "All types", 685. MENU_UNSELECTED); 686. invlet = 'b'; 687. } else 688. invlet = 'a'; 689. do { 690. collected_type_name = FALSE; 691. for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 692. if (curr->oclass == *pack) { 693. if ((qflags & WORN_TYPES) && 694. !(curr->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP))) 695. continue; 696. if (!collected_type_name) { 697. any.a_void = 0; 698. any.a_int = curr->oclass; 699. add_menu(win, NO_GLYPH, &any, invlet++, ATR_NONE, 700. let_to_name(*pack, FALSE), 701. MENU_UNSELECTED); 702. collected_type_name = TRUE; 703. } 704. } 705. } 706. pack++; 707. if (invlet >= 'u') { 708. impossible("query_category: too many categories"); 709. return 0; 710. } 711. } while (*pack); 712. /* unpaid items if there are any */ 713. if (do_unpaid) { 714. invlet = 'u'; 715. any.a_void = 0; 716. any.a_int = 'u'; 717. add_menu(win, NO_GLYPH, &any, invlet, ATR_NONE, 718. "Unpaid items", MENU_UNSELECTED); 719. } 720. /* billed items: checked by caller, so always include if BILLED_TYPES */ 721. if (qflags & BILLED_TYPES) { 722. invlet = 'x'; 723. any.a_void = 0; 724. any.a_int = 'x'; 725. add_menu(win, NO_GLYPH, &any, invlet, ATR_NONE, 726. "Unpaid items already used up", MENU_UNSELECTED); 727. } 728. if (qflags & CHOOSE_ALL) { 729. invlet = 'A'; 730. any.a_void = 0; 731. any.a_int = 'A'; 732. add_menu(win, NO_GLYPH, &any, invlet, ATR_NONE, 733. (qflags & WORN_TYPES) ? 734. "Auto-select every item being worn" : 735. "Auto-select every item", MENU_UNSELECTED); 736. } 737. end_menu(win, qstr); 738. n = select_menu(win, how, pick_list); 739. destroy_nhwindow(win); 740. if (n < 0) 741. n = 0; /* caller's don't expect -1 */ 742. return n; 743. } 744. 745. static int 746. count_categories(olist, qflags) 747. struct obj *olist; 748. int qflags; 749. { 750. char *pack; 751. boolean counted_category; 752. int ccount = 0; 753. struct obj *curr; 754. 755. pack = flags.inv_order; 756. do { 757. counted_category = FALSE; 758. for (curr = olist; curr; curr = FOLLOW(curr, qflags)) { 759. if (curr->oclass == *pack) { 760. if ((qflags & WORN_TYPES) && 761. !(curr->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL | W_WEP))) 762. continue; 763. if (!counted_category) { 764. ccount++; 765. counted_category = TRUE; 766. } 767. } 768. } 769. pack++; 770. } while (*pack); 771. return ccount; 772. } 773. 774. /* could we carry `obj'? if not, could we carry some of it/them? */ 775. static 776. long carry_count(obj, container, count, telekinesis, wt_before, wt_after) 777. struct obj *obj, *container; /* object to pick up, bag it's coming out of */ 778. long count; 779. boolean telekinesis; 780. int *wt_before, *wt_after; 781. { 782. boolean adjust_wt = container && carried(container), 783. is_gold = obj->oclass == GOLD_CLASS; 784. int wt, iw, ow, oow; 785. long qq, savequan; 786. unsigned saveowt; 787. const char *verb, *prefx1, *prefx2, *suffx; 788. char obj_nambuf[BUFSZ], where[BUFSZ]; 789. 790. savequan = obj->quan; 791. saveowt = obj->owt; 792. iw = max_capacity(); 793. if (count != savequan) { 794. obj->quan = count; 795. obj->owt = (unsigned)weight(obj); 796. } 797. wt = iw + (int)obj->owt; 798. if (adjust_wt) 799. wt -= (container->otyp == BAG_OF_HOLDING) ? 800. (int)DELTA_CWT(container, obj) : (int)obj->owt; 801. if (is_gold) /* merged gold might affect cumulative weight */ 802. wt -= (GOLD_WT(u.ugold) + GOLD_WT(count) - GOLD_WT(u.ugold + count)); 803. if (count != savequan) { 804. obj->quan = savequan; 805. obj->owt = saveowt; 806. } 807. *wt_before = iw; 808. *wt_after = wt; 809. if (wt < 0) 810. return count; 811. 812. /* see how many we can lift */ 813. if (is_gold) { 814. iw -= (int)GOLD_WT(u.ugold); 815. if (!adjust_wt) { 816. qq = GOLD_CAPACITY((long)iw, u.ugold); 817. } else { 818. oow = 0; 819. qq = 50L - (u.ugold % 100L) - 1L; 820. if (qq < 0L) qq += 100L; 821. for ( ; qq <= count; qq += 100L) { 822. obj->quan = qq; 823. obj->owt = (unsigned)GOLD_WT(qq); 824. ow = (int)GOLD_WT(u.ugold + qq); 825. ow -= (container->otyp == BAG_OF_HOLDING) ? 826. (int)DELTA_CWT(container, obj) : (int)obj->owt; 827. if (iw + ow >= 0) break; 828. oow = ow; 829. } 830. iw -= oow; 831. qq -= 100L; 832. } 833. if (qq < 0L) qq = 0L; 834. else if (qq > count) qq = count; 835. wt = iw + (int)GOLD_WT(u.ugold + qq); 836. } else if (count > 1 || count < obj->quan) { 837. /* 838. * Ugh. Calc num to lift by changing the quan of of the 839. * object and calling weight. 840. * 841. * This works for containers only because containers 842. * don't merge. -dean 843. */ 844. for (qq = 1L; qq <= count; qq++) { 845. obj->quan = qq; 846. obj->owt = (unsigned)(ow = weight(obj)); 847. if (adjust_wt) 848. ow -= (container->otyp == BAG_OF_HOLDING) ? 849. (int)DELTA_CWT(container, obj) : (int)obj->owt; 850. if (iw + ow >= 0) 851. break; 852. wt = iw + ow; 853. } 854. --qq; 855. } else { 856. /* there's only one, and we can't lift it */ 857. qq = 0L; 858. } 859. obj->quan = savequan; 860. obj->owt = saveowt; 861. 862. if (qq < count) { 863. /* some message will be given */ 864. Strcpy(obj_nambuf, doname(obj)); 865. if (container) { 866. Sprintf(where, "in %s", the(xname(container))); 867. verb = "carry"; 868. } else { 869. Strcpy(where, "lying here"); 870. verb = telekinesis ? "acquire" : "lift"; 871. } 872. } else { 873. /* lint supppression */ 874. *obj_nambuf = *where = '\0'; 875. verb = ""; 876. } 877. /* we can carry qq of them */ 878. if (qq > 0) { 879. if (qq < count) 880. You("can only %s %s of the %s %s.", 881. verb, (qq == 1L) ? "one" : "some", obj_nambuf, where); 882. *wt_after = wt; 883. return qq; 884. } 885. 886. if (!container) Strcpy(where, "here"); /* slightly shorter form */ 887. if (invent || u.ugold) { 888. prefx1 = "you cannot "; 889. prefx2 = ""; 890. suffx = " any more"; 891. } else { 892. prefx1 = (obj->quan == 1L) ? "it " : "even one "; 893. prefx2 = "is too heavy for you to "; 894. suffx = ""; 895. } 896. pline("There %s %s %s, but %s%s%s%s.", 897. (obj->quan == 1L) ? "is" : "are", obj_nambuf, where, 898. prefx1, prefx2, verb, suffx); 899. 900. /* *wt_after = iw; */ 901. return 0L; 902. } 903. 904. /* determine whether character is able and player is willing to carry `obj' */ 905. static 906. int lift_object(obj, container, cnt_p, telekinesis) 907. struct obj *obj, *container; /* object to pick up, bag it's coming out of */ 908. long *cnt_p; 909. boolean telekinesis; 910. { 911. int result, old_wt, new_wt, prev_encumbr, next_encumbr; 912. 913. if (obj->otyp == LOADSTONE || 914. (obj->otyp == BOULDER && throws_rocks(uasmon))) 915. return 1; /* lift regardless of current situation */ 916. 917. *cnt_p = carry_count(obj, container, *cnt_p, telekinesis, &old_wt, &new_wt); 918. if (*cnt_p < 1L) { 919. result = -1; /* nothing lifted */ 920. } else if (obj->oclass != GOLD_CLASS && inv_cnt() >= 52 && 921. !merge_choice(invent, obj)) { 922. Your("knapsack cannot accommodate any more items."); 923. result = -1; /* nothing lifted */ 924. } else { 925. result = 1; 926. prev_encumbr = near_capacity(); 927. if (prev_encumbr < MOD_ENCUMBER) prev_encumbr = MOD_ENCUMBER; 928. next_encumbr = calc_capacity(new_wt - old_wt); 929. if (next_encumbr > prev_encumbr) { 930. if (telekinesis) { 931. result = 0; /* don't lift */ 932. } else { 933. char qbuf[QBUFSZ]; 934. long savequan = obj->quan; 935. 936. obj->quan = *cnt_p; 937. Sprintf(qbuf, "%s %s. Continue?", 938. next_encumbr==HVY_ENCUMBER ? nearloadmsg : overloadmsg, 939. doname(obj)); 940. obj->quan = savequan; 941. switch (ynq(qbuf)) { 942. case 'q': result = -1; break; 943. case 'n': result = 0; break; 944. default: break; /* 'y' => result == 1 */ 945. } 946. } 947. } 948. } 949. 950. if (obj->otyp == SCR_SCARE_MONSTER && result <= 0 && !container) 951. obj->spe = 0; 952. return result; 953. } 954. 955. /* 956. * Pick up of obj from the ground and add it to the hero's inventory. 957. * Returns -1 if caller should break out of its loop, 0 if nothing picked 958. * up, 1 if otherwise. 959. */ 960. int 961. pickup_object(obj, count, telekinesis) 962. struct obj *obj; 963. long count; 964. boolean telekinesis; /* not picking it up directly by hand */ 965. { 966. int res, nearload; 967. 968. if (obj->quan < count) { 969. impossible("pickup_object: count %ld > quan %ld?", 970. count, obj->quan); 971. return 0; 972. } 973. 974. /* In case of auto-pickup, where we haven't had a chance 975. to look at it yet; affects docall(SCR_SCARE_MONSTER). */ 976. if (!Blind) obj->dknown = 1; 977. 978. if (obj == uchain) { /* do not pick up attached chain */ 979. return 0; 980. } else if (obj->oartifact && !touch_artifact(obj,&youmonst)) { 981. return 0; 982. } else if (obj->oclass == GOLD_CLASS) { 983. /* Special consideration for gold pieces... */ 984. long iw = (long)max_capacity() - GOLD_WT(u.ugold); 985. long gold_capacity = GOLD_CAPACITY(iw, u.ugold); 986. 987. if (gold_capacity <= 0L) { 988. pline("There %s %ld gold piece%s here, but you cannot carry any more.", 989. (obj->quan == 1L) ? "is" : "are", 990. obj->quan, plur(obj->quan)); 991. return 0; 992. } else if (gold_capacity < count) { 993. You("can only %s %s of the %ld gold pieces lying here.", 994. telekinesis ? "acquire" : "carry", 995. gold_capacity == 1L ? "one" : "some", obj->quan); 996. pline("%s %ld gold piece%s.", 997. nearloadmsg, gold_capacity, plur(gold_capacity)); 998. u.ugold += gold_capacity; 999. obj->quan -= gold_capacity; 1000. costly_gold(obj->ox, obj->oy, gold_capacity); 1001. } else { 1002. u.ugold += count; 1003. if ((nearload = near_capacity()) != 0) 1004. pline("%s %ld gold piece%s.", 1005. nearload < MOD_ENCUMBER ? 1006. moderateloadmsg : nearloadmsg, 1007. count, plur(count)); 1008. else 1009. prinv((char *) 0, obj, count); 1010. costly_gold(obj->ox, obj->oy, count); 1011. if (count == obj->quan) 1012. delobj(obj); 1013. else 1014. obj->quan -= count; 1015. } 1016. flags.botl = 1; 1017. if (flags.run) nomul(0); 1018. return 1; 1019. } else if (obj->otyp == CORPSE) { 1020. if (obj->corpsenm == PM_COCKATRICE && !uarmg 1021. && !resists_ston(&youmonst) && !telekinesis) { 1022. if (poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM)) 1023. display_nhwindow(WIN_MESSAGE, FALSE); 1024. else { 1025. pline("Touching the cockatrice corpse is a fatal mistake."); 1026. instapetrify("cockatrice corpse"); 1027. return -1; 1028. } 1029. } else if (is_rider(&mons[obj->corpsenm])) { 1030. pline("At your %s, the corpse suddenly moves...", 1031. telekinesis ? "attempted acquisition" : "touch"); 1032. (void) revive_corpse(obj); 1033. exercise(A_WIS, FALSE); 1034. return -1; 1035. } 1036. } else if (obj->otyp == SCR_SCARE_MONSTER) { 1037. if (obj->blessed) obj->blessed = 0; 1038. else if (!obj->spe && !obj->cursed) obj->spe = 1; 1039. else { 1040. pline_The("scroll%s turn%s to dust as you %s %s up.", 1041. plur(obj->quan), (obj->quan == 1L) ? "s" : "", 1042. telekinesis ? "raise" : "pick", 1043. (obj->quan == 1L) ? "it" : "them"); 1044. if (!(objects[SCR_SCARE_MONSTER].oc_name_known) && 1045. !(objects[SCR_SCARE_MONSTER].oc_uname)) 1046. docall(obj); 1047. useupf(obj); 1048. return 1; /* tried to pick something up and failed, but 1049. don't want to terminate pickup loop yet */ 1050. } 1051. } 1052. 1053. if ((res = lift_object(obj, (struct obj *)0, &count, telekinesis)) <= 0) 1054. return res; 1055. 1056. if (obj->quan != count && obj->otyp != LOADSTONE) 1057. (void) splitobj(obj, count); 1058. 1059. obj = pick_obj(obj); 1060. 1061. if (uwep && uwep == obj) mrg_to_wielded = TRUE; 1062. nearload = near_capacity(); 1063. prinv(nearload == SLT_ENCUMBER ? moderateloadmsg : (char *) 0, obj, count); 1064. mrg_to_wielded = FALSE; 1065. return 1; 1066. } 1067. 1068. /* 1069. * Do the actual work of picking otmp from the floor and putting 1070. * it in the hero's inventory. Take care of billing. Return a 1071. * pointer to the object where otmp ends up. This may be different 1072. * from otmp because of merging. 1073. * 1074. * Gold never reaches this routine. 1075. */ 1076. struct obj * 1077. pick_obj(otmp) 1078. register struct obj *otmp; 1079. { 1080. obj_extract_self(otmp); 1081. if (*u.ushops && costly_spot(u.ux, u.uy) && 1082. otmp != uball) /* don't charge for this - kd, 1/17/90 */ 1083. /* sets obj->unpaid if necessary */ 1084. addtobill(otmp, TRUE, FALSE, FALSE); 1085. if(Invisible) newsym(u.ux,u.uy); 1086. return(addinv(otmp)); /* might merge it with other objects */ 1087. } 1088. 1089. /* 1090. * prints a message if encumbrance changed since the last check and 1091. * returns the new encumbrance value (from near_capacity()). 1092. */ 1093. int 1094. encumber_msg() 1095. { 1096. static int oldcap = UNENCUMBERED; 1097. int newcap = near_capacity(); 1098. 1099. if(oldcap < newcap) { 1100. switch(newcap) { 1101. case 1: Your("movements are slowed slightly because of your load."); 1102. break; 1103. case 2: You("rebalance your load. Movement is difficult."); 1104. break; 1105. case 3: You("stagger under your heavy load. Movement is very hard."); 1106. break; 1107. default: You("%s move a handspan with this load!", 1108. newcap == 4 ? "can barely" : "can't even"); 1109. break; 1110. } 1111. flags.botl = 1; 1112. } else if(oldcap > newcap) { 1113. switch(newcap) { 1114. case 0: Your("movements are now unencumbered."); 1115. break; 1116. case 1: Your("movements are only slowed slightly by your load."); 1117. break; 1118. case 2: You("rebalance your load. Movement is still difficult."); 1119. break; 1120. case 3: You("stagger under your load. Movement is still very hard."); 1121. break; 1122. } 1123. flags.botl = 1; 1124. } 1125. 1126. oldcap = newcap; 1127. return (newcap); 1128. } 1129. 1130. int 1131. doloot() /* loot a container on the floor. */ 1132. { 1133. register struct obj *cobj, *nobj; 1134. register int c = -1; 1135. int timepassed = 0; 1136. 1137. if (check_capacity((char *)0)) { 1138. /* "Can't do that while carrying so much stuff." */ 1139. return 0; 1140. } else if (!can_reach_floor()) { 1141. You("cannot reach the %s.", surface(u.ux, u.uy)); 1142. return(0); 1143. } else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) { 1144. /* at present, can't loot in water even when Underwater */ 1145. You("cannot loot things that are deep in the %s.", 1146. is_lava(u.ux, u.uy) ? "lava" : "water"); 1147. return(0); 1148. } else if (nolimbs(uasmon)) { 1149. pline("Without limbs, you cannot loot anything."); 1150. return(0); 1151. } 1152. 1153. for(cobj = level.objects[u.ux][u.uy]; cobj; cobj = nobj) { 1154. nobj = cobj->nexthere; 1155. 1156. if(Is_container(cobj)) { 1157. char qbuf[QBUFSZ]; 1158. 1159. Sprintf(qbuf, "There is %s here, loot it?", doname(cobj)); 1160. c = ynq(qbuf); 1161. if(c == 'q') return (timepassed); 1162. if(c == 'n') continue; 1163. 1164. if(cobj->olocked) { 1165. pline("Hmmm, it seems to be locked."); 1166. continue; 1167. } 1168. if(cobj->otyp == BAG_OF_TRICKS) { 1169. You("carefully open the bag..."); 1170. pline("It develops a huge set of teeth and bites you!"); 1171. c = rnd(10); 1172. if(Half_physical_damage) c = (c+1) / 2; 1173. losehp(c, "carnivorous bag", KILLED_BY_AN); 1174. makeknown(BAG_OF_TRICKS); 1175. timepassed = 1; 1176. continue; 1177. } 1178. 1179. You("carefully open %s...", the(xname(cobj))); 1180. if (cobj->otrapped && chest_trap(cobj, FINGER, FALSE)) { 1181. timepassed = 1; 1182. continue; /* explosion destroyed cobj */ 1183. } 1184. if(multi < 0) return (1); /* a paralysis trap */ 1185. 1186. timepassed |= use_container(cobj, 0); 1187. } 1188. } 1189. if(c == -1){ 1190. if(Confusion){ 1191. if(u.ugold){ 1192. long contribution = rnd((int)min(LARGEST_INT,u.ugold)); 1193. struct obj *goldob = mkgoldobj(contribution); 1194. if(IS_THRONE(levl[u.ux][u.uy].typ)){ 1195. struct obj *coffers; 1196. int pass; 1197. /* find the original coffers chest, or any chest */ 1198. for(pass = 2; pass > -1; pass -= 2) 1199. for(coffers=fobj; coffers; coffers=coffers->nobj) 1200. if(coffers->otyp==CHEST && coffers->spe ==pass) 1201. goto gotit; /* two level break */ 1202. gotit: 1203. if(coffers){ 1204. struct obj *tmp; 1205. verbalize("Thank you for your contribution to reduce the debt."); 1206. for (tmp = coffers->cobj; tmp; tmp = tmp->nobj) 1207. if (tmp->otyp == goldob->otyp) break; 1208. 1209. if (tmp) { 1210. tmp->quan += goldob->quan; 1211. delobj(goldob); 1212. } else { 1213. add_to_container(coffers, goldob); 1214. } 1215. } else { 1216. struct monst *mon = makemon(courtmon(), u.ux, u.uy); 1217. if (mon) { 1218. mon->mgold += goldob->quan; 1219. delobj(goldob); 1220. pline( 1221. "The exchequer accepts your contribution."); 1222. } else { 1223. dropx(goldob); 1224. } 1225. } 1226. } else { 1227. dropx(goldob); 1228. pline("Ok, now there is loot here."); 1229. } 1230. } 1231. } else { 1232. You("don't find anything here to loot."); 1233. } 1234. } 1235. return (timepassed); 1236. } 1237. 1238. /* 1239. * Decide whether an object being placed into a magic bag will cause 1240. * it to explode. If the object is a bag itself, check recursively. 1241. */ 1242. static boolean 1243. mbag_explodes(obj, depthin) 1244. struct obj *obj; 1245. int depthin; 1246. { 1247. /* odds: 1/1, 2/2, 3/4, 4/8, 5/16, 6/32, 7/64, 8/128, 9/128, 10/128,... */ 1248. if ((Is_mbag(obj) || (obj->otyp == WAN_CANCELLATION && obj->spe > 0)) && 1249. (rn2(1 << (depthin > 7 ? 7 : depthin)) <= depthin)) 1250. return TRUE; 1251. else if (Has_contents(obj)) { 1252. struct obj *otmp; 1253. 1254. for (otmp = obj->cobj; otmp; otmp = otmp->nobj) 1255. if (mbag_explodes(otmp, depthin+1)) return TRUE; 1256. } 1257. return FALSE; 1258. } 1259. 1260. /* A variable set in use_container(), to be used by the callback routines */ 1261. /* in_container(), and out_container() from askchain() and use_container(). */ 1262. static NEARDATA struct obj *current_container; 1263. #define Icebox (current_container->otyp == ICE_BOX) 1264. 1265. /* Returns: -1 to stop, 1 item was inserted, 0 item was not inserted. */ 1266. STATIC_PTR int 1267. in_container(obj) 1268. register struct obj *obj; 1269. { 1270. register struct obj *gold; 1271. boolean is_gold = (obj->oclass == GOLD_CLASS); 1272. boolean floor_container = !carried(current_container); 1273. char buf[BUFSZ]; 1274. 1275. if (!current_container) { 1276. impossible(" no current_container?"); 1277. return 0; 1278. } else if (obj == uball || obj == uchain) { 1279. You("must be kidding."); 1280. return 0; 1281. } else if (obj == current_container) { 1282. pline("That would be an interesting topological exercise."); 1283. return 0; 1284. } else if (obj->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) { 1285. Norep("You cannot %s %s you are wearing.", 1286. Icebox ? "refrigerate" : "stash", something); 1287. return 0; 1288. } else if ((obj->otyp == LOADSTONE) && obj->cursed) { 1289. obj->bknown = 1; 1290. pline_The("stone%s won't leave your person.", plur(obj->quan)); 1291. return 0; 1292. } else if (obj->otyp == AMULET_OF_YENDOR || 1293. obj->otyp == CANDELABRUM_OF_INVOCATION || 1294. obj->otyp == BELL_OF_OPENING || 1295. obj->otyp == SPE_BOOK_OF_THE_DEAD) { 1296. /* Prohibit Amulets in containers; if you allow it, monsters can't 1297. * steal them. It also becomes a pain to check to see if someone 1298. * has the Amulet. Ditto for the Candelabrum, the Bell and the Book. 1299. */ 1300. pline("%s cannot be confined in such trappings.", The(xname(obj))); 1301. return 0; 1302. } else if (obj->otyp == LEASH && obj->leashmon != 0) { 1303. pline("%s is attached to your pet.", The(xname(obj))); 1304. return 0; 1305. } else if (obj == uwep) { 1306. if (welded(obj)) { 1307. weldmsg(obj, FALSE); 1308. return 0; 1309. } 1310. setuwep((struct obj *) 0); 1311. if (uwep) return 0; /* unwielded, died, rewielded */ 1312. } 1313. 1314. /* boxes can't fit into any container */ 1315. if (obj->otyp == ICE_BOX || Is_box(obj)) { 1316. /* 1317. * xname() uses a static result array. Save obj's name 1318. * before current_container's name is computed. Don't 1319. * use the result of strcpy() within You() --- the order 1320. * of evaluation of the parameters is undefined. 1321. */ 1322. Strcpy(buf, the(xname(obj))); 1323. You("cannot fit %s into %s.", buf, 1324. the(xname(current_container))); 1325. return 0; 1326. } 1327. 1328. freeinv(obj); 1329. 1330. if (is_gold) { /* look for other money to merge within the container */ 1331. for (gold = current_container->cobj; gold; gold = gold->nobj) 1332. if (gold->otyp == obj->otyp) break; 1333. } else 1334. gold = 0; 1335. 1336. if (gold) { 1337. gold->quan += obj->quan; 1338. } else { 1339. add_to_container(current_container, obj); 1340. } 1341. 1342. current_container->owt = weight(current_container); 1343. 1344. Strcpy(buf, the(xname(current_container))); 1345. You("put %s into %s.", doname(obj), buf); 1346. 1347. if (obj_is_burning(obj)) /* this used to be part of freeinv() */ 1348. (void) snuff_lit(obj); 1349. 1350. if (floor_container && costly_spot(u.ux, u.uy)) { 1351. sellobj_state(TRUE); 1352. sellobj(obj, u.ux, u.uy); 1353. sellobj_state(FALSE); 1354. } 1355. if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN 1356. && !Is_candle(obj)) { 1357. obj->age = monstermoves - obj->age; /* actual age */ 1358. /* stop any corpse timeouts when frozen */ 1359. if (obj->otyp == CORPSE && obj->timed) { 1360. (void) stop_timer(ROT_CORPSE, (genericptr_t)obj); 1361. (void) stop_timer(REVIVE_MON, (genericptr_t)obj); 1362. } 1363. } 1364. 1365. else if (Is_mbag(current_container) && mbag_explodes(obj, 0)) { 1366. You("are blasted by a magical explosion!"); 1367. 1368. /* the !floor_container case is taken care of */ 1369. if(*u.ushops && costly_spot(u.ux, u.uy) && floor_container) { 1370. register struct monst *shkp; 1371. 1372. if ((shkp = shop_keeper(*u.ushops)) != 0) 1373. (void)stolen_value(current_container, u.ux, u.uy, 1374. (boolean)shkp->mpeaceful, FALSE); 1375. } 1376. delete_contents(current_container); 1377. if (!floor_container) 1378. useup(current_container); 1379. else if (obj_here(current_container, u.ux, u.uy)) 1380. useupf(current_container); 1381. else 1382. panic("in_container: bag not found."); 1383. 1384. losehp(d(6,6),"magical explosion", KILLED_BY_AN); 1385. current_container = 0; /* baggone = TRUE; */ 1386. } 1387. 1388. if (is_gold) { 1389. if (gold) dealloc_obj(obj); 1390. bot(); /* update character's gold piece count immediately */ 1391. } 1392. 1393. return(current_container ? 1 : -1); 1394. } 1395. 1396. STATIC_PTR int 1397. ck_bag(obj) 1398. struct obj *obj; 1399. { 1400. return current_container && obj != current_container; 1401. } 1402. 1403. /* Returns: -1 to stop, 1 item was removed, 0 item was not removed. */ 1404. STATIC_PTR int 1405. out_container(obj) 1406. register struct obj *obj; 1407. { 1408. register struct obj *otmp; 1409. boolean is_gold = (obj->oclass == GOLD_CLASS); 1410. int res, loadlev; 1411. long count; 1412. 1413. if (!current_container) { 1414. impossible(" no current_container?"); 1415. return -1; 1416. } else if (is_gold) { 1417. obj->owt = weight(obj); 1418. } 1419. 1420. if(obj->oartifact && !touch_artifact(obj,&youmonst)) return 0; 1421. 1422. count = obj->quan; 1423. if ((res = lift_object(obj, current_container, &count, FALSE)) <= 0) 1424. return res; 1425. 1426. if (obj->quan != count && obj->otyp != LOADSTONE) 1427. (void) splitobj(obj, count); 1428. 1429. /* Remove the object from the list. */ 1430. obj_extract_self(obj); 1431. current_container->owt = weight(current_container); 1432. 1433. if (Icebox && obj->otyp != OIL_LAMP && obj->otyp != BRASS_LANTERN 1434. && !Is_candle(obj)) { 1435. obj->age = monstermoves - obj->age; /* actual age */ 1436. if (obj->otyp == CORPSE) 1437. start_corpse_timeout(obj); 1438. } 1439. /* simulated point of time */ 1440. 1441. if(!obj->unpaid && !carried(current_container) && 1442. costly_spot(current_container->ox, current_container->oy)) { 1443. 1444. obj->ox = current_container->ox; 1445. obj->oy = current_container->oy; 1446. addtobill(obj, FALSE, FALSE, FALSE); 1447. } 1448. 1449. otmp = addinv(obj); 1450. loadlev = near_capacity(); 1451. prinv(loadlev ? 1452. (loadlev < MOD_ENCUMBER ? 1453. "You have a little trouble removing" : 1454. "You have much trouble removing") : (char *)0, 1455. otmp, count); 1456. 1457. if (is_gold) { 1458. dealloc_obj(obj); 1459. bot(); /* update character's gold piece count immediately */ 1460. } 1461. return 1; 1462. } 1463. 1464. #undef Icebox 1465. 1466. int 1467. use_container(obj, held) 1468. register struct obj *obj; 1469. register int held; 1470. { 1471. struct obj *curr, *otmp, *u_gold = (struct obj *)0; 1472. struct monst *shkp; 1473. boolean one_by_one, allflag, loot_out = FALSE, loot_in = FALSE; 1474. char select[MAXOCLASSES+1]; 1475. char buf[BUFSZ], qbuf[QBUFSZ]; 1476. long loss = 0L; 1477. int cnt = 0, used = 0, lcnt = 0, 1478. menu_on_request; 1479. 1480. current_container = obj; /* for use by in/out_container */ 1481. if (obj->olocked) { 1482. pline("%s seems to be locked.", The(xname(obj))); 1483. if (held) You("must put it down to unlock."); 1484. return 0; 1485. } 1486. if (obj->spe == 1) { 1487. static NEARDATA const char sc[] = "Schroedinger's Cat"; 1488. struct obj *ocat; 1489. struct monst *cat; 1490. 1491. obj->spe = 0; /* obj->owt will be updated below */ 1492. /* this isn't really right, since any form of observation 1493. (telepathic or monster/object/food detection) ought to 1494. force the determination of alive vs dead state; but basing 1495. it just on opening the box is much simpler to cope with */ 1496. cat = rn2(2) ? makemon(&mons[PM_HOUSECAT], obj->ox, obj->oy) : 0; 1497. if (cat) { 1498. cat->mpeaceful = 1; 1499. set_malign(cat); 1500. if (Blind) 1501. You("think %s brushed your %s.", something, 1502. body_part(FOOT)); 1503. else 1504. pline("%s inside the box is still alive!", Monnam(cat)); 1505. (void) christen_monst(cat, sc); 1506. } else { 1507. ocat = mk_named_object(CORPSE, &mons[PM_HOUSECAT], 1508. obj->ox, obj->oy, sc); 1509. if (ocat) { 1510. obj_extract_self(ocat); 1511. add_to_container(obj, ocat); /* weight handled below */ 1512. } 1513. pline_The("%s inside the box is dead!", 1514. Hallucination ? rndmonnam() : "housecat"); 1515. } 1516. used = 1; 1517. } 1518. /* Count the number of contained objects. Sometimes toss objects if */ 1519. /* a cursed magic bag. */ 1520. for (curr = obj->cobj; curr; curr = otmp) { 1521. otmp = curr->nobj; 1522. if (Is_mbag(obj) && obj->cursed && !rn2(13)) { 1523. if (curr->dknown) 1524. pline("%s to have vanished!", The(aobjnam(curr,"seem"))); 1525. else 1526. You("%s %s disappear.", Blind ? "notice" : "see", 1527. doname(curr)); 1528. obj_extract_self(curr); 1529. if (*u.ushops && (shkp = shop_keeper(*u.ushops)) != 0) { 1530. if(held) { 1531. if(curr->unpaid) 1532. loss += stolen_value(curr, u.ux, u.uy, 1533. (boolean)shkp->mpeaceful, TRUE); 1534. lcnt++; 1535. } else if(costly_spot(u.ux, u.uy)) { 1536. loss += stolen_value(curr, u.ux, u.uy, 1537. (boolean)shkp->mpeaceful, TRUE); 1538. lcnt++; 1539. } 1540. } 1541. /* obfree() will free all contained objects */ 1542. obfree(curr, (struct obj *) 0); 1543. used = 1; 1544. } else { 1545. cnt++; 1546. } 1547. } 1548. 1549. if (cnt && loss) 1550. You("owe %ld zorkmids for lost item%s.", 1551. loss, lcnt > 1 ? "s" : ""); 1552. 1553. obj->owt = weight(obj); 1554. 1555. if (!cnt) { 1556. pline("%s %s is empty.", Shk_Your(buf, obj), xname(obj)); 1557. } else { 1558. Sprintf(qbuf, "Do you want to take %s out of %s %s?", 1559. something, shk_your(buf, obj), xname(obj)); 1560. if (flags.menu_style != MENU_TRADITIONAL) { 1561. if (flags.menu_style == MENU_FULL) { 1562. int t = in_or_out_menu("Do what?", current_container); 1563. if (t <= 0) return 0; 1564. loot_out = (t & 0x01) != 0; 1565. loot_in = (t & 0x02) != 0; 1566. } else { /* MENU_COMBINATION or MENU_PARTIAL */ 1567. loot_out = (yn_function(qbuf, "ynq", 'n') == 'y'); 1568. } 1569. if (loot_out) { 1570. add_valid_menu_class(0); /* reset */ 1571. used |= menu_loot(0, current_container, FALSE) > 0; 1572. } 1573. } else { 1574. /* traditional code */ 1575. ask_again2: 1576. menu_on_request = 0; 1577. add_valid_menu_class(0); /* reset */ 1578. switch (yn_function(qbuf, ":ynq", 'n')) { 1579. case ':': 1580. container_contents(current_container, FALSE, FALSE); 1581. goto ask_again2; 1582. case 'y': 1583. if (query_classes(select, &one_by_one, &allflag, "take out", 1584. current_container->cobj, 1585. FALSE, FALSE, &menu_on_request)) { 1586. if (askchain((struct obj **)¤t_container->cobj, 1587. (one_by_one ? (char *)0 : select), allflag, 1588. out_container, (int (*)())0, 0, "nodot")) 1589. used = 1; 1590. } else if (menu_on_request < 0) { 1591. used |= menu_loot(menu_on_request, 1592. current_container, FALSE) > 0; 1593. } 1594. /*FALLTHRU*/ 1595. case 'n': 1596. break; 1597. case 'q': 1598. default: 1599. return used; 1600. } 1601. } 1602. } 1603. 1604. if (!invent && u.ugold == 0) { 1605. /* nothing to put in, but some feedback is necessary */ 1606. You("don't have anything to put in."); 1607. return used; 1608. } 1609. if (flags.menu_style != MENU_FULL || !cnt) { 1610. loot_in = (yn_function("Do you wish to put something in?", 1611. ynqchars, 'n') == 'y'); 1612. } 1613. /* 1614. * Gone: being nice about only selecting food if we know we are 1615. * putting things in an ice chest. 1616. */ 1617. if (loot_in) { 1618. if (u.ugold) { 1619. /* 1620. * Hack: gold is not in the inventory, so make a gold object 1621. * and put it at the head of the inventory list. 1622. */ 1623. u_gold = mkgoldobj(u.ugold); /* removes from u.ugold */ 1624. u.ugold = u_gold->quan; /* put the gold back */ 1625. assigninvlet(u_gold); /* might end up as NOINVSYM */ 1626. u_gold->nobj = invent; 1627. invent = u_gold; 1628. } 1629. add_valid_menu_class(0); /* reset */ 1630. if (flags.menu_style != MENU_TRADITIONAL) { 1631. used |= menu_loot(0, current_container, TRUE) > 0; 1632. } else { 1633. /* traditional code */ 1634. menu_on_request = 0; 1635. if (query_classes(select, &one_by_one, &allflag, "put in", 1636. invent, FALSE, (u.ugold != 0L), 1637. &menu_on_request)) { 1638. (void) askchain((struct obj **)&invent, 1639. (one_by_one ? (char *)0 : select), allflag, 1640. in_container, ck_bag, 0, "nodot"); 1641. used = 1; 1642. } else if (menu_on_request < 0) { 1643. used |= menu_loot(menu_on_request, 1644. current_container, TRUE) > 0; 1645. } 1646. } 1647. } 1648. 1649. if (u_gold && invent && invent->oclass == GOLD_CLASS) { 1650. /* didn't stash [all of] it */ 1651. u_gold = invent; 1652. invent = u_gold->nobj; 1653. dealloc_obj(u_gold); 1654. } 1655. 1656. return used; 1657. } 1658. 1659. /* Loot a container (take things out, put things in), using a menu. */ 1660. static int 1661. menu_loot(retry, container, put_in) 1662. int retry; 1663. struct obj *container; 1664. boolean put_in; 1665. { 1666. int n, i, n_looted = 0; 1667. boolean all_categories = TRUE, loot_everything = FALSE; 1668. char buf[BUFSZ]; 1669. const char *takeout = "Take out", *putin = "Put in"; 1670. menu_item *pick_list; 1671. int mflags, res; 1672. 1673. if (retry) { 1674. all_categories = (retry == -2); 1675. } else if (flags.menu_style == MENU_FULL) { 1676. all_categories = FALSE; 1677. Sprintf(buf,"%s what type of objects?", put_in ? putin : takeout); 1678. mflags = put_in ? ALL_TYPES : ALL_TYPES|CHOOSE_ALL; 1679. n = query_category(buf, put_in ? invent : container->cobj, 1680. mflags, &pick_list, PICK_ANY); 1681. if (!n) return 0; 1682. for (i = 0; i < n; i++) { 1683. if (pick_list[i].item.a_int == 'A') 1684. loot_everything = TRUE; 1685. else if (pick_list[i].item.a_int == ALL_TYPES_SELECTED) 1686. all_categories = TRUE; 1687. else 1688. add_valid_menu_class(pick_list[i].item.a_int); 1689. } 1690. free((genericptr_t) pick_list); 1691. } 1692. 1693. if (loot_everything) { 1694. struct obj *otmp, *otmp2; 1695. 1696. for (otmp = container->cobj; otmp; otmp = otmp2) { 1697. otmp2 = otmp->nobj; 1698. res = out_container(otmp); 1699. if (res < 0) break; 1700. } 1701. } else { 1702. mflags = INVORDER_SORT; 1703. if (put_in && flags.invlet_constant) mflags |= USE_INVLET; 1704. Sprintf(buf,"%s what?", put_in ? putin : takeout); 1705. n = query_objlist(buf, put_in ? invent : container->cobj, 1706. mflags, &pick_list, PICK_ANY, 1707. all_categories ? allow_all : allow_category); 1708. if (n) { 1709. n_looted = n; 1710. for (i = 0; i < n; i++) { 1711. if (pick_list[i].item.a_obj->quan != pick_list[i].count) { 1712. (void) splitobj(pick_list[i].item.a_obj, 1713. pick_list[i].count); 1714. } 1715. res = put_in ? in_container(pick_list[i].item.a_obj) : 1716. out_container(pick_list[i].item.a_obj); 1717. if (res < 0) 1718. break; 1719. } 1720. free((genericptr_t)pick_list); 1721. } 1722. } 1723. return n_looted; 1724. } 1725. 1726. static int 1727. in_or_out_menu(prompt, obj) 1728. const char *prompt; 1729. struct obj *obj; 1730. { 1731. winid win; 1732. anything any; 1733. menu_item *pick_list; 1734. char buf[BUFSZ]; 1735. int n; 1736. 1737. any.a_void = 0; 1738. win = create_nhwindow(NHW_MENU); 1739. start_menu(win); 1740. any.a_int = 1; 1741. Sprintf(buf,"Take something out of %s", the(xname(obj))); 1742. add_menu(win, NO_GLYPH, &any, 'a', ATR_NONE, buf, MENU_UNSELECTED); 1743. any.a_int = 2; 1744. Sprintf(buf,"Put something into %s",the(xname(obj))); 1745. add_menu(win, NO_GLYPH, &any, 'b', ATR_NONE, buf, MENU_UNSELECTED); 1746. any.a_int = 3; 1747. add_menu(win, NO_GLYPH, &any, 'c', ATR_NONE, 1748. "Both of the above", MENU_UNSELECTED); 1749. end_menu(win, prompt); 1750. n = select_menu(win, PICK_ONE, &pick_list); 1751. destroy_nhwindow(win); 1752. if (n > 0) { 1753. n = pick_list[0].item.a_int; 1754. free((genericptr_t) pick_list); 1755. } 1756. return n; 1757. } 1758. 1759. /*pickup.c*/
|