[Performance] Improvements to ScanCloseMobs logic (#4534)

* [Performance] Minor improvements to ScanCloseMobs

* Remove timer checks one level up to reduce branching

* Reserve memory in m_close_mobs to avoid frequent re-allocations if not already reserved.
This commit is contained in:
Chris Miles 2024-11-08 17:48:39 -06:00 committed by GitHub
parent 1ce51ca3b0
commit 0ea47fadee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 42 additions and 47 deletions

View File

@ -1578,7 +1578,10 @@ bool Bot::Process()
return false;
}
ScanCloseMobProcess();
if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
SpellProcess();
if (tic_timer.Check()) {

View File

@ -5013,7 +5013,11 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
SetMoving(!(cy == m_Position.y && cx == m_Position.x));
CheckClientToNpcAggroTimer();
CheckScanCloseMobsMovingTimer();
if (m_mob_check_moving_timer.Check()) {
CheckScanCloseMobsMovingTimer();
}
CheckSendBulkClientPositionUpdate();
int32 new_animation = ppu->animation;

View File

@ -281,7 +281,9 @@ bool Client::Process() {
}
}
ScanCloseMobProcess();
if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
if (RuleB(Inventory, LazyLoadBank)) {
// poll once a second to see if we are close to a banker and we haven't loaded the bank yet

View File

@ -2947,6 +2947,12 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
{
float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance);
// Reserve memory in m_close_mobs to avoid frequent re-allocations if not already reserved.
// Assuming mob_list.size() as an upper bound for reservation.
if (scanning_mob->m_close_mobs.bucket_count() < mob_list.size()) {
scanning_mob->m_close_mobs.reserve(mob_list.size());
}
scanning_mob->m_close_mobs.clear();
for (auto &e : mob_list) {
@ -2957,28 +2963,14 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
if (distance <= scan_range || mob->GetAggroRange() >= scan_range) {
scanning_mob->m_close_mobs.emplace(std::pair<uint16, Mob *>(mob->GetID(), mob));
// add self to other mobs close list
if (scanning_mob->GetID() > 0) {
bool has_mob = false;
for (auto &cm: mob->m_close_mobs) {
if (scanning_mob->GetID() == cm.first) {
has_mob = true;
break;
}
}
if (!has_mob) {
mob->m_close_mobs.insert(std::pair<uint16, Mob *>(scanning_mob->GetID(), scanning_mob));
}
}
// add mob to scanning_mob's close list and vice versa
mob->m_close_mobs[scanning_mob->GetID()] = scanning_mob;
scanning_mob->m_close_mobs[mob->GetID()] = mob;
}
}
LogAIScanCloseDetail(
"[{}] Scanning Close List | list_size [{}] moving [{}]",
LogAIScanClose(
"[{}] Scanning close list > list_size [{}] moving [{}]",
scanning_mob->GetCleanName(),
scanning_mob->m_close_mobs.size(),
scanning_mob->IsMoving() ? "true" : "false"

View File

@ -8584,6 +8584,7 @@ bool Mob::HasBotAttackFlag(Mob* tar) {
const uint16 scan_close_mobs_timer_moving = 6000; // 6 seconds
const uint16 scan_close_mobs_timer_idle = 60000; // 60 seconds
// If the moving timer triggers, lets see if we are moving or idle to restart the appropriate dynamic timer
void Mob::CheckScanCloseMobsMovingTimer()
{
LogAIScanCloseDetail(
@ -8593,31 +8594,20 @@ void Mob::CheckScanCloseMobsMovingTimer()
m_scan_close_mobs_timer.GetRemainingTime()
);
// If the moving timer triggers, lets see if we are moving or idle to restart the appropriate
// dynamic timer
if (m_mob_check_moving_timer.Check()) {
// If the mob is still moving, restart the moving timer
if (moving) {
if (m_scan_close_mobs_timer.GetRemainingTime() > scan_close_mobs_timer_moving) {
LogAIScanCloseDetail("Mob [{}] Restarting with moving timer", GetCleanName());
m_scan_close_mobs_timer.Disable();
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_moving);
m_scan_close_mobs_timer.Trigger();
}
}
// If the mob is not moving, restart the idle timer
else if (m_scan_close_mobs_timer.GetDuration() == scan_close_mobs_timer_moving) {
LogAIScanCloseDetail("Mob [{}] Restarting with idle timer", GetCleanName());
// If the mob is still moving, restart the moving timer
if (moving) {
if (m_scan_close_mobs_timer.GetRemainingTime() > scan_close_mobs_timer_moving) {
LogAIScanCloseDetail("Mob [{}] Restarting with moving timer", GetCleanName());
m_scan_close_mobs_timer.Disable();
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_idle);
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_moving);
m_scan_close_mobs_timer.Trigger();
}
}
}
void Mob::ScanCloseMobProcess()
{
if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
// If the mob is not moving, restart the idle timer
else if (m_scan_close_mobs_timer.GetDuration() == scan_close_mobs_timer_moving) {
LogAIScanCloseDetail("Mob [{}] Restarting with idle timer", GetCleanName());
m_scan_close_mobs_timer.Disable();
m_scan_close_mobs_timer.Start(scan_close_mobs_timer_idle);
}
}

View File

@ -1488,7 +1488,6 @@ public:
bool IsCloseToBanker();
void ScanCloseMobProcess();
std::unordered_map<uint16, Mob *> &GetCloseMobList(float distance = 0.0f);
void CheckScanCloseMobsMovingTimer();

View File

@ -601,8 +601,13 @@ bool NPC::Process()
DepopSwarmPets();
}
ScanCloseMobProcess();
CheckScanCloseMobsMovingTimer();
if (m_scan_close_mobs_timer.Check()) {
entity_list.ScanCloseMobs(this);
}
if (m_mob_check_moving_timer.Check()) {
CheckScanCloseMobsMovingTimer();
}
if (hp_regen_per_second > 0 && hp_regen_per_second_timer.Check()) {
if (GetHP() < GetMaxHP()) {