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