aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkwolekr <kwolekr@minetest.net>2015-05-05 14:30:46 -0400
committerkwolekr <kwolekr@minetest.net>2015-05-05 16:21:59 -0400
commitb785577f03d00c83236782876def4c900edbba4e (patch)
tree389f3baa9e4b3d6abcab1d752a248bcdc933b52d
parentb45df9d6a73d97671cbdd38d77e9b153a80fb458 (diff)
downloadminetest-b785577f03d00c83236782876def4c900edbba4e.tar.gz
minetest-b785577f03d00c83236782876def4c900edbba4e.tar.bz2
minetest-b785577f03d00c83236782876def4c900edbba4e.zip
Add core.find_nodes_with_meta() script API
-rw-r--r--doc/lua_api.txt2
-rw-r--r--src/map.cpp34
-rw-r--r--src/map.h3
-rw-r--r--src/nodemetadata.cpp34
-rw-r--r--src/nodemetadata.h15
-rw-r--r--src/script/lua_api/l_env.cpp17
-rw-r--r--src/script/lua_api/l_env.h4
7 files changed, 89 insertions, 20 deletions
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 6325ed35d..c01ef208c 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -1871,6 +1871,8 @@ and `minetest.auth_reload` call the authetification handler.
* `minetest.punch_node(pos)`
* 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)`
* Get a `NodeMetaRef` at that position
* `minetest.get_node_timer(pos)`
diff --git a/src/map.cpp b/src/map.cpp
index 9fead00c6..7f8059cc4 100644
--- a/src/map.cpp
+++ b/src/map.cpp
@@ -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)
{
v3s16 blockpos = getNodeBlockPos(p);
diff --git a/src/map.h b/src/map.h
index 325a02e60..5500ccf91 100644
--- a/src/map.h
+++ b/src/map.h
@@ -301,7 +301,8 @@ public:
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.
diff --git a/src/nodemetadata.cpp b/src/nodemetadata.cpp
index 1e40a1630..bd54d2256 100644
--- a/src/nodemetadata.cpp
+++ b/src/nodemetadata.cpp
@@ -157,10 +157,21 @@ NodeMetadataList::~NodeMetadataList()
clear();
}
-NodeMetadata* NodeMetadataList::get(v3s16 p)
+std::vector<v3s16> NodeMetadataList::getAllKeys()
{
- std::map<v3s16, NodeMetadata*>::const_iterator n = m_data.find(p);
- if(n == m_data.end())
+ std::vector<v3s16> keys;
+
+ 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 n->second;
}
@@ -168,8 +179,7 @@ NodeMetadata* NodeMetadataList::get(v3s16 p)
void NodeMetadataList::remove(v3s16 p)
{
NodeMetadata *olddata = get(p);
- if(olddata)
- {
+ if (olddata) {
delete olddata;
m_data.erase(p);
}
@@ -183,16 +193,15 @@ void NodeMetadataList::set(v3s16 p, NodeMetadata *d)
void NodeMetadataList::clear()
{
- for(std::map<v3s16, NodeMetadata*>::iterator
- i = m_data.begin();
- i != m_data.end(); i++)
- {
- delete i->second;
+ std::map<v3s16, NodeMetadata*>::iterator it;
+ for (it = m_data.begin(); it != m_data.end(); ++it) {
+ delete it->second;
}
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;
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) {
return str;
diff --git a/src/nodemetadata.h b/src/nodemetadata.h
index 6baf3b3d3..acd45bdf9 100644
--- a/src/nodemetadata.h
+++ b/src/nodemetadata.h
@@ -23,6 +23,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "irr_v3d.h"
#include <string>
#include <iostream>
+#include <vector>
#include <map>
/*
@@ -42,10 +43,10 @@ class NodeMetadata
public:
NodeMetadata(IGameDef *gamedef);
~NodeMetadata();
-
+
void serialize(std::ostream &os) const;
void deSerialize(std::istream &is);
-
+
void clear();
// Generic key/value store
@@ -81,18 +82,20 @@ public:
void serialize(std::ostream &os) const;
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
- NodeMetadata* get(v3s16 p);
+ NodeMetadata *get(v3s16 p);
// Deletes data
void remove(v3s16 p);
// Deletes old data and sets a new one
void set(v3s16 p, NodeMetadata *d);
// Deletes all
void clear();
-
+
private:
- std::map<v3s16, NodeMetadata*> m_data;
+ std::map<v3s16, NodeMetadata *> m_data;
};
#endif
diff --git a/src/script/lua_api/l_env.cpp b/src/script/lua_api/l_env.cpp
index 0fe1ddec3..9581d1ef3 100644
--- a/src/script/lua_api/l_env.cpp
+++ b/src/script/lua_api/l_env.cpp
@@ -334,6 +334,22 @@ int ModApiEnvMod::l_add_node_level(lua_State *L)
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)
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(add_node_level);
API_FCT(add_entity);
+ API_FCT(find_nodes_with_meta);
API_FCT(get_meta);
API_FCT(get_node_timer);
API_FCT(get_player_by_name);
diff --git a/src/script/lua_api/l_env.h b/src/script/lua_api/l_env.h
index 5c9afd2f1..0d4ca788e 100644
--- a/src/script/lua_api/l_env.h
+++ b/src/script/lua_api/l_env.h
@@ -64,7 +64,6 @@ private:
// pos = {x=num, y=num, z=num}
static int l_punch_node(lua_State *L);
-
// get_node_max_level(pos)
// pos = {x=num, y=num, z=num}
static int l_get_node_max_level(lua_State *L);
@@ -81,6 +80,9 @@ private:
// pos = {x=num, y=num, z=num}
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)
static int l_get_meta(lua_State *L);