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
136 Craft recipe priorities, from low to high
138 Recipes are searched from latest to first.
139 If a recipe with higher priority than a previous found one is
140 encountered, it is selected instead.
146 SHAPELESS_AND_GROUPS,
152 CraftDefinition() = default;
153 virtual ~CraftDefinition() = default;
155 // Returns type of crafting definition
156 virtual std::string getName() const=0;
158 // Checks whether the recipe is applicable
159 virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
160 RecipePriority getPriority() const
164 // Returns the output structure, meaning depends on crafting method
165 // The implementation can assume that check(input) returns true
166 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
167 // the inverse of the above
168 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
169 // Decreases count of every input item
170 virtual void decrementInput(CraftInput &input,
171 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const=0;
173 CraftHashType getHashType() const
177 virtual u64 getHash(CraftHashType type) const = 0;
179 // to be called after all mods are loaded, so that we catch all aliases
180 virtual void initHash(IGameDef *gamedef) = 0;
182 virtual std::string dump() const=0;
185 CraftHashType hash_type;
186 RecipePriority priority;
190 A plain-jane (shaped) crafting definition
192 Supported crafting method: CRAFT_METHOD_NORMAL.
193 Requires the input items to be arranged exactly like in the recipe.
195 class CraftDefinitionShaped: public CraftDefinition
198 CraftDefinitionShaped() = delete;
200 CraftDefinitionShaped(
201 const std::string &output_,
203 const std::vector<std::string> &recipe_,
204 const CraftReplacements &replacements_):
205 output(output_), width(width_), recipe(recipe_),
206 replacements(replacements_)
208 virtual ~CraftDefinitionShaped() = default;
210 virtual std::string getName() const;
211 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
212 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
213 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
214 virtual void decrementInput(CraftInput &input,
215 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
217 virtual u64 getHash(CraftHashType type) const;
219 virtual void initHash(IGameDef *gamedef);
221 virtual std::string dump() const;
225 std::string output = "";
227 unsigned int width = 1;
228 // Recipe matrix (itemstrings)
229 std::vector<std::string> recipe;
230 // Recipe matrix (item names)
231 std::vector<std::string> recipe_names;
232 // bool indicating if initHash has been called already
233 bool hash_inited = false;
234 // Replacement items for decrementInput()
235 CraftReplacements replacements;
239 A shapeless crafting definition
240 Supported crafting method: CRAFT_METHOD_NORMAL.
241 Input items can arranged in any way.
243 class CraftDefinitionShapeless: public CraftDefinition
246 CraftDefinitionShapeless() = delete;
247 CraftDefinitionShapeless(
248 const std::string &output_,
249 const std::vector<std::string> &recipe_,
250 const CraftReplacements &replacements_):
251 output(output_), recipe(recipe_), replacements(replacements_)
253 virtual ~CraftDefinitionShapeless() = default;
255 virtual std::string getName() const;
256 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
257 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
258 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
259 virtual void decrementInput(CraftInput &input,
260 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
262 virtual u64 getHash(CraftHashType type) const;
264 virtual void initHash(IGameDef *gamedef);
266 virtual std::string dump() const;
271 // Recipe list (itemstrings)
272 std::vector<std::string> recipe;
273 // Recipe list (item names)
274 std::vector<std::string> recipe_names;
275 // bool indicating if initHash has been called already
276 bool hash_inited = false;
277 // Replacement items for decrementInput()
278 CraftReplacements replacements;
282 Tool repair crafting definition
283 Supported crafting method: CRAFT_METHOD_NORMAL.
284 Put two damaged tools into the crafting grid, get one tool back.
285 There should only be one crafting definition of this type.
287 class CraftDefinitionToolRepair: public CraftDefinition
290 CraftDefinitionToolRepair() = delete;
291 CraftDefinitionToolRepair(float additional_wear_):
292 additional_wear(additional_wear_)
294 virtual ~CraftDefinitionToolRepair() = default;
296 virtual std::string getName() const;
297 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
298 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
299 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
300 virtual void decrementInput(CraftInput &input,
301 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
303 virtual u64 getHash(CraftHashType type) const { return 2; }
305 virtual void initHash(IGameDef *gamedef)
307 hash_type = CRAFT_HASH_TYPE_COUNT;
308 priority = TOOLREPAIR;
311 virtual std::string dump() const;
314 // This is a constant that is added to the wear of the result.
315 // May be positive or negative, allowed range [-1,1].
316 // 1 = new tool is completely broken
317 // 0 = simply add remaining uses of both input tools
318 // -1 = new tool is completely pristine
319 float additional_wear = 0.0f;
323 A cooking (in furnace) definition
324 Supported crafting method: CRAFT_METHOD_COOKING.
326 class CraftDefinitionCooking: public CraftDefinition
329 CraftDefinitionCooking() = delete;
330 CraftDefinitionCooking(
331 const std::string &output_,
332 const std::string &recipe_,
334 const CraftReplacements &replacements_):
335 output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
337 virtual ~CraftDefinitionCooking() = default;
339 virtual std::string getName() const;
340 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
341 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
342 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
343 virtual void decrementInput(CraftInput &input,
344 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
346 virtual u64 getHash(CraftHashType type) const;
348 virtual void initHash(IGameDef *gamedef);
350 virtual std::string dump() const;
358 std::string recipe_name;
359 // bool indicating if initHash has been called already
360 bool hash_inited = false;
363 // Replacement items for decrementInput()
364 CraftReplacements replacements;
368 A fuel (for furnace) definition
369 Supported crafting method: CRAFT_METHOD_FUEL.
371 class CraftDefinitionFuel: public CraftDefinition
374 CraftDefinitionFuel() = delete;
375 CraftDefinitionFuel(const std::string &recipe_,
377 const CraftReplacements &replacements_):
378 recipe(recipe_), burntime(burntime_), replacements(replacements_)
380 virtual ~CraftDefinitionFuel() = default;
382 virtual std::string getName() const;
383 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
384 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
385 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
386 virtual void decrementInput(CraftInput &input,
387 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
389 virtual u64 getHash(CraftHashType type) const;
391 virtual void initHash(IGameDef *gamedef);
393 virtual std::string dump() const;
399 std::string recipe_name;
400 // bool indicating if initHash has been called already
401 bool hash_inited = false;
404 // Replacement items for decrementInput()
405 CraftReplacements replacements;
409 Crafting definition manager
411 class ICraftDefManager
414 ICraftDefManager() = default;
415 virtual ~ICraftDefManager() = default;
417 // The main crafting function
418 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
419 std::vector<ItemStack> &output_replacements,
420 bool decrementInput, IGameDef *gamedef) const=0;
421 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
422 IGameDef *gamedef, unsigned limit=0) const=0;
424 // Print crafting recipes for debugging
425 virtual std::string dump() const=0;
428 class IWritableCraftDefManager : public ICraftDefManager
431 IWritableCraftDefManager() = default;
432 virtual ~IWritableCraftDefManager() = default;
434 // The main crafting function
435 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
436 std::vector<ItemStack> &output_replacements,
437 bool decrementInput, IGameDef *gamedef) const=0;
438 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
439 IGameDef *gamedef, unsigned limit=0) const=0;
441 virtual bool clearCraftRecipesByOutput(const CraftOutput &output, IGameDef *gamedef) = 0;
442 virtual bool clearCraftRecipesByInput(CraftMethod craft_method,
443 unsigned int craft_grid_width, const std::vector<std::string> &recipe, IGameDef *gamedef) = 0;
445 // Print crafting recipes for debugging
446 virtual std::string dump() const=0;
448 // Add a crafting definition.
449 // After calling this, the pointer belongs to the manager.
450 virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0;
452 // Delete all crafting definitions
453 virtual void clear()=0;
455 // To be called after all mods are loaded, so that we catch all aliases
456 virtual void initHashes(IGameDef *gamedef) = 0;
459 IWritableCraftDefManager* createCraftDefManager();