This commit is contained in:
Akkadius 2024-11-14 23:46:59 -06:00
parent c18cba4faf
commit abc507d173
8 changed files with 67 additions and 13 deletions

View File

@ -143,6 +143,7 @@ namespace Logs {
Corpses,
XTargets,
EvolveItem,
Visibility,
MaxCategoryID /* Don't Remove this */
};
@ -244,7 +245,8 @@ namespace Logs {
"EqTime",
"Corpses",
"XTargets",
"EvolveItem"
"EvolveItem",
"Visibility"
};
}

View File

@ -854,6 +854,16 @@
OutF(LogSys, Logs::Detail, Logs::XTargets, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogVisibility(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::General, Logs::Visibility))\
OutF(LogSys, Logs::General, Logs::Visibility, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define LogVisibilityDetail(message, ...) do {\
if (LogSys.IsLogEnabled(Logs::Detail, Logs::Visibility))\
OutF(LogSys, Logs::Detail, Logs::Visibility, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
} while (0)
#define Log(debug_level, log_category, message, ...) do {\
if (LogSys.IsLogEnabled(debug_level, log_category))\
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\

View File

@ -86,6 +86,9 @@ struct BenchTimer
void reset() { start_time = clock::now(); }
// this is seconds
double elapsed() { return std::chrono::duration<double> (clock::now() - start_time).count(); }
std::chrono::milliseconds::rep elapsedMilliseconds() { return std::chrono::duration_cast<std::chrono::milliseconds>(clock::now() - start_time).count(); }
std::chrono::microseconds::rep elapsedMicroseconds() { return std::chrono::duration_cast<std::chrono::microseconds>(clock::now() - start_time).count(); }
std::chrono::nanoseconds::rep elapsedNanoseconds() { return std::chrono::duration_cast<std::chrono::nanoseconds>(clock::now() - start_time).count(); }
private:
std::chrono::time_point<std::chrono::high_resolution_clock> start_time;
};

View File

@ -4956,6 +4956,20 @@ void Client::Handle_OP_ClientUpdate(const EQApplicationPacket *app) {
CheckScanCloseMobsMovingTimer();
}
// see_close
if (moving) {
if (m_see_close_mobs_timer.GetRemainingTime() > 1000) {
m_see_close_mobs_timer.Disable();
m_see_close_mobs_timer.Start(1000);
m_see_close_mobs_timer.Trigger();
}
}
else if (m_see_close_mobs_timer.GetDuration() == 1000) {
m_see_close_mobs_timer.Disable();
m_see_close_mobs_timer.Start(60000);
m_see_close_mobs_timer.Trigger();
}
CheckSendBulkClientPositionUpdate();
int32 new_animation = ppu->animation;

View File

@ -285,6 +285,10 @@ bool Client::Process() {
entity_list.ScanCloseMobs(this);
}
if (m_see_close_mobs_timer.Check()) {
entity_list.UpdateVisibility(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
if (!m_lazy_load_bank && lazy_load_bank_check_timer.Check()) {

View File

@ -2869,6 +2869,7 @@ bool EntityList::RemoveMobFromCloseLists(Mob *mob)
);
it->second->m_close_mobs.erase(entity_id);
it->second->m_can_see_mob.erase(entity_id);
++it;
}
@ -2922,6 +2923,9 @@ void EntityList::RemoveAuraFromMobs(Mob *aura)
// All of the above makes a tremendous impact on the bottom line of cpu cycle performance because we run an order of magnitude
// less checks by focusing our hot path logic down to a very small subset of relevant entities instead of looping an entire
// entity list (zone wide)
BenchTimer g_scan_bench_timer;
void EntityList::ScanCloseMobs(Mob *scanning_mob)
{
if (!scanning_mob) {
@ -2932,6 +2936,8 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
return;
}
g_scan_bench_timer.reset();
float scan_range = zone->GetMaxUpdateRange();
// Reserve memory in m_close_mobs to avoid frequent re-allocations if not already reserved.
@ -2959,22 +2965,27 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
}
}
UpdateVisibility(scanning_mob);
LogAIScanClose(
"[{}] Scanning close list > list_size [{}] moving [{}]",
"[{}] Scanning close list > list_size [{}] moving [{}] elapsed [{}] us",
scanning_mob->GetCleanName(),
scanning_mob->m_close_mobs.size(),
scanning_mob->IsMoving() ? "true" : "false"
scanning_mob->IsMoving() ? "true" : "false",
g_scan_bench_timer.elapsedMicroseconds()
);
}
BenchTimer g_vis_bench_timer;
void EntityList::UpdateVisibility(Mob *scanning_mob)
{
if (!scanning_mob || !scanning_mob->IsClient()) {
return;
}
ScanCloseMobs(scanning_mob);
g_vis_bench_timer.reset();
// Ensure sufficient capacity in the visibility map
if (scanning_mob->m_can_see_mob.bucket_count() < scanning_mob->m_close_mobs.size()) {
scanning_mob->m_can_see_mob.reserve(scanning_mob->m_close_mobs.size());
@ -2991,7 +3002,7 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
auto [it_scanning_visible, inserted_scanning_visible] = scanning_mob->m_can_see_mob.try_emplace(mob_id, false);
bool scanning_last_known_visible = it_scanning_visible->second;
if (!scanning_last_known_visible) {
if (!scanning_last_known_visible && mob->IsClient()) {
scanning_mob->SendAppearancePacket(
AppearanceType::Invisibility,
0,
@ -3000,14 +3011,14 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
mob->CastToClient()
);
it_scanning_visible->second = true;
scanning_mob->Shout(fmt::format("Setting scanning_mob visible to mob [{}]", mob->GetCleanName()).c_str());
LogVisibilityDetail("Setting scanning_mob [{}] visible to mob [{}]", scanning_mob->GetCleanName(), mob->GetCleanName());
}
// Now update the visibility for `mob` to `scanning_mob`
auto [it_mob_visible, inserted_mob_visible] = mob->m_can_see_mob.try_emplace(scanning_mob->GetID(), false);
bool mob_last_known_visible = it_mob_visible->second;
if (!mob_last_known_visible) {
if (!mob_last_known_visible && scanning_mob->IsClient()) {
mob->SendAppearancePacket(
AppearanceType::Invisibility,
0,
@ -3016,7 +3027,7 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
scanning_mob->CastToClient()
);
it_mob_visible->second = true;
mob->Shout(fmt::format("Setting mob visible to scanning_mob [{}]", scanning_mob->GetCleanName()).c_str());
LogVisibilityDetail("Setting mob [{}] visible to scanning_mob [{}]", mob->GetCleanName(), scanning_mob->GetCleanName());
}
}
@ -3032,7 +3043,7 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
auto [it, inserted] = scanning_mob->m_can_see_mob.try_emplace(mob_id, false);
bool last_known_visible = it->second;
if (!is_on_close_list && last_known_visible) {
if (!is_on_close_list && last_known_visible && mob->IsClient()) {
scanning_mob->SendAppearancePacket(
AppearanceType::Invisibility,
3001,
@ -3041,12 +3052,12 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
mob->CastToClient()
);
it->second = false;
scanning_mob->Shout(fmt::format("Setting mob [{}] invisible to scanning_mob", mob->GetCleanName()).c_str());
LogVisibilityDetail("Setting mob [{}] invisible to scanning_mob [{}]", mob->GetCleanName(), scanning_mob->GetCleanName());
}
// Inverse: Update mob's view of scanning_mob visibility
auto it_mob = mob->m_can_see_mob.find(scanning_mob->GetID());
if (it_mob != mob->m_can_see_mob.end() && !scanning_mob->m_close_mobs.count(mob_id) && it_mob->second) {
if (it_mob != mob->m_can_see_mob.end() && !scanning_mob->m_close_mobs.count(mob_id) && it_mob->second && scanning_mob->IsClient()) {
mob->SendAppearancePacket(
AppearanceType::Invisibility,
3001,
@ -3055,9 +3066,17 @@ void EntityList::UpdateVisibility(Mob *scanning_mob)
scanning_mob->CastToClient()
);
it_mob->second = false;
mob->Shout(fmt::format("Setting scanning_mob [{}] invisible to mob", scanning_mob->GetCleanName()).c_str());
LogVisibilityDetail("Setting scanning_mob [{}] invisible to mob [{}]", scanning_mob->GetCleanName(), mob->GetCleanName());
}
}
LogVisibility(
"[{}] Visibility > list_size [{}] moving [{}] elapsed [{}] us",
scanning_mob->GetCleanName(),
scanning_mob->m_can_see_mob.size(),
scanning_mob->IsMoving() ? "true" : "false",
g_vis_bench_timer.elapsedMicroseconds()
);
}
bool EntityList::RemoveMerc(uint16 delete_id)

View File

@ -129,6 +129,7 @@ Mob::Mob(
position_update_melee_push_timer(500),
hate_list_cleanup_timer(6000),
m_scan_close_mobs_timer(6000),
m_see_close_mobs_timer(1000),
m_mob_check_moving_timer(1000),
bot_attack_flag_timer(10000)
{

View File

@ -204,6 +204,7 @@ public:
std::unordered_map<uint16, Mob *> m_close_mobs;
std::unordered_map<int, bool> m_can_see_mob;
Timer m_scan_close_mobs_timer;
Timer m_see_close_mobs_timer;
Timer m_mob_check_moving_timer;
// Bot attack flag