Fix various copy instead of const ref reported by cppcheck (#5615)
[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         The type a hash can be. The earlier a type is mentioned in this enum,
48         the earlier it is tried at crafting, and the less likely is a collision.
49         Changing order causes changes in behaviour, so know what you do.
50  */
51 enum CraftHashType
52 {
53         // Hashes the normalized names of the recipe's elements.
54         // Only recipes without group usage can be found here,
55         // because groups can't be guessed efficiently.
56         CRAFT_HASH_TYPE_ITEM_NAMES,
57
58         // Counts the non-empty slots.
59         CRAFT_HASH_TYPE_COUNT,
60
61         // This layer both spares an extra variable, and helps to retain (albeit rarely used) functionality. Maps to 0.
62         // Before hashes are "initialized", all hashes reside here, after initialisation, none are.
63         CRAFT_HASH_TYPE_UNHASHED
64
65 };
66 const int craft_hash_type_max = (int) CRAFT_HASH_TYPE_UNHASHED;
67
68 /*
69         Input: The contents of the crafting slots, arranged in matrix form
70 */
71 struct CraftInput
72 {
73         CraftMethod method;
74         unsigned int width;
75         std::vector<ItemStack> items;
76
77         CraftInput():
78                 method(CRAFT_METHOD_NORMAL), width(0), items()
79         {}
80         CraftInput(CraftMethod method_, unsigned int width_,
81                         const std::vector<ItemStack> &items_):
82                 method(method_), width(width_), items(items_)
83         {}
84         std::string dump() const;
85 };
86
87 /*
88         Output: Result of crafting operation
89 */
90 struct CraftOutput
91 {
92         // Used for normal crafting and cooking, itemstring
93         std::string item;
94         // Used for cooking (cook time) and fuel (burn time), seconds
95         float time;
96
97         CraftOutput():
98                 item(""), time(0)
99         {}
100         CraftOutput(const std::string &item_, float time_):
101                 item(item_), time(time_)
102         {}
103         std::string dump() const;
104 };
105
106 /*
107         A list of replacements. A replacement indicates that a specific
108         input item should not be deleted (when crafting) but replaced with
109         a different item. Each replacements is a pair (itemstring to remove,
110         itemstring to replace with)
111
112         Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a
113         replacement pair, the crafting input slot that contained a water
114         bucket will contain an empty bucket after crafting.
115
116         Note: replacements only work correctly when stack_max of the item
117         to be replaced is 1. It is up to the mod writer to ensure this.
118 */
119 struct CraftReplacements
120 {
121         // List of replacements
122         std::vector<std::pair<std::string, std::string> > pairs;
123
124         CraftReplacements():
125                 pairs()
126         {}
127         CraftReplacements(const std::vector<std::pair<std::string, std::string> > &pairs_):
128                 pairs(pairs_)
129         {}
130         std::string dump() const;
131 };
132
133 /*
134         Crafting definition base class
135 */
136 class CraftDefinition
137 {
138 public:
139         CraftDefinition(){}
140         virtual ~CraftDefinition(){}
141
142         // Returns type of crafting definition
143         virtual std::string getName() const=0;
144
145         // Checks whether the recipe is applicable
146         virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
147         // Returns the output structure, meaning depends on crafting method
148         // The implementation can assume that check(input) returns true
149         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
150         // the inverse of the above
151         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
152         // Decreases count of every input item
153         virtual void decrementInput(CraftInput &input,
154                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0;
155
156         virtual CraftHashType getHashType() const = 0;
157         virtual u64 getHash(CraftHashType type) const = 0;
158
159         // to be called after all mods are loaded, so that we catch all aliases
160         virtual void initHash(IGameDef *gamedef) = 0;
161
162         virtual std::string dump() const=0;
163 };
164
165 /*
166         A plain-jane (shaped) crafting definition
167
168         Supported crafting method: CRAFT_METHOD_NORMAL.
169         Requires the input items to be arranged exactly like in the recipe.
170 */
171 class CraftDefinitionShaped: public CraftDefinition
172 {
173 public:
174         CraftDefinitionShaped():
175                 output(""), width(1), recipe(), hash_inited(false), replacements()
176         {}
177         CraftDefinitionShaped(
178                         const std::string &output_,
179                         unsigned int width_,
180                         const std::vector<std::string> &recipe_,
181                         const CraftReplacements &replacements_):
182                 output(output_), width(width_), recipe(recipe_),
183                 hash_inited(false), replacements(replacements_)
184         {}
185         virtual ~CraftDefinitionShaped(){}
186
187         virtual std::string getName() const;
188         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
189         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
190         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
191         virtual void decrementInput(CraftInput &input,
192                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
193
194         virtual CraftHashType getHashType() const;
195         virtual u64 getHash(CraftHashType type) const;
196
197         virtual void initHash(IGameDef *gamedef);
198
199         virtual std::string dump() const;
200
201 private:
202         // Output itemstring
203         std::string output;
204         // Width of recipe
205         unsigned int width;
206         // Recipe matrix (itemstrings)
207         std::vector<std::string> recipe;
208         // Recipe matrix (item names)
209         std::vector<std::string> recipe_names;
210         // bool indicating if initHash has been called already
211         bool hash_inited;
212         // Replacement items for decrementInput()
213         CraftReplacements replacements;
214 };
215
216 /*
217         A shapeless crafting definition
218         Supported crafting method: CRAFT_METHOD_NORMAL.
219         Input items can arranged in any way.
220 */
221 class CraftDefinitionShapeless: public CraftDefinition
222 {
223 public:
224         CraftDefinitionShapeless():
225                 output(""), recipe(), hash_inited(false), replacements()
226         {}
227         CraftDefinitionShapeless(
228                         const std::string &output_,
229                         const std::vector<std::string> &recipe_,
230                         const CraftReplacements &replacements_):
231                 output(output_), recipe(recipe_),
232                 hash_inited(false), replacements(replacements_)
233         {}
234         virtual ~CraftDefinitionShapeless(){}
235
236         virtual std::string getName() const;
237         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
238         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
239         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
240         virtual void decrementInput(CraftInput &input,
241                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
242
243         virtual CraftHashType getHashType() const;
244         virtual u64 getHash(CraftHashType type) const;
245
246         virtual void initHash(IGameDef *gamedef);
247
248         virtual std::string dump() const;
249
250 private:
251         // Output itemstring
252         std::string output;
253         // Recipe list (itemstrings)
254         std::vector<std::string> recipe;
255         // Recipe list (item names)
256         std::vector<std::string> recipe_names;
257         // bool indicating if initHash has been called already
258         bool hash_inited;
259         // Replacement items for decrementInput()
260         CraftReplacements replacements;
261 };
262
263 /*
264         Tool repair crafting definition
265         Supported crafting method: CRAFT_METHOD_NORMAL.
266         Put two damaged tools into the crafting grid, get one tool back.
267         There should only be one crafting definition of this type.
268 */
269 class CraftDefinitionToolRepair: public CraftDefinition
270 {
271 public:
272         CraftDefinitionToolRepair():
273                 additional_wear(0)
274         {}
275         CraftDefinitionToolRepair(float additional_wear_):
276                 additional_wear(additional_wear_)
277         {}
278         virtual ~CraftDefinitionToolRepair(){}
279
280         virtual std::string getName() const;
281         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
282         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
283         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
284         virtual void decrementInput(CraftInput &input,
285                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
286
287         virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; }
288         virtual u64 getHash(CraftHashType type) const { return 2; }
289
290         virtual void initHash(IGameDef *gamedef) {}
291
292         virtual std::string dump() const;
293
294 private:
295         // This is a constant that is added to the wear of the result.
296         // May be positive or negative, allowed range [-1,1].
297         // 1 = new tool is completely broken
298         // 0 = simply add remaining uses of both input tools
299         // -1 = new tool is completely pristine
300         float additional_wear;
301 };
302
303 /*
304         A cooking (in furnace) definition
305         Supported crafting method: CRAFT_METHOD_COOKING.
306 */
307 class CraftDefinitionCooking: public CraftDefinition
308 {
309 public:
310         CraftDefinitionCooking():
311                 output(""), recipe(""), hash_inited(false), cooktime()
312         {}
313         CraftDefinitionCooking(
314                         const std::string &output_,
315                         const std::string &recipe_,
316                         float cooktime_,
317                         const CraftReplacements &replacements_):
318                 output(output_), recipe(recipe_), hash_inited(false),
319                 cooktime(cooktime_), replacements(replacements_)
320         {}
321         virtual ~CraftDefinitionCooking(){}
322
323         virtual std::string getName() const;
324         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
325         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
326         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
327         virtual void decrementInput(CraftInput &input,
328                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
329
330         virtual CraftHashType getHashType() const;
331         virtual u64 getHash(CraftHashType type) const;
332
333         virtual void initHash(IGameDef *gamedef);
334
335         virtual std::string dump() const;
336
337 private:
338         // Output itemstring
339         std::string output;
340         // Recipe itemstring
341         std::string recipe;
342         // Recipe item name
343         std::string recipe_name;
344         // bool indicating if initHash has been called already
345         bool hash_inited;
346         // Time in seconds
347         float cooktime;
348         // Replacement items for decrementInput()
349         CraftReplacements replacements;
350 };
351
352 /*
353         A fuel (for furnace) definition
354         Supported crafting method: CRAFT_METHOD_FUEL.
355 */
356 class CraftDefinitionFuel: public CraftDefinition
357 {
358 public:
359         CraftDefinitionFuel():
360                 recipe(""), hash_inited(false), burntime()
361         {}
362         CraftDefinitionFuel(const std::string &recipe_,
363                         float burntime_,
364                         const CraftReplacements &replacements_):
365                 recipe(recipe_),
366                 hash_inited(false),
367                 burntime(burntime_),
368                 replacements(replacements_)
369         {}
370         virtual ~CraftDefinitionFuel(){}
371
372         virtual std::string getName() const;
373         virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
374         virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
375         virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
376         virtual void decrementInput(CraftInput &input,
377                 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
378
379         virtual CraftHashType getHashType() const;
380         virtual u64 getHash(CraftHashType type) const;
381
382         virtual void initHash(IGameDef *gamedef);
383
384         virtual std::string dump() const;
385
386 private:
387         // Recipe itemstring
388         std::string recipe;
389         // Recipe item name
390         std::string recipe_name;
391         // bool indicating if initHash has been called already
392         bool hash_inited;
393         // Time in seconds
394         float burntime;
395         // Replacement items for decrementInput()
396         CraftReplacements replacements;
397 };
398
399 /*
400         Crafting definition manager
401 */
402 class ICraftDefManager
403 {
404 public:
405         ICraftDefManager(){}
406         virtual ~ICraftDefManager(){}
407
408         // The main crafting function
409         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
410                         std::vector<ItemStack> &output_replacements,
411                         bool decrementInput, IGameDef *gamedef) const=0;
412         virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
413                         IGameDef *gamedef, unsigned limit=0) const=0;
414
415         // Print crafting recipes for debugging
416         virtual std::string dump() const=0;
417 };
418
419 class IWritableCraftDefManager : public ICraftDefManager
420 {
421 public:
422         IWritableCraftDefManager(){}
423         virtual ~IWritableCraftDefManager(){}
424
425         // The main crafting function
426         virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
427                         std::vector<ItemStack> &output_replacements,
428                         bool decrementInput, IGameDef *gamedef) const=0;
429         virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
430                         IGameDef *gamedef, unsigned limit=0) const=0;
431
432         virtual bool clearCraftRecipesByOutput(const CraftOutput &output, IGameDef *gamedef) = 0;
433         virtual bool clearCraftRecipesByInput(CraftMethod craft_method,
434                         unsigned int craft_grid_width, const std::vector<std::string> &recipe, IGameDef *gamedef) = 0;
435
436         // Print crafting recipes for debugging
437         virtual std::string dump() const=0;
438
439         // Add a crafting definition.
440         // After calling this, the pointer belongs to the manager.
441         virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0;
442
443         // Delete all crafting definitions
444         virtual void clear()=0;
445
446         // To be called after all mods are loaded, so that we catch all aliases
447         virtual void initHashes(IGameDef *gamedef) = 0;
448 };
449
450 IWritableCraftDefManager* createCraftDefManager();
451
452 #endif
453