Make INodeDefManager::getIds return a vector, not a set
parent
5b3fbf9cf7
commit
17fd5fe935
|
@ -38,6 +38,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include "gamedef.h"
|
#include "gamedef.h"
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
#include <fstream> // Used in applyTextureOverrides()
|
#include <fstream> // Used in applyTextureOverrides()
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NodeBox
|
NodeBox
|
||||||
|
@ -485,7 +486,7 @@ void ContentFeatures::deSerialize(std::istream &is)
|
||||||
u16 connects_to_size = readU16(is);
|
u16 connects_to_size = readU16(is);
|
||||||
connects_to_ids.clear();
|
connects_to_ids.clear();
|
||||||
for (u16 i = 0; i < connects_to_size; i++)
|
for (u16 i = 0; i < connects_to_size; i++)
|
||||||
connects_to_ids.insert(readU16(is));
|
connects_to_ids.push_back(readU16(is));
|
||||||
post_effect_color.setAlpha(readU8(is));
|
post_effect_color.setAlpha(readU8(is));
|
||||||
post_effect_color.setRed(readU8(is));
|
post_effect_color.setRed(readU8(is));
|
||||||
post_effect_color.setGreen(readU8(is));
|
post_effect_color.setGreen(readU8(is));
|
||||||
|
@ -845,7 +846,7 @@ public:
|
||||||
inline virtual const ContentFeatures& get(const MapNode &n) const;
|
inline virtual const ContentFeatures& get(const MapNode &n) const;
|
||||||
virtual bool getId(const std::string &name, content_t &result) const;
|
virtual bool getId(const std::string &name, content_t &result) const;
|
||||||
virtual content_t getId(const std::string &name) const;
|
virtual content_t getId(const std::string &name) const;
|
||||||
virtual bool getIds(const std::string &name, std::set<content_t> &result) const;
|
virtual bool getIds(const std::string &name, std::vector<content_t> &result) const;
|
||||||
virtual const ContentFeatures& get(const std::string &name) const;
|
virtual const ContentFeatures& get(const std::string &name) const;
|
||||||
content_t allocateId();
|
content_t allocateId();
|
||||||
virtual content_t set(const std::string &name, const ContentFeatures &def);
|
virtual content_t set(const std::string &name, const ContentFeatures &def);
|
||||||
|
@ -892,10 +893,10 @@ private:
|
||||||
|
|
||||||
std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases;
|
std::unordered_map<std::string, content_t> m_name_id_mapping_with_aliases;
|
||||||
|
|
||||||
// A mapping from groups to a list of content_ts (and their levels)
|
// A mapping from groups to a vector of content_ts that belong to it.
|
||||||
// that belong to it. Necessary for a direct lookup in getIds().
|
// Necessary for a direct lookup in getIds().
|
||||||
// Note: Not serialized.
|
// Note: Not serialized.
|
||||||
std::unordered_map<std::string, GroupItems> m_group_to_items;
|
std::unordered_map<std::string, std::vector<content_t>> m_group_to_items;
|
||||||
|
|
||||||
// Next possibly free id
|
// Next possibly free id
|
||||||
content_t m_next_id;
|
content_t m_next_id;
|
||||||
|
@ -1037,28 +1038,25 @@ content_t CNodeDefManager::getId(const std::string &name) const
|
||||||
|
|
||||||
|
|
||||||
bool CNodeDefManager::getIds(const std::string &name,
|
bool CNodeDefManager::getIds(const std::string &name,
|
||||||
std::set<content_t> &result) const
|
std::vector<content_t> &result) const
|
||||||
{
|
{
|
||||||
//TimeTaker t("getIds", NULL, PRECISION_MICRO);
|
//TimeTaker t("getIds", NULL, PRECISION_MICRO);
|
||||||
if (name.substr(0,6) != "group:") {
|
if (name.substr(0,6) != "group:") {
|
||||||
content_t id = CONTENT_IGNORE;
|
content_t id = CONTENT_IGNORE;
|
||||||
bool exists = getId(name, id);
|
bool exists = getId(name, id);
|
||||||
if (exists)
|
if (exists)
|
||||||
result.insert(id);
|
result.push_back(id);
|
||||||
return exists;
|
return exists;
|
||||||
}
|
}
|
||||||
std::string group = name.substr(6);
|
std::string group = name.substr(6);
|
||||||
|
|
||||||
std::unordered_map<std::string, GroupItems>::const_iterator
|
std::unordered_map<std::string, std::vector<content_t>>::const_iterator
|
||||||
i = m_group_to_items.find(group);
|
i = m_group_to_items.find(group);
|
||||||
if (i == m_group_to_items.end())
|
if (i == m_group_to_items.end())
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
const GroupItems &items = i->second;
|
const std::vector<content_t> &items = i->second;
|
||||||
for (const auto &item : items) {
|
result.insert(result.end(), items.begin(), items.end());
|
||||||
if (item.second != 0)
|
|
||||||
result.insert(item.first);
|
|
||||||
}
|
|
||||||
//printf("getIds: %dus\n", t.stop());
|
//printf("getIds: %dus\n", t.stop());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1247,15 +1245,7 @@ content_t CNodeDefManager::set(const std::string &name, const ContentFeatures &d
|
||||||
// belongs to when a node is re-registered
|
// belongs to when a node is re-registered
|
||||||
for (const auto &group : def.groups) {
|
for (const auto &group : def.groups) {
|
||||||
const std::string &group_name = group.first;
|
const std::string &group_name = group.first;
|
||||||
|
m_group_to_items[group_name].push_back(id);
|
||||||
std::unordered_map<std::string, GroupItems>::iterator
|
|
||||||
j = m_group_to_items.find(group_name);
|
|
||||||
if (j == m_group_to_items.end()) {
|
|
||||||
m_group_to_items[group_name].emplace_back(id, group.second);
|
|
||||||
} else {
|
|
||||||
GroupItems &items = j->second;
|
|
||||||
items.emplace_back(id, group.second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -1283,16 +1273,10 @@ void CNodeDefManager::removeNode(const std::string &name)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase node content from all groups it belongs to
|
// Erase node content from all groups it belongs to
|
||||||
for (std::unordered_map<std::string, GroupItems>::iterator iter_groups =
|
for (std::unordered_map<std::string, std::vector<content_t>>::iterator iter_groups =
|
||||||
m_group_to_items.begin(); iter_groups != m_group_to_items.end();) {
|
m_group_to_items.begin(); iter_groups != m_group_to_items.end();) {
|
||||||
GroupItems &items = iter_groups->second;
|
std::vector<content_t> &items = iter_groups->second;
|
||||||
for (GroupItems::iterator iter_groupitems = items.begin();
|
items.erase(std::remove(items.begin(), items.end(), id), items.end());
|
||||||
iter_groupitems != items.end();) {
|
|
||||||
if (iter_groupitems->first == id)
|
|
||||||
items.erase(iter_groupitems++);
|
|
||||||
else
|
|
||||||
++iter_groupitems;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check if group is empty
|
// Check if group is empty
|
||||||
if (items.empty())
|
if (items.empty())
|
||||||
|
@ -1545,9 +1529,8 @@ void CNodeDefManager::mapNodeboxConnections()
|
||||||
if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED)
|
if (f.drawtype != NDT_NODEBOX || f.node_box.type != NODEBOX_CONNECTED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for (std::vector<std::string>::const_iterator it = f.connects_to.begin();
|
for (const std::string &name : f.connects_to) {
|
||||||
it != f.connects_to.end(); ++it) {
|
getIds(name, f.connects_to_ids);
|
||||||
getIds(*it, f.connects_to_ids);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1560,14 +1543,14 @@ bool CNodeDefManager::nodeboxConnects(MapNode from, MapNode to, u8 connect_face)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// lookup target in connected set
|
// lookup target in connected set
|
||||||
if (f1.connects_to_ids.find(to.param0) == f1.connects_to_ids.end())
|
if (!CONTAINS(f1.connects_to_ids, to.param0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
const ContentFeatures &f2 = get(to);
|
const ContentFeatures &f2 = get(to);
|
||||||
|
|
||||||
if ((f2.drawtype == NDT_NODEBOX) && (f2.node_box.type == NODEBOX_CONNECTED))
|
if ((f2.drawtype == NDT_NODEBOX) && (f2.node_box.type == NODEBOX_CONNECTED))
|
||||||
// ignores actually looking if back connection exists
|
// ignores actually looking if back connection exists
|
||||||
return (f2.connects_to_ids.find(from.param0) != f2.connects_to_ids.end());
|
return CONTAINS(f2.connects_to_ids, from.param0);
|
||||||
|
|
||||||
// does to node declare usable faces?
|
// does to node declare usable faces?
|
||||||
if (f2.connect_sides > 0) {
|
if (f2.connect_sides > 0) {
|
||||||
|
@ -1686,11 +1669,7 @@ bool NodeResolver::getIdsFromNrBacklog(std::vector<content_t> *result_out,
|
||||||
success = false;
|
success = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::set<content_t> cids;
|
m_ndef->getIds(name, *result_out);
|
||||||
std::set<content_t>::iterator it;
|
|
||||||
m_ndef->getIds(name, cids);
|
|
||||||
for (it = cids.begin(); it != cids.end(); ++it)
|
|
||||||
result_out->push_back(*it);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <list>
|
|
||||||
#include "mapnode.h"
|
#include "mapnode.h"
|
||||||
#ifndef SERVER
|
#ifndef SERVER
|
||||||
#include "client/tile.h"
|
#include "client/tile.h"
|
||||||
|
@ -42,8 +41,6 @@ class IShaderSource;
|
||||||
class IGameDef;
|
class IGameDef;
|
||||||
class NodeResolver;
|
class NodeResolver;
|
||||||
|
|
||||||
typedef std::list<std::pair<content_t, int> > GroupItems;
|
|
||||||
|
|
||||||
enum ContentParamType
|
enum ContentParamType
|
||||||
{
|
{
|
||||||
CPT_NONE,
|
CPT_NONE,
|
||||||
|
@ -290,7 +287,7 @@ struct ContentFeatures
|
||||||
// for NDT_CONNECTED pairing
|
// for NDT_CONNECTED pairing
|
||||||
u8 connect_sides;
|
u8 connect_sides;
|
||||||
std::vector<std::string> connects_to;
|
std::vector<std::string> connects_to;
|
||||||
std::set<content_t> connects_to_ids;
|
std::vector<content_t> connects_to_ids;
|
||||||
// Post effect color, drawn when the camera is inside the node.
|
// Post effect color, drawn when the camera is inside the node.
|
||||||
video::SColor post_effect_color;
|
video::SColor post_effect_color;
|
||||||
// Flowing liquid or snow, value = default level
|
// Flowing liquid or snow, value = default level
|
||||||
|
@ -424,7 +421,7 @@ public:
|
||||||
virtual content_t getId(const std::string &name) const=0;
|
virtual content_t getId(const std::string &name) const=0;
|
||||||
// Allows "group:name" in addition to regular node names
|
// Allows "group:name" in addition to regular node names
|
||||||
// returns false if node name not found, true otherwise
|
// returns false if node name not found, true otherwise
|
||||||
virtual bool getIds(const std::string &name, std::set<content_t> &result)
|
virtual bool getIds(const std::string &name, std::vector<content_t> &result)
|
||||||
const=0;
|
const=0;
|
||||||
virtual const ContentFeatures &get(const std::string &name) const=0;
|
virtual const ContentFeatures &get(const std::string &name) const=0;
|
||||||
|
|
||||||
|
@ -452,7 +449,7 @@ public:
|
||||||
// If not found, returns CONTENT_IGNORE
|
// If not found, returns CONTENT_IGNORE
|
||||||
virtual content_t getId(const std::string &name) const=0;
|
virtual content_t getId(const std::string &name) const=0;
|
||||||
// Allows "group:name" in addition to regular node names
|
// Allows "group:name" in addition to regular node names
|
||||||
virtual bool getIds(const std::string &name, std::set<content_t> &result)
|
virtual bool getIds(const std::string &name, std::vector<content_t> &result)
|
||||||
const=0;
|
const=0;
|
||||||
// If not found, returns the features of CONTENT_UNKNOWN
|
// If not found, returns the features of CONTENT_UNKNOWN
|
||||||
virtual const ContentFeatures &get(const std::string &name) const=0;
|
virtual const ContentFeatures &get(const std::string &name) const=0;
|
||||||
|
|
|
@ -108,7 +108,7 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
|
||||||
int id = lua_tonumber(L, -2);
|
int id = lua_tonumber(L, -2);
|
||||||
int current_abm = lua_gettop(L);
|
int current_abm = lua_gettop(L);
|
||||||
|
|
||||||
std::set<std::string> trigger_contents;
|
std::vector<std::string> trigger_contents;
|
||||||
lua_getfield(L, current_abm, "nodenames");
|
lua_getfield(L, current_abm, "nodenames");
|
||||||
if (lua_istable(L, -1)) {
|
if (lua_istable(L, -1)) {
|
||||||
int table = lua_gettop(L);
|
int table = lua_gettop(L);
|
||||||
|
@ -116,16 +116,16 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
|
||||||
while (lua_next(L, table)) {
|
while (lua_next(L, table)) {
|
||||||
// key at index -2 and value at index -1
|
// key at index -2 and value at index -1
|
||||||
luaL_checktype(L, -1, LUA_TSTRING);
|
luaL_checktype(L, -1, LUA_TSTRING);
|
||||||
trigger_contents.insert(lua_tostring(L, -1));
|
trigger_contents.push_back(lua_tostring(L, -1));
|
||||||
// removes value, keeps key for next iteration
|
// removes value, keeps key for next iteration
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
} else if (lua_isstring(L, -1)) {
|
} else if (lua_isstring(L, -1)) {
|
||||||
trigger_contents.insert(lua_tostring(L, -1));
|
trigger_contents.push_back(lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
std::set<std::string> required_neighbors;
|
std::vector<std::string> required_neighbors;
|
||||||
lua_getfield(L, current_abm, "neighbors");
|
lua_getfield(L, current_abm, "neighbors");
|
||||||
if (lua_istable(L, -1)) {
|
if (lua_istable(L, -1)) {
|
||||||
int table = lua_gettop(L);
|
int table = lua_gettop(L);
|
||||||
|
@ -133,12 +133,12 @@ void ScriptApiEnv::initializeEnvironment(ServerEnvironment *env)
|
||||||
while (lua_next(L, table)) {
|
while (lua_next(L, table)) {
|
||||||
// key at index -2 and value at index -1
|
// key at index -2 and value at index -1
|
||||||
luaL_checktype(L, -1, LUA_TSTRING);
|
luaL_checktype(L, -1, LUA_TSTRING);
|
||||||
required_neighbors.insert(lua_tostring(L, -1));
|
required_neighbors.push_back(lua_tostring(L, -1));
|
||||||
// removes value, keeps key for next iteration
|
// removes value, keeps key for next iteration
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
} else if (lua_isstring(L, -1)) {
|
} else if (lua_isstring(L, -1)) {
|
||||||
required_neighbors.insert(lua_tostring(L, -1));
|
required_neighbors.push_back(lua_tostring(L, -1));
|
||||||
}
|
}
|
||||||
lua_pop(L, 1);
|
lua_pop(L, 1);
|
||||||
|
|
||||||
|
|
|
@ -719,7 +719,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
|
||||||
INodeDefManager *ndef = getGameDef(L)->ndef();
|
INodeDefManager *ndef = getGameDef(L)->ndef();
|
||||||
v3s16 pos = read_v3s16(L, 1);
|
v3s16 pos = read_v3s16(L, 1);
|
||||||
int radius = luaL_checkinteger(L, 2);
|
int radius = luaL_checkinteger(L, 2);
|
||||||
std::set<content_t> filter;
|
std::vector<content_t> filter;
|
||||||
if (lua_istable(L, 3)) {
|
if (lua_istable(L, 3)) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, 3) != 0) {
|
while (lua_next(L, 3) != 0) {
|
||||||
|
@ -748,7 +748,7 @@ int ModApiEnvMod::l_find_node_near(lua_State *L)
|
||||||
for (const v3s16 &i : list) {
|
for (const v3s16 &i : list) {
|
||||||
v3s16 p = pos + i;
|
v3s16 p = pos + i;
|
||||||
content_t c = env->getMap().getNodeNoEx(p).getContent();
|
content_t c = env->getMap().getNodeNoEx(p).getContent();
|
||||||
if (filter.count(c) != 0) {
|
if (CONTAINS(filter, c)) {
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -780,7 +780,7 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<content_t> filter;
|
std::vector<content_t> filter;
|
||||||
if (lua_istable(L, 3)) {
|
if (lua_istable(L, 3)) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
while (lua_next(L, 3) != 0) {
|
while (lua_next(L, 3) != 0) {
|
||||||
|
@ -794,7 +794,8 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
||||||
ndef->getIds(lua_tostring(L, 3), filter);
|
ndef->getIds(lua_tostring(L, 3), filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unordered_map<content_t, u32> individual_count;
|
std::vector<u32> individual_count;
|
||||||
|
individual_count.resize(filter.size());
|
||||||
|
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
u64 i = 0;
|
u64 i = 0;
|
||||||
|
@ -803,16 +804,20 @@ int ModApiEnvMod::l_find_nodes_in_area(lua_State *L)
|
||||||
for (s16 z = minp.Z; z <= maxp.Z; z++) {
|
for (s16 z = minp.Z; z <= maxp.Z; z++) {
|
||||||
v3s16 p(x, y, z);
|
v3s16 p(x, y, z);
|
||||||
content_t c = env->getMap().getNodeNoEx(p).getContent();
|
content_t c = env->getMap().getNodeNoEx(p).getContent();
|
||||||
if (filter.count(c) != 0) {
|
|
||||||
|
std::vector<content_t>::iterator it = std::find(filter.begin(), filter.end(), c);
|
||||||
|
if (it != filter.end()) {
|
||||||
push_v3s16(L, p);
|
push_v3s16(L, p);
|
||||||
lua_rawseti(L, -2, ++i);
|
lua_rawseti(L, -2, ++i);
|
||||||
individual_count[c]++;
|
|
||||||
|
u32 filt_index = it - filter.begin();
|
||||||
|
individual_count[filt_index]++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
for (content_t it : filter) {
|
for (u32 i = 0; i < filter.size(); i++) {
|
||||||
lua_pushnumber(L, individual_count[it]);
|
lua_pushnumber(L, individual_count[i]);
|
||||||
lua_setfield(L, -2, ndef->get(it).name.c_str());
|
lua_setfield(L, -2, ndef->get(filter[i]).name.c_str());
|
||||||
}
|
}
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
|
@ -847,7 +852,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set<content_t> filter;
|
std::vector<content_t> filter;
|
||||||
|
|
||||||
if (lua_istable(L, 3)) {
|
if (lua_istable(L, 3)) {
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
|
@ -873,7 +878,7 @@ int ModApiEnvMod::l_find_nodes_in_area_under_air(lua_State *L)
|
||||||
v3s16 psurf(x, y + 1, z);
|
v3s16 psurf(x, y + 1, z);
|
||||||
content_t csurf = env->getMap().getNodeNoEx(psurf).getContent();
|
content_t csurf = env->getMap().getNodeNoEx(psurf).getContent();
|
||||||
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
|
if (c != CONTENT_AIR && csurf == CONTENT_AIR &&
|
||||||
filter.count(c) != 0) {
|
CONTAINS(filter, c)) {
|
||||||
push_v3s16(L, v3s16(x, y, z));
|
push_v3s16(L, v3s16(x, y, z));
|
||||||
lua_rawseti(L, -2, ++i);
|
lua_rawseti(L, -2, ++i);
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,15 +188,15 @@ class LuaABM : public ActiveBlockModifier {
|
||||||
private:
|
private:
|
||||||
int m_id;
|
int m_id;
|
||||||
|
|
||||||
std::set<std::string> m_trigger_contents;
|
std::vector<std::string> m_trigger_contents;
|
||||||
std::set<std::string> m_required_neighbors;
|
std::vector<std::string> m_required_neighbors;
|
||||||
float m_trigger_interval;
|
float m_trigger_interval;
|
||||||
u32 m_trigger_chance;
|
u32 m_trigger_chance;
|
||||||
bool m_simple_catch_up;
|
bool m_simple_catch_up;
|
||||||
public:
|
public:
|
||||||
LuaABM(lua_State *L, int id,
|
LuaABM(lua_State *L, int id,
|
||||||
const std::set<std::string> &trigger_contents,
|
const std::vector<std::string> &trigger_contents,
|
||||||
const std::set<std::string> &required_neighbors,
|
const std::vector<std::string> &required_neighbors,
|
||||||
float trigger_interval, u32 trigger_chance, bool simple_catch_up):
|
float trigger_interval, u32 trigger_chance, bool simple_catch_up):
|
||||||
m_id(id),
|
m_id(id),
|
||||||
m_trigger_contents(trigger_contents),
|
m_trigger_contents(trigger_contents),
|
||||||
|
@ -206,11 +206,11 @@ public:
|
||||||
m_simple_catch_up(simple_catch_up)
|
m_simple_catch_up(simple_catch_up)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
virtual const std::set<std::string> &getTriggerContents() const
|
virtual const std::vector<std::string> &getTriggerContents() const
|
||||||
{
|
{
|
||||||
return m_trigger_contents;
|
return m_trigger_contents;
|
||||||
}
|
}
|
||||||
virtual const std::set<std::string> &getRequiredNeighbors() const
|
virtual const std::vector<std::string> &getRequiredNeighbors() const
|
||||||
{
|
{
|
||||||
return m_required_neighbors;
|
return m_required_neighbors;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
#if USE_POSTGRESQL
|
#if USE_POSTGRESQL
|
||||||
#include "database-postgresql.h"
|
#include "database-postgresql.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#define LBM_NAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_:"
|
#define LBM_NAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyz0123456789_:"
|
||||||
|
|
||||||
|
@ -84,7 +85,7 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed
|
||||||
lbm_list.push_back(lbm_def);
|
lbm_list.push_back(lbm_def);
|
||||||
|
|
||||||
for (const std::string &nodeTrigger: lbm_def->trigger_contents) {
|
for (const std::string &nodeTrigger: lbm_def->trigger_contents) {
|
||||||
std::set<content_t> c_ids;
|
std::vector<content_t> c_ids;
|
||||||
bool found = nodedef->getIds(nodeTrigger, c_ids);
|
bool found = nodedef->getIds(nodeTrigger, c_ids);
|
||||||
if (!found) {
|
if (!found) {
|
||||||
content_t c_id = gamedef->allocateUnknownNodeId(nodeTrigger);
|
content_t c_id = gamedef->allocateUnknownNodeId(nodeTrigger);
|
||||||
|
@ -94,7 +95,7 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed
|
||||||
<< "\" while loading LBM \"" << lbm_def->name << "\"." << std::endl;
|
<< "\" while loading LBM \"" << lbm_def->name << "\"." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
c_ids.insert(c_id);
|
c_ids.push_back(c_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (content_t c_id : c_ids) {
|
for (content_t c_id : c_ids) {
|
||||||
|
@ -646,7 +647,8 @@ struct ActiveABM
|
||||||
{
|
{
|
||||||
ActiveBlockModifier *abm;
|
ActiveBlockModifier *abm;
|
||||||
int chance;
|
int chance;
|
||||||
std::set<content_t> required_neighbors;
|
std::vector<content_t> required_neighbors;
|
||||||
|
bool check_required_neighbors; // false if required_neighbors is known to be empty
|
||||||
};
|
};
|
||||||
|
|
||||||
class ABMHandler
|
class ABMHandler
|
||||||
|
@ -693,16 +695,17 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger neighbors
|
// Trigger neighbors
|
||||||
const std::set<std::string> &required_neighbors_s =
|
const std::vector<std::string> &required_neighbors_s =
|
||||||
abm->getRequiredNeighbors();
|
abm->getRequiredNeighbors();
|
||||||
for (const std::string &required_neighbor_s : required_neighbors_s) {
|
for (const std::string &required_neighbor_s : required_neighbors_s) {
|
||||||
ndef->getIds(required_neighbor_s, aabm.required_neighbors);
|
ndef->getIds(required_neighbor_s, aabm.required_neighbors);
|
||||||
}
|
}
|
||||||
|
aabm.check_required_neighbors = !required_neighbors_s.empty();
|
||||||
|
|
||||||
// Trigger contents
|
// Trigger contents
|
||||||
const std::set<std::string> &contents_s = abm->getTriggerContents();
|
const std::vector<std::string> &contents_s = abm->getTriggerContents();
|
||||||
for (const std::string &content_s : contents_s) {
|
for (const std::string &content_s : contents_s) {
|
||||||
std::set<content_t> ids;
|
std::vector<content_t> ids;
|
||||||
ndef->getIds(content_s, ids);
|
ndef->getIds(content_s, ids);
|
||||||
for (content_t c : ids) {
|
for (content_t c : ids) {
|
||||||
if (c >= m_aabms.size())
|
if (c >= m_aabms.size())
|
||||||
|
@ -777,7 +780,7 @@ public:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Check neighbors
|
// Check neighbors
|
||||||
if (!aabm.required_neighbors.empty()) {
|
if (aabm.check_required_neighbors) {
|
||||||
v3s16 p1;
|
v3s16 p1;
|
||||||
for(p1.X = p0.X-1; p1.X <= p0.X+1; p1.X++)
|
for(p1.X = p0.X-1; p1.X <= p0.X+1; p1.X++)
|
||||||
for(p1.Y = p0.Y-1; p1.Y <= p0.Y+1; p1.Y++)
|
for(p1.Y = p0.Y-1; p1.Y <= p0.Y+1; p1.Y++)
|
||||||
|
@ -796,12 +799,9 @@ public:
|
||||||
MapNode n = map->getNodeNoEx(p1 + block->getPosRelative());
|
MapNode n = map->getNodeNoEx(p1 + block->getPosRelative());
|
||||||
c = n.getContent();
|
c = n.getContent();
|
||||||
}
|
}
|
||||||
std::set<content_t>::const_iterator k;
|
if (CONTAINS(aabm.required_neighbors, c))
|
||||||
k = aabm.required_neighbors.find(c);
|
|
||||||
if(k != aabm.required_neighbors.end()){
|
|
||||||
goto neighbor_found;
|
goto neighbor_found;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
// No required neighbor found
|
// No required neighbor found
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,10 @@ public:
|
||||||
virtual ~ActiveBlockModifier() = default;
|
virtual ~ActiveBlockModifier() = default;
|
||||||
|
|
||||||
// Set of contents to trigger on
|
// Set of contents to trigger on
|
||||||
virtual const std::set<std::string> &getTriggerContents() const = 0;
|
virtual const std::vector<std::string> &getTriggerContents() const = 0;
|
||||||
// Set of required neighbors (trigger doesn't happen if none are found)
|
// Set of required neighbors (trigger doesn't happen if none are found)
|
||||||
// Empty = do not check neighbors
|
// Empty = do not check neighbors
|
||||||
virtual const std::set<std::string> &getRequiredNeighbors() const = 0;
|
virtual const std::vector<std::string> &getRequiredNeighbors() const = 0;
|
||||||
// Trigger interval in seconds
|
// Trigger interval in seconds
|
||||||
virtual float getTriggerInterval() = 0;
|
virtual float getTriggerInterval() = 0;
|
||||||
// Random chance of (1 / return value), 0 is disallowed
|
// Random chance of (1 / return value), 0 is disallowed
|
||||||
|
|
Loading…
Reference in New Issue