diff options
Diffstat (limited to 'src/craftdef.cpp')
-rw-r--r-- | src/craftdef.cpp | 103 |
1 files changed, 28 insertions, 75 deletions
diff --git a/src/craftdef.cpp b/src/craftdef.cpp index 80937ccb7..bca16a4c6 100644 --- a/src/craftdef.cpp +++ b/src/craftdef.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "gamedef.h" #include "inventory.h" #include "util/serialize.h" +#include "util/numeric.h" #include "strfnd.h" #include "exceptions.h" @@ -931,85 +932,30 @@ 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<CraftDefinition*>::const_reverse_iterator - i = m_craft_definitions.rbegin(); - i != m_craft_definitions.rend(); i++) - { - CraftDefinition *def = *i; - - /*infostream<<"Checking "<<input.dump()<<std::endl - <<" against "<<def->dump()<<std::endl;*/ - try { - tmpout = def->getOutput(input, gamedef); - if((tmpout.item.substr(0,output.item.length()) == output.item) && - ((tmpout.item[output.item.length()] == 0) || - (tmpout.item[output.item.length()] == ' '))) - { - // Get output, then decrement input (if requested) - input = def->getInput(output, gamedef); - return true; - } - } - catch(SerializationError &e) - { - errorstream<<"getCraftResult: ERROR: " - <<"Serialization error in recipe " - <<def->dump()<<std::endl; - // then go on with the next craft definition - } - } - return false; - } virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, - IGameDef *gamedef) const + IGameDef *gamedef, unsigned limit=0) const { - std::vector<CraftDefinition*> recipes_list; - CraftInput input; - CraftOutput tmpout; - tmpout.item = ""; - tmpout.time = 0; + std::vector<CraftDefinition*> recipes; - for(std::vector<CraftDefinition*>::const_reverse_iterator - i = m_craft_definitions.rbegin(); - i != m_craft_definitions.rend(); i++) - { - CraftDefinition *def = *i; + std::map<std::string, std::vector<CraftDefinition*> >::const_iterator + vec_iter = m_output_craft_definitions.find(output.item); - /*infostream<<"Checking "<<input.dump()<<std::endl - <<" against "<<def->dump()<<std::endl;*/ + if (vec_iter == m_output_craft_definitions.end()) + return recipes; - try { - tmpout = def->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); - recipes_list.push_back(*i); - } - } - catch(SerializationError &e) - { - errorstream<<"getCraftResult: ERROR: " - <<"Serialization error in recipe " - <<def->dump()<<std::endl; - // then go on with the next craft definition - } + const std::vector<CraftDefinition*> &vec = vec_iter->second; + + recipes.reserve(limit ? MYMIN(limit, vec.size()) : vec.size()); + + for (std::vector<CraftDefinition*>::const_reverse_iterator + it = vec.rbegin(); it != vec.rend(); ++it) { + if (limit && recipes.size() >= limit) + break; + recipes.push_back(*it); } - return recipes_list; + + return recipes; } virtual std::string dump() const { @@ -1023,11 +969,16 @@ public: } return os.str(); } - virtual void registerCraft(CraftDefinition *def) + virtual void registerCraft(CraftDefinition *def, IGameDef *gamedef) { verbosestream<<"registerCraft: registering craft definition: " <<def->dump()<<std::endl; m_craft_definitions.push_back(def); + + CraftInput input; + std::string output_name = craftGetItemName( + def->getOutput(input, gamedef).item, gamedef); + m_output_craft_definitions[output_name].push_back(def); } virtual void clear() { @@ -1037,6 +988,7 @@ public: delete *i; } m_craft_definitions.clear(); + m_output_craft_definitions.clear(); } virtual void serialize(std::ostream &os) const { @@ -1053,7 +1005,7 @@ public: os<<serializeString(tmp_os.str()); } } - virtual void deSerialize(std::istream &is) + virtual void deSerialize(std::istream &is, IGameDef *gamedef) { // Clear everything clear(); @@ -1067,11 +1019,12 @@ public: std::istringstream tmp_is(deSerializeString(is), std::ios::binary); CraftDefinition *def = CraftDefinition::deSerialize(tmp_is); // Register - registerCraft(def); + registerCraft(def, gamedef); } } private: std::vector<CraftDefinition*> m_craft_definitions; + std::map<std::string, std::vector<CraftDefinition*> > m_output_craft_definitions; }; IWritableCraftDefManager* createCraftDefManager() |