Re-add jungles, apple trees
[oweals/minetest.git] / src / craftdef.h
1 /*
2 Minetest
3 Copyright (C) 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 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         void serialize(std::ostream &os) const;
110         void deSerialize(std::istream &is);
111 };
112
113 /*
114         Crafting definition base class
115 */
116 class CraftDefinition
117 {
118 public:
119         CraftDefinition(){}
120         virtual ~CraftDefinition(){}
121
122         void serialize(std::ostream &os) const;
123         static CraftDefinition* deSerialize(std::istream &is);
124
125         // Returns type of crafting definition
126         virtual std::string getName() const=0;
127
128         // Checks whether the recipe is applicable
129         virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
130         // Returns the output structure, meaning depends on crafting method
131         // The implementation can assume that check(input) returns true
132         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
133         // the inverse of the above
134         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
135         // Decreases count of every input item
136         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
137
138         virtual std::string dump() const=0;
139
140 protected:
141         virtual void serializeBody(std::ostream &os) const=0;
142         virtual void deSerializeBody(std::istream &is, int version)=0;
143 };
144
145 /*
146         A plain-jane (shaped) crafting definition
147
148         Supported crafting method: CRAFT_METHOD_NORMAL.
149         Requires the input items to be arranged exactly like in the recipe.
150 */
151 class CraftDefinitionShaped: public CraftDefinition
152 {
153 public:
154         CraftDefinitionShaped():
155                 output(""), width(1), recipe(), replacements()
156         {}
157         CraftDefinitionShaped(
158                         const std::string &output_,
159                         unsigned int width_,
160                         const std::vector<std::string> &recipe_,
161                         const CraftReplacements &replacements_):
162                 output(output_), width(width_), recipe(recipe_), replacements(replacements_)
163         {}
164         virtual ~CraftDefinitionShaped(){}
165
166         virtual std::string getName() const;
167         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
168         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
169         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
170         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
171
172         virtual std::string dump() const;
173
174 protected:
175         virtual void serializeBody(std::ostream &os) const;
176         virtual void deSerializeBody(std::istream &is, int version);
177
178 private:
179         // Output itemstring
180         std::string output;
181         // Width of recipe
182         unsigned int width;
183         // Recipe matrix (itemstrings)
184         std::vector<std::string> recipe;
185         // Replacement items for decrementInput()
186         CraftReplacements replacements;
187 };
188
189 /*
190         A shapeless crafting definition
191         Supported crafting method: CRAFT_METHOD_NORMAL.
192         Input items can arranged in any way.
193 */
194 class CraftDefinitionShapeless: public CraftDefinition
195 {
196 public:
197         CraftDefinitionShapeless():
198                 output(""), recipe(), replacements()
199         {}
200         CraftDefinitionShapeless(
201                         const std::string &output_,
202                         const std::vector<std::string> &recipe_,
203                         const CraftReplacements &replacements_):
204                 output(output_), recipe(recipe_), replacements(replacements_)
205         {}
206         virtual ~CraftDefinitionShapeless(){}
207
208         virtual std::string getName() const;
209         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
210         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
211         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
212         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
213
214         virtual std::string dump() const;
215
216 protected:
217         virtual void serializeBody(std::ostream &os) const;
218         virtual void deSerializeBody(std::istream &is, int version);
219
220 private:
221         // Output itemstring
222         std::string output;
223         // Recipe list (itemstrings)
224         std::vector<std::string> recipe;
225         // Replacement items for decrementInput()
226         CraftReplacements replacements;
227 };
228
229 /*
230         Tool repair crafting definition
231         Supported crafting method: CRAFT_METHOD_NORMAL.
232         Put two damaged tools into the crafting grid, get one tool back.
233         There should only be one crafting definition of this type.
234 */
235 class CraftDefinitionToolRepair: public CraftDefinition
236 {
237 public:
238         CraftDefinitionToolRepair():
239                 additional_wear(0)
240         {}
241         CraftDefinitionToolRepair(float additional_wear_):
242                 additional_wear(additional_wear_)
243         {}
244         virtual ~CraftDefinitionToolRepair(){}
245
246         virtual std::string getName() const;
247         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
248         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
249         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
250         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
251
252         virtual std::string dump() const;
253
254 protected:
255         virtual void serializeBody(std::ostream &os) const;
256         virtual void deSerializeBody(std::istream &is, int version);
257
258 private:
259         // This is a constant that is added to the wear of the result.
260         // May be positive or negative, allowed range [-1,1].
261         // 1 = new tool is completely broken
262         // 0 = simply add remaining uses of both input tools
263         // -1 = new tool is completely pristine
264         float additional_wear;
265 };
266
267 /*
268         A cooking (in furnace) definition
269         Supported crafting method: CRAFT_METHOD_COOKING.
270 */
271 class CraftDefinitionCooking: public CraftDefinition
272 {
273 public:
274         CraftDefinitionCooking():
275                 output(""), recipe(""), cooktime()
276         {}
277         CraftDefinitionCooking(
278                         const std::string &output_,
279                         const std::string &recipe_,
280                         float cooktime_,
281                         const CraftReplacements &replacements_):
282                 output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
283         {}
284         virtual ~CraftDefinitionCooking(){}
285
286         virtual std::string getName() const;
287         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
288         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
289         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
290         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
291
292         virtual std::string dump() const;
293
294 protected:
295         virtual void serializeBody(std::ostream &os) const;
296         virtual void deSerializeBody(std::istream &is, int version);
297
298 private:
299         // Output itemstring
300         std::string output;
301         // Recipe itemstring
302         std::string recipe;
303         // Time in seconds
304         float cooktime;
305         // Replacement items for decrementInput()
306         CraftReplacements replacements;
307 };
308
309 /*
310         A fuel (for furnace) definition
311         Supported crafting method: CRAFT_METHOD_FUEL.
312 */
313 class CraftDefinitionFuel: public CraftDefinition
314 {
315 public:
316         CraftDefinitionFuel():
317                 recipe(""), burntime()
318         {}
319         CraftDefinitionFuel(std::string recipe_,
320                         float burntime_,
321                         const CraftReplacements &replacements_):
322                 recipe(recipe_), burntime(burntime_), replacements(replacements_)
323         {}
324         virtual ~CraftDefinitionFuel(){}
325
326         virtual std::string getName() const;
327         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
328         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
329         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
330         virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
331
332         virtual std::string dump() const;
333
334 protected:
335         virtual void serializeBody(std::ostream &os) const;
336         virtual void deSerializeBody(std::istream &is, int version);
337
338 private:
339         // Recipe itemstring
340         std::string recipe;
341         // Time in seconds
342         float burntime;
343         // Replacement items for decrementInput()
344         CraftReplacements replacements;
345 };
346
347 /*
348         Crafting definition manager
349 */
350 class ICraftDefManager
351 {
352 public:
353         ICraftDefManager(){}
354         virtual ~ICraftDefManager(){}
355
356         // The main crafting function
357         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
358                         bool decrementInput, IGameDef *gamedef) const=0;
359         virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
360                         IGameDef *gamedef) const=0;
361         virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
362                         IGameDef *gamedef) const=0;
363         
364         // Print crafting recipes for debugging
365         virtual std::string dump() const=0;
366
367         virtual void serialize(std::ostream &os) const=0;
368 };
369
370 class IWritableCraftDefManager : public ICraftDefManager
371 {
372 public:
373         IWritableCraftDefManager(){}
374         virtual ~IWritableCraftDefManager(){}
375
376         // The main crafting function
377         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
378                         bool decrementInput, IGameDef *gamedef) const=0;
379         virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
380                         IGameDef *gamedef) const=0;
381         virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, 
382                         IGameDef *gamedef) const=0;
383
384         // Print crafting recipes for debugging
385         virtual std::string dump() const=0;
386
387         // Add a crafting definition.
388         // After calling this, the pointer belongs to the manager.
389         virtual void registerCraft(CraftDefinition *def)=0;
390         // Delete all crafting definitions
391         virtual void clear()=0;
392
393         virtual void serialize(std::ostream &os) const=0;
394         virtual void deSerialize(std::istream &is)=0;
395 };
396
397 IWritableCraftDefManager* createCraftDefManager();
398
399 #endif
400