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:
parent
387856a1c3
commit
7ae51382c8
7 changed files with 295 additions and 269 deletions
|
@ -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++)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue