diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index feca199c1..b10d49f27 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -424,6 +424,7 @@ set(common_SRCS version.cpp voxel.cpp voxelalgorithms.cpp + itemstackmetadata.cpp ${common_network_SRCS} ${JTHREAD_SRCS} ${common_SCRIPT_SRCS} diff --git a/src/content_cao.cpp b/src/content_cao.cpp index d701e4f72..0db0e4267 100644 --- a/src/content_cao.cpp +++ b/src/content_cao.cpp @@ -948,7 +948,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr, if(m_prop.textures.size() >= 1){ infostream<<"textures[0]: "<idef(); - ItemStack item(m_prop.textures[0], 1, 0, "", idef); + ItemStack item(m_prop.textures[0], 1, 0, idef); m_wield_meshnode = new WieldMeshSceneNode( smgr->getRootSceneNode(), smgr, -1); diff --git a/src/craftdef.cpp b/src/craftdef.cpp index d3f1edaf9..51eb5e4d9 100644 --- a/src/craftdef.cpp +++ b/src/craftdef.cpp @@ -139,7 +139,7 @@ static std::vector craftGetItems( for (std::vector::size_type i = 0; i < items.size(); i++) { result.push_back(ItemStack(std::string(items[i]), (u16)1, - (u16)0, "", gamedef->getItemDefManager())); + (u16)0, gamedef->getItemDefManager())); } return result; } diff --git a/src/inventory.cpp b/src/inventory.cpp index fce8575e7..7a65b296d 100644 --- a/src/inventory.cpp +++ b/src/inventory.cpp @@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "nameidmapping.h" // For loading legacy MaterialItems #include "util/serialize.h" #include "util/string.h" +#include "itemstackmetadata.h" /* ItemStack @@ -110,7 +111,7 @@ static std::string deSerializeJsonStringIfNeeded(std::istream &is) ItemStack::ItemStack(std::string name_, u16 count_, - u16 wear_, std::string metadata_, + u16 wear_, ItemStackMetadata metadata_, IItemDefManager *itemdef) { name = itemdef->getAlias(name_); @@ -123,6 +124,19 @@ ItemStack::ItemStack(std::string name_, u16 count_, else if(itemdef->get(name).type == ITEM_TOOL) count = 1; } +ItemStack::ItemStack(std::string name_, u16 count_, + u16 wear_, + IItemDefManager *itemdef) +{ + name = itemdef->getAlias(name_); + count = count_; + wear = wear_; + + if(name.empty() || count == 0) + clear(); + else if(itemdef->get(name).type == ITEM_TOOL) + count = 1; +} void ItemStack::serialize(std::ostream &os) const { @@ -137,7 +151,7 @@ void ItemStack::serialize(std::ostream &os) const parts = 2; if(wear != 0) parts = 3; - if(metadata != "") + if(!metadata.isEmpty()) parts = 4; os<= 3) os<<" "<= 4) - os<<" "<= 4) { + os<<" "< #include #include +#include "itemstackmetadata.h" struct ToolCapabilities; struct ItemStack { - ItemStack(): name(""), count(0), wear(0), metadata("") {} + ItemStack(): name(""), count(0), wear(0), metadata() {} ItemStack(std::string name_, u16 count_, - u16 wear, std::string metadata_, + u16 wear, ItemStackMetadata metadata_, IItemDefManager *itemdef); + //constructor for empty metadata. before the item meta k-v-store was implemented, functions used to call above constructor with an empty string. + ItemStack(std::string name_, u16 count_, + u16 wear, + IItemDefManager *itemdef); ~ItemStack() {} // Serialization @@ -61,7 +66,7 @@ struct ItemStack name = ""; count = 0; wear = 0; - metadata = ""; + metadata.clear(); } void add(u16 n) @@ -167,7 +172,7 @@ struct ItemStack std::string name; u16 count; u16 wear; - std::string metadata; + ItemStackMetadata metadata; }; class InventoryList diff --git a/src/itemstackmetadata.cpp b/src/itemstackmetadata.cpp new file mode 100644 index 000000000..92fd469f0 --- /dev/null +++ b/src/itemstackmetadata.cpp @@ -0,0 +1,106 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "itemstackmetadata.h" +#include "exceptions.h" +#include "gamedef.h" +#include "inventory.h" +#include "log.h" +#include "util/serialize.h" +#include "util/strfnd.h" +#include "constants.h" // MAP_BLOCKSIZE +#include + +/* + ItemStackMetadata +*/ + +std::string ItemStackMetadata::serialize() const +{ + std::ostringstream os; + os << "$"; + for (StringMap::const_iterator + it = m_stringvars.begin(); + it != m_stringvars.end(); ++it) { + os << it->first << "="; + os << serializeJsonString(it->second) << "\n"; + } + return os.str(); +} + +void ItemStackMetadata::deSerialize(std::string &in) +{ + m_stringvars.clear(); + //to indicate new serialisation version, a dollar sign has to be the first char in the serialized string. if not, apply legacy deserialization + if (in[0] == '$') { + Strfnd fnd(in); + fnd.to(1); + while ( !fnd.at_end() ) { + std::string name = fnd.next("="); + std::string var_json=fnd.next("\n"); + std::istringstream var_stream(var_json); + std::string var = deSerializeJsonString(var_stream); + m_stringvars[name] = var; + } + }else{ + //legacy: store value in empty field ("") + m_stringvars[""]=in; + } +} + +void ItemStackMetadata::clear() +{ + m_stringvars.clear(); +} +bool ItemStackMetadata::isEmpty() const +{ + return m_stringvars.empty(); +} + +std::string ItemStackMetadata::getString(const std::string &name, + unsigned short recursion) const +{ + StringMap::const_iterator it = m_stringvars.find(name); + if (it == m_stringvars.end()) + return ""; + + return resolveString(it->second, recursion); +} + +void ItemStackMetadata::setString(const std::string &name, const std::string &var) +{ + if (var.empty()) { + m_stringvars.erase(name); + } else { + m_stringvars[name] = var; + } +} + +std::string ItemStackMetadata::resolveString(const std::string &str, + unsigned short recursion) const +{ + if (recursion > 1) { + return str; + } + if (str.substr(0, 2) == "${" && str[str.length() - 1] == '}') { + return getString(str.substr(2, str.length() - 3), recursion + 1); + } + return str; +} + diff --git a/src/itemstackmetadata.h b/src/itemstackmetadata.h new file mode 100644 index 000000000..7475e8c08 --- /dev/null +++ b/src/itemstackmetadata.h @@ -0,0 +1,62 @@ +/* +Minetest +Copyright (C) 2010-2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#ifndef ITEMSTACKMETADATA_HEADER +#define ITEMSTACKMETADATA_HEADER + +#include "irr_v3d.h" +#include +#include +#include "util/string.h" + +/* + ItemStackMetadata stores arbitary amounts of data for items as a key-value store. +*/ + +class Inventory; +class IItemDefManager; + +class ItemStackMetadata +{ +public: + ItemStackMetadata(): + m_stringvars() + { + }; + ~ItemStackMetadata(){}; + + std::string serialize() const; + void deSerialize(std::string &in); + + void clear(); + bool isEmpty() const; + // Generic key/value store + std::string getString(const std::string &name, unsigned short recursion = 0) const; + void setString(const std::string &name, const std::string &var); + // Support variable names in values + std::string resolveString(const std::string &str, unsigned short recursion = 0) const; + StringMap getStrings(){ + return m_stringvars; + }; +private: + StringMap m_stringvars; +}; + +#endif + diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp index 06e20c2a0..91f661c9f 100644 --- a/src/script/common/c_content.cpp +++ b/src/script/common/c_content.cpp @@ -811,8 +811,7 @@ ItemStack read_item(lua_State* L, int index,Server* srv) std::string name = getstringfield_default(L, index, "name", ""); int count = getintfield_default(L, index, "count", 1); int wear = getintfield_default(L, index, "wear", 0); - std::string metadata = getstringfield_default(L, index, "metadata", ""); - return ItemStack(name, count, wear, metadata, idef); + return ItemStack(name, count, wear, idef); } else { diff --git a/src/script/lua_api/CMakeLists.txt b/src/script/lua_api/CMakeLists.txt index d507dcf70..092b70672 100644 --- a/src/script/lua_api/CMakeLists.txt +++ b/src/script/lua_api/CMakeLists.txt @@ -7,6 +7,7 @@ set(common_SCRIPT_LUA_API_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/l_itemstackmeta.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_nodetimer.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp ${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp index af89da9a1..7f4ad569e 100644 --- a/src/script/lua_api/l_env.cpp +++ b/src/script/lua_api/l_env.cpp @@ -280,7 +280,7 @@ int ModApiEnvMod::l_place_node(lua_State *L) return 1; } // Create item to place - ItemStack item(ndef->get(n).name, 1, 0, "", idef); + ItemStack item(ndef->get(n).name, 1, 0, idef); // Make pointed position PointedThing pointed; pointed.type = POINTEDTHING_NODE; diff --git a/src/script/lua_api/l_item.cpp b/src/script/lua_api/l_item.cpp index 5381cba76..a66b4d2fd 100644 --- a/src/script/lua_api/l_item.cpp +++ b/src/script/lua_api/l_item.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "content_sao.h" #include "inventory.h" #include "log.h" +#include "lua_api/l_itemstackmeta.h" // garbage collector @@ -137,13 +138,24 @@ int LuaItemStack::l_set_wear(lua_State *L) return 1; } +// get_meta(self) -> userdata //note get_metadata and set_metadata mimic old behavior +int LuaItemStack::l_get_meta(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + LuaItemStack *o = checkobject(L, 1); + ItemStack &item = o->m_stack; + ItemStackMetaRef::create(L, &item); + return 1; +} +//LEGACY metadata access // get_metadata(self) -> string int LuaItemStack::l_get_metadata(lua_State *L) { NO_MAP_LOCK_REQUIRED; LuaItemStack *o = checkobject(L, 1); ItemStack &item = o->m_stack; - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); + std::string metastr=item.metadata.getString(""); + lua_pushlstring(L, metastr.c_str(), metastr.size()); return 1; } @@ -156,7 +168,9 @@ int LuaItemStack::l_set_metadata(lua_State *L) size_t len = 0; const char *ptr = luaL_checklstring(L, 2, &len); - item.metadata.assign(ptr, len); + std::string metastr; + metastr.assign(ptr, len); + item.metadata.setString("", metastr); lua_pushboolean(L, true); return 1; @@ -211,8 +225,6 @@ int LuaItemStack::l_to_table(lua_State *L) lua_setfield(L, -2, "count"); lua_pushinteger(L, item.wear); lua_setfield(L, -2, "wear"); - lua_pushlstring(L, item.metadata.c_str(), item.metadata.size()); - lua_setfield(L, -2, "metadata"); } return 1; } @@ -443,8 +455,9 @@ const luaL_reg LuaItemStack::methods[] = { luamethod(LuaItemStack, set_count), luamethod(LuaItemStack, get_wear), luamethod(LuaItemStack, set_wear), - luamethod(LuaItemStack, get_metadata), - luamethod(LuaItemStack, set_metadata), + luamethod(LuaItemStack, get_meta), + luamethod(LuaItemStack, get_metadata),//legacy + luamethod(LuaItemStack, set_metadata),//legacy luamethod(LuaItemStack, clear), luamethod(LuaItemStack, replace), luamethod(LuaItemStack, to_string), diff --git a/src/script/lua_api/l_item.h b/src/script/lua_api/l_item.h index 0f9e4ba9b..63040b69c 100644 --- a/src/script/lua_api/l_item.h +++ b/src/script/lua_api/l_item.h @@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_base.h" #include "inventory.h" // ItemStack +#include "lua_api/l_itemstackmeta.h" +#include "itemstackmetadata.h" class LuaItemStack : public ModApiBase { private: @@ -56,10 +58,13 @@ private: // set_wear(self, number) static int l_set_wear(lua_State *L); - // get_metadata(self) -> string + // get_meta(self) -> userdata(ItemStackMetaRef) + static int l_get_meta(lua_State *L); + + // get_metadata(self) -> string (legacy) static int l_get_metadata(lua_State *L); - // set_metadata(self, string) + // set_metadata(self, string) (legacy) static int l_set_metadata(lua_State *L); // clear(self) -> true diff --git a/src/script/lua_api/l_itemstackmeta.cpp b/src/script/lua_api/l_itemstackmeta.cpp new file mode 100644 index 000000000..c281bb992 --- /dev/null +++ b/src/script/lua_api/l_itemstackmeta.cpp @@ -0,0 +1,304 @@ +/* +Minetest +Copyright (C) 2013 celeron55, Perttu Ahola + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ + +#include "lua_api/l_itemstackmeta.h" +#include "lua_api/l_internal.h" +#include "lua_api/l_inventory.h" +#include "common/c_converter.h" +#include "common/c_content.h" +#include "gamedef.h" +#include "inventory.h" +#include "itemstackmetadata.h" + + + +/* + ItemStackMetaRef +*/ +ItemStackMetaRef* ItemStackMetaRef::checkobject(lua_State *L, int narg) +{ + luaL_checktype(L, narg, LUA_TUSERDATA); + void *ud = luaL_checkudata(L, narg, className); + if(!ud) luaL_typerror(L, narg, className); + return *(ItemStackMetaRef**)ud; // unbox pointer +} + +ItemStackMetadata* ItemStackMetaRef::getmeta(ItemStackMetaRef *ref) +{ + ItemStackMetadata *meta = &(ref->m_istack->metadata); + return meta; +} + + +void ItemStackMetaRef::reportMetadataChange(ItemStackMetaRef *ref) +{ + //At the moment, it does not seem to be neccessary to notify anything about changed metadata. + //Reserved for future use. +} + + +// Exported functions + +// garbage collector +int ItemStackMetaRef::gc_object(lua_State *L) { + ItemStackMetaRef *o = *(ItemStackMetaRef **)(lua_touserdata(L, 1)); + delete o; + return 0; +} + +// get_string(self, name) +int ItemStackMetaRef::l_get_string(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL){ + lua_pushlstring(L, "", 0); + return 1; + } + std::string str = meta->getString(name); + lua_pushlstring(L, str.c_str(), str.size()); + return 1; +} + +// set_string(self, name, var) +int ItemStackMetaRef::l_set_string(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = luaL_checkstring(L, 2); + size_t len = 0; + const char *s = lua_tolstring(L, 3, &len); + std::string str(s, len); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL || str == meta->getString(name)) + return 0; + meta->setString(name, str); + reportMetadataChange(ref); + return 0; +} + +// get_int(self, name) +int ItemStackMetaRef::l_get_int(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL){ + lua_pushnumber(L, 0); + return 1; + } + std::string str = meta->getString(name); + lua_pushnumber(L, stoi(str)); + return 1; +} + +// set_int(self, name, var) +int ItemStackMetaRef::l_set_int(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + int a = lua_tointeger(L, 3); + std::string str = itos(a); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL || str == meta->getString(name)) + return 0; + meta->setString(name, str); + reportMetadataChange(ref); + return 0; +} + +// get_float(self, name) +int ItemStackMetaRef::l_get_float(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL){ + lua_pushnumber(L, 0); + return 1; + } + std::string str = meta->getString(name); + lua_pushnumber(L, stof(str)); + return 1; +} + +// set_float(self, name, var) +int ItemStackMetaRef::l_set_float(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + std::string name = lua_tostring(L, 2); + float a = lua_tonumber(L, 3); + std::string str = ftos(a); + + ItemStackMetadata *meta = getmeta(ref); + if(meta == NULL || str == meta->getString(name)) + return 0; + meta->setString(name, str); + reportMetadataChange(ref); + return 0; +} + +// to_table(self) +int ItemStackMetaRef::l_to_table(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + + ItemStackMetadata *meta = getmeta(ref); + if (meta == NULL) { + lua_pushnil(L); + return 1; + } + lua_newtable(L); + + { + StringMap fields = meta->getStrings(); + for (StringMap::const_iterator + it = fields.begin(); it != fields.end(); ++it) { + const std::string &name = it->first; + const std::string &value = it->second; + lua_pushlstring(L, name.c_str(), name.size()); + lua_pushlstring(L, value.c_str(), value.size()); + lua_settable(L, -3); + } + } + + return 1; +} + +// from_table(self, table) +int ItemStackMetaRef::l_from_table(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + + ItemStackMetaRef *ref = checkobject(L, 1); + int base = 2; + + ItemStackMetadata *meta = getmeta(ref); + + if(meta == NULL){ + lua_pushboolean(L, false); + return 1; + } + + meta->clear(); + + if(lua_isnil(L, base)){ + // No metadata + lua_pushboolean(L, true); + return 1; + } + + // Set fields + int fieldstable = lua_gettop(L); + lua_pushnil(L); + while(lua_next(L, fieldstable) != 0){ + // key at index -2 and value at index -1 + std::string name = lua_tostring(L, -2); + size_t cl; + const char *cs = lua_tolstring(L, -1, &cl); + std::string value(cs, cl); + meta->setString(name, value); + lua_pop(L, 1); // removes value, keeps key for next iteration + } + + reportMetadataChange(ref); + lua_pushboolean(L, true); + return 1; +} + + +ItemStackMetaRef::ItemStackMetaRef(ItemStack *istack): + m_istack(istack) +{ +} + +ItemStackMetaRef::~ItemStackMetaRef() +{ +} + +// Creates an ItemStackMetaRef and leaves it on top of stack +// Not callable from Lua; all references are created on the C side. +void ItemStackMetaRef::create(lua_State *L, ItemStack *istack) +{ + ItemStackMetaRef *o = new ItemStackMetaRef(istack); + //infostream<<"ItemStackMetaRef::create: o="< + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU Lesser General Public License as published by +the Free Software Foundation; either version 2.1 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU Lesser General Public License for more details. + +You should have received a copy of the GNU Lesser General Public License along +with this program; if not, write to the Free Software Foundation, Inc., +51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +#ifndef L_ITEMSTACKMETA_H_ +#define L_ITEMSTACKMETA_H_ + +#include "lua_api/l_base.h" +#include "irrlichttypes_bloated.h" +#include "inventory.h" + +class ServerEnvironment; +class ItemStackMetadata; + +/* + ItemStackMetaRef +*/ + +class ItemStackMetaRef : public ModApiBase { +private: + ItemStack *m_istack; + + static const char className[]; + static const luaL_reg methods[]; + + static ItemStackMetaRef *checkobject(lua_State *L, int narg); + + /** + * Retrieve metadata for an itemstack (the one given as pointer as member variable). + * @return pointer to a @c ItemStackMetadata object. + */ + static ItemStackMetadata* getmeta(ItemStackMetaRef *ref); + + static void reportMetadataChange(ItemStackMetaRef *ref); + + // Exported functions + + // garbage collector + static int gc_object(lua_State *L); + + // get_string(self, name) + static int l_get_string(lua_State *L); + + // set_string(self, name, var) + static int l_set_string(lua_State *L); + + // get_int(self, name) + static int l_get_int(lua_State *L); + + // set_int(self, name, var) + static int l_set_int(lua_State *L); + + // get_float(self, name) + static int l_get_float(lua_State *L); + + // set_float(self, name, var) + static int l_set_float(lua_State *L); + + // get_inventory(self) + static int l_get_inventory(lua_State *L); + + // to_table(self) + static int l_to_table(lua_State *L); + + // from_table(self, table) + static int l_from_table(lua_State *L); + +public: + ItemStackMetaRef(ItemStack *istack); + + ~ItemStackMetaRef(); + + // Creates an ItemStackMetaRef and leaves it on top of stack + // Not callable from Lua; all references are created on the C side. + static void create(lua_State *L, ItemStack *istack); + + static void Register(lua_State *L); +}; + +#endif /* L_NODEMETA_H_ */ diff --git a/src/script/scripting_game.cpp b/src/script/scripting_game.cpp index e313d55f8..5f904a0c7 100644 --- a/src/script/scripting_game.cpp +++ b/src/script/scripting_game.cpp @@ -30,6 +30,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "lua_api/l_item.h" #include "lua_api/l_mapgen.h" #include "lua_api/l_nodemeta.h" +#include "lua_api/l_itemstackmeta.h" #include "lua_api/l_nodetimer.h" #include "lua_api/l_noise.h" #include "lua_api/l_object.h" @@ -103,6 +104,7 @@ void GameScripting::InitializeModApi(lua_State *L, int top) LuaSecureRandom::Register(L); LuaVoxelManip::Register(L); NodeMetaRef::Register(L); + ItemStackMetaRef::Register(L); NodeTimerRef::Register(L); ObjectRef::Register(L); LuaSettings::Register(L);