@@ -287,6 +287,15 @@ std::string craftDumpMatrix(const std::vector<ItemStack> &items,
287287 CraftInput
288288*/
289289
290+ bool CraftInput::empty () const
291+ {
292+ for (const auto &item : items) {
293+ if (!item.empty ())
294+ return false ;
295+ }
296+ return true ;
297+ }
298+
290299std::string CraftInput::dump () const
291300{
292301 std::ostringstream os (std::ios::binary);
@@ -906,18 +915,7 @@ class CCraftDefManager: public IWritableCraftDefManager
906915 std::vector<ItemStack> &output_replacement, bool decrementInput,
907916 IGameDef *gamedef) const
908917 {
909- output.item = " " ;
910- output.time = 0 ;
911-
912- // If all input items are empty, abort.
913- bool all_empty = true ;
914- for (const auto &item : input.items ) {
915- if (!item.empty ()) {
916- all_empty = false ;
917- break ;
918- }
919- }
920- if (all_empty)
918+ if (input.empty ())
921919 return false ;
922920
923921 std::vector<std::string> input_names;
@@ -1002,84 +1000,48 @@ class CCraftDefManager: public IWritableCraftDefManager
10021000 return recipes;
10031001 }
10041002
1005- virtual bool clearCraftRecipesByOutput (const CraftOutput &output, IGameDef *gamedef)
1003+ virtual bool clearCraftsByOutput (const CraftOutput &output, IGameDef *gamedef)
10061004 {
1007- auto vec_iter = m_output_craft_definitions.find (output.item );
1005+ auto to_clear = m_output_craft_definitions.find (output.item );
10081006
1009- if (vec_iter == m_output_craft_definitions.end ())
1007+ if (to_clear == m_output_craft_definitions.end ())
10101008 return false ;
10111009
1012- std::vector<CraftDefinition*> &vec = vec_iter->second ;
1013- for (auto def : vec) {
1010+ for (auto def : to_clear->second ) {
10141011 // Recipes are not yet hashed at this point
1015- std::vector<CraftDefinition*> &unhashed_inputs_vec = m_craft_defs[(int ) CRAFT_HASH_TYPE_UNHASHED][0 ];
1016- std::vector<CraftDefinition*> new_vec_by_input;
1017- /* We will preallocate necessary memory addresses, so we don't need to reallocate them later.
1018- This would save us some performance. */
1019- new_vec_by_input.reserve (unhashed_inputs_vec.size ());
1020- for (auto &i2 : unhashed_inputs_vec) {
1021- if (def != i2) {
1022- new_vec_by_input.push_back (i2);
1023- }
1024- }
1025- m_craft_defs[(int ) CRAFT_HASH_TYPE_UNHASHED][0 ].swap (new_vec_by_input);
1012+ std::vector<CraftDefinition *> &defs = m_craft_defs[(int )CRAFT_HASH_TYPE_UNHASHED][0 ];
1013+ defs.erase (std::remove (defs.begin (), defs.end (), def), defs.end ());
1014+ delete def;
10261015 }
1027- m_output_craft_definitions.erase (output. item );
1016+ m_output_craft_definitions.erase (to_clear );
10281017 return true ;
10291018 }
10301019
1031- virtual bool clearCraftRecipesByInput (CraftMethod craft_method, unsigned int craft_grid_width,
1032- const std::vector<std::string> &recipe, IGameDef *gamedef)
1020+ virtual bool clearCraftsByInput (const CraftInput &input, IGameDef *gamedef)
10331021 {
1034- bool all_empty = true ;
1035- for (const auto &i : recipe) {
1036- if (!i.empty ()) {
1037- all_empty = false ;
1038- break ;
1039- }
1040- }
1041- if (all_empty)
1022+ if (input.empty ())
10421023 return false ;
10431024
1044- CraftInput input (craft_method, craft_grid_width, craftGetItems (recipe, gamedef));
10451025 // Recipes are not yet hashed at this point
1046- std::vector<CraftDefinition*> &unhashed_inputs_vec = m_craft_defs[(int ) CRAFT_HASH_TYPE_UNHASHED][0 ];
1047- std::vector<CraftDefinition*> new_vec_by_input ;
1026+ std::vector<CraftDefinition *> &defs = m_craft_defs[(int )CRAFT_HASH_TYPE_UNHASHED][0 ];
1027+ std::vector<CraftDefinition *> new_defs ;
10481028 bool got_hit = false ;
1049- for (std::vector<CraftDefinition*>::size_type
1050- i = unhashed_inputs_vec.size (); i > 0 ; i--) {
1051- CraftDefinition *def = unhashed_inputs_vec[i - 1 ];
1052- /* If the input doesn't match the recipe definition, this recipe definition later
1053- will be added back in source map. */
1029+ for (auto def : defs) {
10541030 if (!def->check (input, gamedef)) {
1055- new_vec_by_input .push_back (def);
1031+ new_defs .push_back (def);
10561032 continue ;
10571033 }
1058- CraftOutput output = def->getOutput (input, gamedef);
10591034 got_hit = true ;
1060- auto vec_iter = m_output_craft_definitions.find (output.item );
1061- if (vec_iter == m_output_craft_definitions.end ())
1035+ std::string output = def->getOutput (input, gamedef).item ;
1036+ delete def;
1037+ auto it = m_output_craft_definitions.find (craftGetItemName (output, gamedef));
1038+ if (it == m_output_craft_definitions.end ())
10621039 continue ;
1063- std::vector<CraftDefinition*> &vec = vec_iter->second ;
1064- std::vector<CraftDefinition*> new_vec_by_output;
1065- /* We will preallocate necessary memory addresses, so we don't need
1066- to reallocate them later. This would save us some performance. */
1067- new_vec_by_output.reserve (vec.size ());
1068- for (auto &vec_i : vec) {
1069- /* If pointers from map by input and output are not same,
1070- we will add 'CraftDefinition*' to a new vector. */
1071- if (def != vec_i) {
1072- /* Adding dereferenced iterator value (which are
1073- 'CraftDefinition' reference) to a new vector. */
1074- new_vec_by_output.push_back (vec_i);
1075- }
1076- }
1077- // Swaps assigned to current key value with new vector for output map.
1078- m_output_craft_definitions[output.item ].swap (new_vec_by_output);
1040+ std::vector<CraftDefinition *> &outdefs = it->second ;
1041+ outdefs.erase (std::remove (outdefs.begin (), outdefs.end (), def), outdefs.end ());
10791042 }
10801043 if (got_hit)
1081- // Swaps value with new vector for input map.
1082- m_craft_defs[(int ) CRAFT_HASH_TYPE_UNHASHED][0 ].swap (new_vec_by_input);
1044+ defs.swap (new_defs);
10831045
10841046 return got_hit;
10851047 }
0 commit comments