Add core.find_nodes_with_meta() script API

This commit is contained in:
kwolekr 2015-05-05 14:30:46 -04:00
parent b45df9d6a7
commit b785577f03
7 changed files with 89 additions and 20 deletions

View File

@ -1871,6 +1871,8 @@ and `minetest.auth_reload` call the authetification handler.
* `minetest.punch_node(pos)` * `minetest.punch_node(pos)`
* Punch node with the same effects that a player would cause * Punch node with the same effects that a player would cause
* `minetest.find_nodes_with_meta(pos1, pos2)`
* Get a table of positions of nodes that have metadata within a region {pos1, pos2}
* `minetest.get_meta(pos)` * `minetest.get_meta(pos)`
* Get a `NodeMetaRef` at that position * Get a `NodeMetaRef` at that position
* `minetest.get_node_timer(pos)` * `minetest.get_node_timer(pos)`

View File

@ -1890,6 +1890,40 @@ void Map::transformLiquids(std::map<v3s16, MapBlock*> & modified_blocks)
} }
} }
std::vector<v3s16> Map::findNodesWithMetadata(v3s16 p1, v3s16 p2)
{
std::vector<v3s16> positions_with_meta;
sortBoxVerticies(p1, p2);
v3s16 bpmin = getNodeBlockPos(p1);
v3s16 bpmax = getNodeBlockPos(p2);
for (s16 z = bpmin.Z; z <= bpmax.Z; z++)
for (s16 y = bpmin.Y; y <= bpmax.Y; y++)
for (s16 x = bpmin.X; x <= bpmax.X; x++) {
v3s16 blockpos(x, y, z);
MapBlock *block = getBlockNoCreateNoEx(blockpos);
if (!block) {
verbosestream << "Map::getNodeMetadata(): Need to emerge "
<< PP(blockpos) << std::endl;
block = emergeBlock(blockpos, false);
}
if (!block) {
infostream << "WARNING: Map::getNodeMetadata(): Block not found"
<< std::endl;
continue;
}
v3s16 p_base = blockpos * MAP_BLOCKSIZE;
std::vector<v3s16> keys = block->m_node_metadata.getAllKeys();
for (size_t i = 0; i != keys.size(); i++)
positions_with_meta.push_back(keys[i] + p_base);
}
return positions_with_meta;
}
NodeMetadata *Map::getNodeMetadata(v3s16 p) NodeMetadata *Map::getNodeMetadata(v3s16 p)
{ {
v3s16 blockpos = getNodeBlockPos(p); v3s16 blockpos = getNodeBlockPos(p);

View File

@ -301,7 +301,8 @@ public:
These are basically coordinate wrappers to MapBlock These are basically coordinate wrappers to MapBlock
*/ */
NodeMetadata* getNodeMetadata(v3s16 p); std::vector<v3s16> findNodesWithMetadata(v3s16 p1, v3s16 p2);
NodeMetadata *getNodeMetadata(v3s16 p);
/** /**
* Sets metadata for a node. * Sets metadata for a node.

View File

@ -157,10 +157,21 @@ NodeMetadataList::~NodeMetadataList()
clear(); clear();
} }
NodeMetadata* NodeMetadataList::get(v3s16 p) std::vector<v3s16> NodeMetadataList::getAllKeys()
{ {
std::map<v3s16, NodeMetadata*>::const_iterator n = m_data.find(p); std::vector<v3s16> keys;
if(n == m_data.end())
std::map<v3s16, NodeMetadata *>::const_iterator it;
for (it = m_data.begin(); it != m_data.end(); ++it)
keys.push_back(it->first);
return keys;
}
NodeMetadata *NodeMetadataList::get(v3s16 p)
{
std::map<v3s16, NodeMetadata *>::const_iterator n = m_data.find(p);
if (n == m_data.end())
return NULL; return NULL;
return n->second; return n->second;
} }
@ -168,8 +179,7 @@ NodeMetadata* NodeMetadataList::get(v3s16 p)
void NodeMetadataList::remove(v3s16 p) void NodeMetadataList::remove(v3s16 p)
{ {
NodeMetadata *olddata = get(p); NodeMetadata *olddata = get(p);
if(olddata) if (olddata) {
{
delete olddata; delete olddata;
m_data.erase(p); m_data.erase(p);
} }
@ -183,16 +193,15 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
void NodeMetadataList::clear() void NodeMetadataList::clear()
{ {
for(std::map<v3s16, NodeMetadata*>::iterator std::map<v3s16, NodeMetadata*>::iterator it;
i = m_data.begin(); for (it = m_data.begin(); it != m_data.end(); ++it) {
i != m_data.end(); i++) delete it->second;
{
delete i->second;
} }
m_data.clear(); m_data.clear();
} }
std::string NodeMetadata::getString(const std::string &name, unsigned short recursion) const std::string NodeMetadata::getString(const std::string &name,
unsigned short recursion) const
{ {
std::map<std::string, std::string>::const_iterator it; std::map<std::string, std::string>::const_iterator it;
it = m_stringvars.find(name); it = m_stringvars.find(name);
@ -211,7 +220,8 @@ void NodeMetadata::setString(const std::string &name, const std::string &var)
} }
} }
std::string NodeMetadata::resolveString(const std::string &str, unsigned short recursion) const std::string NodeMetadata::resolveString(const std::string &str,
unsigned short recursion) const
{ {
if (recursion > 1) { if (recursion > 1) {
return str; return str;

View File

@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h" #include "irr_v3d.h"
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <vector>
#include <map> #include <map>
/* /*
@ -42,10 +43,10 @@ class NodeMetadata
public: public:
NodeMetadata(IGameDef *gamedef); NodeMetadata(IGameDef *gamedef);
~NodeMetadata(); ~NodeMetadata();
void serialize(std::ostream &os) const; void serialize(std::ostream &os) const;
void deSerialize(std::istream &is); void deSerialize(std::istream &is);
void clear(); void clear();
// Generic key/value store // Generic key/value store
@ -81,18 +82,20 @@ public:
void serialize(std::ostream &os) const; void serialize(std::ostream &os) const;
void deSerialize(std::istream &is, IGameDef *gamedef); void deSerialize(std::istream &is, IGameDef *gamedef);
// Add all keys in this list to the vector keys
std::vector<v3s16> getAllKeys();
// Get pointer to data // Get pointer to data
NodeMetadata* get(v3s16 p); NodeMetadata *get(v3s16 p);
// Deletes data // Deletes data
void remove(v3s16 p); void remove(v3s16 p);
// Deletes old data and sets a new one // Deletes old data and sets a new one
void set(v3s16 p, NodeMetadata *d); void set(v3s16 p, NodeMetadata *d);
// Deletes all // Deletes all
void clear(); void clear();
private: private:
std::map<v3s16, NodeMetadata*> m_data; std::map<v3s16, NodeMetadata *> m_data;
}; };
#endif #endif

View File

@ -334,6 +334,22 @@ int ModApiEnvMod::l_add_node_level(lua_State *L)
return 1; return 1;
} }
// find_nodes_with_meta(pos1, pos2)
int ModApiEnvMod::l_find_nodes_with_meta(lua_State *L)
{
GET_ENV_PTR;
std::vector<v3s16> positions = env->getMap().findNodesWithMetadata(
check_v3s16(L, 1), check_v3s16(L, 2));
lua_newtable(L);
for (size_t i = 0; i != positions.size(); i++) {
push_v3s16(L, positions[i]);
lua_rawseti(L, -2, i + 1);
}
return 1;
}
// get_meta(pos) // get_meta(pos)
int ModApiEnvMod::l_get_meta(lua_State *L) int ModApiEnvMod::l_get_meta(lua_State *L)
@ -912,6 +928,7 @@ void ModApiEnvMod::Initialize(lua_State *L, int top)
API_FCT(set_node_level); API_FCT(set_node_level);
API_FCT(add_node_level); API_FCT(add_node_level);
API_FCT(add_entity); API_FCT(add_entity);
API_FCT(find_nodes_with_meta);
API_FCT(get_meta); API_FCT(get_meta);
API_FCT(get_node_timer); API_FCT(get_node_timer);
API_FCT(get_player_by_name); API_FCT(get_player_by_name);

View File

@ -64,7 +64,6 @@ private:
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
static int l_punch_node(lua_State *L); static int l_punch_node(lua_State *L);
// get_node_max_level(pos) // get_node_max_level(pos)
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
static int l_get_node_max_level(lua_State *L); static int l_get_node_max_level(lua_State *L);
@ -81,6 +80,9 @@ private:
// pos = {x=num, y=num, z=num} // pos = {x=num, y=num, z=num}
static int l_add_node_level(lua_State *L); static int l_add_node_level(lua_State *L);
// find_nodes_with_meta(pos1, pos2)
static int l_find_nodes_with_meta(lua_State *L);
// get_meta(pos) // get_meta(pos)
static int l_get_meta(lua_State *L); static int l_get_meta(lua_State *L);