1 /**
2  * @file
3  * @brief Misc (mostly) inventory related functions.
4 **/
5 
6 #pragma once
7 
8 #include <vector>
9 
10 #include "equipment-type.h"
11 #include "god-type.h"
12 #include "mon-inv-type.h"
13 #include "item-prop.h"
14 #include "tag-version.h"
15 
16 using std::vector;
17 
18 // Ways to get items, other than finding them on the ground or looting them
19 // from slain monsters.
20 enum item_source_type
21 {
22     IT_SRC_NONE   = 0,
23 
24     // Empty space for the gods
25 
26     AQ_SCROLL     = 100,
27 #if TAG_MAJOR_VERSION == 34
28     AQ_CARD_GENIE,
29 #endif
30     IT_SRC_START,
31     IT_SRC_SHOP,
32 
33     // Empty space for new non-wizmode acquisition methods
34 
35     AQ_WIZMODE    = 200,
36 };
37 
38 enum autopickup_level_type
39 {
40     AP_FORCE_OFF = -1,
41     AP_FORCE_NONE = 0,
42     AP_FORCE_ON = 1,
43 };
44 
45 /// top-priority item override colour
46 #define FORCED_ITEM_COLOUR_KEY "forced_item_colour"
47 
48 pair<bool, int> item_int(item_def &item);
49 item_def& item_from_int(bool, int);
50 
51 int get_max_subtype(object_class_type base_type);
52 bool item_type_has_unidentified(object_class_type base_type);
53 
54 bool dec_inv_item_quantity(int obj, int amount);
55 bool dec_mitm_item_quantity(int obj, int amount);
56 
57 void inc_inv_item_quantity(int obj, int amount);
58 void inc_mitm_item_quantity(int obj, int amount);
59 
60 bool move_item_to_grid(int *const obj, const coord_def& p,
61                         bool silent = false);
62 void move_item_stack_to_grid(const coord_def& from, const coord_def& to);
63 void note_inscribe_item(item_def &item);
64 bool move_item_to_inv(item_def& item);
65 bool move_item_to_inv(int obj, int quant_got, bool quiet = false);
66 item_def* auto_assign_item_slot(item_def& item);
67 void mark_items_non_pickup_at(const coord_def &pos);
68 void clear_item_pickup_flags(item_def &item);
69 bool is_stackable_item(const item_def &item);
70 bool items_similar(const item_def &item1, const item_def &item2);
71 bool items_stack(const item_def &item1, const item_def &item2);
72 void get_gold(const item_def& item, int quant, bool quiet);
73 
74 item_def *find_floor_item(object_class_type cls, int sub_type = -1);
75 int item_on_floor(const item_def &item, const coord_def& where);
76 
77 void init_item(int item);
78 
79 void add_held_books_to_library();
80 
81 void link_items();
82 
83 void fix_item_coordinates();
84 
85 int get_mitm_slot(int reserve = 50);
86 
87 void unlink_item(int dest);
88 void destroy_item(item_def &item, bool never_created = false);
89 void destroy_item(int dest, bool never_created = false);
90 void lose_item_stack(const coord_def& where);
91 
92 string item_message(vector<const item_def *> const &items);
93 void item_check();
94 void identify_item(item_def& item);
95 void request_autopickup(bool do_pickup = true);
96 void id_floor_items();
97 
98 bool player_on_single_stack();
99 void pickup_menu(int item_link);
100 void pickup(bool partial_quantity = false);
101 
102 bool item_is_branded(const item_def& item);
103 vector<const item_def*> item_list_on_square(int obj);
104 
105 bool copy_item_to_grid(item_def &item, const coord_def& p,
106                        int quant_drop = -1,    // item.quantity by default
107                        bool mark_dropped = false,
108                        bool silent = false);
109 coord_def item_pos(const item_def &item);
110 
111 bool move_top_item(const coord_def &src, const coord_def &dest);
112 
113 // Get the top item in a given cell. If there are no items, return nullptr.
114 const item_def* top_item_at(const coord_def& where);
115 
116 // Returns whether there is more than one item in a given cell.
117 bool multiple_items_at(const coord_def& where);
118 
119 void drop();
120 
121 int inv_count();
122 int runes_in_pack();
123 
124 bool pickup_single_item(int link, int qty);
125 
126 bool drop_item(int item_dropped, int quant_drop);
127 void drop_last();
128 
129 int          get_equip_slot(const item_def *item);
130 mon_inv_type get_mon_equip_slot(const monster* mon, const item_def &item);
131 
132 void origin_reset(item_def &item);
133 void origin_set(const coord_def& where);
134 void origin_set_monster(item_def &item, const monster* mons);
135 bool origin_known(const item_def &item);
136 bool origin_describable(const item_def &item);
137 string origin_desc(const item_def &item);
138 void origin_purchased(item_def &item);
139 void origin_acquired(item_def &item, int agent);
140 void origin_set_startequip(item_def &item);
141 void origin_set_unknown(item_def &item);
142 god_type origin_as_god_gift(const item_def& item);
143 bool origin_is_acquirement(const item_def& item,
144                            item_source_type *type = nullptr);
145 
146 bool item_needs_autopickup(const item_def &, bool ignore_force = false);
147 bool can_autopickup();
148 
149 bool need_to_autopickup();
150 void autopickup(bool forced = false);
151 
152 void set_item_autopickup(const item_def &item, autopickup_level_type ap);
153 int item_autopickup_level(const item_def &item);
154 
155 int find_free_slot(const item_def &i);
156 
157 bool need_to_autoinscribe();
158 void request_autoinscribe(bool do_inscribe = true);
159 void autoinscribe();
160 
161 bool item_is_equipped(const item_def &item, bool quiver_too = false);
162 bool item_is_melded(const item_def& item);
163 equipment_type item_equip_slot(const item_def &item);
164 
165 void item_was_lost(const item_def &item);
166 void item_was_destroyed(const item_def &item);
167 
168 bool get_item_by_name(item_def *item, const char* specs,
169                       object_class_type class_wanted,
170                       bool create_for_real = false);
171 
172 bool get_item_by_exact_name(item_def &item, const char* name);
173 
174 void move_items(const coord_def r, const coord_def p);
175 object_class_type get_random_item_mimic_type();
176 
177 bool maybe_identify_base_type(item_def &item);
178 int count_movable_items(int obj);
179 
180 // stack_iterator guarantees validity so long as you don't manually
181 // mess with item_def.link: i.e., you can kill the item you're
182 // examining but you can't kill the item linked to it.
183 class stack_iterator : public iterator<forward_iterator_tag, item_def>
184 {
185 public:
186     explicit stack_iterator(const coord_def& pos, bool accessible = false);
187     explicit stack_iterator(int start_link);
188 
189     operator bool() const;
190     item_def& operator *() const;
191     item_def* operator->() const;
192     int index() const;
193 
194     const stack_iterator& operator ++ ();
195     stack_iterator operator ++ (int);
196 private:
197     int cur_link;
198     int next_link;
199 };
200 
201 class mon_inv_iterator : public iterator<forward_iterator_tag, item_def>
202 {
203 public:
204     explicit mon_inv_iterator(monster& _mon);
205 
slot()206     mon_inv_type slot() const
207     {
208         return type;
209     }
210 
211     operator bool() const;
212     item_def& operator *() const;
213     item_def* operator->() const;
214 
215     mon_inv_iterator& operator ++ ();
216     mon_inv_iterator operator ++ (int);
217 private:
218     monster& mon;
219     mon_inv_type type;
220 };
221 
222 /** All non-removed item subtypes for the specified base type */
all_item_subtypes(object_class_type base)223 static inline vector<int> all_item_subtypes(object_class_type base)
224 {
225     vector<int> subtypes;
226     for (int i = 0; i < get_max_subtype(base); ++i)
227     {
228         if (!item_type_removed(base, i))
229             subtypes.push_back(i);
230     }
231     return subtypes;
232 }
233