]> git.lizzy.rs Git - dragonfireclient.git/blob - src/inventory.h
Chests work now!
[dragonfireclient.git] / src / inventory.h
1 /*
2 Minetest-c55
3 Copyright (C) 2010 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 /*
21 (c) 2010 Perttu Ahola <celeron55@gmail.com>
22 */
23
24 #ifndef INVENTORY_HEADER
25 #define INVENTORY_HEADER
26
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 #include "common_irrlicht.h"
31 #include "debug.h"
32 #include "mapblockobject.h"
33 // For g_materials
34 #include "main.h"
35
36 #define QUANTITY_ITEM_MAX_COUNT 99
37
38 class InventoryItem
39 {
40 public:
41         InventoryItem(u16 count);
42         virtual ~InventoryItem();
43         
44         static InventoryItem* deSerialize(std::istream &is);
45         
46         virtual const char* getName() const = 0;
47         // Shall write the name and the parameters
48         virtual void serialize(std::ostream &os) = 0;
49         // Shall make an exact clone of the item
50         virtual InventoryItem* clone() = 0;
51 #ifndef SERVER
52         // Shall return an image to show in the GUI (or NULL)
53         virtual video::ITexture * getImage() { return NULL; }
54 #endif
55         // Shall return a text to show in the GUI
56         virtual std::string getText() { return ""; }
57
58         // Shall return true if the item can be add()ed to the other
59         virtual bool addableTo(InventoryItem *other)
60         {
61                 return false;
62         }
63         
64         /*
65                 Quantity methods
66         */
67         u16 getCount()
68         {
69                 return m_count;
70         }
71         void setCount(u16 count)
72         {
73                 m_count = count;
74         }
75         virtual u16 freeSpace()
76         {
77                 return 0;
78         }
79         void add(u16 count)
80         {
81                 assert(m_count + count <= QUANTITY_ITEM_MAX_COUNT);
82                 m_count += count;
83         }
84         void remove(u16 count)
85         {
86                 assert(m_count >= count);
87                 m_count -= count;
88         }
89
90 protected:
91         u16 m_count;
92 };
93
94 class MaterialItem : public InventoryItem
95 {
96 public:
97         MaterialItem(u8 content, u16 count):
98                 InventoryItem(count)
99         {
100                 m_content = content;
101         }
102         /*
103                 Implementation interface
104         */
105         virtual const char* getName() const
106         {
107                 return "MaterialItem";
108         }
109         virtual void serialize(std::ostream &os)
110         {
111                 //os.imbue(std::locale("C"));
112                 os<<getName();
113                 os<<" ";
114                 os<<(unsigned int)m_content;
115                 os<<" ";
116                 os<<m_count;
117         }
118         virtual InventoryItem* clone()
119         {
120                 return new MaterialItem(m_content, m_count);
121         }
122 #ifndef SERVER
123         video::ITexture * getImage()
124         {
125                 return content_features(m_content).inventory_texture;
126                 return NULL;
127         }
128 #endif
129         std::string getText()
130         {
131                 std::ostringstream os;
132                 os<<m_count;
133                 return os.str();
134         }
135
136         virtual bool addableTo(InventoryItem *other)
137         {
138                 if(std::string(other->getName()) != "MaterialItem")
139                         return false;
140                 MaterialItem *m = (MaterialItem*)other;
141                 if(m->getMaterial() != m_content)
142                         return false;
143                 return true;
144         }
145         u16 freeSpace()
146         {
147                 if(m_count > QUANTITY_ITEM_MAX_COUNT)
148                         return 0;
149                 return QUANTITY_ITEM_MAX_COUNT - m_count;
150         }
151         /*
152                 Special methods
153         */
154         u8 getMaterial()
155         {
156                 return m_content;
157         }
158 private:
159         u8 m_content;
160 };
161
162 class MapBlockObjectItem : public InventoryItem
163 {
164 public:
165         MapBlockObjectItem(std::string inventorystring):
166                 InventoryItem(1)
167         {
168                 m_inventorystring = inventorystring;
169         }
170         
171         /*
172                 Implementation interface
173         */
174         virtual const char* getName() const
175         {
176                 return "MBOItem";
177         }
178         virtual void serialize(std::ostream &os)
179         {
180                 for(;;)
181                 {
182                         size_t t = m_inventorystring.find('|');
183                         if(t == std::string::npos)
184                                 break;
185                         m_inventorystring[t] = '?';
186                 }
187                 os<<getName();
188                 os<<" ";
189                 os<<m_inventorystring;
190                 os<<"|";
191         }
192         virtual InventoryItem* clone()
193         {
194                 return new MapBlockObjectItem(m_inventorystring);
195         }
196
197 #ifndef SERVER
198         video::ITexture * getImage();
199 #endif
200         std::string getText();
201
202         /*
203                 Special methods
204         */
205         std::string getInventoryString()
206         {
207                 return m_inventorystring;
208         }
209
210         MapBlockObject * createObject(v3f pos, f32 player_yaw, f32 player_pitch);
211
212 private:
213         std::string m_inventorystring;
214 };
215
216 /*
217         An item that is used as a mid-product when crafting.
218         Subnames:
219         - Stick
220 */
221 class CraftItem : public InventoryItem
222 {
223 public:
224         CraftItem(std::string subname, u16 count):
225                 InventoryItem(count)
226         {
227                 m_subname = subname;
228         }
229         /*
230                 Implementation interface
231         */
232         virtual const char* getName() const
233         {
234                 return "CraftItem";
235         }
236         virtual void serialize(std::ostream &os)
237         {
238                 os<<getName();
239                 os<<" ";
240                 os<<m_subname;
241                 os<<" ";
242                 os<<m_count;
243         }
244         virtual InventoryItem* clone()
245         {
246                 return new CraftItem(m_subname, m_count);
247         }
248 #ifndef SERVER
249         video::ITexture * getImage()
250         {
251                 if(g_texturesource == NULL)
252                         return NULL;
253                 
254                 std::string name;
255
256                 if(m_subname == "Stick")
257                         name = "stick.png";
258                 else if(m_subname == "lump_of_coal")
259                         name = "lump_of_coal.png";
260                 else if(m_subname == "lump_of_iron")
261                         name = "lump_of_iron.png";
262                 else
263                         name = "cloud.png";
264                 
265                 // Get such a texture
266                 //return g_irrlicht->getTexture(name);
267                 return g_texturesource->getTextureRaw(name);
268         }
269 #endif
270         std::string getText()
271         {
272                 std::ostringstream os;
273                 os<<m_count;
274                 return os.str();
275         }
276         virtual bool addableTo(InventoryItem *other)
277         {
278                 if(std::string(other->getName()) != "CraftItem")
279                         return false;
280                 CraftItem *m = (CraftItem*)other;
281                 if(m->m_subname != m_subname)
282                         return false;
283                 return true;
284         }
285         u16 freeSpace()
286         {
287                 if(m_count > QUANTITY_ITEM_MAX_COUNT)
288                         return 0;
289                 return QUANTITY_ITEM_MAX_COUNT - m_count;
290         }
291         /*
292                 Special methods
293         */
294         std::string getSubName()
295         {
296                 return m_subname;
297         }
298 private:
299         std::string m_subname;
300 };
301
302 class ToolItem : public InventoryItem
303 {
304 public:
305         ToolItem(std::string toolname, u16 wear):
306                 InventoryItem(1)
307         {
308                 m_toolname = toolname;
309                 m_wear = wear;
310         }
311         /*
312                 Implementation interface
313         */
314         virtual const char* getName() const
315         {
316                 return "ToolItem";
317         }
318         virtual void serialize(std::ostream &os)
319         {
320                 os<<getName();
321                 os<<" ";
322                 os<<m_toolname;
323                 os<<" ";
324                 os<<m_wear;
325         }
326         virtual InventoryItem* clone()
327         {
328                 return new ToolItem(m_toolname, m_wear);
329         }
330 #ifndef SERVER
331         video::ITexture * getImage()
332         {
333                 if(g_texturesource == NULL)
334                         return NULL;
335                 
336                 std::string basename;
337                 if(m_toolname == "WPick")
338                         basename = "tool_wpick.png";
339                 else if(m_toolname == "STPick")
340                         basename = "tool_stpick.png";
341                 else if(m_toolname == "MesePick")
342                         basename = "tool_mesepick.png";
343                 else
344                         basename = "cloud.png";
345                 
346                 /*
347                         Calculate a progress value with sane amount of
348                         maximum states
349                 */
350                 u32 maxprogress = 30;
351                 u32 toolprogress = (65535-m_wear)/(65535/maxprogress);
352                 
353                 float value_f = (float)toolprogress / (float)maxprogress;
354                 std::ostringstream os;
355                 os<<basename<<"^[progressbar"<<value_f;
356
357                 return g_texturesource->getTextureRaw(os.str());
358
359                 /*TextureSpec spec;
360                 spec.addTid(g_irrlicht->getTextureId(basename));
361                 spec.addTid(g_irrlicht->getTextureId(os.str()));
362                 return g_irrlicht->getTexture(spec);*/
363         }
364 #endif
365         std::string getText()
366         {
367                 return "";
368                 
369                 /*std::ostringstream os;
370                 u16 f = 4;
371                 u16 d = 65535/f;
372                 u16 i;
373                 for(i=0; i<(65535-m_wear)/d; i++)
374                         os<<'X';
375                 for(; i<f; i++)
376                         os<<'-';
377                 return os.str();*/
378                 
379                 /*std::ostringstream os;
380                 os<<m_toolname;
381                 os<<" ";
382                 os<<(m_wear/655);
383                 return os.str();*/
384         }
385         /*
386                 Special methods
387         */
388         std::string getToolName()
389         {
390                 return m_toolname;
391         }
392         u16 getWear()
393         {
394                 return m_wear;
395         }
396         // Returns true if weared out
397         bool addWear(u16 add)
398         {
399                 if(m_wear >= 65535 - add)
400                 {
401                         m_wear = 65535;
402                         return true;
403                 }
404                 else
405                 {
406                         m_wear += add;
407                         return false;
408                 }
409         }
410 private:
411         std::string m_toolname;
412         u16 m_wear;
413 };
414
415 class InventoryList
416 {
417 public:
418         InventoryList(std::string name, u32 size);
419         ~InventoryList();
420         void clearItems();
421         void serialize(std::ostream &os);
422         void deSerialize(std::istream &is);
423
424         InventoryList(const InventoryList &other);
425         InventoryList & operator = (const InventoryList &other);
426
427         std::string getName();
428         u32 getSize();
429         // Count used slots
430         u32 getUsedSlots();
431         
432         // Get pointer to item
433         InventoryItem * getItem(u32 i);
434         // Returns old item (or NULL). Parameter can be NULL.
435         InventoryItem * changeItem(u32 i, InventoryItem *newitem);
436         // Delete item
437         void deleteItem(u32 i);
438         // Adds an item to a suitable place. Returns leftover item.
439         // If all went into the list, returns NULL.
440         InventoryItem * addItem(InventoryItem *newitem);
441
442         // If possible, adds item to given slot.
443         // If cannot be added at all, returns the item back.
444         // If can be added partly, decremented item is returned back.
445         // If can be added fully, NULL is returned.
446         InventoryItem * addItem(u32 i, InventoryItem *newitem);
447
448         // Takes some items from a slot.
449         // If there are not enough, takes as many as it can.
450         // Returns NULL if couldn't take any.
451         InventoryItem * takeItem(u32 i, u32 count);
452
453         // Decrements amount of every material item
454         void decrementMaterials(u16 count);
455
456         void print(std::ostream &o);
457         
458 private:
459         core::array<InventoryItem*> m_items;
460         u32 m_size;
461         std::string m_name;
462 };
463
464 class Inventory
465 {
466 public:
467         ~Inventory();
468
469         void clear();
470
471         Inventory();
472         Inventory(const Inventory &other);
473         Inventory & operator = (const Inventory &other);
474         
475         void serialize(std::ostream &os);
476         void deSerialize(std::istream &is);
477
478         InventoryList * addList(const std::string &name, u32 size);
479         InventoryList * getList(const std::string &name);
480         bool deleteList(const std::string &name);
481         // A shorthand for adding items.
482         // Returns NULL if the item was fully added, leftover otherwise.
483         InventoryItem * addItem(const std::string &listname, InventoryItem *newitem)
484         {
485                 InventoryList *list = getList(listname);
486                 if(list == NULL)
487                         return newitem;
488                 return list->addItem(newitem);
489         }
490         
491 private:
492         // -1 if not found
493         s32 getListIndex(const std::string &name);
494
495         core::array<InventoryList*> m_lists;
496 };
497
498 class Player;
499
500 struct InventoryContext
501 {
502         Player *current_player;
503         
504         InventoryContext():
505                 current_player(NULL)
506         {}
507 };
508
509 class InventoryAction;
510
511 class InventoryManager
512 {
513 public:
514         InventoryManager(){}
515         virtual ~InventoryManager(){}
516         
517         /*
518                 Get a pointer to an inventory specified by id.
519                 id can be:
520                 - "current_player"
521                 - "nodemeta:X,Y,Z"
522         */
523         virtual Inventory* getInventory(InventoryContext *c, std::string id)
524                 {return NULL;}
525         // Used on the server by InventoryAction::apply
526         virtual void inventoryModified(InventoryContext *c, std::string id)
527                 {}
528         // Used on the client
529         virtual void inventoryAction(InventoryAction *a)
530                 {}
531 };
532
533 #define IACTION_MOVE 0
534
535 struct InventoryAction
536 {
537         static InventoryAction * deSerialize(std::istream &is);
538         
539         virtual u16 getType() const = 0;
540         virtual void serialize(std::ostream &os) = 0;
541         virtual void apply(InventoryContext *c, InventoryManager *mgr) = 0;
542 };
543
544 struct IMoveAction : public InventoryAction
545 {
546         // count=0 means "everything"
547         u16 count;
548         std::string from_inv;
549         std::string from_list;
550         s16 from_i;
551         std::string to_inv;
552         std::string to_list;
553         s16 to_i;
554         
555         IMoveAction()
556         {
557                 count = 0;
558                 from_i = -1;
559                 to_i = -1;
560         }
561         IMoveAction(std::istream &is)
562         {
563                 std::string ts;
564
565                 std::getline(is, ts, ' ');
566                 count = stoi(ts);
567
568                 std::getline(is, from_inv, ' ');
569
570                 std::getline(is, from_list, ' ');
571
572                 std::getline(is, ts, ' ');
573                 from_i = stoi(ts);
574
575                 std::getline(is, to_inv, ' ');
576
577                 std::getline(is, to_list, ' ');
578
579                 std::getline(is, ts, ' ');
580                 to_i = stoi(ts);
581         }
582
583         u16 getType() const
584         {
585                 return IACTION_MOVE;
586         }
587
588         void serialize(std::ostream &os)
589         {
590                 os<<"Move ";
591                 os<<count<<" ";
592                 os<<from_inv<<" ";
593                 os<<from_list<<" ";
594                 os<<from_i<<" ";
595                 os<<to_inv<<" ";
596                 os<<to_list<<" ";
597                 os<<to_i;
598         }
599
600         void apply(InventoryContext *c, InventoryManager *mgr);
601 };
602
603 #endif
604