Minetest  5.4.0
inventory.h
Go to the documentation of this file.
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 #pragma once
21 
22 #include "itemdef.h"
23 #include "irrlichttypes.h"
24 #include "itemstackmetadata.h"
25 #include <istream>
26 #include <ostream>
27 #include <string>
28 #include <vector>
29 #include <cassert>
30 
31 struct ToolCapabilities;
32 
33 struct ItemStack
34 {
35  ItemStack() = default;
36 
37  ItemStack(const std::string &name_, u16 count_,
38  u16 wear, IItemDefManager *itemdef);
39 
40  ~ItemStack() = default;
41 
42  // Serialization
43  void serialize(std::ostream &os, bool serialize_meta = true) const;
44  // Deserialization. Pass itemdef unless you don't want aliases resolved.
45  void deSerialize(std::istream &is, IItemDefManager *itemdef = NULL);
46  void deSerialize(const std::string &s, IItemDefManager *itemdef = NULL);
47 
48  // Returns the string used for inventory
49  std::string getItemString(bool include_meta = true) const;
50  // Returns the tooltip
51  std::string getDescription(IItemDefManager *itemdef) const;
52  std::string getShortDescription(IItemDefManager *itemdef) const;
53 
54  /*
55  Quantity methods
56  */
57 
58  bool empty() const
59  {
60  return count == 0;
61  }
62 
63  void clear()
64  {
65  name = "";
66  count = 0;
67  wear = 0;
68  metadata.clear();
69  }
70 
71  void add(u16 n)
72  {
73  count += n;
74  }
75 
76  void remove(u16 n)
77  {
78  assert(count >= n); // Pre-condition
79  count -= n;
80  if(count == 0)
81  clear(); // reset name, wear and metadata too
82  }
83 
84  // Maximum size of a stack
85  u16 getStackMax(IItemDefManager *itemdef) const
86  {
87  return itemdef->get(name).stack_max;
88  }
89 
90  // Number of items that can be added to this stack
91  u16 freeSpace(IItemDefManager *itemdef) const
92  {
93  u16 max = getStackMax(itemdef);
94  if (count >= max)
95  return 0;
96  return max - count;
97  }
98 
99  // Returns false if item is not known and cannot be used
100  bool isKnown(IItemDefManager *itemdef) const
101  {
102  return itemdef->isKnown(name);
103  }
104 
105  // Returns a pointer to the item definition struct,
106  // or a fallback one (name="unknown") if the item is unknown.
108  IItemDefManager *itemdef) const
109  {
110  return itemdef->get(name);
111  }
112 
113  // Get tool digging properties, or those of the hand if not a tool
115  IItemDefManager *itemdef) const
116  {
117  const ToolCapabilities *item_cap =
118  itemdef->get(name).tool_capabilities;
119 
120  if (item_cap == NULL)
121  // Fall back to the hand's tool capabilities
122  item_cap = itemdef->get("").tool_capabilities;
123 
124  assert(item_cap != NULL);
125  return metadata.getToolCapabilities(*item_cap); // Check for override
126  }
127 
128  // Wear out (only tools)
129  // Returns true if the item is (was) a tool
130  bool addWear(s32 amount, IItemDefManager *itemdef)
131  {
132  if(getDefinition(itemdef).type == ITEM_TOOL)
133  {
134  if(amount > 65535 - wear)
135  clear();
136  else if(amount < -wear)
137  wear = 0;
138  else
139  wear += amount;
140  return true;
141  }
142 
143  return false;
144  }
145 
146  // If possible, adds newitem to this item.
147  // If cannot be added at all, returns the item back.
148  // If can be added partly, decremented item is returned back.
149  // If can be added fully, empty item is returned.
150  ItemStack addItem(ItemStack newitem, IItemDefManager *itemdef);
151 
152  // Checks whether newitem could be added.
153  // If restitem is non-NULL, it receives the part of newitem that
154  // would be left over after adding.
155  bool itemFits(ItemStack newitem,
156  ItemStack *restitem, // may be NULL
157  IItemDefManager *itemdef) const;
158 
159  // Takes some items.
160  // If there are not enough, takes as many as it can.
161  // Returns empty item if couldn't take any.
162  ItemStack takeItem(u32 takecount);
163 
164  // Similar to takeItem, but keeps this ItemStack intact.
165  ItemStack peekItem(u32 peekcount) const;
166 
167  bool operator ==(const ItemStack &s) const
168  {
169  return (this->name == s.name &&
170  this->count == s.count &&
171  this->wear == s.wear &&
172  this->metadata == s.metadata);
173  }
174 
175  bool operator !=(const ItemStack &s) const
176  {
177  return !(*this == s);
178  }
179 
180  /*
181  Properties
182  */
183  std::string name = "";
184  u16 count = 0;
185  u16 wear = 0;
187 };
188 
190 {
191 public:
192  InventoryList(const std::string &name, u32 size, IItemDefManager *itemdef);
193  ~InventoryList() = default;
194  void clearItems();
195  void setSize(u32 newsize);
196  void setWidth(u32 newWidth);
197  void setName(const std::string &name);
198  void serialize(std::ostream &os, bool incremental) const;
199  void deSerialize(std::istream &is);
200 
201  InventoryList(const InventoryList &other);
202  InventoryList & operator = (const InventoryList &other);
203  bool operator == (const InventoryList &other) const;
204  bool operator != (const InventoryList &other) const
205  {
206  return !(*this == other);
207  }
208 
209  const std::string &getName() const;
210  u32 getSize() const;
211  u32 getWidth() const;
212  // Count used slots
213  u32 getUsedSlots() const;
214  u32 getFreeSlots() const;
215 
216  // Get reference to item
217  const ItemStack& getItem(u32 i) const;
218  ItemStack& getItem(u32 i);
219  // Returns old item. Parameter can be an empty item.
220  ItemStack changeItem(u32 i, const ItemStack &newitem);
221  // Delete item
222  void deleteItem(u32 i);
223 
224  // Adds an item to a suitable place. Returns leftover item (possibly empty).
225  ItemStack addItem(const ItemStack &newitem);
226 
227  // If possible, adds item to given slot.
228  // If cannot be added at all, returns the item back.
229  // If can be added partly, decremented item is returned back.
230  // If can be added fully, empty item is returned.
231  ItemStack addItem(u32 i, const ItemStack &newitem);
232 
233  // Checks whether the item could be added to the given slot
234  // If restitem is non-NULL, it receives the part of newitem that
235  // would be left over after adding.
236  bool itemFits(const u32 i, const ItemStack &newitem,
237  ItemStack *restitem = NULL) const;
238 
239  // Checks whether there is room for a given item
240  bool roomForItem(const ItemStack &item) const;
241 
242  // Checks whether the given count of the given item
243  // exists in this inventory list.
244  // If match_meta is false, only the items' names are compared.
245  bool containsItem(const ItemStack &item, bool match_meta) const;
246 
247  // Removes the given count of the given item name from
248  // this inventory list. Walks the list in reverse order.
249  // If not as many items exist as requested, removes as
250  // many as possible.
251  // Returns the items that were actually removed.
252  ItemStack removeItem(const ItemStack &item);
253 
254  // Takes some items from a slot.
255  // If there are not enough, takes as many as it can.
256  // Returns empty item if couldn't take any.
257  ItemStack takeItem(u32 i, u32 takecount);
258 
259  // Move an item to a different list (or a different stack in the same list)
260  // count is the maximum number of items to move (0 for everything)
261  // returns number of moved items
262  u32 moveItem(u32 i, InventoryList *dest, u32 dest_i,
263  u32 count = 0, bool swap_if_needed = true, bool *did_swap = NULL);
264 
265  // like moveItem, but without a fixed destination index
266  // also with optional rollback recording
267  void moveItemSomewhere(u32 i, InventoryList *dest, u32 count);
268 
269  inline bool checkModified() const { return m_dirty; }
270  inline void setModified(bool dirty = true) { m_dirty = dirty; }
271 
272 private:
273  std::vector<ItemStack> m_items;
274  std::string m_name;
275  u32 m_size;
276  u32 m_width = 0;
278  bool m_dirty = true;
279 };
280 
282 {
283 public:
284  ~Inventory();
285 
286  void clear();
287 
288  Inventory(IItemDefManager *itemdef);
289  Inventory(const Inventory &other);
290  Inventory & operator = (const Inventory &other);
291  bool operator == (const Inventory &other) const;
292  bool operator != (const Inventory &other) const
293  {
294  return !(*this == other);
295  }
296 
297  // Never ever serialize to disk using "incremental"!
298  void serialize(std::ostream &os, bool incremental = false) const;
299  void deSerialize(std::istream &is);
300 
301  InventoryList * addList(const std::string &name, u32 size);
302  InventoryList * getList(const std::string &name);
303  const InventoryList * getList(const std::string &name) const;
304  std::vector<const InventoryList*> getLists();
305  bool deleteList(const std::string &name);
306  // A shorthand for adding items. Returns leftover item (possibly empty).
307  ItemStack addItem(const std::string &listname, const ItemStack &newitem)
308  {
309  InventoryList *list = getList(listname);
310  if(list == NULL)
311  return newitem;
312  return list->addItem(newitem);
313  }
314 
315  inline bool checkModified() const
316  {
317  if (m_dirty)
318  return true;
319 
320  for (const auto &list : m_lists)
321  if (list->checkModified())
322  return true;
323 
324  return false;
325  }
326 
327  inline void setModified(bool dirty = true)
328  {
329  m_dirty = dirty;
330  // Set all as handled
331  if (!dirty) {
332  for (const auto &list : m_lists)
333  list->setModified(dirty);
334  }
335  }
336 private:
337  // -1 if not found
338  const s32 getListIndex(const std::string &name) const;
339 
340  std::vector<InventoryList*> m_lists;
342  bool m_dirty = true;
343 };
Definition: itemdef.h:105
virtual const ItemDefinition & get(const std::string &name) const =0
virtual bool isKnown(const std::string &name) const =0
Definition: inventory.h:190
bool operator==(const InventoryList &other) const
Definition: inventory.cpp:524
u32 getSize() const
Definition: inventory.cpp:544
bool containsItem(const ItemStack &item, bool match_meta) const
Definition: inventory.cpp:675
const ItemStack & getItem(u32 i) const
Definition: inventory.cpp:569
ItemStack addItem(const ItemStack &newitem)
Definition: inventory.cpp:599
std::vector< ItemStack > m_items
Definition: inventory.h:273
bool operator!=(const InventoryList &other) const
Definition: inventory.h:204
IItemDefManager * m_itemdef
Definition: inventory.h:277
bool m_dirty
Definition: inventory.h:278
void setName(const std::string &name)
Definition: inventory.cpp:422
void setWidth(u32 newWidth)
Definition: inventory.cpp:416
bool checkModified() const
Definition: inventory.h:269
ItemStack removeItem(const ItemStack &item)
Definition: inventory.cpp:694
std::string m_name
Definition: inventory.h:274
u32 m_size
Definition: inventory.h:275
void deSerialize(std::istream &is)
Definition: inventory.cpp:450
u32 getUsedSlots() const
Definition: inventory.cpp:554
InventoryList(const std::string &name, u32 size, IItemDefManager *itemdef)
Definition: inventory.cpp:387
u32 moveItem(u32 i, InventoryList *dest, u32 dest_i, u32 count=0, bool swap_if_needed=true, bool *did_swap=NULL)
Definition: inventory.cpp:746
u32 getWidth() const
Definition: inventory.cpp:549
ItemStack changeItem(u32 i, const ItemStack &newitem)
Definition: inventory.cpp:581
void setModified(bool dirty=true)
Definition: inventory.h:270
void setSize(u32 newsize)
Definition: inventory.cpp:406
u32 getFreeSlots() const
Definition: inventory.cpp:564
InventoryList & operator=(const InventoryList &other)
Definition: inventory.cpp:512
void clearItems()
Definition: inventory.cpp:395
~InventoryList()=default
void serialize(std::ostream &os, bool incremental) const
Definition: inventory.cpp:428
void deleteItem(u32 i)
Definition: inventory.cpp:592
const std::string & getName() const
Definition: inventory.cpp:539
bool roomForItem(const ItemStack &item) const
Definition: inventory.cpp:662
u32 m_width
Definition: inventory.h:276
ItemStack takeItem(u32 i, u32 takecount)
Definition: inventory.cpp:714
bool itemFits(const u32 i, const ItemStack &newitem, ItemStack *restitem=NULL) const
Definition: inventory.cpp:649
void moveItemSomewhere(u32 i, InventoryList *dest, u32 count)
Definition: inventory.cpp:725
Definition: inventory.h:282
const s32 getListIndex(const std::string &name) const
Definition: inventory.cpp:1001
ItemStack addItem(const std::string &listname, const ItemStack &newitem)
Definition: inventory.h:307
void clear()
Definition: inventory.cpp:802
Inventory(IItemDefManager *itemdef)
Definition: inventory.cpp:811
InventoryList * getList(const std::string &name)
Definition: inventory.cpp:964
bool deleteList(const std::string &name)
Definition: inventory.cpp:981
InventoryList * addList(const std::string &name, u32 size)
Definition: inventory.cpp:938
bool operator==(const Inventory &other) const
Definition: inventory.cpp:837
bool checkModified() const
Definition: inventory.h:315
IItemDefManager * m_itemdef
Definition: inventory.h:341
std::vector< const InventoryList * > getLists()
Definition: inventory.cpp:972
~Inventory()
Definition: inventory.cpp:797
void setModified(bool dirty=true)
Definition: inventory.h:327
void serialize(std::ostream &os, bool incremental=false) const
Definition: inventory.cpp:850
bool m_dirty
Definition: inventory.h:342
void deSerialize(std::istream &is)
Definition: inventory.cpp:865
Inventory & operator=(const Inventory &other)
Definition: inventory.cpp:822
std::vector< InventoryList * > m_lists
Definition: inventory.h:340
bool operator!=(const Inventory &other) const
Definition: inventory.h:292
Definition: itemstackmetadata.h:29
const ToolCapabilities & getToolCapabilities(const ToolCapabilities &default_caps) const
Definition: itemstackmetadata.h:40
void clear() override
Definition: itemstackmetadata.cpp:35
@ ITEM_TOOL
Definition: itemdef.h:48
Definition: itemdef.h:52
u16 stack_max
Definition: itemdef.h:75
ToolCapabilities * tool_capabilities
Definition: itemdef.h:79
Definition: inventory.h:34
void add(u16 n)
Definition: inventory.h:71
std::string getDescription(IItemDefManager *itemdef) const
Definition: inventory.cpp:253
u16 count
Definition: inventory.h:184
ItemStack peekItem(u32 peekcount) const
Definition: inventory.cpp:372
u16 getStackMax(IItemDefManager *itemdef) const
Definition: inventory.h:85
std::string getShortDescription(IItemDefManager *itemdef) const
Definition: inventory.cpp:261
void clear()
Definition: inventory.h:63
ItemStack takeItem(u32 takecount)
Definition: inventory.cpp:352
bool operator!=(const ItemStack &s) const
Definition: inventory.h:175
void serialize(std::ostream &os, bool serialize_meta=true) const
Definition: inventory.cpp:59
std::string getItemString(bool include_meta=true) const
Definition: inventory.cpp:246
bool itemFits(ItemStack newitem, ItemStack *restitem, IItemDefManager *itemdef) const
Definition: inventory.cpp:313
ItemStackMetadata metadata
Definition: inventory.h:186
bool isKnown(IItemDefManager *itemdef) const
Definition: inventory.h:100
ItemStack()=default
~ItemStack()=default
const ToolCapabilities & getToolCapabilities(IItemDefManager *itemdef) const
Definition: inventory.h:114
const ItemDefinition & getDefinition(IItemDefManager *itemdef) const
Definition: inventory.h:107
bool empty() const
Definition: inventory.h:58
std::string name
Definition: inventory.h:183
u16 wear
Definition: inventory.h:185
void deSerialize(std::istream &is, IItemDefManager *itemdef=NULL)
Definition: inventory.cpp:87
bool operator==(const ItemStack &s) const
Definition: inventory.h:167
void remove(u16 n)
Definition: inventory.h:76
u16 freeSpace(IItemDefManager *itemdef) const
Definition: inventory.h:91
ItemStack addItem(ItemStack newitem, IItemDefManager *itemdef)
Definition: inventory.cpp:276
bool addWear(s32 amount, IItemDefManager *itemdef)
Definition: inventory.h:130
Definition: tool.h:58