1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-15 18:57:08 +00:00

ABM without_neighbors (#14116)

This commit is contained in:
sfence 2024-09-26 17:32:55 +02:00 committed by GitHub
parent c1ea49940b
commit d08d34d803
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 347 additions and 6 deletions

View file

@ -34,10 +34,11 @@ with this program; if not, write to the Free Software Foundation, Inc.,
class LuaABM : public ActiveBlockModifier {
private:
int m_id;
const int m_id;
std::vector<std::string> m_trigger_contents;
std::vector<std::string> m_required_neighbors;
std::vector<std::string> m_without_neighbors;
float m_trigger_interval;
u32 m_trigger_chance;
bool m_simple_catch_up;
@ -47,11 +48,13 @@ public:
LuaABM(int id,
const std::vector<std::string> &trigger_contents,
const std::vector<std::string> &required_neighbors,
const std::vector<std::string> &without_neighbors,
float trigger_interval, u32 trigger_chance, bool simple_catch_up,
s16 min_y, s16 max_y):
m_id(id),
m_trigger_contents(trigger_contents),
m_required_neighbors(required_neighbors),
m_without_neighbors(without_neighbors),
m_trigger_interval(trigger_interval),
m_trigger_chance(trigger_chance),
m_simple_catch_up(simple_catch_up),
@ -67,6 +70,10 @@ public:
{
return m_required_neighbors;
}
virtual const std::vector<std::string> &getWithoutNeighbors() const
{
return m_without_neighbors;
}
virtual float getTriggerInterval()
{
return m_trigger_interval;
@ -230,6 +237,11 @@ void ScriptApiEnv::readABMs()
read_nodenames(L, -1, required_neighbors);
lua_pop(L, 1);
std::vector<std::string> without_neighbors;
lua_getfield(L, current_abm, "without_neighbors");
read_nodenames(L, -1, without_neighbors);
lua_pop(L, 1);
float trigger_interval = 10.0;
getfloatfield(L, current_abm, "interval", trigger_interval);
@ -250,7 +262,8 @@ void ScriptApiEnv::readABMs()
lua_pop(L, 1);
LuaABM *abm = new LuaABM(id, trigger_contents, required_neighbors,
trigger_interval, trigger_chance, simple_catch_up, min_y, max_y);
without_neighbors, trigger_interval, trigger_chance,
simple_catch_up, min_y, max_y);
env->addActiveBlockModifier(abm);

View file

@ -827,6 +827,7 @@ struct ActiveABM
{
ActiveBlockModifier *abm;
std::vector<content_t> required_neighbors;
std::vector<content_t> without_neighbors;
int chance;
s16 min_y, max_y;
};
@ -885,6 +886,10 @@ public:
ndef->getIds(s, aabm.required_neighbors);
SORT_AND_UNIQUE(aabm.required_neighbors);
for (const auto &s : abm->getWithoutNeighbors())
ndef->getIds(s, aabm.without_neighbors);
SORT_AND_UNIQUE(aabm.without_neighbors);
// Trigger contents
std::vector<content_t> ids;
for (const auto &s : abm->getTriggerContents())
@ -996,8 +1001,11 @@ public:
continue;
// Check neighbors
if (!aabm.required_neighbors.empty()) {
const bool check_required_neighbors = !aabm.required_neighbors.empty();
const bool check_without_neighbors = !aabm.without_neighbors.empty();
if (check_required_neighbors || check_without_neighbors) {
v3s16 p1;
bool have_required = false;
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.Z = p0.Z-1; p1.Z <= p0.Z+1; p1.Z++)
@ -1015,12 +1023,25 @@ public:
MapNode n = map->getNode(p1 + block->getPosRelative());
c = n.getContent();
}
if (CONTAINS(aabm.required_neighbors, c))
goto neighbor_found;
if (check_required_neighbors && !have_required) {
if (CONTAINS(aabm.required_neighbors, c)) {
if (!check_without_neighbors)
goto neighbor_found;
have_required = true;
}
}
if (check_without_neighbors) {
if (CONTAINS(aabm.without_neighbors, c))
goto neighbor_invalid;
}
}
if (have_required || !check_required_neighbors)
goto neighbor_found;
// No required neighbor found
neighbor_invalid:
continue;
}
neighbor_found:
abms_run++;

View file

@ -63,6 +63,9 @@ public:
// Set of required neighbors (trigger doesn't happen if none are found)
// Empty = do not check neighbors
virtual const std::vector<std::string> &getRequiredNeighbors() const = 0;
// Set of without neighbors (trigger doesn't happen if any are found)
// Empty = do not check neighbors
virtual const std::vector<std::string> &getWithoutNeighbors() const = 0;
// Trigger interval in seconds
virtual float getTriggerInterval() = 0;
// Random chance of (1 / return value), 0 is disallowed

View file

@ -122,7 +122,7 @@ void TestServerModManager::testGetMods()
ServerModManager sm(m_worlddir);
const auto &mods = sm.getMods();
// `ls ./games/devtest/mods | wc -l` + 1 (test mod)
UASSERTEQ(std::size_t, mods.size(), 32 + 1);
UASSERTEQ(std::size_t, mods.size(), 33 + 1);
// Ensure we found basenodes mod (part of devtest)
// and test_mod (for testing MINETEST_MOD_PATH).