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

@ -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)`

@ -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);

@ -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.

@ -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;

@ -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

@ -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);

@ -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);