#include "inventory.h"
#include "util/serialize.h"
#include "strfnd.h"
+#include "exceptions.h"
// Check if input matches recipe
// Takes recipe groups into account
return success;
}
-#if 0
-// This became useless when group support was added to shapeless recipes
-// Convert a list of item names to a multiset
-static std::multiset<std::string> craftMakeMultiset(const std::vector<std::string> &names)
-{
- std::multiset<std::string> set;
- for(std::vector<std::string>::const_iterator
- i = names.begin();
- i != names.end(); i++)
- {
- if(*i != "")
- set.insert(*i);
- }
- return set;
-}
-#endif
-
// Removes 1 from each item stack
static void craftDecrementInput(CraftInput &input, IGameDef *gamedef)
{
return false; // it was empty
// Different sizes?
- if(inp_max_x - inp_min_x != rec_max_x - rec_min_x)
- return false;
- if(inp_max_y - inp_min_y != rec_max_y - rec_min_y)
+ if(inp_max_x - inp_min_x != rec_max_x - rec_min_x ||
+ inp_max_y - inp_min_y != rec_max_y - rec_min_y)
return false;
// Verify that all item names in the bounding box are equal
unsigned int w = inp_max_x - inp_min_x + 1;
unsigned int h = inp_max_y - inp_min_y + 1;
- for(unsigned int y=0; y<h; y++)
- for(unsigned int x=0; x<w; x++)
- {
- unsigned int inp_x = inp_min_x + x;
- unsigned int inp_y = inp_min_y + y;
- unsigned int rec_x = rec_min_x + x;
- unsigned int rec_y = rec_min_y + y;
-
- if(!inputItemMatchesRecipe(
- inp_names[inp_y * inp_width + inp_x],
- rec_names[rec_y * rec_width + rec_x], gamedef->idef())
- ){
- return false;
+
+ for(unsigned int y=0; y < h; y++) {
+ unsigned int inp_y = (inp_min_y + y) * inp_width;
+ unsigned int rec_y = (rec_min_y + y) * rec_width;
+
+ for(unsigned int x=0; x < w; x++) {
+ unsigned int inp_x = inp_min_x + x;
+ unsigned int rec_x = rec_min_x + x;
+
+ if(!inputItemMatchesRecipe(
+ inp_names[inp_y + inp_x],
+ rec_names[rec_y + rec_x], gamedef->idef())
+ ) {
+ return false;
+ }
}
}
}
// Try with all permutations of the recipe
- std::vector<std::string> recipe_copy = recipe;
+ std::vector<std::string> recipe_copy = craftGetItemNames(recipe, gamedef);
// Start from the lexicographically first permutation (=sorted)
std::sort(recipe_copy.begin(), recipe_copy.end());
//while(std::prev_permutation(recipe_copy.begin(), recipe_copy.end())){}
try {
tmpout = def->getOutput(input, gamedef);
- if(tmpout.item.substr(0,output.item.length()) == output.item)
+ 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 false;
}
+ virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
+ IGameDef *gamedef) const
+ {
+ std::vector<CraftDefinition*> recipes_list;
+ CraftInput input;
+ CraftOutput tmpout;
+ tmpout.item = "";
+ tmpout.time = 0;
+
+ 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)
+ {
+ // 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
+ }
+ }
+ return recipes_list;
+ }
virtual std::string dump() const
{
std::ostringstream os(std::ios::binary);