Add MoveSomewhere inventory action
[oweals/minetest.git] / src / inventorymanager.h
1 /*
2 Minetest
3 Copyright (C) 2010-2013 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 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.
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 Lesser General Public License for more details.
14
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.
18 */
19
20 #ifndef INVENTORYMANAGER_HEADER
21 #define INVENTORYMANAGER_HEADER
22
23 #include "inventory.h"
24 #include <iostream>
25 #include <string>
26 class ServerActiveObject;
27
28 struct InventoryLocation
29 {
30         enum Type{
31                 UNDEFINED,
32                 CURRENT_PLAYER,
33                 PLAYER,
34                 NODEMETA,
35         DETACHED,
36         } type;
37
38         std::string name; // PLAYER, DETACHED
39         v3s16 p; // NODEMETA
40
41         InventoryLocation()
42         {
43                 setUndefined();
44         }
45         void setUndefined()
46         {
47                 type = UNDEFINED;
48         }
49         void setCurrentPlayer()
50         {
51                 type = CURRENT_PLAYER;
52         }
53         void setPlayer(const std::string &name_)
54         {
55                 type = PLAYER;
56                 name = name_;
57         }
58         void setNodeMeta(v3s16 p_)
59         {
60                 type = NODEMETA;
61                 p = p_;
62         }
63         void setDetached(const std::string &name_)
64         {
65                 type = DETACHED;
66                 name = name_;
67         }
68
69         bool operator==(const InventoryLocation &other) const
70         {
71                 if(type != other.type)
72                         return false;
73                 switch(type){
74                 case UNDEFINED:
75                         return false;
76                 case CURRENT_PLAYER:
77                         return true;
78                 case PLAYER:
79                         return (name == other.name);
80                 case NODEMETA:
81                         return (p == other.p);
82                 case DETACHED:
83                         return (name == other.name);
84                 }
85                 return false;
86         }
87         bool operator!=(const InventoryLocation &other) const
88         {
89                 return !(*this == other);
90         }
91
92         void applyCurrentPlayer(const std::string &name_)
93         {
94                 if(type == CURRENT_PLAYER)
95                         setPlayer(name_);
96         }
97
98         std::string dump() const;
99         void serialize(std::ostream &os) const;
100         void deSerialize(std::istream &is);
101         void deSerialize(std::string s);
102 };
103
104 struct InventoryAction;
105
106 class InventoryManager
107 {
108 public:
109         InventoryManager(){}
110         virtual ~InventoryManager(){}
111         
112         // Get an inventory (server and client)
113         virtual Inventory* getInventory(const InventoryLocation &loc){return NULL;}
114     // Set modified (will be saved and sent over network; only on server)
115         virtual void setInventoryModified(const InventoryLocation &loc, bool playerSend = true){}
116     // Send inventory action to server (only on client)
117         virtual void inventoryAction(InventoryAction *a){}
118 };
119
120 #define IACTION_MOVE 0
121 #define IACTION_DROP 1
122 #define IACTION_CRAFT 2
123
124 struct InventoryAction
125 {
126         static InventoryAction * deSerialize(std::istream &is);
127         
128         virtual u16 getType() const = 0;
129         virtual void serialize(std::ostream &os) const = 0;
130         virtual void apply(InventoryManager *mgr, ServerActiveObject *player,
131                         IGameDef *gamedef) = 0;
132         virtual void clientApply(InventoryManager *mgr, IGameDef *gamedef) = 0;
133         virtual ~InventoryAction() {};
134 };
135
136 struct IMoveAction : public InventoryAction
137 {
138         // count=0 means "everything"
139         u16 count;
140         InventoryLocation from_inv;
141         std::string from_list;
142         s16 from_i;
143         InventoryLocation to_inv;
144         std::string to_list;
145         s16 to_i;
146         bool move_somewhere;
147
148         // treat these as private
149         // related to movement to somewhere
150         bool caused_by_move_somewhere;
151         u32 move_count;
152         
153         IMoveAction()
154         {
155                 count = 0;
156                 from_i = -1;
157                 to_i = -1;
158                 move_somewhere = false;
159                 caused_by_move_somewhere = false;
160                 move_count = 0;
161         }
162         
163         IMoveAction(std::istream &is, bool somewhere);
164
165         u16 getType() const
166         {
167                 return IACTION_MOVE;
168         }
169
170         void serialize(std::ostream &os) const
171         {
172                 if (!move_somewhere)
173                         os << "Move ";
174                 else
175                         os << "MoveSomewhere ";
176                 os << count << " ";
177                 os << from_inv.dump() << " ";
178                 os << from_list << " ";
179                 os << from_i << " ";
180                 os << to_inv.dump() << " ";
181                 os << to_list;
182                 if (!move_somewhere)
183                         os << " " << to_i;
184         }
185
186         void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef);
187
188         void clientApply(InventoryManager *mgr, IGameDef *gamedef);
189 };
190
191 struct IDropAction : public InventoryAction
192 {
193         // count=0 means "everything"
194         u16 count;
195         InventoryLocation from_inv;
196         std::string from_list;
197         s16 from_i;
198         
199         IDropAction()
200         {
201                 count = 0;
202                 from_i = -1;
203         }
204         
205         IDropAction(std::istream &is);
206
207         u16 getType() const
208         {
209                 return IACTION_DROP;
210         }
211
212         void serialize(std::ostream &os) const
213         {
214                 os<<"Drop ";
215                 os<<count<<" ";
216                 os<<from_inv.dump()<<" ";
217                 os<<from_list<<" ";
218                 os<<from_i;
219         }
220
221         void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef);
222
223         void clientApply(InventoryManager *mgr, IGameDef *gamedef);
224 };
225
226 struct ICraftAction : public InventoryAction
227 {
228         // count=0 means "everything"
229         u16 count;
230         InventoryLocation craft_inv;
231         
232         ICraftAction()
233         {
234                 count = 0;
235         }
236         
237         ICraftAction(std::istream &is);
238
239         u16 getType() const
240         {
241                 return IACTION_CRAFT;
242         }
243
244         void serialize(std::ostream &os) const
245         {
246                 os<<"Craft ";
247                 os<<count<<" ";
248                 os<<craft_inv.dump()<<" ";
249         }
250
251         void apply(InventoryManager *mgr, ServerActiveObject *player, IGameDef *gamedef);
252
253         void clientApply(InventoryManager *mgr, IGameDef *gamedef);
254 };
255
256 // Crafting helper
257 bool getCraftingResult(Inventory *inv, ItemStack& result,
258                 std::vector<ItemStack> &output_replacements,
259                 bool decrementInput, IGameDef *gamedef);
260
261 #endif
262