3 Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
23 #include "irrlichttypes.h"
24 #include "itemstackmetadata.h"
31 struct ToolCapabilities
;
35 ItemStack() = default;
37 ItemStack(const std::string
&name_
, u16 count_
,
38 u16 wear
, IItemDefManager
*itemdef
);
40 ~ItemStack() = default;
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
);
48 // Returns the string used for inventory
49 std::string
getItemString(bool include_meta
= true) const;
50 // Returns the tooltip
51 std::string
getDescription(const IItemDefManager
*itemdef
) const;
52 std::string
getShortDescription(const IItemDefManager
*itemdef
) const;
54 std::string
getInventoryImage(const IItemDefManager
*itemdef
) const;
55 std::string
getInventoryOverlay(const IItemDefManager
*itemdef
) const;
56 std::string
getWieldImage(const IItemDefManager
*itemdef
) const;
57 std::string
getWieldOverlay(const IItemDefManager
*itemdef
) const;
58 v3f
getWieldScale(const IItemDefManager
*itemdef
) const;
84 assert(count
>= n
); // Pre-condition
87 clear(); // reset name, wear and metadata too
90 // Maximum size of a stack
91 u16
getStackMax(const IItemDefManager
*itemdef
) const
93 return itemdef
->get(name
).stack_max
;
96 // Number of items that can be added to this stack
97 u16
freeSpace(const IItemDefManager
*itemdef
) const
99 u16 max
= getStackMax(itemdef
);
105 // Returns false if item is not known and cannot be used
106 bool isKnown(const IItemDefManager
*itemdef
) const
108 return itemdef
->isKnown(name
);
111 // Returns a pointer to the item definition struct,
112 // or a fallback one (name="unknown") if the item is unknown.
113 const ItemDefinition
& getDefinition(
114 const IItemDefManager
*itemdef
) const
116 return itemdef
->get(name
);
119 // Get tool digging properties, or those of the hand if not a tool
120 const ToolCapabilities
& getToolCapabilities(
121 const IItemDefManager
*itemdef
) const
123 const ToolCapabilities
*item_cap
=
124 itemdef
->get(name
).tool_capabilities
;
126 if (item_cap
== NULL
)
127 // Fall back to the hand's tool capabilities
128 item_cap
= itemdef
->get("").tool_capabilities
;
130 assert(item_cap
!= NULL
);
131 return metadata
.getToolCapabilities(*item_cap
); // Check for override
134 const std::optional
<WearBarParams
> &getWearBarParams(
135 const IItemDefManager
*itemdef
) const
137 auto &meta_override
= metadata
.getWearBarParamOverride();
138 if (meta_override
.has_value())
139 return meta_override
;
140 return itemdef
->get(name
).wear_bar_params
;
143 // Wear out (only tools)
144 // Returns true if the item is (was) a tool
145 bool addWear(s32 amount
, const IItemDefManager
*itemdef
)
147 if(getDefinition(itemdef
).type
== ITEM_TOOL
)
149 if(amount
> 65535 - wear
)
151 else if(amount
< -wear
)
161 // If possible, adds newitem to this item.
162 // If cannot be added at all, returns the item back.
163 // If can be added partly, decremented item is returned back.
164 // If can be added fully, empty item is returned.
165 ItemStack
addItem(ItemStack newitem
, IItemDefManager
*itemdef
);
167 // Checks whether newitem could be added.
168 // If restitem is non-NULL, it receives the part of newitem that
169 // would be left over after adding.
170 bool itemFits(ItemStack newitem
,
171 ItemStack
*restitem
, // may be NULL
172 IItemDefManager
*itemdef
) const;
174 // Checks if another itemstack would stack with this one.
175 // Does not check if the item actually fits in the stack.
176 bool stacksWith(const ItemStack
&other
) const;
179 // If there are not enough, takes as many as it can.
180 // Returns empty item if couldn't take any.
181 ItemStack
takeItem(u32 takecount
);
183 // Similar to takeItem, but keeps this ItemStack intact.
184 ItemStack
peekItem(u32 peekcount
) const;
186 bool operator ==(const ItemStack
&s
) const
188 return (this->name
== s
.name
&&
189 this->count
== s
.count
&&
190 this->wear
== s
.wear
&&
191 this->metadata
== s
.metadata
);
194 bool operator !=(const ItemStack
&s
) const
196 return !(*this == s
);
202 std::string name
= "";
205 ItemStackMetadata metadata
;
211 InventoryList(const std::string
&name
, u32 size
, IItemDefManager
*itemdef
);
212 ~InventoryList() = default;
214 void setSize(u32 newsize
);
215 void setWidth(u32 newWidth
);
216 void setName(const std::string
&name
);
217 void serialize(std::ostream
&os
, bool incremental
) const;
218 void deSerialize(std::istream
&is
);
220 InventoryList(const InventoryList
&other
) { *this = other
; }
221 InventoryList
& operator = (const InventoryList
&other
);
222 bool operator == (const InventoryList
&other
) const;
223 bool operator != (const InventoryList
&other
) const
225 return !(*this == other
);
228 const std::string
&getName() const { return m_name
; }
229 u32
getSize() const { return static_cast<u32
>(m_items
.size()); }
230 u32
getWidth() const { return m_width
; }
232 u32
getUsedSlots() const;
234 // Get reference to item
235 const ItemStack
&getItem(u32 i
) const
237 assert(i
< m_size
); // Pre-condition
240 ItemStack
&getItem(u32 i
)
242 assert(i
< m_size
); // Pre-condition
245 // Get reference to all items
246 const std::vector
<ItemStack
> &getItems() const { return m_items
; }
247 // Returns old item. Parameter can be an empty item.
248 ItemStack
changeItem(u32 i
, const ItemStack
&newitem
);
250 void deleteItem(u32 i
);
252 // Adds an item to a suitable place. Returns leftover item (possibly empty).
253 ItemStack
addItem(const ItemStack
&newitem
);
255 // If possible, adds item to given slot.
256 // If cannot be added at all, returns the item back.
257 // If can be added partly, decremented item is returned back.
258 // If can be added fully, empty item is returned.
259 ItemStack
addItem(u32 i
, const ItemStack
&newitem
);
261 // Checks whether the item could be added to the given slot
262 // If restitem is non-NULL, it receives the part of newitem that
263 // would be left over after adding.
264 bool itemFits(const u32 i
, const ItemStack
&newitem
,
265 ItemStack
*restitem
= NULL
) const;
267 // Checks whether there is room for a given item
268 bool roomForItem(const ItemStack
&item
) const;
270 // Checks whether the given count of the given item
271 // exists in this inventory list.
272 // If match_meta is false, only the items' names are compared.
273 bool containsItem(const ItemStack
&item
, bool match_meta
) const;
275 // Removes the given count of the given item name from
276 // this inventory list. Walks the list in reverse order.
277 // If not as many items exist as requested, removes as
279 // Returns the items that were actually removed.
280 ItemStack
removeItem(const ItemStack
&item
);
282 // Takes some items from a slot.
283 // If there are not enough, takes as many as it can.
284 // Returns empty item if couldn't take any.
285 ItemStack
takeItem(u32 i
, u32 takecount
);
287 // Move an item to a different list (or a different stack in the same list)
288 // count is the maximum number of items to move (0 for everything)
289 // returns the moved stack
290 ItemStack
moveItem(u32 i
, InventoryList
*dest
, u32 dest_i
,
291 u32 count
= 0, bool swap_if_needed
= true, bool *did_swap
= NULL
);
293 // like moveItem, but without a fixed destination index
294 // also with optional rollback recording
295 void moveItemSomewhere(u32 i
, InventoryList
*dest
, u32 count
);
297 inline bool checkModified() const { return m_dirty
; }
298 inline void setModified(bool dirty
= true) { m_dirty
= dirty
; }
300 // Problem: C++ keeps references to InventoryList and ItemStack indices
301 // until a better solution is found, this serves as a guard to prevent side-effects
302 struct ResizeUnlocker
{
303 void operator()(InventoryList
*invlist
)
305 invlist
->m_resize_locks
-= 1;
308 using ResizeLocked
= std::unique_ptr
<InventoryList
, ResizeUnlocker
>;
310 void checkResizeLock();
312 inline ResizeLocked
resizeLock()
315 return ResizeLocked(this);
319 std::vector
<ItemStack
> m_items
;
321 u32 m_size
; // always the same as m_items.size()
323 IItemDefManager
*m_itemdef
;
325 int m_resize_locks
= 0; // Lua callback sanity
335 Inventory(IItemDefManager
*itemdef
);
336 Inventory(const Inventory
&other
);
337 Inventory
& operator = (const Inventory
&other
);
338 bool operator == (const Inventory
&other
) const;
339 bool operator != (const Inventory
&other
) const
341 return !(*this == other
);
344 // Never ever serialize to disk using "incremental"!
345 void serialize(std::ostream
&os
, bool incremental
= false) const;
346 void deSerialize(std::istream
&is
);
348 // Creates a new list if none exists or truncates existing lists
349 InventoryList
* addList(const std::string
&name
, u32 size
);
350 InventoryList
* getList(const std::string
&name
);
351 const InventoryList
* getList(const std::string
&name
) const;
352 const std::vector
<InventoryList
*> &getLists() const { return m_lists
; }
353 bool deleteList(const std::string
&name
);
354 // A shorthand for adding items. Returns leftover item (possibly empty).
355 ItemStack
addItem(const std::string
&listname
, const ItemStack
&newitem
)
357 InventoryList
*list
= getList(listname
);
360 return list
->addItem(newitem
);
363 inline bool checkModified() const
368 for (const auto &list
: m_lists
)
369 if (list
->checkModified())
375 inline void setModified(bool dirty
= true)
378 // Set all as handled
380 for (const auto &list
: m_lists
)
381 list
->setModified(dirty
);
386 s32
getListIndex(const std::string
&name
) const;
388 std::vector
<InventoryList
*> m_lists
;
389 IItemDefManager
*m_itemdef
;