1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-07-02 16:38:41 +00:00

Refactor ABM/LBM related code

This commit is contained in:
sfan5 2024-08-11 13:34:03 +02:00
parent 387856a1c3
commit 7ae51382c8
7 changed files with 295 additions and 269 deletions

View file

@ -77,11 +77,11 @@ ABMWithState::ABMWithState(ActiveBlockModifier *abm_):
LBMManager
*/
void LBMContentMapping::deleteContents()
LBMContentMapping::~LBMContentMapping()
{
for (auto &it : lbm_list) {
map.clear();
for (auto &it : lbm_list)
delete it;
}
}
void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamedef)
@ -90,29 +90,32 @@ void LBMContentMapping::addLBM(LoadingBlockModifierDef *lbm_def, IGameDef *gamed
// Unknown names get added to the global NameIdMapping.
const NodeDefManager *nodedef = gamedef->ndef();
FATAL_ERROR_IF(CONTAINS(lbm_list, lbm_def), "Same LBM registered twice");
lbm_list.push_back(lbm_def);
for (const std::string &nodeTrigger: lbm_def->trigger_contents) {
std::vector<content_t> c_ids;
bool found = nodedef->getIds(nodeTrigger, c_ids);
std::vector<content_t> c_ids;
for (const auto &node : lbm_def->trigger_contents) {
bool found = nodedef->getIds(node, c_ids);
if (!found) {
content_t c_id = gamedef->allocateUnknownNodeId(nodeTrigger);
content_t c_id = gamedef->allocateUnknownNodeId(node);
if (c_id == CONTENT_IGNORE) {
// Seems it can't be allocated.
warningstream << "Could not internalize node name \"" << nodeTrigger
warningstream << "Could not internalize node name \"" << node
<< "\" while loading LBM \"" << lbm_def->name << "\"." << std::endl;
continue;
}
c_ids.push_back(c_id);
}
for (content_t c_id : c_ids) {
map[c_id].push_back(lbm_def);
}
}
SORT_AND_UNIQUE(c_ids);
for (content_t c_id : c_ids)
map[c_id].push_back(lbm_def);
}
const std::vector<LoadingBlockModifierDef *> *
const LBMContentMapping::lbm_vector *
LBMContentMapping::lookup(content_t c) const
{
lbm_map::const_iterator it = map.find(c);
@ -130,9 +133,7 @@ LBMManager::~LBMManager()
delete m_lbm_def.second;
}
for (auto &it : m_lbm_lookup) {
(it.second).deleteContents();
}
m_lbm_lookup.clear();
}
void LBMManager::addLBMDef(LoadingBlockModifierDef *lbm_def)
@ -236,7 +237,7 @@ std::string LBMManager::createIntroductionTimesString()
std::ostringstream oss;
for (const auto &it : m_lbm_lookup) {
u32 time = it.first;
const std::vector<LoadingBlockModifierDef *> &lbm_list = it.second.lbm_list;
auto &lbm_list = it.second.getList();
for (const auto &lbm_def : lbm_list) {
// Don't add if the LBM runs at every load,
// then introducement time is hardcoded
@ -255,16 +256,17 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block,
// Precondition, we need m_lbm_lookup to be initialized
FATAL_ERROR_IF(!m_query_mode,
"attempted to query on non fully set up LBMManager");
v3s16 pos_of_block = block->getPosRelative();
const v3s16 pos_of_block = block->getPosRelative();
v3s16 pos;
MapNode n;
content_t c;
auto it = getLBMsIntroducedAfter(stamp);
// Note: the iteration count of this outer loop is typically very low, so it's ok.
for (; it != m_lbm_lookup.end(); ++it) {
// Cache previous version to speedup lookup which has a very high performance
// penalty on each call
// Cache previous lookup result since it has a high performance penalty.
content_t previous_c = CONTENT_IGNORE;
const std::vector<LoadingBlockModifierDef *> *lbm_list = nullptr;
const LBMContentMapping::lbm_vector *lbm_list = nullptr;
for (pos.Z = 0; pos.Z < MAP_BLOCKSIZE; pos.Z++)
for (pos.Y = 0; pos.Y < MAP_BLOCKSIZE; pos.Y++)
@ -272,7 +274,6 @@ void LBMManager::applyLBMs(ServerEnvironment *env, MapBlock *block,
n = block->getNodeNoCheck(pos);
c = n.getContent();
// If content_t are not matching perform an LBM lookup
if (previous_c != c) {
lbm_list = it->second.lookup(c);
previous_c = c;
@ -792,11 +793,9 @@ void ServerEnvironment::loadDefaultMeta()
struct ActiveABM
{
ActiveBlockModifier *abm;
int chance;
std::vector<content_t> required_neighbors;
bool check_required_neighbors; // false if required_neighbors is known to be empty
s16 min_y;
s16 max_y;
int chance;
s16 min_y, max_y;
};
#define CONTENT_TYPE_CACHE_MAX 64
@ -812,16 +811,16 @@ public:
bool use_timers):
m_env(env)
{
if(dtime_s < 0.001)
if (dtime_s < 0.001f)
return;
const NodeDefManager *ndef = env->getGameDef()->ndef();
for (ABMWithState &abmws : abms) {
ActiveBlockModifier *abm = abmws.abm;
float trigger_interval = abm->getTriggerInterval();
if(trigger_interval < 0.001)
trigger_interval = 0.001;
if (trigger_interval < 0.001f)
trigger_interval = 0.001f;
float actual_interval = dtime_s;
if(use_timers){
if (use_timers) {
abmws.timer += dtime_s;
if(abmws.timer < trigger_interval)
continue;
@ -831,6 +830,7 @@ public:
float chance = abm->getTriggerChance();
if (chance == 0)
chance = 1;
ActiveABM aabm;
aabm.abm = abm;
if (abm->getSimpleCatchUp()) {
@ -848,25 +848,21 @@ public:
aabm.max_y = abm->getMaxY();
// Trigger neighbors
const std::vector<std::string> &required_neighbors_s =
abm->getRequiredNeighbors();
for (const std::string &required_neighbor_s : required_neighbors_s) {
ndef->getIds(required_neighbor_s, aabm.required_neighbors);
}
aabm.check_required_neighbors = !required_neighbors_s.empty();
for (const auto &s : abm->getRequiredNeighbors())
ndef->getIds(s, aabm.required_neighbors);
SORT_AND_UNIQUE(aabm.required_neighbors);
// Trigger contents
const std::vector<std::string> &contents_s = abm->getTriggerContents();
for (const std::string &content_s : contents_s) {
std::vector<content_t> ids;
ndef->getIds(content_s, ids);
for (content_t c : ids) {
if (c >= m_aabms.size())
m_aabms.resize(c + 256, NULL);
if (!m_aabms[c])
m_aabms[c] = new std::vector<ActiveABM>;
m_aabms[c]->push_back(aabm);
}
std::vector<content_t> ids;
for (const auto &s : abm->getTriggerContents())
ndef->getIds(s, ids);
SORT_AND_UNIQUE(ids);
for (content_t c : ids) {
if (c >= m_aabms.size())
m_aabms.resize(c + 256, nullptr);
if (!m_aabms[c])
m_aabms[c] = new std::vector<ActiveABM>;
m_aabms[c]->push_back(aabm);
}
}
}
@ -967,7 +963,7 @@ public:
continue;
// Check neighbors
if (aabm.check_required_neighbors) {
if (!aabm.required_neighbors.empty()) {
v3s16 p1;
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++)