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 // Returns true if all items are empty.
86 std::string dump() const;
90 Output: Result of crafting operation
94 // Used for normal crafting and cooking, itemstring
95 std::string item = "";
96 // Used for cooking (cook time) and fuel (burn time), seconds
99 CraftOutput() = default;
101 CraftOutput(const std::string &item_, float time_):
102 item(item_), time(time_)
104 std::string dump() const;
108 A list of replacements. A replacement indicates that a specific
109 input item should not be deleted (when crafting) but replaced with
110 a different item. Each replacements is a pair (itemstring to remove,
111 itemstring to replace with)
113 Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a
114 replacement pair, the crafting input slot that contained a water
115 bucket will contain an empty bucket after crafting.
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 PRIORITY_SHAPELESS_AND_GROUPS,
148 PRIORITY_SHAPED_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;
199 CraftDefinitionShaped(
200 const std::string &output_,
202 const std::vector<std::string> &recipe_,
203 const CraftReplacements &replacements_);
205 virtual ~CraftDefinitionShaped() = default;
207 virtual std::string getName() const;
208 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
209 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
210 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
211 virtual void decrementInput(CraftInput &input,
212 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
214 virtual u64 getHash(CraftHashType type) const;
216 virtual void initHash(IGameDef *gamedef);
218 virtual std::string dump() const;
222 std::string output = "";
224 unsigned int width = 1;
225 // Recipe matrix (itemstrings)
226 std::vector<std::string> recipe;
227 // Recipe matrix (item names)
228 std::vector<std::string> recipe_names;
229 // bool indicating if initHash has been called already
230 bool hash_inited = false;
231 // Replacement items for decrementInput()
232 CraftReplacements replacements;
236 A shapeless crafting definition
237 Supported crafting method: CRAFT_METHOD_NORMAL.
238 Input items can arranged in any way.
240 class CraftDefinitionShapeless: public CraftDefinition
243 CraftDefinitionShapeless() = delete;
244 CraftDefinitionShapeless(
245 const std::string &output_,
246 const std::vector<std::string> &recipe_,
247 const CraftReplacements &replacements_);
249 virtual ~CraftDefinitionShapeless() = default;
251 virtual std::string getName() const;
252 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
253 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
254 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
255 virtual void decrementInput(CraftInput &input,
256 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
258 virtual u64 getHash(CraftHashType type) const;
260 virtual void initHash(IGameDef *gamedef);
262 virtual std::string dump() const;
267 // Recipe list (itemstrings)
268 std::vector<std::string> recipe;
269 // Recipe list (item names)
270 std::vector<std::string> recipe_names;
271 // bool indicating if initHash has been called already
272 bool hash_inited = false;
273 // Replacement items for decrementInput()
274 CraftReplacements replacements;
278 Tool repair crafting definition
279 Supported crafting method: CRAFT_METHOD_NORMAL.
280 Put two damaged tools into the crafting grid, get one tool back.
281 There should only be one crafting definition of this type.
283 class CraftDefinitionToolRepair: public CraftDefinition
286 CraftDefinitionToolRepair() = delete;
287 CraftDefinitionToolRepair(float additional_wear_);
289 virtual ~CraftDefinitionToolRepair() = default;
291 virtual std::string getName() const;
292 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
293 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
294 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
295 virtual void decrementInput(CraftInput &input,
296 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
298 virtual u64 getHash(CraftHashType type) const { return 2; }
300 virtual void initHash(IGameDef *gamedef)
302 hash_type = CRAFT_HASH_TYPE_COUNT;
305 virtual std::string dump() const;
308 // This is a constant that is added to the wear of the result.
309 // May be positive or negative, allowed range [-1,1].
310 // 1 = new tool is completely broken
311 // 0 = simply add remaining uses of both input tools
312 // -1 = new tool is completely pristine
313 float additional_wear = 0.0f;
317 A cooking (in furnace) definition
318 Supported crafting method: CRAFT_METHOD_COOKING.
320 class CraftDefinitionCooking: public CraftDefinition
323 CraftDefinitionCooking() = delete;
324 CraftDefinitionCooking(
325 const std::string &output_,
326 const std::string &recipe_,
328 const CraftReplacements &replacements_);
330 virtual ~CraftDefinitionCooking() = default;
332 virtual std::string getName() const;
333 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
334 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
335 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
336 virtual void decrementInput(CraftInput &input,
337 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
339 virtual u64 getHash(CraftHashType type) const;
341 virtual void initHash(IGameDef *gamedef);
343 virtual std::string dump() const;
351 std::string recipe_name;
352 // bool indicating if initHash has been called already
353 bool hash_inited = false;
356 // Replacement items for decrementInput()
357 CraftReplacements replacements;
361 A fuel (for furnace) definition
362 Supported crafting method: CRAFT_METHOD_FUEL.
364 class CraftDefinitionFuel: public CraftDefinition
367 CraftDefinitionFuel() = delete;
369 const std::string &recipe_,
371 const CraftReplacements &replacements_);
373 virtual ~CraftDefinitionFuel() = default;
375 virtual std::string getName() const;
376 virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
377 virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
378 virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
379 virtual void decrementInput(CraftInput &input,
380 std::vector<ItemStack> &output_replacements, IGameDef *gamedef) const;
382 virtual u64 getHash(CraftHashType type) const;
384 virtual void initHash(IGameDef *gamedef);
386 virtual std::string dump() const;
392 std::string recipe_name;
393 // bool indicating if initHash has been called already
394 bool hash_inited = false;
397 // Replacement items for decrementInput()
398 CraftReplacements replacements;
402 Crafting definition manager
404 class ICraftDefManager
407 ICraftDefManager() = default;
408 virtual ~ICraftDefManager() = default;
411 * The main crafting function.
413 * @param input The input grid.
414 * @param output CraftOutput where the result is placed.
415 * @param output_replacements A vector of ItemStacks where replacements are
416 * placed if they cannot be placed in the input. Replacements can be placed
417 * in the input if the stack of the replaced item has a count of 1.
418 * @param decrementInput If true, consume or replace input items.
420 * @return true if a result was found, otherwise false.
422 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
423 std::vector<ItemStack> &output_replacements,
424 bool decrementInput, IGameDef *gamedef) const=0;
426 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
427 IGameDef *gamedef, unsigned limit=0) const=0;
429 // Print crafting recipes for debugging
430 virtual std::string dump() const=0;
433 class IWritableCraftDefManager : public ICraftDefManager
436 IWritableCraftDefManager() = default;
437 virtual ~IWritableCraftDefManager() = default;
439 // The main crafting function
440 virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
441 std::vector<ItemStack> &output_replacements,
442 bool decrementInput, IGameDef *gamedef) const=0;
443 virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
444 IGameDef *gamedef, unsigned limit=0) const=0;
446 virtual bool clearCraftsByOutput(const CraftOutput &output, IGameDef *gamedef) = 0;
447 virtual bool clearCraftsByInput(const CraftInput &input, IGameDef *gamedef) = 0;
449 // Print crafting recipes for debugging
450 virtual std::string dump() const=0;
452 // Add a crafting definition.
453 // After calling this, the pointer belongs to the manager.
454 virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) = 0;
456 // Delete all crafting definitions
457 virtual void clear()=0;
459 // To be called after all mods are loaded, so that we catch all aliases
460 virtual void initHashes(IGameDef *gamedef) = 0;
463 IWritableCraftDefManager* createCraftDefManager();