Line data Source code
1 : /*
2 : Minetest
3 : Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 :
5 : This program is free software; you can redistribute it and/or modify
6 : it under the terms of the GNU Lesser General Public License as published by
7 : the Free Software Foundation; either version 2.1 of the License, or
8 : (at your option) any later version.
9 :
10 : This program is distributed in the hope that it will be useful,
11 : but WITHOUT ANY WARRANTY; without even the implied warranty of
12 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 : GNU Lesser General Public License for more details.
14 :
15 : You should have received a copy of the GNU Lesser General Public License along
16 : with this program; if not, write to the Free Software Foundation, Inc.,
17 : 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 : */
19 :
20 : #ifndef INVENTORY_HEADER
21 : #define INVENTORY_HEADER
22 :
23 : #include "debug.h"
24 : #include "itemdef.h"
25 : #include "irrlichttypes.h"
26 : #include <istream>
27 : #include <ostream>
28 : #include <string>
29 : #include <vector>
30 :
31 : struct ToolCapabilities;
32 :
33 22327 : struct ItemStack
34 : {
35 14470 : ItemStack(): name(""), count(0), wear(0), metadata("") {}
36 : ItemStack(std::string name_, u16 count_,
37 : u16 wear, std::string metadata_,
38 : IItemDefManager *itemdef);
39 32939 : ~ItemStack() {}
40 :
41 : // Serialization
42 : void serialize(std::ostream &os) const;
43 : // Deserialization. Pass itemdef unless you don't want aliases resolved.
44 : void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
45 : void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
46 :
47 : // Returns the string used for inventory
48 : std::string getItemString() const;
49 :
50 : /*
51 : Quantity methods
52 : */
53 :
54 10604 : bool empty() const
55 : {
56 10604 : return count == 0;
57 : }
58 :
59 5224 : void clear()
60 : {
61 5224 : name = "";
62 5224 : count = 0;
63 5224 : wear = 0;
64 5224 : metadata = "";
65 5224 : }
66 :
67 0 : void add(u16 n)
68 : {
69 0 : count += n;
70 0 : }
71 :
72 0 : void remove(u16 n)
73 : {
74 : assert(count >= n); // Pre-condition
75 0 : count -= n;
76 0 : if(count == 0)
77 0 : clear(); // reset name, wear and metadata too
78 0 : }
79 :
80 : // Maximum size of a stack
81 0 : u16 getStackMax(IItemDefManager *itemdef) const
82 : {
83 0 : s16 max = itemdef->get(name).stack_max;
84 0 : return (max >= 0) ? max : 0;
85 : }
86 :
87 : // Number of items that can be added to this stack
88 0 : u16 freeSpace(IItemDefManager *itemdef) const
89 : {
90 0 : u16 max = getStackMax(itemdef);
91 0 : if(count > max)
92 0 : return 0;
93 0 : return max - count;
94 : }
95 :
96 : // Returns false if item is not known and cannot be used
97 0 : bool isKnown(IItemDefManager *itemdef) const
98 : {
99 0 : return itemdef->isKnown(name);
100 : }
101 :
102 : // Returns a pointer to the item definition struct,
103 : // or a fallback one (name="unknown") if the item is unknown.
104 9369 : const ItemDefinition& getDefinition(
105 : IItemDefManager *itemdef) const
106 : {
107 9369 : return itemdef->get(name);
108 : }
109 :
110 : // Get tool digging properties, or those of the hand if not a tool
111 1451 : const ToolCapabilities& getToolCapabilities(
112 : IItemDefManager *itemdef) const
113 : {
114 : ToolCapabilities *cap;
115 1451 : cap = itemdef->get(name).tool_capabilities;
116 1451 : if(cap == NULL)
117 771 : cap = itemdef->get("").tool_capabilities;
118 : assert(cap != NULL);
119 1451 : return *cap;
120 : }
121 :
122 : // Wear out (only tools)
123 : // Returns true if the item is (was) a tool
124 0 : bool addWear(s32 amount, IItemDefManager *itemdef)
125 : {
126 0 : if(getDefinition(itemdef).type == ITEM_TOOL)
127 : {
128 0 : if(amount > 65535 - wear)
129 0 : clear();
130 0 : else if(amount < -wear)
131 0 : wear = 0;
132 : else
133 0 : wear += amount;
134 0 : return true;
135 : }
136 : else
137 : {
138 0 : return false;
139 : }
140 : }
141 :
142 : // If possible, adds newitem to this item.
143 : // If cannot be added at all, returns the item back.
144 : // If can be added partly, decremented item is returned back.
145 : // If can be added fully, empty item is returned.
146 : ItemStack addItem(const ItemStack &newitem,
147 : IItemDefManager *itemdef);
148 :
149 : // Checks whether newitem could be added.
150 : // If restitem is non-NULL, it receives the part of newitem that
151 : // would be left over after adding.
152 : bool itemFits(const ItemStack &newitem,
153 : ItemStack *restitem, // may be NULL
154 : IItemDefManager *itemdef) const;
155 :
156 : // Takes some items.
157 : // If there are not enough, takes as many as it can.
158 : // Returns empty item if couldn't take any.
159 : ItemStack takeItem(u32 takecount);
160 :
161 : // Similar to takeItem, but keeps this ItemStack intact.
162 : ItemStack peekItem(u32 peekcount) const;
163 :
164 : /*
165 : Properties
166 : */
167 : std::string name;
168 : u16 count;
169 : u16 wear;
170 : std::string metadata;
171 : };
172 :
173 : class InventoryList
174 : {
175 : public:
176 : InventoryList(std::string name, u32 size, IItemDefManager *itemdef);
177 : ~InventoryList();
178 : void clearItems();
179 : void setSize(u32 newsize);
180 : void setWidth(u32 newWidth);
181 : void setName(const std::string &name);
182 : void serialize(std::ostream &os) const;
183 : void deSerialize(std::istream &is);
184 :
185 : InventoryList(const InventoryList &other);
186 : InventoryList & operator = (const InventoryList &other);
187 : bool operator == (const InventoryList &other) const;
188 0 : bool operator != (const InventoryList &other) const
189 : {
190 0 : return !(*this == other);
191 : }
192 :
193 : const std::string &getName() const;
194 : u32 getSize() const;
195 : u32 getWidth() const;
196 : // Count used slots
197 : u32 getUsedSlots() const;
198 : u32 getFreeSlots() const;
199 :
200 : // Get reference to item
201 : const ItemStack& getItem(u32 i) const;
202 : ItemStack& getItem(u32 i);
203 : // Returns old item. Parameter can be an empty item.
204 : ItemStack changeItem(u32 i, const ItemStack &newitem);
205 : // Delete item
206 : void deleteItem(u32 i);
207 :
208 : // Adds an item to a suitable place. Returns leftover item (possibly empty).
209 : ItemStack addItem(const ItemStack &newitem);
210 :
211 : // If possible, adds item to given slot.
212 : // If cannot be added at all, returns the item back.
213 : // If can be added partly, decremented item is returned back.
214 : // If can be added fully, empty item is returned.
215 : ItemStack addItem(u32 i, const ItemStack &newitem);
216 :
217 : // Checks whether the item could be added to the given slot
218 : // If restitem is non-NULL, it receives the part of newitem that
219 : // would be left over after adding.
220 : bool itemFits(const u32 i, const ItemStack &newitem,
221 : ItemStack *restitem = NULL) const;
222 :
223 : // Checks whether there is room for a given item
224 : bool roomForItem(const ItemStack &item) const;
225 :
226 : // Checks whether the given count of the given item name
227 : // exists in this inventory list.
228 : bool containsItem(const ItemStack &item) const;
229 :
230 : // Removes the given count of the given item name from
231 : // this inventory list. Walks the list in reverse order.
232 : // If not as many items exist as requested, removes as
233 : // many as possible.
234 : // Returns the items that were actually removed.
235 : ItemStack removeItem(const ItemStack &item);
236 :
237 : // Takes some items from a slot.
238 : // If there are not enough, takes as many as it can.
239 : // Returns empty item if couldn't take any.
240 : ItemStack takeItem(u32 i, u32 takecount);
241 :
242 : // Similar to takeItem, but keeps the slot intact.
243 : ItemStack peekItem(u32 i, u32 peekcount) const;
244 :
245 : // Move an item to a different list (or a different stack in the same list)
246 : // count is the maximum number of items to move (0 for everything)
247 : // returns number of moved items
248 : u32 moveItem(u32 i, InventoryList *dest, u32 dest_i,
249 : u32 count = 0, bool swap_if_needed = true);
250 :
251 : // like moveItem, but without a fixed destination index
252 : // also with optional rollback recording
253 : void moveItemSomewhere(u32 i, InventoryList *dest, u32 count);
254 :
255 : private:
256 : std::vector<ItemStack> m_items;
257 : u32 m_size, m_width;
258 : std::string m_name;
259 : IItemDefManager *m_itemdef;
260 : };
261 :
262 : class Inventory
263 : {
264 : public:
265 : ~Inventory();
266 :
267 : void clear();
268 : void clearContents();
269 :
270 : Inventory(IItemDefManager *itemdef);
271 : Inventory(const Inventory &other);
272 : Inventory & operator = (const Inventory &other);
273 : bool operator == (const Inventory &other) const;
274 : bool operator != (const Inventory &other) const
275 : {
276 : return !(*this == other);
277 : }
278 :
279 : void serialize(std::ostream &os) const;
280 : void deSerialize(std::istream &is);
281 :
282 : InventoryList * addList(const std::string &name, u32 size);
283 : InventoryList * getList(const std::string &name);
284 : const InventoryList * getList(const std::string &name) const;
285 : std::vector<const InventoryList*> getLists();
286 : bool deleteList(const std::string &name);
287 : // A shorthand for adding items. Returns leftover item (possibly empty).
288 : ItemStack addItem(const std::string &listname, const ItemStack &newitem)
289 : {
290 : m_dirty = true;
291 : InventoryList *list = getList(listname);
292 : if(list == NULL)
293 : return newitem;
294 : return list->addItem(newitem);
295 : }
296 :
297 0 : bool checkModified() const
298 : {
299 0 : return m_dirty;
300 : }
301 :
302 1 : void setModified(const bool x)
303 : {
304 1 : m_dirty = x;
305 1 : }
306 :
307 : private:
308 : // -1 if not found
309 : const s32 getListIndex(const std::string &name) const;
310 :
311 : std::vector<InventoryList*> m_lists;
312 : IItemDefManager *m_itemdef;
313 : bool m_dirty;
314 : };
315 :
316 : #endif
317 :
|