From 38580fbee71d9833ae05eae604ce2301cd23218f Mon Sep 17 00:00:00 2001 From: darkrose Date: Thu, 12 Jul 2012 04:46:10 +1000 Subject: Add minetest.get_craft_recipe() --- src/craftdef.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 2 deletions(-) (limited to 'src/craftdef.cpp') diff --git a/src/craftdef.cpp b/src/craftdef.cpp index ddb334fe2..ab78e7560 100644 --- a/src/craftdef.cpp +++ b/src/craftdef.cpp @@ -35,7 +35,7 @@ static bool inputItemMatchesRecipe(const std::string &inp_name, // Exact name if(inp_name == rec_name) return true; - + // Group if(rec_name.substr(0,6) == "group:" && idef->isKnown(inp_name)){ std::string rec_group = rec_name.substr(6); @@ -43,7 +43,7 @@ static bool inputItemMatchesRecipe(const std::string &inp_name, if(itemgroup_get(def.groups, rec_group) != 0) return true; } - + // Didn't match return false; } @@ -84,6 +84,20 @@ static std::vector craftGetItemNames( return result; } +// convert a list of item names, to ItemStacks. +static std::vector craftGetItems( + const std::vector &items, IGameDef *gamedef) +{ + std::vector result; + for(std::vector::const_iterator + i = items.begin(); + i != items.end(); i++) + { + result.push_back(ItemStack(std::string(*i),(u16)1,(u16)0,"",gamedef->getItemDefManager())); + } + return result; +} + // Compute bounding rectangle given a matrix of items // Returns false if every item is "" static bool craftGetBounds(const std::vector &items, unsigned int width, @@ -439,6 +453,11 @@ CraftOutput CraftDefinitionShaped::getOutput(const CraftInput &input, IGameDef * return CraftOutput(output, 0); } +CraftInput CraftDefinitionShaped::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + return CraftInput(CRAFT_METHOD_NORMAL,width,craftGetItems(recipe,gamedef)); +} + void CraftDefinitionShaped::decrementInput(CraftInput &input, IGameDef *gamedef) const { craftDecrementOrReplaceInput(input, replacements, gamedef); @@ -507,6 +526,11 @@ CraftOutput CraftDefinitionShapeless::getOutput(const CraftInput &input, IGameDe return CraftOutput(output, 0); } +CraftInput CraftDefinitionShapeless::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + return CraftInput(CRAFT_METHOD_NORMAL,0,craftGetItems(recipe,gamedef)); +} + void CraftDefinitionShapeless::decrementInput(CraftInput &input, IGameDef *gamedef) const { craftDecrementOrReplaceInput(input, replacements, gamedef); @@ -625,6 +649,13 @@ CraftOutput CraftDefinitionToolRepair::getOutput(const CraftInput &input, IGameD return CraftOutput(repaired.getItemString(), 0); } +CraftInput CraftDefinitionToolRepair::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector stack; + stack.push_back(ItemStack()); + return CraftInput(CRAFT_METHOD_COOKING,additional_wear,stack); +} + void CraftDefinitionToolRepair::decrementInput(CraftInput &input, IGameDef *gamedef) const { craftDecrementInput(input, gamedef); @@ -680,6 +711,13 @@ CraftOutput CraftDefinitionCooking::getOutput(const CraftInput &input, IGameDef return CraftOutput(output, cooktime); } +CraftInput CraftDefinitionCooking::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector rec; + rec.push_back(recipe); + return CraftInput(CRAFT_METHOD_COOKING,cooktime,craftGetItems(rec,gamedef)); +} + void CraftDefinitionCooking::decrementInput(CraftInput &input, IGameDef *gamedef) const { craftDecrementOrReplaceInput(input, replacements, gamedef); @@ -744,6 +782,13 @@ CraftOutput CraftDefinitionFuel::getOutput(const CraftInput &input, IGameDef *ga return CraftOutput("", burntime); } +CraftInput CraftDefinitionFuel::getInput(const CraftOutput &output, IGameDef *gamedef) const +{ + std::vector rec; + rec.push_back(recipe); + return CraftInput(CRAFT_METHOD_COOKING,(int)burntime,craftGetItems(rec,gamedef)); +} + void CraftDefinitionFuel::decrementInput(CraftInput &input, IGameDef *gamedef) const { craftDecrementOrReplaceInput(input, replacements, gamedef); @@ -837,6 +882,47 @@ public: } return false; } + virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output, + IGameDef *gamedef) const + { + CraftOutput tmpout; + tmpout.item = ""; + tmpout.time = 0; + + // If output item is empty, abort. + if(output.item.empty()) + return false; + + // Walk crafting definitions from back to front, so that later + // definitions can override earlier ones. + for(std::vector::const_reverse_iterator + i = m_craft_definitions.rbegin(); + i != m_craft_definitions.rend(); i++) + { + CraftDefinition *def = *i; + + /*infostream<<"Checking "<dump()<getOutput(input, gamedef); + if(tmpout.item.substr(0,output.item.length()) == output.item) + { + // Get output, then decrement input (if requested) + input = def->getInput(output, gamedef); + return true; + } + } + catch(SerializationError &e) + { + errorstream<<"getCraftResult: ERROR: " + <<"Serialization error in recipe " + <dump()<