mirror of
https://github.com/luanti-org/luanti.git
synced 2025-10-28 22:25:20 +01:00
Turn item metadata into a key-value store while keeping compatibility to the old interface via the empty string field
This commit is contained in:
@@ -424,6 +424,7 @@ set(common_SRCS
|
|||||||
version.cpp
|
version.cpp
|
||||||
voxel.cpp
|
voxel.cpp
|
||||||
voxelalgorithms.cpp
|
voxelalgorithms.cpp
|
||||||
|
itemstackmetadata.cpp
|
||||||
${common_network_SRCS}
|
${common_network_SRCS}
|
||||||
${JTHREAD_SRCS}
|
${JTHREAD_SRCS}
|
||||||
${common_SCRIPT_SRCS}
|
${common_SCRIPT_SRCS}
|
||||||
|
|||||||
@@ -948,7 +948,7 @@ void GenericCAO::addToScene(scene::ISceneManager *smgr,
|
|||||||
if(m_prop.textures.size() >= 1){
|
if(m_prop.textures.size() >= 1){
|
||||||
infostream<<"textures[0]: "<<m_prop.textures[0]<<std::endl;
|
infostream<<"textures[0]: "<<m_prop.textures[0]<<std::endl;
|
||||||
IItemDefManager *idef = m_gamedef->idef();
|
IItemDefManager *idef = m_gamedef->idef();
|
||||||
ItemStack item(m_prop.textures[0], 1, 0, "", idef);
|
ItemStack item(m_prop.textures[0], 1, 0, idef);
|
||||||
|
|
||||||
m_wield_meshnode = new WieldMeshSceneNode(
|
m_wield_meshnode = new WieldMeshSceneNode(
|
||||||
smgr->getRootSceneNode(), smgr, -1);
|
smgr->getRootSceneNode(), smgr, -1);
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ static std::vector<ItemStack> craftGetItems(
|
|||||||
for (std::vector<std::string>::size_type i = 0;
|
for (std::vector<std::string>::size_type i = 0;
|
||||||
i < items.size(); i++) {
|
i < items.size(); i++) {
|
||||||
result.push_back(ItemStack(std::string(items[i]), (u16)1,
|
result.push_back(ItemStack(std::string(items[i]), (u16)1,
|
||||||
(u16)0, "", gamedef->getItemDefManager()));
|
(u16)0, gamedef->getItemDefManager()));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "nameidmapping.h" // For loading legacy MaterialItems
|
#include "nameidmapping.h" // For loading legacy MaterialItems
|
||||||
#include "util/serialize.h"
|
#include "util/serialize.h"
|
||||||
#include "util/string.h"
|
#include "util/string.h"
|
||||||
|
#include "itemstackmetadata.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ItemStack
|
ItemStack
|
||||||
@@ -110,7 +111,7 @@ static std::string deSerializeJsonStringIfNeeded(std::istream &is)
|
|||||||
|
|
||||||
|
|
||||||
ItemStack::ItemStack(std::string name_, u16 count_,
|
ItemStack::ItemStack(std::string name_, u16 count_,
|
||||||
u16 wear_, std::string metadata_,
|
u16 wear_, ItemStackMetadata metadata_,
|
||||||
IItemDefManager *itemdef)
|
IItemDefManager *itemdef)
|
||||||
{
|
{
|
||||||
name = itemdef->getAlias(name_);
|
name = itemdef->getAlias(name_);
|
||||||
@@ -123,6 +124,19 @@ ItemStack::ItemStack(std::string name_, u16 count_,
|
|||||||
else if(itemdef->get(name).type == ITEM_TOOL)
|
else if(itemdef->get(name).type == ITEM_TOOL)
|
||||||
count = 1;
|
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
|
void ItemStack::serialize(std::ostream &os) const
|
||||||
{
|
{
|
||||||
@@ -137,7 +151,7 @@ void ItemStack::serialize(std::ostream &os) const
|
|||||||
parts = 2;
|
parts = 2;
|
||||||
if(wear != 0)
|
if(wear != 0)
|
||||||
parts = 3;
|
parts = 3;
|
||||||
if(metadata != "")
|
if(!metadata.isEmpty())
|
||||||
parts = 4;
|
parts = 4;
|
||||||
|
|
||||||
os<<serializeJsonStringIfNeeded(name);
|
os<<serializeJsonStringIfNeeded(name);
|
||||||
@@ -145,8 +159,9 @@ void ItemStack::serialize(std::ostream &os) const
|
|||||||
os<<" "<<count;
|
os<<" "<<count;
|
||||||
if(parts >= 3)
|
if(parts >= 3)
|
||||||
os<<" "<<wear;
|
os<<" "<<wear;
|
||||||
if(parts >= 4)
|
if(parts >= 4) {
|
||||||
os<<" "<<serializeJsonStringIfNeeded(metadata);
|
os<<" "<<serializeJsonStringIfNeeded(metadata.serialize());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
||||||
@@ -289,8 +304,8 @@ void ItemStack::deSerialize(std::istream &is, IItemDefManager *itemdef)
|
|||||||
wear = stoi(wear_str);
|
wear = stoi(wear_str);
|
||||||
|
|
||||||
// Read metadata
|
// Read metadata
|
||||||
metadata = deSerializeJsonStringIfNeeded(is);
|
std::string readMeta=deSerializeJsonStringIfNeeded(is);
|
||||||
|
metadata.deSerialize(readMeta);
|
||||||
// In case fields are added after metadata, skip space here:
|
// In case fields are added after metadata, skip space here:
|
||||||
//std::getline(is, tmp, ' ');
|
//std::getline(is, tmp, ' ');
|
||||||
//if(!tmp.empty())
|
//if(!tmp.empty())
|
||||||
@@ -579,8 +594,8 @@ bool InventoryList::operator == (const InventoryList &other) const
|
|||||||
{
|
{
|
||||||
ItemStack s1 = m_items[i];
|
ItemStack s1 = m_items[i];
|
||||||
ItemStack s2 = other.m_items[i];
|
ItemStack s2 = other.m_items[i];
|
||||||
if(s1.name != s2.name || s1.wear!= s2.wear || s1.count != s2.count ||
|
//TODO possible error source: stack metadata are not compared!
|
||||||
s1.metadata != s2.metadata)
|
if(s1.name != s2.name || s1.wear!= s2.wear || s1.count != s2.count)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,15 +27,20 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include "itemstackmetadata.h"
|
||||||
|
|
||||||
struct ToolCapabilities;
|
struct ToolCapabilities;
|
||||||
|
|
||||||
struct ItemStack
|
struct ItemStack
|
||||||
{
|
{
|
||||||
ItemStack(): name(""), count(0), wear(0), metadata("") {}
|
ItemStack(): name(""), count(0), wear(0), metadata() {}
|
||||||
ItemStack(std::string name_, u16 count_,
|
ItemStack(std::string name_, u16 count_,
|
||||||
u16 wear, std::string metadata_,
|
u16 wear, ItemStackMetadata metadata_,
|
||||||
IItemDefManager *itemdef);
|
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() {}
|
~ItemStack() {}
|
||||||
|
|
||||||
// Serialization
|
// Serialization
|
||||||
@@ -61,7 +66,7 @@ struct ItemStack
|
|||||||
name = "";
|
name = "";
|
||||||
count = 0;
|
count = 0;
|
||||||
wear = 0;
|
wear = 0;
|
||||||
metadata = "";
|
metadata.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void add(u16 n)
|
void add(u16 n)
|
||||||
@@ -167,7 +172,7 @@ struct ItemStack
|
|||||||
std::string name;
|
std::string name;
|
||||||
u16 count;
|
u16 count;
|
||||||
u16 wear;
|
u16 wear;
|
||||||
std::string metadata;
|
ItemStackMetadata metadata;
|
||||||
};
|
};
|
||||||
|
|
||||||
class InventoryList
|
class InventoryList
|
||||||
|
|||||||
106
src/itemstackmetadata.cpp
Normal file
106
src/itemstackmetadata.cpp
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
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 <sstream>
|
||||||
|
|
||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
62
src/itemstackmetadata.h
Normal file
62
src/itemstackmetadata.h
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
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 <iostream>
|
||||||
|
#include <vector>
|
||||||
|
#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
|
||||||
|
|
||||||
@@ -811,8 +811,7 @@ ItemStack read_item(lua_State* L, int index,Server* srv)
|
|||||||
std::string name = getstringfield_default(L, index, "name", "");
|
std::string name = getstringfield_default(L, index, "name", "");
|
||||||
int count = getintfield_default(L, index, "count", 1);
|
int count = getintfield_default(L, index, "count", 1);
|
||||||
int wear = getintfield_default(L, index, "wear", 0);
|
int wear = getintfield_default(L, index, "wear", 0);
|
||||||
std::string metadata = getstringfield_default(L, index, "metadata", "");
|
return ItemStack(name, count, wear, idef);
|
||||||
return ItemStack(name, count, wear, metadata, idef);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ set(common_SCRIPT_LUA_API_SRCS
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/l_item.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/l_mapgen.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/l_nodemeta.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_nodetimer.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/l_noise.cpp
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
|
${CMAKE_CURRENT_SOURCE_DIR}/l_object.cpp
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ int ModApiEnvMod::l_place_node(lua_State *L)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
// Create item to place
|
// 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
|
// Make pointed position
|
||||||
PointedThing pointed;
|
PointedThing pointed;
|
||||||
pointed.type = POINTEDTHING_NODE;
|
pointed.type = POINTEDTHING_NODE;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
#include "content_sao.h"
|
#include "content_sao.h"
|
||||||
#include "inventory.h"
|
#include "inventory.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "lua_api/l_itemstackmeta.h"
|
||||||
|
|
||||||
|
|
||||||
// garbage collector
|
// garbage collector
|
||||||
@@ -137,13 +138,24 @@ int LuaItemStack::l_set_wear(lua_State *L)
|
|||||||
return 1;
|
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
|
// get_metadata(self) -> string
|
||||||
int LuaItemStack::l_get_metadata(lua_State *L)
|
int LuaItemStack::l_get_metadata(lua_State *L)
|
||||||
{
|
{
|
||||||
NO_MAP_LOCK_REQUIRED;
|
NO_MAP_LOCK_REQUIRED;
|
||||||
LuaItemStack *o = checkobject(L, 1);
|
LuaItemStack *o = checkobject(L, 1);
|
||||||
ItemStack &item = o->m_stack;
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,7 +168,9 @@ int LuaItemStack::l_set_metadata(lua_State *L)
|
|||||||
|
|
||||||
size_t len = 0;
|
size_t len = 0;
|
||||||
const char *ptr = luaL_checklstring(L, 2, &len);
|
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);
|
lua_pushboolean(L, true);
|
||||||
return 1;
|
return 1;
|
||||||
@@ -211,8 +225,6 @@ int LuaItemStack::l_to_table(lua_State *L)
|
|||||||
lua_setfield(L, -2, "count");
|
lua_setfield(L, -2, "count");
|
||||||
lua_pushinteger(L, item.wear);
|
lua_pushinteger(L, item.wear);
|
||||||
lua_setfield(L, -2, "wear");
|
lua_setfield(L, -2, "wear");
|
||||||
lua_pushlstring(L, item.metadata.c_str(), item.metadata.size());
|
|
||||||
lua_setfield(L, -2, "metadata");
|
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -443,8 +455,9 @@ const luaL_reg LuaItemStack::methods[] = {
|
|||||||
luamethod(LuaItemStack, set_count),
|
luamethod(LuaItemStack, set_count),
|
||||||
luamethod(LuaItemStack, get_wear),
|
luamethod(LuaItemStack, get_wear),
|
||||||
luamethod(LuaItemStack, set_wear),
|
luamethod(LuaItemStack, set_wear),
|
||||||
luamethod(LuaItemStack, get_metadata),
|
luamethod(LuaItemStack, get_meta),
|
||||||
luamethod(LuaItemStack, set_metadata),
|
luamethod(LuaItemStack, get_metadata),//legacy
|
||||||
|
luamethod(LuaItemStack, set_metadata),//legacy
|
||||||
luamethod(LuaItemStack, clear),
|
luamethod(LuaItemStack, clear),
|
||||||
luamethod(LuaItemStack, replace),
|
luamethod(LuaItemStack, replace),
|
||||||
luamethod(LuaItemStack, to_string),
|
luamethod(LuaItemStack, to_string),
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
|||||||
|
|
||||||
#include "lua_api/l_base.h"
|
#include "lua_api/l_base.h"
|
||||||
#include "inventory.h" // ItemStack
|
#include "inventory.h" // ItemStack
|
||||||
|
#include "lua_api/l_itemstackmeta.h"
|
||||||
|
#include "itemstackmetadata.h"
|
||||||
|
|
||||||
class LuaItemStack : public ModApiBase {
|
class LuaItemStack : public ModApiBase {
|
||||||
private:
|
private:
|
||||||
@@ -56,10 +58,13 @@ private:
|
|||||||
// set_wear(self, number)
|
// set_wear(self, number)
|
||||||
static int l_set_wear(lua_State *L);
|
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);
|
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);
|
static int l_set_metadata(lua_State *L);
|
||||||
|
|
||||||
// clear(self) -> true
|
// clear(self) -> true
|
||||||
|
|||||||
304
src/script/lua_api/l_itemstackmeta.cpp
Normal file
304
src/script/lua_api/l_itemstackmeta.cpp
Normal file
@@ -0,0 +1,304 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
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="<<o<<std::endl;
|
||||||
|
*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
|
||||||
|
luaL_getmetatable(L, className);
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ItemStackMetaRef::Register(lua_State *L)
|
||||||
|
{
|
||||||
|
lua_newtable(L);
|
||||||
|
int methodtable = lua_gettop(L);
|
||||||
|
luaL_newmetatable(L, className);
|
||||||
|
int metatable = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__metatable");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable); // hide metatable from Lua getmetatable()
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__index");
|
||||||
|
lua_pushvalue(L, methodtable);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pushliteral(L, "__gc");
|
||||||
|
lua_pushcfunction(L, gc_object);
|
||||||
|
lua_settable(L, metatable);
|
||||||
|
|
||||||
|
lua_pop(L, 1); // drop metatable
|
||||||
|
|
||||||
|
luaL_openlib(L, 0, methods, 0); // fill methodtable
|
||||||
|
lua_pop(L, 1); // drop methodtable
|
||||||
|
|
||||||
|
// Cannot be created from Lua
|
||||||
|
//lua_register(L, className, create_object);
|
||||||
|
}
|
||||||
|
|
||||||
|
const char ItemStackMetaRef::className[] = "ItemStackMetaRef";
|
||||||
|
const luaL_reg ItemStackMetaRef::methods[] = {
|
||||||
|
luamethod(ItemStackMetaRef, get_string),
|
||||||
|
luamethod(ItemStackMetaRef, set_string),
|
||||||
|
luamethod(ItemStackMetaRef, get_int),
|
||||||
|
luamethod(ItemStackMetaRef, set_int),
|
||||||
|
luamethod(ItemStackMetaRef, get_float),
|
||||||
|
luamethod(ItemStackMetaRef, set_float),
|
||||||
|
luamethod(ItemStackMetaRef, to_table),
|
||||||
|
luamethod(ItemStackMetaRef, from_table),
|
||||||
|
{0,0}
|
||||||
|
};
|
||||||
94
src/script/lua_api/l_itemstackmeta.h
Normal file
94
src/script/lua_api/l_itemstackmeta.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
Minetest
|
||||||
|
Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
|
||||||
|
|
||||||
|
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_ */
|
||||||
@@ -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_item.h"
|
||||||
#include "lua_api/l_mapgen.h"
|
#include "lua_api/l_mapgen.h"
|
||||||
#include "lua_api/l_nodemeta.h"
|
#include "lua_api/l_nodemeta.h"
|
||||||
|
#include "lua_api/l_itemstackmeta.h"
|
||||||
#include "lua_api/l_nodetimer.h"
|
#include "lua_api/l_nodetimer.h"
|
||||||
#include "lua_api/l_noise.h"
|
#include "lua_api/l_noise.h"
|
||||||
#include "lua_api/l_object.h"
|
#include "lua_api/l_object.h"
|
||||||
@@ -103,6 +104,7 @@ void GameScripting::InitializeModApi(lua_State *L, int top)
|
|||||||
LuaSecureRandom::Register(L);
|
LuaSecureRandom::Register(L);
|
||||||
LuaVoxelManip::Register(L);
|
LuaVoxelManip::Register(L);
|
||||||
NodeMetaRef::Register(L);
|
NodeMetaRef::Register(L);
|
||||||
|
ItemStackMetaRef::Register(L);
|
||||||
NodeTimerRef::Register(L);
|
NodeTimerRef::Register(L);
|
||||||
ObjectRef::Register(L);
|
ObjectRef::Register(L);
|
||||||
LuaSettings::Register(L);
|
LuaSettings::Register(L);
|
||||||
|
|||||||
Reference in New Issue
Block a user