OSDN Git Service

[Refactor] #40399 Renamed object1.c/h to object-info.c/h
[hengband/hengband.git] / src / autopick / autopick.c
1 /*!
2  * @file autopick.c
3  * @brief 自動拾い機能の実装 / Object Auto-picker/Destroyer
4  * @date 2014/01/02
5  * @author
6  * Copyright (c) 2002  Mogami\n
7  *\n
8  * This software may be copied and distributed for educational, research, and\n
9  * not for profit purposes provided that this copyright and statement are\n
10  * included in all such copies.\n
11  * 2014 Deskull rearranged comment for Doxygen.\n
12  */
13
14 #include "autopick/autopick.h"
15 #include "autopick/autopick-destroyer.h"
16 #include "autopick/autopick-finder.h"
17 #include "autopick/autopick-menu-data-table.h"
18 #include "autopick/autopick-methods-table.h"
19 #include "floor/floor-object.h"
20 #include "inventory/inventory-object.h"
21 #include "object/object-flavor.h"
22 #include "object/object-mark-types.h"
23 #include "object/object-info.h"
24 #include "player/player-move.h"
25 #include "util/util.h"
26
27 /*
28  *  Auto-destroy marked item
29  */
30 static void autopick_delayed_alter_aux(player_type *player_ptr, INVENTORY_IDX item)
31 {
32         object_type *o_ptr;
33         o_ptr = ref_item(player_ptr, item);
34
35         if (o_ptr->k_idx == 0 || !(o_ptr->marked & OM_AUTODESTROY)) return;
36
37         GAME_TEXT o_name[MAX_NLEN];
38         object_desc(player_ptr, o_name, o_ptr, 0);
39         if (item >= 0)
40         {
41                 inven_item_increase(player_ptr, item, -(o_ptr->number));
42                 inven_item_optimize(player_ptr, item);
43         }
44         else
45         {
46                 delete_object_idx(player_ptr, 0 - item);
47         }
48
49         msg_format(_("%sを自動破壊します。", "Auto-destroying %s."), o_name);
50 }
51
52
53 /*
54  *  Auto-destroy marked items in inventry and on floor
55  */
56 void autopick_delayed_alter(player_type *owner_ptr)
57 {
58         INVENTORY_IDX item;
59
60         /*
61          * Scan inventry in reverse order to prevent
62          * skipping after inven_item_optimize()
63          */
64         for (item = INVEN_TOTAL - 1; item >= 0; item--)
65                 autopick_delayed_alter_aux(owner_ptr, item);
66
67         floor_type *floor_ptr = owner_ptr->current_floor_ptr;
68         item = floor_ptr->grid_array[owner_ptr->y][owner_ptr->x].o_idx;
69         while (item)
70         {
71                 OBJECT_IDX next = floor_ptr->o_list[item].next_o_idx;
72                 autopick_delayed_alter_aux(owner_ptr, -item);
73                 item = next;
74         }
75 }
76
77
78 /*
79  * Auto-inscription and/or destroy
80  *
81  * Auto-destroyer works only on inventory or on floor stack only when
82  * requested.
83  */
84 void autopick_alter_item(player_type *player_ptr, INVENTORY_IDX item, bool destroy)
85 {
86         object_type *o_ptr;
87         o_ptr = ref_item(player_ptr, item);
88         int idx = find_autopick_list(player_ptr, o_ptr);
89         auto_inscribe_item(player_ptr, o_ptr, idx);
90         if (destroy && item <= INVEN_PACK)
91                 auto_destroy_item(player_ptr, o_ptr, idx);
92 }
93
94
95 /*
96  * Automatically pickup/destroy items in this grid.
97  */
98 void autopick_pickup_items(player_type* player_ptr, grid_type *g_ptr)
99 {
100         OBJECT_IDX this_o_idx, next_o_idx = 0;
101         for (this_o_idx = g_ptr->o_idx; this_o_idx; this_o_idx = next_o_idx)
102         {
103                 object_type *o_ptr = &player_ptr->current_floor_ptr->o_list[this_o_idx];
104                 next_o_idx = o_ptr->next_o_idx;
105                 int idx = find_autopick_list(player_ptr, o_ptr);
106                 auto_inscribe_item(player_ptr, o_ptr, idx);
107                 bool is_auto_pickup = idx >= 0;
108                 is_auto_pickup &= (autopick_list[idx].action & (DO_AUTOPICK | DO_QUERY_AUTOPICK)) != 0;
109                 if (!is_auto_pickup)
110                 {
111                         auto_destroy_item(player_ptr, o_ptr, idx);
112                         continue;
113                 }
114
115                 disturb(player_ptr, FALSE, FALSE);
116                 if (!check_store_item_to_inventory(o_ptr))
117                 {
118                         GAME_TEXT o_name[MAX_NLEN];
119                         object_desc(player_ptr, o_name, o_ptr, 0);
120                         msg_format(_("ザックには%sを入れる隙間がない。", "You have no room for %s."), o_name);
121                         o_ptr->marked |= OM_NOMSG;
122                         continue;
123                 }
124
125                 if (!(autopick_list[idx].action & DO_QUERY_AUTOPICK))
126                 {
127                         py_pickup_aux(player_ptr, this_o_idx);
128                         continue;
129                 }
130
131                 char out_val[MAX_NLEN + 20];
132                 GAME_TEXT o_name[MAX_NLEN];
133                 if (o_ptr->marked & OM_NO_QUERY)
134                 {
135                         continue;
136                 }
137
138                 object_desc(player_ptr, o_name, o_ptr, 0);
139                 sprintf(out_val, _("%sを拾いますか? ", "Pick up %s? "), o_name);
140                 if (!get_check(out_val))
141                 {
142                         o_ptr->marked |= OM_NOMSG | OM_NO_QUERY;
143                         continue;
144                 }
145
146                 py_pickup_aux(player_ptr, this_o_idx);
147         }
148 }