]> git.lizzy.rs Git - dragonfireclient.git/blob - src/inventory.h
Fix key change menu a bit
[dragonfireclient.git] / src / inventory.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010-2011 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 General Public License as published by
7 the Free Software Foundation; either version 2 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 General Public License for more details.
14
15 You should have received a copy of the GNU 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 <iostream>
24 #include <sstream>
25 #include <string>
26 #include "common_irrlicht.h"
27 #include "debug.h"
28 #include "mapnode.h" // For content_t
29
30 #define QUANTITY_ITEM_MAX_COUNT 99
31
32 class ServerActiveObject;
33 class ServerEnvironment;
34 struct PointedThing;
35 class ITextureSource;
36 class IGameDef;
37
38 class InventoryItem
39 {
40 public:
41         InventoryItem(IGameDef *gamedef, u16 count);
42         virtual ~InventoryItem();
43         
44         static InventoryItem* deSerialize(std::istream &is, IGameDef *gamedef);
45         static InventoryItem* deSerialize(const std::string &str,
46                         IGameDef *gamedef);
47         
48         virtual const char* getName() const = 0;
49         // Shall write the name and the parameters
50         virtual void serialize(std::ostream &os) const = 0;
51         // Shall make an exact clone of the item
52         virtual InventoryItem* clone() = 0;
53         // Return the name of the image for this item
54         virtual std::string getImageBasename() const { return ""; }
55 #ifndef SERVER
56         // Shall return an image of the item (or NULL)
57         virtual video::ITexture * getImage() const
58                 { return NULL; }
59         // Shall return an image of the item without embellishments (or NULL)
60         virtual video::ITexture * getImageRaw() const
61                 { return getImage(); }
62 #endif
63         // Shall return a text to show in the GUI
64         virtual std::string getText() { return ""; }
65         // Returns the string used for inventory
66         virtual std::string getItemString();
67         
68         // Shall return false if item is not known and cannot be used
69         virtual bool isKnown() const { return true; }
70
71         /*
72                 Quantity methods
73         */
74
75         // Return true if the item can be add()ed to the other
76         virtual bool addableTo(const InventoryItem *other) const
77         { return false; }
78         // Return true if the other item contains this item
79         virtual bool isSubsetOf(const InventoryItem *other) const
80         { return false; }
81         // Remove the other item from this one if possible and return true
82         // Return false if not possible
83         virtual bool removeOther(const InventoryItem *other)
84         { return false; }
85         
86         u16 getCount() const
87         { return m_count; }
88         void setCount(u16 count)
89         { m_count = count; }
90
91         u16 freeSpace() const
92         {
93                 u16 max = getStackMax();
94                 if(m_count > max)
95                         return 0;
96                 return max - m_count;
97         }
98
99         void add(u16 count)
100         {
101                 m_count += count;
102         }
103         void remove(u16 count)
104         {
105                 assert(m_count >= count);
106                 m_count -= count;
107         }
108
109         /*
110                 Other properties
111         */
112
113         // Maximum size of a stack
114         virtual u16 getStackMax() const {return 1;}
115         // Whether it can be used
116         virtual bool isUsable() const {return false;}
117         // Whether it can be cooked
118         virtual bool isCookable() const {return false;}
119         // Result of cooking (can randomize)
120         virtual InventoryItem *createCookResult() const {return NULL;}
121         // Time of cooking
122         virtual float getCookTime() const {return 3.0;}
123         // Whether it can be burned (<0 = cannot be burned)
124         virtual float getBurnTime() const {return -1;}
125         // Gets amount of items that dropping one ItemSAO will decrement
126         // -1 means as many as possible
127         virtual s16 getDropCount() const { return -1; }
128         // Whether this item can point to liquids
129         virtual bool areLiquidsPointable() const { return false; }
130
131         // Creates an object from the item and places it in the world.
132         // If return value is true, item should be removed.
133         virtual bool dropOrPlace(ServerEnvironment *env,
134                         ServerActiveObject *dropper,
135                         v3f pos, bool place, s16 count);
136
137         // Eat, press, activate, whatever.
138         // Called when item is left-clicked while in hand.
139         // If returns true, item shall be deleted.
140         virtual bool use(ServerEnvironment *env,
141                         ServerActiveObject *user,
142                         const PointedThing& pointed){return false;}
143
144 protected:
145         IGameDef *m_gamedef;
146         u16 m_count;
147 };
148
149 class MaterialItem : public InventoryItem
150 {
151 public:
152         MaterialItem(IGameDef *gamedef, std::string nodename, u16 count);
153         // Legacy constructor
154         MaterialItem(IGameDef *gamedef, content_t content, u16 count);
155         /*
156                 Implementation interface
157         */
158         virtual const char* getName() const
159         {
160                 return "MaterialItem";
161         }
162         virtual void serialize(std::ostream &os) const
163         {
164                 os<<"node";
165                 os<<" \"";
166                 os<<m_nodename;
167                 os<<"\" ";
168                 os<<m_count;
169         }
170         virtual InventoryItem* clone()
171         {
172                 return new MaterialItem(m_gamedef, m_nodename, m_count);
173         }
174 #ifndef SERVER
175         video::ITexture * getImage() const;
176 #endif
177         std::string getText()
178         {
179                 std::ostringstream os;
180                 os<<m_count;
181                 return os.str();
182         }
183
184         virtual bool addableTo(const InventoryItem *other) const
185         {
186                 if(std::string(other->getName()) != "MaterialItem")
187                         return false;
188                 MaterialItem *m = (MaterialItem*)other;
189                 if(m->m_nodename != m_nodename)
190                         return false;
191                 return true;
192         }
193         virtual bool isSubsetOf(const InventoryItem *other) const
194         {
195                 if(std::string(other->getName()) != "MaterialItem")
196                         return false;
197                 MaterialItem *m = (MaterialItem*)other;
198                 if(m->m_nodename != m_nodename)
199                         return false;
200                 return m_count <= m->m_count;
201         }
202         virtual bool removeOther(const InventoryItem *other)
203         {
204                 if(!other->isSubsetOf(this))
205                         return false;
206                 MaterialItem *m = (MaterialItem*)other;
207                 m_count += m->m_count;
208                 return true;
209         }
210
211         u16 getStackMax() const
212         {
213                 return QUANTITY_ITEM_MAX_COUNT;
214         }
215
216         /*
217                 Other properties
218         */
219         bool isCookable() const;
220         InventoryItem *createCookResult() const;
221         float getCookTime() const;
222         float getBurnTime() const;
223         /*
224                 Special properties (not part of virtual interface)
225         */
226         std::string getNodeName() const
227         { return m_nodename; }
228         content_t getMaterial() const;
229 private:
230         std::string m_nodename;
231 };
232
233 /*
234         An item that is used as a mid-product when crafting.
235         Subnames:
236         - Stick
237 */
238 class CraftItem : public InventoryItem
239 {
240 public:
241         CraftItem(IGameDef *gamedef, std::string subname, u16 count);
242         /*
243                 Implementation interface
244         */
245         virtual const char* getName() const
246         {
247                 return "CraftItem";
248         }
249         virtual void serialize(std::ostream &os) const
250         {
251                 os<<"craft";
252                 os<<" \"";
253                 os<<m_subname;
254                 os<<"\" ";
255                 os<<m_count;
256         }
257         virtual InventoryItem* clone()
258         {
259                 return new CraftItem(m_gamedef, m_subname, m_count);
260         }
261 #ifndef SERVER
262         video::ITexture * getImage() const;
263 #endif
264         std::string getText()
265         {
266                 std::ostringstream os;
267                 os<<m_count;
268                 return os.str();
269         }
270
271         virtual bool isKnown() const;
272
273         virtual bool addableTo(const InventoryItem *other) const
274         {
275                 if(std::string(other->getName()) != "CraftItem")
276                         return false;
277                 CraftItem *m = (CraftItem*)other;
278                 if(m->m_subname != m_subname)
279                         return false;
280                 return true;
281         }
282         virtual bool isSubsetOf(const InventoryItem *other) const
283         {
284                 if(std::string(other->getName()) != "CraftItem")
285                         return false;
286                 CraftItem *m = (CraftItem*)other;
287                 if(m->m_subname != m_subname)
288                         return false;
289                 return m_count <= m->m_count;
290         }
291         virtual bool removeOther(const InventoryItem *other)
292         {
293                 if(!other->isSubsetOf(this))
294                         return false;
295                 CraftItem *m = (CraftItem*)other;
296                 m_count += m->m_count;
297                 return true;
298         }
299
300         /*
301                 Other properties
302         */
303
304         u16 getStackMax() const;
305         bool isUsable() const;
306         bool isCookable() const;
307         InventoryItem *createCookResult() const;
308         float getCookTime() const;
309         float getBurnTime() const;
310         s16 getDropCount() const;
311         bool areLiquidsPointable() const;
312
313         bool dropOrPlace(ServerEnvironment *env,
314                         ServerActiveObject *dropper,
315                         v3f pos, bool place, s16 count);
316         bool use(ServerEnvironment *env,
317                         ServerActiveObject *user,
318                         const PointedThing& pointed);
319
320         /*
321                 Special methods
322         */
323         std::string getSubName()
324         {
325                 return m_subname;
326         }
327 private:
328         std::string m_subname;
329 };
330
331 class ToolItem : public InventoryItem
332 {
333 public:
334         ToolItem(IGameDef *gamedef, std::string toolname, u16 wear);
335         /*
336                 Implementation interface
337         */
338         virtual const char* getName() const
339         {
340                 return "ToolItem";
341         }
342         virtual void serialize(std::ostream &os) const
343         {
344                 os<<"tool";
345                 os<<" \"";
346                 os<<m_toolname;
347                 os<<"\" ";
348                 os<<m_wear;
349         }
350         virtual InventoryItem* clone()
351         {
352                 return new ToolItem(m_gamedef, m_toolname, m_wear);
353         }
354
355         std::string getImageBasename() const;
356 #ifndef SERVER
357         video::ITexture * getImage() const;
358         video::ITexture * getImageRaw() const;
359 #endif
360
361         std::string getText()
362         {
363                 return "";
364         }
365         
366         virtual bool isKnown() const;
367
368         virtual bool isSubsetOf(const InventoryItem *other) const
369         {
370                 if(std::string(other->getName()) != "ToolItem")
371                         return false;
372                 ToolItem *m = (ToolItem*)other;
373                 if(m->m_toolname != m_toolname)
374                         return false;
375                 return m_wear <= m->m_wear;
376         }
377         virtual bool removeOther(const InventoryItem *other)
378         {
379                 if(!other->isSubsetOf(this))
380                         return false;
381                 ToolItem *m = (ToolItem*)other;
382                 m_wear -= m->m_wear;
383                 return true;
384         }
385
386         /*
387                 Special methods
388         */
389         std::string getToolName()
390         {
391                 return m_toolname;
392         }
393         u16 getWear()
394         {
395                 return m_wear;
396         }
397         // Returns true if weared out
398         bool addWear(u16 add)
399         {
400                 if(m_wear >= 65535 - add)
401                 {
402                         m_wear = 65535;
403                         return true;
404                 }
405                 else
406                 {
407                         m_wear += add;
408                         return false;
409                 }
410         }
411 private:
412         std::string m_toolname;
413         u16 m_wear;
414 };
415
416 class InventoryList
417 {
418 public:
419         InventoryList(std::string name, u32 size);
420         ~InventoryList();
421         void clearItems();
422         void setSize(u32 newsize);
423         void serialize(std::ostream &os) const;
424         void deSerialize(std::istream &is, IGameDef *gamedef);
425
426         InventoryList(const InventoryList &other);
427         InventoryList & operator = (const InventoryList &other);
428
429         const std::string &getName() const;
430         u32 getSize();
431         // Count used slots
432         u32 getUsedSlots();
433         u32 getFreeSlots();
434
435         /*bool getDirty(){ return m_dirty; }
436         void setDirty(bool dirty=true){ m_dirty = dirty; }*/
437         
438         // Get pointer to item
439         const InventoryItem * getItem(u32 i) const;
440         InventoryItem * getItem(u32 i);
441         // Returns old item (or NULL). Parameter can be NULL.
442         InventoryItem * changeItem(u32 i, InventoryItem *newitem);
443         // Delete item
444         void deleteItem(u32 i);
445
446         // Adds an item to a suitable place. Returns leftover item.
447         // If all went into the list, returns NULL.
448         InventoryItem * addItem(InventoryItem *newitem);
449
450         // If possible, adds item to given slot.
451         // If cannot be added at all, returns the item back.
452         // If can be added partly, decremented item is returned back.
453         // If can be added fully, NULL is returned.
454         InventoryItem * addItem(u32 i, InventoryItem *newitem);
455
456         // Checks whether the item could be added to the given slot
457         bool itemFits(const u32 i, const InventoryItem *newitem);
458
459         // Checks whether there is room for a given item
460         bool roomForItem(const InventoryItem *item);
461
462         // Checks whether there is room for a given item aftr it has been cooked
463         bool roomForCookedItem(const InventoryItem *item);
464
465         // Takes some items from a slot.
466         // If there are not enough, takes as many as it can.
467         // Returns NULL if couldn't take any.
468         InventoryItem * takeItem(u32 i, u32 count);
469
470         // Decrements amount of every material item
471         void decrementMaterials(u16 count);
472
473         void print(std::ostream &o);
474         
475 private:
476         core::array<InventoryItem*> m_items;
477         u32 m_size;
478         std::string m_name;
479         //bool m_dirty;
480 };
481
482 class Inventory
483 {
484 public:
485         ~Inventory();
486
487         void clear();
488
489         Inventory();
490         Inventory(const Inventory &other);
491         Inventory & operator = (const Inventory &other);
492         
493         void serialize(std::ostream &os) const;
494         void deSerialize(std::istream &is, IGameDef *gamedef);
495
496         InventoryList * addList(const std::string &name, u32 size);
497         InventoryList * getList(const std::string &name);
498         const InventoryList * getList(const std::string &name) const;
499         bool deleteList(const std::string &name);
500         // A shorthand for adding items.
501         // Returns NULL if the item was fully added, leftover otherwise.
502         InventoryItem * addItem(const std::string &listname, InventoryItem *newitem)
503         {
504                 InventoryList *list = getList(listname);
505                 if(list == NULL)
506                         return newitem;
507                 return list->addItem(newitem);
508         }
509         
510 private:
511         // -1 if not found
512         const s32 getListIndex(const std::string &name) const;
513
514         core::array<InventoryList*> m_lists;
515 };
516
517 #endif
518