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) { // 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; }
// get_all_craft_recipes(result item) int ModApiCraft::l_get_all_craft_recipes(lua_State *L) { NO_MAP_LOCK_REQUIRED; std::string o_item = luaL_checkstring(L,1); IGameDef *gdef = getServer(L); ICraftDefManager *cdef = gdef->cdef(); CraftInput input; CraftOutput output(o_item,0); std::vector<CraftDefinition*> recipes_list = cdef->getCraftRecipes(output, gdef); if (recipes_list.empty()) { lua_pushnil(L); return 1; } // Get the table insert function lua_getglobal(L, "table"); lua_getfield(L, -1, "insert"); int table_insert = lua_gettop(L); lua_newtable(L); int table = lua_gettop(L); for (std::vector<CraftDefinition*>::const_iterator i = recipes_list.begin(); i != recipes_list.end(); i++) { CraftOutput tmpout; tmpout.item = ""; tmpout.time = 0; CraftDefinition *def = *i; tmpout = def->getOutput(input, gdef); std::string query = tmpout.item; char *fmtpos, *fmt = &query[0]; if (strtok_r(fmt, " ", &fmtpos) == output.item) { input = def->getInput(output, gdef); lua_pushvalue(L, table_insert); lua_pushvalue(L, table); lua_newtable(L); int k = 1; lua_newtable(L); for(std::vector<ItemStack>::const_iterator i = input.items.begin(); i != input.items.end(); i++, k++) { if (i->empty()) continue; lua_pushinteger(L,k); lua_pushstring(L,i->name.c_str()); lua_settable(L, -3); } lua_setfield(L, -2, "items"); setintfield(L, -1, "width", input.width); switch (input.method) { case CRAFT_METHOD_NORMAL: lua_pushstring(L,"normal"); break; case CRAFT_METHOD_COOKING: lua_pushstring(L,"cooking"); break; case CRAFT_METHOD_FUEL: lua_pushstring(L,"fuel"); break; default: lua_pushstring(L,"unknown"); } lua_setfield(L, -2, "type"); lua_pushstring(L, &tmpout.item[0]); lua_setfield(L, -2, "output"); if (lua_pcall(L, 2, 0, 0)) script_error(L); } } return 1; }