]> git.lizzy.rs Git - dragonfireclient.git/blob - src/inventory.h
797a675094a342ea77b94d311d2158e96dd2df5f
[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                 if(m_content >= USEFUL_CONTENT_COUNT)
126                         return NULL;
127                         
128                 return g_irrlicht->getTexture(g_content_inventory_texture_paths[m_content]);
129         }
130 #endif
131         std::string getText()
132         {
133                 std::ostringstream os;
134                 os<<m_count;
135                 return os.str();
136         }
137
138         virtual bool addableTo(InventoryItem *other)
139         {
140                 if(std::string(other->getName()) != "MaterialItem")
141                         return false;
142                 MaterialItem *m = (MaterialItem*)other;
143                 if(m->getMaterial() != m_content)
144                         return false;
145                 return true;
146         }
147         u16 freeSpace()
148         {
149                 if(m_count > QUANTITY_ITEM_MAX_COUNT)
150                         return 0;
151                 return QUANTITY_ITEM_MAX_COUNT - m_count;
152         }
153         /*
154                 Special methods
155         */
156         u8 getMaterial()
157         {
158                 return m_content;
159         }
160 private:
161         u8 m_content;
162 };
163
164 class MapBlockObjectItem : public InventoryItem
165 {
166 public:
167         MapBlockObjectItem(std::string inventorystring):
168                 InventoryItem(1)
169         {
170                 m_inventorystring = inventorystring;
171         }
172         
173         /*
174                 Implementation interface
175         */
176         virtual const char* getName() const
177         {
178                 return "MBOItem";
179         }
180         virtual void serialize(std::ostream &os)
181         {
182                 for(;;)
183                 {
184                         size_t t = m_inventorystring.find('|');
185                         if(t == std::string::npos)
186                                 break;
187                         m_inventorystring[t] = '?';
188                 }
189                 os<<getName();
190                 os<<" ";
191                 os<<m_inventorystring;
192                 os<<"|";
193         }
194         virtual InventoryItem* clone()
195         {
196                 return new MapBlockObjectItem(m_inventorystring);
197         }
198
199 #ifndef SERVER
200         video::ITexture * getImage();
201 #endif
202         std::string getText();
203
204         /*
205                 Special methods
206         */
207         std::string getInventoryString()
208         {
209                 return m_inventorystring;
210         }
211
212         MapBlockObject * createObject(v3f pos, f32 player_yaw, f32 player_pitch);
213
214 private:
215         std::string m_inventorystring;
216 };
217
218 /*
219         An item that is used as a mid-product when crafting.
220         Subnames:
221         - Stick
222 */
223 class CraftItem : public InventoryItem
224 {
225 public:
226         CraftItem(std::string subname, u16 count):
227                 InventoryItem(count)
228         {
229                 m_subname = subname;
230         }
231         /*
232                 Implementation interface
233         */
234         virtual const char* getName() const
235         {
236                 return "CraftItem";
237         }
238         virtual void serialize(std::ostream &os)
239         {
240                 os<<getName();
241                 os<<" ";
242                 os<<m_subname;
243                 os<<" ";
244                 os<<m_count;
245         }
246         virtual InventoryItem* clone()
247         {
248                 return new CraftItem(m_subname, m_count);
249         }
250 #ifndef SERVER
251         video::ITexture * getImage()
252         {
253                 std::string basename;
254
255                 if(m_subname == "Stick")
256                         basename = porting::getDataPath("stick.png");
257                 else if(m_subname == "lump_of_coal")
258                         basename = porting::getDataPath("lump_of_coal.png");
259                 else if(m_subname == "lump_of_iron")
260                         basename = porting::getDataPath("lump_of_iron.png");
261                 else
262                         basename = porting::getDataPath("cloud.png[[mod:crack3");
263                 
264                 // Get such a texture
265                 return g_irrlicht->getTexture(basename);
266         }
267 #endif
268         std::string getText()
269         {
270                 std::ostringstream os;
271                 os<<m_count;
272                 return os.str();
273         }
274         virtual bool addableTo(InventoryItem *other)
275         {
276                 if(std::string(other->getName()) != "CraftItem")
277                         return false;
278                 CraftItem *m = (CraftItem*)other;
279                 if(m->m_subname != m_subname)
280                         return false;
281                 return true;
282         }
283         u16 freeSpace()
284         {
285                 if(m_count > QUANTITY_ITEM_MAX_COUNT)
286                         return 0;
287                 return QUANTITY_ITEM_MAX_COUNT - m_count;
288         }
289         /*
290                 Special methods
291         */
292         std::string getSubName()
293         {
294                 return m_subname;
295         }
296 private:
297         std::string m_subname;
298 };
299
300 class ToolItem : public InventoryItem
301 {
302 public:
303         ToolItem(std::string toolname, u16 wear):
304                 InventoryItem(1)
305         {
306                 m_toolname = toolname;
307                 m_wear = wear;
308         }
309         /*
310                 Implementation interface
311         */
312         virtual const char* getName() const
313         {
314                 return "ToolItem";
315         }
316         virtual void serialize(std::ostream &os)
317         {
318                 os<<getName();
319                 os<<" ";
320                 os<<m_toolname;
321                 os<<" ";
322                 os<<m_wear;
323         }
324         virtual InventoryItem* clone()
325         {
326                 return new ToolItem(m_toolname, m_wear);
327         }
328 #ifndef SERVER
329         video::ITexture * getImage()
330         {
331                 std::string basename;
332                 if(m_toolname == "WPick")
333                         basename = porting::getDataPath("tool_wpick.png").c_str();
334                 else if(m_toolname == "STPick")
335                         basename = porting::getDataPath("tool_stpick.png").c_str();
336                 else if(m_toolname == "MesePick")
337                         basename = porting::getDataPath("tool_mesepick.png").c_str();
338                 // Default to cloud texture
339                 else
340                         basename = porting::getDataPath("cloud.png").c_str();
341                         //basename = tile_texture_path_get(TILE_CLOUD);
342                 
343                 /*
344                         Calculate some progress value with sane amount of
345                         maximum states
346                 */
347                 u32 maxprogress = 30;
348                 u32 toolprogress = (65535-m_wear)/(65535/maxprogress);
349                 
350                 // Make texture name for the new texture with a progress bar
351                 float value_f = (float)toolprogress / (float)maxprogress;
352                 std::ostringstream os;
353                 os<<basename<<"[[mod:progressbar"<<value_f;
354                 return g_irrlicht->getTexture(os.str());
355
356                 /*// Make texture name for the new texture with a progress bar
357                 std::ostringstream os;
358                 os<<basename<<"-toolprogress-"<<toolprogress;
359                 std::string finalname = os.str();
360
361                 float value_f = (float)toolprogress / (float)maxprogress;
362                 
363                 // Get such a texture
364                 TextureMod *mod = new ProgressBarTextureMod(value_f);
365                 return g_irrlicht->getTexture(TextureSpec(finalname, basename, mod));*/
366         }
367 #endif
368         std::string getText()
369         {
370                 return "";
371                 
372                 /*std::ostringstream os;
373                 u16 f = 4;
374                 u16 d = 65535/f;
375                 u16 i;
376                 for(i=0; i<(65535-m_wear)/d; i++)
377                         os<<'X';
378                 for(; i<f; i++)
379                         os<<'-';
380                 return os.str();*/
381                 
382                 /*std::ostringstream os;
383                 os<<m_toolname;
384                 os<<" ";
385                 os<<(m_wear/655);
386                 return os.str();*/
387         }
388         /*
389                 Special methods
390         */
391         std::string getToolName()
392         {
393                 return m_toolname;
394         }
395         u16 getWear()
396         {
397                 return m_wear;
398         }
399         // Returns true if weared out
400         bool addWear(u16 add)
401         {
402                 if(m_wear >= 65535 - add)
403                 {
404                         m_wear = 65535;
405                         return true;
406                 }
407                 else
408                 {
409                         m_wear += add;
410                         return false;
411                 }
412         }
413 private:
414         std::string m_toolname;
415         u16 m_wear;
416 };
417
418 class InventoryList
419 {
420 public:
421         InventoryList(std::string name, u32 size);
422         ~InventoryList();
423         void clearItems();
424         void serialize(std::ostream &os);
425         void deSerialize(std::istream &is);
426
427         InventoryList(const InventoryList &other);
428         InventoryList & operator = (const InventoryList &other);
429
430         std::string getName();
431         u32 getSize();
432         // Count used slots
433         u32 getUsedSlots();
434         
435         // Get pointer to item
436         InventoryItem * getItem(u32 i);
437         // Returns old item (or NULL). Parameter can be NULL.
438         InventoryItem * changeItem(u32 i, InventoryItem *newitem);
439         // Delete item
440         void deleteItem(u32 i);
441         // Adds an item to a suitable place. Returns leftover item.
442         // If all went into the list, returns NULL.
443         InventoryItem * addItem(InventoryItem *newitem);
444
445         // If possible, adds item to given slot.
446         // If cannot be added at all, returns the item back.
447         // If can be added partly, decremented item is returned back.
448         // If can be added fully, NULL is returned.
449         InventoryItem * addItem(u32 i, InventoryItem *newitem);
450
451         // Takes some items from a slot.
452         // If there are not enough, takes as many as it can.
453         // Returns NULL if couldn't take any.
454         InventoryItem * takeItem(u32 i, u32 count);
455
456         // Decrements amount of every material item
457         void decrementMaterials(u16 count);
458
459         void print(std::ostream &o);
460         
461 private:
462         core::array<InventoryItem*> m_items;
463         u32 m_size;
464         std::string m_name;
465 };
466
467 class Inventory
468 {
469 public:
470         ~Inventory();
471
472         void clear();
473
474         Inventory();
475         Inventory(const Inventory &other);
476         Inventory & operator = (const Inventory &other);
477         
478         void serialize(std::ostream &os);
479         void deSerialize(std::istream &is);
480
481         InventoryList * addList(const std::string &name, u32 size);
482         InventoryList * getList(const std::string &name);
483         bool deleteList(const std::string &name);
484         // A shorthand for adding items.
485         // Returns NULL if the item was fully added, leftover otherwise.
486         InventoryItem * addItem(const std::string &listname, InventoryItem *newitem)
487         {
488                 InventoryList *list = getList(listname);
489                 if(list == NULL)
490                         return newitem;
491                 return list->addItem(newitem);
492         }
493         
494 private:
495         // -1 if not found
496         s32 getListIndex(const std::string &name);
497
498         core::array<InventoryList*> m_lists;
499 };
500
501 #define IACTION_MOVE 0
502
503 struct InventoryAction
504 {
505         static InventoryAction * deSerialize(std::istream &is);
506         
507         virtual u16 getType() const = 0;
508         virtual void serialize(std::ostream &os) = 0;
509         virtual void apply(Inventory *inventory) = 0;
510 };
511
512 struct IMoveAction : public InventoryAction
513 {
514         // count=0 means "everything"
515         u16 count;
516         std::string from_name;
517         s16 from_i;
518         std::string to_name;
519         s16 to_i;
520         
521         IMoveAction()
522         {
523                 count = 0;
524                 from_i = -1;
525                 to_i = -1;
526         }
527         IMoveAction(std::istream &is)
528         {
529                 std::string ts;
530
531                 std::getline(is, ts, ' ');
532                 count = stoi(ts);
533
534                 std::getline(is, from_name, ' ');
535
536                 std::getline(is, ts, ' ');
537                 from_i = stoi(ts);
538
539                 std::getline(is, to_name, ' ');
540
541                 std::getline(is, ts, ' ');
542                 to_i = stoi(ts);
543         }
544
545         u16 getType() const
546         {
547                 return IACTION_MOVE;
548         }
549
550         void serialize(std::ostream &os)
551         {
552                 os<<"Move ";
553                 os<<count<<" ";
554                 os<<from_name<<" ";
555                 os<<from_i<<" ";
556                 os<<to_name<<" ";
557                 os<<to_i;
558         }
559
560         void apply(Inventory *inventory);
561 };
562
563 #endif
564