3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
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.
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.
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.
27 #include "inventory.h"
32 The crafting method depends on the inventory list
33 that the crafting input comes from.
39 // Cooking something in a furnace
41 // Using something as fuel for a furnace
46 The type a hash can be. The earlier a type is mentioned in this enum,
47 the earlier it is tried at crafting, and the less likely is a collision.
48 Changing order causes changes in behaviour, so know what you do.
52 // Hashes the normalized names of the recipe's elements.
53 // Only recipes without group usage can be found here,
54 // because groups can't be guessed efficiently.
55 CRAFT_HASH_TYPE_ITEM_NAMES,
57 // Counts the non-empty slots.
58 CRAFT_HASH_TYPE_COUNT,
60 // This layer both spares an extra variable, and helps to retain (albeit rarely used) functionality. Maps to 0.
61 // Before hashes are "initialized", all hashes reside here, after initialisation, none are.
62 CRAFT_HASH_TYPE_UNHASHED
65 const int craft_hash_type_max = (int) CRAFT_HASH_TYPE_UNHASHED;
68 Input: The contents of the crafting slots, arranged in matrix form
72 CraftMethod method = CRAFT_METHOD_NORMAL;
73 unsigned int width = 0;
74 std::vector<ItemStack> items;
76 CraftInput() = default;
78 CraftInput(CraftMethod method_, unsigned int width_,
79 const std::vector<ItemStack> &items_):
80 method(method_), width(width_), items(items_)
83 std::string dump() const;
87 Output: Result of crafting operation
91 // Used for normal crafting and cooking, itemstring
92 std::string item = "";
93 // Used for cooking (cook time) and fuel (burn time), seconds
96 CraftOutput() = default;
98 CraftOutput(const std::string &item_, float time_):
99 item(item_), time(time_)
101 std::string dump() const;
105 A list of replacements. A replacement indicates that a specific
106 input item should not be deleted (when crafting) but replaced with
107 a different item. Each replacements is a pair (itemstring to remove,
108 itemstring to replace with)
110 Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a
111 replacement pair, the crafting input slot that contained a water
112 bucket will contain an empty bucket after crafting.
114 Note: replacements only work correctly when stack_max of the item
115 to be replaced is 1. It is up to the mod writer to ensure this.
117 struct CraftReplacements
119 // List of replacements
120 std::vector<std::pair<std::string, std::string> > pairs;
122 CraftReplacements() = default;
123 CraftReplacements(const std::vector<std::pair<std::string, std::string> > &pairs_):
126 std::string dump() const;
130 Crafting definition base class
132 class CraftDefinition
135 CraftDefinition() = default;
136 virtual ~CraftDefinition() = default;
138 // Returns type of crafting definition
139 virtual std::string getName() const=0;
141 // Checks whether the recipe is applicable
142 virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
143 // Returns the output structure, meaning depends on crafting method
144 // The implementation can assume that check(input) returns true
145 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
146 // the inverse of the above
147 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
148 // Decreases count of every input item
149 virtual void decrementInput(CraftInput &input,
150 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0;
152 virtual CraftHashType getHashType() const = 0;
153 virtual u64 getHash(CraftHashType type) const = 0;
155 // to be called after all mods are loaded, so that we catch all aliases
156 virtual void initHash(IGameDef *gamedef) = 0;
158 virtual std::string dump() const=0;
162 A plain-jane (shaped) crafting definition
164 Supported crafting method: CRAFT_METHOD_NORMAL.
165 Requires the input items to be arranged exactly like in the recipe.
167 class CraftDefinitionShaped: public CraftDefinition
170 CraftDefinitionShaped() = delete;
172 CraftDefinitionShaped(
173 const std::string &output_,
175 const std::vector<std::string> &recipe_,
176 const CraftReplacements &replacements_):
177 output(output_), width(width_), recipe(recipe_),
178 replacements(replacements_)
180 virtual ~CraftDefinitionShaped() = default;
182 virtual std::string getName() const;
183 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
184 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
185 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
186 virtual void decrementInput(CraftInput &input,
187 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
189 virtual CraftHashType getHashType() const;
190 virtual u64 getHash(CraftHashType type) const;
192 virtual void initHash(IGameDef *gamedef);
194 virtual std::string dump() const;
198 std::string output = "";
200 unsigned int width = 1;
201 // Recipe matrix (itemstrings)
202 std::vector<std::string> recipe;
203 // Recipe matrix (item names)
204 std::vector<std::string> recipe_names;
205 // bool indicating if initHash has been called already
206 bool hash_inited = false;
207 // Replacement items for decrementInput()
208 CraftReplacements replacements;
212 A shapeless crafting definition
213 Supported crafting method: CRAFT_METHOD_NORMAL.
214 Input items can arranged in any way.
216 class CraftDefinitionShapeless: public CraftDefinition
219 CraftDefinitionShapeless() = delete;
220 CraftDefinitionShapeless(
221 const std::string &output_,
222 const std::vector<std::string> &recipe_,
223 const CraftReplacements &replacements_):
224 output(output_), recipe(recipe_), replacements(replacements_)
226 virtual ~CraftDefinitionShapeless() = default;
228 virtual std::string getName() const;
229 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
230 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
231 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
232 virtual void decrementInput(CraftInput &input,
233 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
235 virtual CraftHashType getHashType() const;
236 virtual u64 getHash(CraftHashType type) const;
238 virtual void initHash(IGameDef *gamedef);
240 virtual std::string dump() const;
245 // Recipe list (itemstrings)
246 std::vector<std::string> recipe;
247 // Recipe list (item names)
248 std::vector<std::string> recipe_names;
249 // bool indicating if initHash has been called already
250 bool hash_inited = false;
251 // Replacement items for decrementInput()
252 CraftReplacements replacements;
256 Tool repair crafting definition
257 Supported crafting method: CRAFT_METHOD_NORMAL.
258 Put two damaged tools into the crafting grid, get one tool back.
259 There should only be one crafting definition of this type.
261 class CraftDefinitionToolRepair: public CraftDefinition
264 CraftDefinitionToolRepair() = delete;
265 CraftDefinitionToolRepair(float additional_wear_):
266 additional_wear(additional_wear_)
268 virtual ~CraftDefinitionToolRepair() = default;
270 virtual std::string getName() const;
271 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
272 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
273 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
274 virtual void decrementInput(CraftInput &input,
275 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
277 virtual CraftHashType getHashType() const { return CRAFT_HASH_TYPE_COUNT; }
278 virtual u64 getHash(CraftHashType type) const { return 2; }
280 virtual void initHash(IGameDef *gamedef) {}
282 virtual std::string dump() const;
285 // This is a constant that is added to the wear of the result.
286 // May be positive or negative, allowed range [-1,1].
287 // 1 = new tool is completely broken
288 // 0 = simply add remaining uses of both input tools
289 // -1 = new tool is completely pristine
290 float additional_wear = 0.0f;
294 A cooking (in furnace) definition
295 Supported crafting method: CRAFT_METHOD_COOKING.
297 class CraftDefinitionCooking: public CraftDefinition
300 CraftDefinitionCooking() = delete;
301 CraftDefinitionCooking(
302 const std::string &output_,
303 const std::string &recipe_,
305 const CraftReplacements &replacements_):
306 output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
308 virtual ~CraftDefinitionCooking() = default;
310 virtual std::string getName() const;
311 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
312 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
313 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
314 virtual void decrementInput(CraftInput &input,
315 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
317 virtual CraftHashType getHashType() const;
318 virtual u64 getHash(CraftHashType type) const;
320 virtual void initHash(IGameDef *gamedef);
322 virtual std::string dump() const;
330 std::string recipe_name;
331 // bool indicating if initHash has been called already
332 bool hash_inited = false;
335 // Replacement items for decrementInput()
336 CraftReplacements replacements;
340 A fuel (for furnace) definition
341 Supported crafting method: CRAFT_METHOD_FUEL.
343 class CraftDefinitionFuel: public CraftDefinition
346 CraftDefinitionFuel() = delete;
347 CraftDefinitionFuel(const std::string &recipe_,
349 const CraftReplacements &replacements_):
350 recipe(recipe_), burntime(burntime_), replacements(replacements_)
352 virtual ~CraftDefinitionFuel() = default;
354 virtual std::string getName() const;
355 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
356 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
357 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
358 virtual void decrementInput(CraftInput &input,
359 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
361 virtual CraftHashType getHashType() const;
362 virtual u64 getHash(CraftHashType type) const;
364 virtual void initHash(IGameDef *gamedef);
366 virtual std::string dump() const;
372 std::string recipe_name;
373 // bool indicating if initHash has been called already
374 bool hash_inited = false;
377 // Replacement items for decrementInput()
378 CraftReplacements replacements;
382 Crafting definition manager
384 class ICraftDefManager
387 ICraftDefManager() = default;
388 virtual ~ICraftDefManager() = default;
390 // The main crafting function
391 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
392 std::vector<ItemStack> &output_replacements,
393 bool decrementInput, IGameDef *gamedef) const=0;
394 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
395 IGameDef *gamedef, unsigned limit=0) const=0;
397 // Print crafting recipes for debugging
398 virtual std::string dump() const=0;
401 class IWritableCraftDefManager : public ICraftDefManager
404 IWritableCraftDefManager() = default;
405 virtual ~IWritableCraftDefManager() = default;
407 // The main crafting function
408 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
409 std::vector<ItemStack> &output_replacements,
410 bool decrementInput, IGameDef *gamedef) const=0;
411 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
412 IGameDef *gamedef, unsigned limit=0) const=0;
414 virtual bool clearCraftRecipesByOutput(const CraftOutput &output, IGameDef *gamedef) = 0;
415 virtual bool clearCraftRecipesByInput(CraftMethod craft_method,
416 unsigned int craft_grid_width, const std::vector<std::string> &recipe, IGameDef *gamedef) = 0;
418 // Print crafting recipes for debugging
419 virtual std::string dump() const=0;
421 // Add a crafting definition.
422 // After calling this, the pointer belongs to the manager.
423 virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0;
425 // Delete all crafting definitions
426 virtual void clear()=0;
428 // To be called after all mods are loaded, so that we catch all aliases
429 virtual void initHashes(IGameDef *gamedef) = 0;
432 IWritableCraftDefManager* createCraftDefManager();