| 495 | | static bool auto_pickup_okay(const object_type *o_ptr, bool check_pack) |
|---|
| 496 | | { |
|---|
| 497 | | const char *inscrip = (o_ptr->note ? quark_str(o_ptr->note) : NULL); |
|---|
| 498 | | const char *s; |
|---|
| 499 | | |
|---|
| 500 | | /*** Negative checks ***/ |
|---|
| 501 | | |
|---|
| 502 | | /* It can't be carried */ |
|---|
| 503 | | if (!inven_carry_okay(o_ptr)) return (FALSE); |
|---|
| 504 | | |
|---|
| 505 | | /* Ignore squelched items */ |
|---|
| 506 | | if (inscrip && streq(inscrip, "squelch")) return (FALSE); |
|---|
| 507 | | |
|---|
| 508 | | |
|---|
| 509 | | |
|---|
| 510 | | /*** Positive checks ***/ |
|---|
| 511 | | |
|---|
| 512 | | /* Pickup if it matches the inventory */ |
|---|
| 513 | | if (pickup_inven && inven_stack_okay(o_ptr)) return (TRUE); |
|---|
| 514 | | |
|---|
| 515 | | /* Option to vacuum up things on the floor (not recommended) */ |
|---|
| 516 | | if (always_pickup && !query_floor) return (TRUE); |
|---|
| 517 | | |
|---|
| 518 | | /* Check inscription */ |
|---|
| 519 | | if (o_ptr->note) |
|---|
| 520 | | { |
|---|
| 521 | | /* Find a '=' */ |
|---|
| 522 | | s = strchr(quark_str(o_ptr->note), '='); |
|---|
| 523 | | |
|---|
| 524 | | /* Process permissions */ |
|---|
| 525 | | while (s) |
|---|
| 526 | | { |
|---|
| 527 | | /* =g ('g'et) means auto pickup */ |
|---|
| 528 | | if (s[1] == 'g') return (TRUE); |
|---|
| 529 | | |
|---|
| 530 | | /* Find another '=' */ |
|---|
| 531 | | s = strchr(s + 1, '='); |
|---|
| 532 | | } |
|---|
| 533 | | } |
|---|
| 534 | | |
|---|
| 535 | | /* Don't auto pickup */ |
|---|
| 536 | | return (FALSE); |
|---|
| 537 | | } |
|---|
| 538 | | |
|---|
| 539 | | |
|---|
| 540 | | /* |
|---|
| 541 | | * Carry an object and delete it. |
|---|
| 542 | | */ |
|---|
| 543 | | static void py_pickup_aux(int o_idx, bool msg) |
|---|
| 544 | | { |
|---|
| 545 | | int slot; |
|---|
| 546 | | |
|---|
| 547 | | char o_name[80]; |
|---|
| 548 | | object_type *o_ptr = &o_list[o_idx]; |
|---|
| 549 | | |
|---|
| 550 | | /* Carry the object */ |
|---|
| 551 | | slot = inven_carry(o_ptr); |
|---|
| 552 | | |
|---|
| 553 | | /* Handle errors (paranoia) */ |
|---|
| 554 | | if (slot < 0) return; |
|---|
| 555 | | |
|---|
| 556 | | /* Get the new object */ |
|---|
| 557 | | o_ptr = &inventory[slot]; |
|---|
| 558 | | |
|---|
| 559 | | /* Set squelch status */ |
|---|
| 560 | | squelch_set(o_ptr); |
|---|
| 561 | | |
|---|
| 562 | | /* Optionally, display a message */ |
|---|
| 563 | | if (msg) |
|---|
| 564 | | { |
|---|
| 565 | | /* Describe the object */ |
|---|
| 566 | | object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); |
|---|
| 567 | | |
|---|
| 568 | | /* Message */ |
|---|
| 569 | | msg_format("You have %s (%c).", o_name, index_to_label(slot)); |
|---|
| 570 | | } |
|---|
| 571 | | |
|---|
| 572 | | /* Delete the object */ |
|---|
| 573 | | delete_object_idx(o_idx); |
|---|
| 574 | | } |
|---|
| 575 | | |
|---|
| 576 | | |
|---|
| 577 | | /* |
|---|
| 578 | | * Pick up objects and treasure on the floor. -LM- |
|---|
| 579 | | * |
|---|
| 580 | | * Called with pickup: |
|---|
| 581 | | * 0 to grab gold, auto-pickup some objects, and describe others objects. |
|---|
| 582 | | * 1 to pick up objects either with or without displaying a menu. |
|---|
| 583 | | * 2 to pick up objects, allowing cancel and quick pickup of single objects. |
|---|
| 584 | | * 3 to pick up objects, forcing a menu for any number of objects. |
|---|
| 585 | | * |
|---|
| 586 | | * Scan the list of objects in that floor grid. Pick up gold automatically. |
|---|
| 587 | | * Pick up objects automatically until pile or backpack space is full if |
|---|
| 588 | | * auto-pickup option is on, carry_query_floor option is not, and menus are |
|---|
| 589 | | * not forced (which the "get" command does). Otherwise, store objects on |
|---|
| 590 | | * floor in an array, and tally both how many there are and can be picked up. |
|---|
| 591 | | * |
|---|
| 592 | | * If not picking up anything, indicate objects on the floor. Show more |
|---|
| 593 | | * details if the "query_floor" option is set. Do the same thing if we |
|---|
| 594 | | * don't have room for anything. |
|---|
| 595 | | * |
|---|
| 596 | | * If we are picking up objects automatically, and have room for at least |
|---|
| 597 | | * one, allow the "query_floor" option to display information about objects |
|---|
| 598 | | * and prompt the player. Otherwise, automatically pick up a single object |
|---|
| 599 | | * or use a menu for more than one (this "blind" autopickup option is |
|---|
| 600 | | * deprecated). |
|---|
| 601 | | * |
|---|
| 602 | | * Pick up multiple objects using Tim Baker's menu system. Recursively |
|---|
| 603 | | * call this function (forcing menus for any number of objects) until |
|---|
| 604 | | * objects are gone, backpack is full, or player is satisfied. |
|---|
| 605 | | * |
|---|
| 606 | | * We keep track of number of objects picked up to calculate time spent. |
|---|
| 607 | | * This tally is incremented even for automatic pickup, so we are careful |
|---|
| 608 | | * (in "dungeon.c" and elsewhere) to handle pickup as either a separate |
|---|
| 609 | | * automated move or a no-cost part of the stay still or 'g'et command. |
|---|
| 610 | | * |
|---|
| 611 | | * Note the lack of chance for the character to be disturbed by unmarked |
|---|
| 612 | | * objects. They are truly "unknown". |
|---|
| 613 | | */ |
|---|
| 614 | | byte py_pickup(int pickup) |
|---|
| | 495 | static bool py_pickup_gold(void) |
|---|
| | 629 | } |
|---|
| | 630 | |
|---|
| | 631 | |
|---|
| | 632 | |
|---|
| | 633 | /* |
|---|
| | 634 | * Determine if the object can be picked up automatically. |
|---|
| | 635 | */ |
|---|
| | 636 | static bool auto_pickup_okay(const object_type *o_ptr) |
|---|
| | 637 | { |
|---|
| | 638 | const char *s; |
|---|
| | 639 | |
|---|
| | 640 | /*** Negative checks ***/ |
|---|
| | 641 | |
|---|
| | 642 | /* It can't be carried */ |
|---|
| | 643 | if (!inven_carry_okay(o_ptr)) return (FALSE); |
|---|
| | 644 | |
|---|
| | 645 | |
|---|
| | 646 | /*** Positive checks ***/ |
|---|
| | 647 | |
|---|
| | 648 | /* Pickup if it matches the inventory */ |
|---|
| | 649 | if (pickup_inven && inven_stack_okay(o_ptr)) return (TRUE); |
|---|
| | 650 | |
|---|
| | 651 | /* Vacuum up everything if requested */ |
|---|
| | 652 | if (pickup_always) return (TRUE); |
|---|
| | 653 | |
|---|
| | 654 | /* Check inscription */ |
|---|
| | 655 | if (o_ptr->note) |
|---|
| | 656 | { |
|---|
| | 657 | /* Find a '=' */ |
|---|
| | 658 | s = strchr(quark_str(o_ptr->note), '='); |
|---|
| | 659 | |
|---|
| | 660 | /* Process permissions */ |
|---|
| | 661 | while (s) |
|---|
| | 662 | { |
|---|
| | 663 | /* =g ('g'et) means auto pickup */ |
|---|
| | 664 | if (s[1] == 'g') return (TRUE); |
|---|
| | 665 | |
|---|
| | 666 | /* Find another '=' */ |
|---|
| | 667 | s = strchr(s + 1, '='); |
|---|
| | 668 | } |
|---|
| | 669 | } |
|---|
| | 670 | |
|---|
| | 671 | /* Don't auto pickup */ |
|---|
| | 672 | return (FALSE); |
|---|
| | 673 | } |
|---|
| | 674 | |
|---|
| | 675 | |
|---|
| | 676 | /* |
|---|
| | 677 | * Carry an object and delete it. |
|---|
| | 678 | */ |
|---|
| | 679 | static void py_pickup_aux(int o_idx, bool msg) |
|---|
| | 680 | { |
|---|
| | 681 | int slot; |
|---|
| | 682 | |
|---|
| | 683 | char o_name[80]; |
|---|
| | 684 | object_type *o_ptr = &o_list[o_idx]; |
|---|
| | 685 | |
|---|
| | 686 | /* Carry the object */ |
|---|
| | 687 | slot = inven_carry(o_ptr); |
|---|
| | 688 | |
|---|
| | 689 | /* Handle errors (paranoia) */ |
|---|
| | 690 | if (slot < 0) return; |
|---|
| | 691 | |
|---|
| | 692 | /* Get the new object */ |
|---|
| | 693 | o_ptr = &inventory[slot]; |
|---|
| | 694 | |
|---|
| | 695 | /* Set squelch status */ |
|---|
| | 696 | squelch_set(o_ptr); |
|---|
| | 697 | |
|---|
| | 698 | /* Optionally, display a message */ |
|---|
| | 699 | if (msg) |
|---|
| | 700 | { |
|---|
| | 701 | /* Describe the object */ |
|---|
| | 702 | object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); |
|---|
| | 703 | |
|---|
| | 704 | /* Message */ |
|---|
| | 705 | msg_format("You have %s (%c).", o_name, index_to_label(slot)); |
|---|
| | 706 | } |
|---|
| | 707 | |
|---|
| | 708 | /* Delete the object */ |
|---|
| | 709 | delete_object_idx(o_idx); |
|---|
| | 710 | } |
|---|
| | 711 | |
|---|
| | 712 | |
|---|
| | 713 | /* |
|---|
| | 714 | * Pick up objects and treasure on the floor. -LM- |
|---|
| | 715 | * |
|---|
| | 716 | * Called with pickup: |
|---|
| | 717 | * 0 to act according to the player's settings |
|---|
| | 718 | * 1 to quickly pickup single objects and present a menu for more |
|---|
| | 719 | * 2 to force a menu for any number of objects |
|---|
| | 720 | * |
|---|
| | 721 | * Scan the list of objects in that floor grid. Pick up gold automatically. |
|---|
| | 722 | * Pick up objects automatically until pile or backpack space is full if |
|---|
| | 723 | * auto-pickup option is on, carry_query_floor option is not, and menus are |
|---|
| | 724 | * not forced (which the "get" command does). Otherwise, store objects on |
|---|
| | 725 | * floor in an array, and tally both how many there are and can be picked up. |
|---|
| | 726 | * |
|---|
| | 727 | * If not picking up anything, indicate objects on the floor. Show more |
|---|
| | 728 | * details if the "pickup_detail" option is set. Do the same thing if we |
|---|
| | 729 | * don't have room for anything. |
|---|
| | 730 | * |
|---|
| | 731 | * If we are picking up objects automatically, and have room for at least |
|---|
| | 732 | * one, allow the "pickup_detail" option to display information about objects |
|---|
| | 733 | * and prompt the player. Otherwise, automatically pick up a single object |
|---|
| | 734 | * or use a menu for more than one. |
|---|
| | 735 | * |
|---|
| | 736 | * Pick up multiple objects using Tim Baker's menu system. Recursively |
|---|
| | 737 | * call this function (forcing menus for any number of objects) until |
|---|
| | 738 | * objects are gone, backpack is full, or player is satisfied. |
|---|
| | 739 | * |
|---|
| | 740 | * We keep track of number of objects picked up to calculate time spent. |
|---|
| | 741 | * This tally is incremented even for automatic pickup, so we are careful |
|---|
| | 742 | * (in "dungeon.c" and elsewhere) to handle pickup as either a separate |
|---|
| | 743 | * automated move or a no-cost part of the stay still or 'g'et command. |
|---|
| | 744 | * |
|---|
| | 745 | * Note the lack of chance for the character to be disturbed by unmarked |
|---|
| | 746 | * objects. They are truly "unknown". |
|---|
| | 747 | */ |
|---|
| | 748 | byte py_pickup(int pickup) |
|---|
| | 749 | { |
|---|
| | 750 | int py = p_ptr->py; |
|---|
| | 751 | int px = p_ptr->px; |
|---|
| | 752 | |
|---|
| | 753 | char o_name[80]; |
|---|
| | 754 | char ch; |
|---|
| | 755 | |
|---|
| | 756 | s16b this_o_idx, next_o_idx = 0; |
|---|
| | 757 | |
|---|
| | 758 | object_type *o_ptr; |
|---|
| | 759 | |
|---|
| | 760 | /* Objects picked up. Used to determine time cost of command. */ |
|---|
| | 761 | byte objs_picked_up = 0; |
|---|
| | 762 | |
|---|
| | 763 | int floor_num = 0, floor_list[MAX_FLOOR_STACK + 1], floor_o_idx = 0; |
|---|
| | 764 | |
|---|
| | 765 | int can_pickup = 0; |
|---|
| | 766 | bool call_function_again = FALSE; |
|---|
| | 767 | int sound_msg; |
|---|
| | 768 | |
|---|
| | 769 | bool blind = ((p_ptr->timed[TMD_BLIND]) || (no_lite())); |
|---|
| | 770 | bool msg = TRUE; |
|---|
| | 771 | |
|---|
| | 772 | |
|---|
| | 773 | /* Nothing to pick up -- return */ |
|---|
| | 774 | if (!cave_o_idx[py][px]) return (0); |
|---|
| | 775 | |
|---|
| | 776 | |
|---|
| | 777 | /* Always pickup gold, effortlessly */ |
|---|
| | 778 | py_pickup_gold(); |
|---|
| 817 | | if (!pickup) |
|---|
| 818 | | { |
|---|
| 819 | | /* Optionally, display more information about floor items */ |
|---|
| 820 | | if ((query_floor) && (floor_num > 1)) |
|---|
| 821 | | { |
|---|
| 822 | | /* Scan all marked objects in the grid */ |
|---|
| 823 | | (void)scan_floor(floor_list, &floor_num, py, px, 0x03); |
|---|
| 824 | | |
|---|
| 825 | | /* Save screen */ |
|---|
| 826 | | screen_save(); |
|---|
| 827 | | |
|---|
| 828 | | /* Display objects on the floor */ |
|---|
| 829 | | show_floor(floor_list, floor_num, FALSE); |
|---|
| 830 | | |
|---|
| 831 | | /* Display prompt */ |
|---|
| 832 | | prt(format("You %s: ", |
|---|
| 833 | | (blind ? "feel something on the floor" : "see")), 0, 0); |
|---|
| 834 | | |
|---|
| 835 | | /* Move cursor back to character, if needed */ |
|---|
| 836 | | if (hilite_player) move_cursor_relative(p_ptr->py, p_ptr->px); |
|---|
| 837 | | |
|---|
| 838 | | /* Wait for it. Use key as next command. */ |
|---|
| 839 | | p_ptr->command_new = inkey(); |
|---|
| 840 | | |
|---|
| 841 | | /* Restore screen */ |
|---|
| 842 | | screen_load(); |
|---|
| 843 | | } |
|---|
| 844 | | |
|---|
| 845 | | /* Display compact information */ |
|---|
| 846 | | else |
|---|
| 847 | | { |
|---|
| 848 | | /* One object */ |
|---|
| 849 | | if (floor_num == 1) |
|---|
| 850 | | { |
|---|
| 851 | | /* Get the object */ |
|---|
| 852 | | o_ptr = &o_list[floor_o_idx]; |
|---|
| 853 | | |
|---|
| 854 | | /* Describe the object. Less detail if blind. */ |
|---|
| 855 | | if (blind) object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 0); |
|---|
| 856 | | else object_desc(o_name, sizeof(o_name), o_ptr, TRUE, 3); |
|---|
| 857 | | |
|---|
| 858 | | message_flush(); |
|---|
| 859 | | |
|---|
| 860 | | /* Message */ |
|---|
| 861 | | msg_format("You %s %s.", (blind ? "feel" : "see"), |
|---|
| 862 | | o_name); |
|---|
| 863 | | } |
|---|
| 864 | | |
|---|
| 865 | | /* Several objects */ |
|---|
| 866 | | else |
|---|
| 867 | | { |
|---|
| 868 | | message_flush(); |
|---|
| 869 | | |
|---|
| 870 | | /* Message */ |
|---|
| 871 | | msg_format("You %s a pile of %d items.", |
|---|
| 872 | | (blind ? "feel" : "see"), floor_num); |
|---|
| 873 | | } |
|---|
| 874 | | } |
|---|
| 875 | | |
|---|
| 876 | | /* Done */ |
|---|
| 877 | | return (objs_picked_up); |
|---|
| 878 | | } |
|---|
| 879 | | |
|---|
| 880 | | |
|---|
| 881 | | /* The player has no room for anything on the floor. */ |
|---|
| 882 | | if (!can_pickup) |
|---|
| 883 | | { |
|---|
| 884 | | /* |
|---|
| 885 | | * One object -- Always display compact information. This |
|---|
| 886 | | * should change if more information would actually be helpful. |
|---|
| 887 | | */ |
|---|
| | 833 | if (pickup == 0 || !can_pickup) |
|---|
| | 834 | { |
|---|
| | 835 | const char *p = "see"; |
|---|
| | 836 | |
|---|
| | 837 | /* One object */ |
|---|
| 950 | | /* |
|---|
| 951 | | * If not deliberately picking up objects, and if requested or |
|---|
| 952 | | * potentially unsafe, ask the player to confirm all pickups. |
|---|
| 953 | | */ |
|---|
| 954 | | if (((query_floor) || (!p_ptr->auto_pickup_okay)) && (pickup <= 1)) |
|---|
| 955 | | { |
|---|
| 956 | | /* Save screen */ |
|---|
| 957 | | screen_save(); |
|---|
| 958 | | |
|---|
| 959 | | /* Display objects on the floor */ |
|---|
| 960 | | show_floor(floor_list, floor_num, FALSE); |
|---|
| 961 | | |
|---|
| 962 | | /* Display prompt */ |
|---|
| 963 | | if (floor_num == 1) |
|---|
| 964 | | { |
|---|
| 965 | | prt("Press Return to pick up this object: ", 0, 0); |
|---|
| 966 | | } |
|---|
| 967 | | else |
|---|
| 968 | | { |
|---|
| 969 | | prt("Press Return to pick up any of the following objects: ", |
|---|
| 970 | | 0, 0); |
|---|
| 971 | | } |
|---|
| 972 | | |
|---|
| 973 | | /* Move cursor back to character, if needed */ |
|---|
| 974 | | if (hilite_player) move_cursor_relative(p_ptr->py, p_ptr->px); |
|---|
| 975 | | |
|---|
| 976 | | /* Get response */ |
|---|
| 977 | | ch = inkey(); |
|---|
| 978 | | |
|---|
| 979 | | /* Restore screen */ |
|---|
| 980 | | screen_load(); |
|---|
| 981 | | |
|---|
| 982 | | /* We don't want to pick up this item */ |
|---|
| 983 | | if ((ch != '\r') && (ch != '\n') && (ch != 'g')) |
|---|
| 984 | | { |
|---|
| 985 | | /* Attempt to turn this command into a direction */ |
|---|
| 986 | | int dir = target_dir(ch); |
|---|
| 987 | | |
|---|
| 988 | | /* We used a movement command */ |
|---|
| 989 | | if (dir) |
|---|
| 990 | | { |
|---|
| 991 | | /* Save as a new command; move later */ |
|---|
| 992 | | p_ptr->command_new = ch; |
|---|
| 993 | | } |
|---|
| 994 | | |
|---|
| 995 | | /* Done */ |
|---|
| 996 | | return (objs_picked_up); |
|---|
| 997 | | } |
|---|
| 998 | | } |
|---|
| 999 | | |
|---|
| 1000 | | /* Use a menu interface for multiple objects */ |
|---|
| | 907 | /* Use a menu interface for multiple objects, or pickup single objects */ |
|---|