Switch the license to be LGPLv2/later, with small parts still remaining as GPLv2...
[oweals/minetest.git] / src / craftdef.h
1 /*
2 Minetest-c55
3 Copyright (C) 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 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 CRAFTDEF_HEADER
21 #define CRAFTDEF_HEADER
22
23 #include <string>
24 #include <iostream>
25 #include <vector>
26 #include <utility>
27 #include "gamedef.h"
28 #include "inventory.h"
29
30 /*
31         Crafting methods.
32
33         The crafting method depends on the inventory list
34         that the crafting input comes from.
35 */
36 enum CraftMethod
37 {
38         // Crafting grid
39         CRAFT_METHOD_NORMAL,
40         // Cooking something in a furnace
41         CRAFT_METHOD_COOKING,
42         // Using something as fuel for a furnace
43         CRAFT_METHOD_FUEL,
44 };
45
46 /*
47         Input: The contents of the crafting slots, arranged in matrix form
48 */
49 struct CraftInput
50 {
51         CraftMethod method;
52         unsigned int width;
53         std::vector<ItemStack> items;
54
55         CraftInput():
56                 method(CRAFT_METHOD_NORMAL), width(0), items()
57         {}
58         CraftInput(CraftMethod method_, unsigned int width_,
59                         const std::vector<ItemStack> &items_):
60                 method(method_), width(width_), items(items_)
61         {}
62         std::string dump() const;
63 };
64
65 /*
66         Output: Result of crafting operation
67 */
68 struct CraftOutput
69 {
70         // Used for normal crafting and cooking, itemstring
71         std::string item;
72         // Used for cooking (cook time) and fuel (burn time), seconds
73         float time;
74
75         CraftOutput():
76                 item(""), time(0)
77         {}
78         CraftOutput(std::string item_, float time_):
79                 item(item_), time(time_)
80         {}
81         std::string dump() const;
82 };
83
84 /*
85         A list of replacements. A replacement indicates that a specific
86         input item should not be deleted (when crafting) but replaced with
87         a different item. Each replacements is a pair (itemstring to remove,
88         itemstring to replace with)
89
90         Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a
91         replacement pair, the crafting input slot that contained a water
92         bucket will contain an empty bucket after crafting.
93
94         Note: replacements only work correctly when stack_max of the item
95         to be replaced is 1. It is up to the mod writer to ensure this.
96 */
97 struct CraftReplacements
98 {
99         // List of replacements
100         std::vector<std::pair<std::string, std::string> > pairs;
101
102         CraftReplacements():
103                 pairs()
104         {}
105         CraftReplacements(std::vector<std::pair<std::string, std::string> > pairs_):
106                 pairs(pairs_)
107         {}
108         std::string dump() const;
109 };
110
111 /*
112         Crafting definition base class
113 */
114 class CraftDefinition
115 {
116 public:
117         CraftDefinition(){}
118         virtual ~CraftDefinition(){}
119
120         void serialize(std::ostream &os) const;
121         static CraftDefinition* deSerialize(std::istream &is);
122
123         // Returns type of crafting definition
124         virtual std::string getName() const=0;
125
126         // Checks whether the recipe is applicable
127         virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
128         // Returns the output structure, meaning depends on crafting method
129         // The implementation can assume that check(input) returns true
130         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
131         // Decreases count of every input item
132         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
133
134         virtual std::string dump() const=0;
135
136 protected:
137         virtual void serializeBody(std::ostream &os) const=0;
138         virtual void deSerializeBody(std::istream &is, int version)=0;
139 };
140
141 /*
142         A plain-jane (shaped) crafting definition
143
144         Supported crafting method: CRAFT_METHOD_NORMAL.
145         Requires the input items to be arranged exactly like in the recipe.
146 */
147 class CraftDefinitionShaped: public CraftDefinition
148 {
149 public:
150         CraftDefinitionShaped():
151                 output(""), width(1), recipe(), replacements()
152         {}
153         CraftDefinitionShaped(
154                         const std::string &output_,
155                         unsigned int width_,
156                         const std::vector<std::string> &recipe_,
157                         const CraftReplacements &replacements_):
158                 output(output_), width(width_), recipe(recipe_), replacements(replacements_)
159         {}
160         virtual ~CraftDefinitionShaped(){}
161
162         virtual std::string getName() const;
163         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
164         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
165         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
166
167         virtual std::string dump() const;
168
169 protected:
170         virtual void serializeBody(std::ostream &os) const;
171         virtual void deSerializeBody(std::istream &is, int version);
172
173 private:
174         // Output itemstring
175         std::string output;
176         // Width of recipe
177         unsigned int width;
178         // Recipe matrix (itemstrings)
179         std::vector<std::string> recipe;
180         // Replacement items for decrementInput()
181         CraftReplacements replacements;
182 };
183
184 /*
185         A shapeless crafting definition
186         Supported crafting method: CRAFT_METHOD_NORMAL.
187         Input items can arranged in any way.
188 */
189 class CraftDefinitionShapeless: public CraftDefinition
190 {
191 public:
192         CraftDefinitionShapeless():
193                 output(""), recipe(), replacements()
194         {}
195         CraftDefinitionShapeless(
196                         const std::string &output_,
197                         const std::vector<std::string> &recipe_,
198                         const CraftReplacements &replacements_):
199                 output(output_), recipe(recipe_), replacements(replacements_)
200         {}
201         virtual ~CraftDefinitionShapeless(){}
202
203         virtual std::string getName() const;
204         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
205         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
206         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
207
208         virtual std::string dump() const;
209
210 protected:
211         virtual void serializeBody(std::ostream &os) const;
212         virtual void deSerializeBody(std::istream &is, int version);
213
214 private:
215         // Output itemstring
216         std::string output;
217         // Recipe list (itemstrings)
218         std::vector<std::string> recipe;
219         // Replacement items for decrementInput()
220         CraftReplacements replacements;
221 };
222
223 /*
224         Tool repair crafting definition
225         Supported crafting method: CRAFT_METHOD_NORMAL.
226         Put two damaged tools into the crafting grid, get one tool back.
227         There should only be one crafting definition of this type.
228 */
229 class CraftDefinitionToolRepair: public CraftDefinition
230 {
231 public:
232         CraftDefinitionToolRepair():
233                 additional_wear(0)
234         {}
235         CraftDefinitionToolRepair(float additional_wear_):
236                 additional_wear(additional_wear_)
237         {}
238         virtual ~CraftDefinitionToolRepair(){}
239
240         virtual std::string getName() const;
241         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
242         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
243         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
244
245         virtual std::string dump() const;
246
247 protected:
248         virtual void serializeBody(std::ostream &os) const;
249         virtual void deSerializeBody(std::istream &is, int version);
250
251 private:
252         // This is a constant that is added to the wear of the result.
253         // May be positive or negative, allowed range [-1,1].
254         // 1 = new tool is completely broken
255         // 0 = simply add remaining uses of both input tools
256         // -1 = new tool is completely pristine
257         float additional_wear;
258 };
259
260 /*
261         A cooking (in furnace) definition
262         Supported crafting method: CRAFT_METHOD_COOKING.
263 */
264 class CraftDefinitionCooking: public CraftDefinition
265 {
266 public:
267         CraftDefinitionCooking():
268                 output(""), recipe(""), cooktime()
269         {}
270         CraftDefinitionCooking(
271                         const std::string &output_,
272                         const std::string &recipe_,
273                         float cooktime_):
274                 output(output_), recipe(recipe_), cooktime(cooktime_)
275         {}
276         virtual ~CraftDefinitionCooking(){}
277
278         virtual std::string getName() const;
279         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
280         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
281         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
282
283         virtual std::string dump() const;
284
285 protected:
286         virtual void serializeBody(std::ostream &os) const;
287         virtual void deSerializeBody(std::istream &is, int version);
288
289 private:
290         // Output itemstring
291         std::string output;
292         // Recipe itemstring
293         std::string recipe;
294         // Time in seconds
295         float cooktime;
296 };
297
298 /*
299         A fuel (for furnace) definition
300         Supported crafting method: CRAFT_METHOD_FUEL.
301 */
302 class CraftDefinitionFuel: public CraftDefinition
303 {
304 public:
305         CraftDefinitionFuel():
306                 recipe(""), burntime()
307         {}
308         CraftDefinitionFuel(std::string recipe_, float burntime_):
309                 recipe(recipe_), burntime(burntime_)
310         {}
311         virtual ~CraftDefinitionFuel(){}
312
313         virtual std::string getName() const;
314         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
315         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
316         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
317
318         virtual std::string dump() const;
319
320 protected:
321         virtual void serializeBody(std::ostream &os) const;
322         virtual void deSerializeBody(std::istream &is, int version);
323
324 private:
325         // Recipe itemstring
326         std::string recipe;
327         // Time in seconds
328         float burntime;
329 };
330
331 /*
332         Crafting definition manager
333 */
334 class ICraftDefManager
335 {
336 public:
337         ICraftDefManager(){}
338         virtual ~ICraftDefManager(){}
339
340         // The main crafting function
341         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
342                         bool decrementInput, IGameDef *gamedef) const=0;
343         
344         // Print crafting recipes for debugging
345         virtual std::string dump() const=0;
346
347         virtual void serialize(std::ostream &os) const=0;
348 };
349
350 class IWritableCraftDefManager : public ICraftDefManager
351 {
352 public:
353         IWritableCraftDefManager(){}
354         virtual ~IWritableCraftDefManager(){}
355
356         // The main crafting function
357         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
358                         bool decrementInput, IGameDef *gamedef) const=0;
359
360         // Print crafting recipes for debugging
361         virtual std::string dump() const=0;
362
363         // Add a crafting definition.
364         // After calling this, the pointer belongs to the manager.
365         virtual void registerCraft(CraftDefinition *def)=0;
366         // Delete all crafting definitions
367         virtual void clear()=0;
368
369         virtual void serialize(std::ostream &os) const=0;
370         virtual void deSerialize(std::istream &is)=0;
371 };
372
373 IWritableCraftDefManager* createCraftDefManager();
374
375 #endif
376