Added method to get all registered recipes for item(node)
authorRealBadAngel <mk@realbadangel.pl>
Mon, 4 Mar 2013 00:55:16 +0000 (01:55 +0100)
committerkwolekr <kwolekr@minetest.net>
Wed, 6 Mar 2013 04:32:33 +0000 (23:32 -0500)
doc/lua_api.txt
src/craftdef.cpp
src/craftdef.h
src/scriptapi.cpp

index 8246377e29c01e394211c69c3028b8183cda3cf7..809d3d9d09a6c70e07ead766241fe093b9050b98 100644 (file)
@@ -922,12 +922,17 @@ minetest.get_craft_result(input) -> output, decremented_input
 ^ output.time = number, if unsuccessful: 0
 ^ decremented_input = like input
 minetest.get_craft_recipe(output) -> input
+^ returns last registered recipe for output item (node)
 ^ output is a node or item type such as 'default:torch'
 ^ input.method = 'normal' or 'cooking' or 'fuel'
 ^ input.width = for example 3
 ^ input.items = for example { stack 1, stack 2, stack 3, stack 4,
                               stack 5, stack 6, stack 7, stack 8, stack 9 }
 ^ input.items = nil if no recipe found
+minetest.get_all_craft_recipes(output) -> table or nil
+^ returns table with all registered recipes for output item (node)
+^ returns nil if no recipe was found
+^ table entries have same format as minetest.get_craft_recipe
 minetest.handle_node_drops(pos, drops, digger)
 ^ drops: list of itemstrings
 ^ Handles drops from nodes after digging: Default action is to put them into
index 99e3fcc3d93c2d22581962e471c13e673e0b067d..c79408f9986b177aa0933f7aa777e6ef38aea78f 100644 (file)
@@ -987,6 +987,43 @@ public:
                }
                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);
index eb3cd7e391486e8a9530d2043ed1c5bf270ba5ce..14dc530031ba4eaa834eb49ccfc08e112ae3cd63 100644 (file)
@@ -358,6 +358,8 @@ public:
                        bool decrementInput, IGameDef *gamedef) const=0;
        virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
                        IGameDef *gamedef) const=0;
+       virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
+                       IGameDef *gamedef) const=0;
        
        // Print crafting recipes for debugging
        virtual std::string dump() const=0;
@@ -376,6 +378,8 @@ public:
                        bool decrementInput, IGameDef *gamedef) const=0;
        virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
                        IGameDef *gamedef) const=0;
+       virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output, 
+                       IGameDef *gamedef) const=0;
 
        // Print crafting recipes for debugging
        virtual std::string dump() const=0;
index ef8a1454a4689b7e36b71419a1d2f8dc2e41c1a5..074a2eb0de6397ff1fc3b3cc5826ffae27a9386d 100644 (file)
@@ -1000,6 +1000,79 @@ static int l_notify_authentication_modified(lua_State *L)
        return 0;
 }
 
+// get_craft_recipes(result item)
+static int l_get_all_craft_recipes(lua_State *L)
+{
+       char tmp[20];
+       int input_i = 1;
+       std::string o_item = luaL_checkstring(L,input_i);
+       IGameDef *gdef = get_server(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);
+               if(tmpout.item.substr(0,output.item.length()) == output.item)
+               {
+                       input = def->getInput(output, gdef);
+                       lua_pushvalue(L, table_insert);
+                       lua_pushvalue(L, table);
+                       lua_newtable(L);
+                       int k = 0;
+                       lua_newtable(L);
+                       for(std::vector<ItemStack>::const_iterator
+                               i = input.items.begin();
+                               i != input.items.end(); i++, k++)
+                       {
+                               if (i->empty()) continue;
+                               sprintf(tmp,"%d",k);
+                               lua_pushstring(L,tmp);
+                               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");
+                       if(lua_pcall(L, 2, 0, 0))
+                       script_error(L, "error: %s", lua_tostring(L, -1));
+               }
+       }
+       return 1;
+}
+
 // rollback_get_last_node_actor(p, range, seconds) -> actor, p, seconds
 static int l_rollback_get_last_node_actor(lua_State *L)
 {
@@ -1086,6 +1159,7 @@ static const struct luaL_Reg minetest_f [] = {
        {"notify_authentication_modified", l_notify_authentication_modified},
        {"get_craft_result", l_get_craft_result},
        {"get_craft_recipe", l_get_craft_recipe},
+       {"get_all_craft_recipes", l_get_all_craft_recipes},
        {"rollback_get_last_node_actor", l_rollback_get_last_node_actor},
        {"rollback_revert_actions_by", l_rollback_revert_actions_by},
        {NULL, NULL}