mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-14 15:41:30 +00:00
Zone optimizations
This commit is contained in:
parent
75698a809f
commit
010ba01ee7
@ -225,6 +225,7 @@ int command_init(void)
|
||||
command_add("suspend", "[name] [days] [reason] - Suspend by character name and for specificed number of days", AccountStatus::GMLeadAdmin, command_suspend) ||
|
||||
command_add("suspendmulti", "[Character Name One|Character Name Two|etc] [Days] [Reason] - Suspend multiple characters by name for specified number of days", AccountStatus::GMLeadAdmin, command_suspendmulti) ||
|
||||
command_add("takeplatinum", "[Platinum] - Takes specified amount of platinum from you or your player target", AccountStatus::GMMgmt, command_takeplatinum) ||
|
||||
command_add("test", "Test Command", AccountStatus::GMLeadAdmin, command_test) ||
|
||||
command_add("task", "(subcommand) - Task system commands", AccountStatus::GMLeadAdmin, command_task) ||
|
||||
command_add("petname", "[newname] - Temporarily renames your pet. Leave name blank to restore the original name.", AccountStatus::GMAdmin, command_petname) ||
|
||||
command_add("traindisc", "[level] - Trains all the disciplines usable by the target, up to level specified. (may freeze client for a few seconds)", AccountStatus::GMLeadAdmin, command_traindisc) ||
|
||||
@ -920,6 +921,7 @@ void command_bot(Client *c, const Seperator *sep)
|
||||
#include "gm_commands/suspend.cpp"
|
||||
#include "gm_commands/suspendmulti.cpp"
|
||||
#include "gm_commands/takeplatinum.cpp"
|
||||
#include "gm_commands/test.cpp"
|
||||
#include "gm_commands/task.cpp"
|
||||
#include "gm_commands/traindisc.cpp"
|
||||
#include "gm_commands/tune.cpp"
|
||||
|
||||
@ -179,6 +179,7 @@ void command_summonitem(Client *c, const Seperator *sep);
|
||||
void command_suspend(Client *c, const Seperator *sep);
|
||||
void command_suspendmulti(Client *c, const Seperator *sep);
|
||||
void command_takeplatinum(Client* c, const Seperator* sep);
|
||||
void command_test(Client *c, const Seperator *sep);
|
||||
void command_task(Client *c, const Seperator *sep);
|
||||
void command_petname(Client *c, const Seperator *sep);
|
||||
void command_traindisc(Client *c, const Seperator *sep);
|
||||
|
||||
@ -2941,7 +2941,7 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
|
||||
return;
|
||||
}
|
||||
|
||||
float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance);
|
||||
float scan_range = zone->GetMaxUpdateRange();
|
||||
|
||||
// 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.
|
||||
@ -2957,7 +2957,7 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
|
||||
continue;
|
||||
}
|
||||
|
||||
float distance = DistanceSquared(scanning_mob->GetPosition(), mob->GetPosition());
|
||||
float distance = Distance(scanning_mob->GetPosition(), mob->GetPosition());
|
||||
if (distance <= scan_range || mob->GetAggroRange() >= scan_range) {
|
||||
// add mob to scanning_mob's close list and vice versa
|
||||
// check if the mob is already in the close mobs list before inserting
|
||||
@ -2968,6 +2968,8 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
|
||||
}
|
||||
}
|
||||
|
||||
UpdateVisibility(scanning_mob);
|
||||
|
||||
LogAIScanClose(
|
||||
"[{}] Scanning close list > list_size [{}] moving [{}]",
|
||||
scanning_mob->GetCleanName(),
|
||||
@ -2976,6 +2978,97 @@ void EntityList::ScanCloseMobs(Mob *scanning_mob)
|
||||
);
|
||||
}
|
||||
|
||||
void EntityList::UpdateVisibility(Mob *scanning_mob)
|
||||
{
|
||||
if (!scanning_mob || !scanning_mob->IsClient()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 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());
|
||||
}
|
||||
|
||||
// Update visibility for all mobs in the close list of `scanning_mob`
|
||||
for (auto &e : scanning_mob->m_close_mobs) {
|
||||
auto mob = e.second;
|
||||
if (!mob) continue;
|
||||
|
||||
int mob_id = mob->GetID();
|
||||
|
||||
// Update visibility for `scanning_mob` to `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) {
|
||||
scanning_mob->SendAppearancePacket(
|
||||
AppearanceType::Invisibility,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
mob->CastToClient()
|
||||
);
|
||||
it_scanning_visible->second = true;
|
||||
scanning_mob->Shout(fmt::format("Setting scanning_mob visible to mob [{}]", mob->GetCleanName()).c_str());
|
||||
}
|
||||
|
||||
// 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) {
|
||||
mob->SendAppearancePacket(
|
||||
AppearanceType::Invisibility,
|
||||
0,
|
||||
false,
|
||||
true,
|
||||
scanning_mob->CastToClient()
|
||||
);
|
||||
it_mob_visible->second = true;
|
||||
mob->Shout(fmt::format("Setting mob visible to scanning_mob [{}]", scanning_mob->GetCleanName()).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// Check all other mobs to make invisible if they are no longer close
|
||||
for (auto &e : mob_list) {
|
||||
auto mob = e.second;
|
||||
if (!mob) continue;
|
||||
|
||||
int mob_id = mob->GetID();
|
||||
bool is_on_close_list = mob->m_close_mobs.find(scanning_mob->GetID()) != mob->m_close_mobs.end();
|
||||
|
||||
// Update scanning_mob's view of mob visibility
|
||||
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) {
|
||||
scanning_mob->SendAppearancePacket(
|
||||
AppearanceType::Invisibility,
|
||||
3001,
|
||||
false,
|
||||
true,
|
||||
mob->CastToClient()
|
||||
);
|
||||
it->second = false;
|
||||
scanning_mob->Shout(fmt::format("Setting mob [{}] invisible to scanning_mob", mob->GetCleanName()).c_str());
|
||||
}
|
||||
|
||||
// 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) {
|
||||
mob->SendAppearancePacket(
|
||||
AppearanceType::Invisibility,
|
||||
3001,
|
||||
false,
|
||||
true,
|
||||
scanning_mob->CastToClient()
|
||||
);
|
||||
it_mob->second = false;
|
||||
mob->Shout(fmt::format("Setting scanning_mob [{}] invisible to mob", scanning_mob->GetCleanName()).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool EntityList::RemoveMerc(uint16 delete_id)
|
||||
{
|
||||
auto it = merc_list.find(delete_id);
|
||||
|
||||
@ -570,6 +570,7 @@ public:
|
||||
void RefreshClientXTargets(Client *c);
|
||||
void SendAlternateAdvancementStats();
|
||||
void ScanCloseMobs(Mob *scanning_mob);
|
||||
void UpdateVisibility(Mob *scanning_mob);
|
||||
|
||||
void GetTrapInfo(Client* c);
|
||||
bool IsTrapGroupSpawned(uint32 trap_id, uint8 group);
|
||||
|
||||
14
zone/gm_commands/test.cpp
Executable file
14
zone/gm_commands/test.cpp
Executable file
@ -0,0 +1,14 @@
|
||||
|
||||
void command_test(Client *c, const Seperator *sep)
|
||||
{
|
||||
const int arguments = sep->argnum;
|
||||
|
||||
for (auto &e : entity_list.GetMobList()) {
|
||||
auto mob = e.second;
|
||||
if (Distance(c->GetPosition(), mob->GetPosition()) > 100) {
|
||||
mob->SendAppearancePacket(AppearanceType::Invisibility, 3001);
|
||||
} else {
|
||||
mob->SendAppearancePacket(AppearanceType::Invisibility, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -202,6 +202,7 @@ public:
|
||||
void DisplayInfo(Mob *mob);
|
||||
|
||||
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_mob_check_moving_timer;
|
||||
|
||||
|
||||
@ -2780,7 +2780,7 @@ void Zone::CalculateNpcUpdateDistanceSpread()
|
||||
int x_spread = int(std::abs(max_x - min_x));
|
||||
int y_spread = int(std::abs(max_y - min_y));
|
||||
int combined_spread = int(std::abs((x_spread + y_spread) / 2));
|
||||
int update_distance = EQ::ClampLower(int(combined_spread / 4), int(zone->GetMaxMovementUpdateRange()));
|
||||
int update_distance = EQ::ClampLower(int(combined_spread / 4), int(zone->GetMaxUpdateRange()));
|
||||
|
||||
SetNpcPositionUpdateDistance(update_distance);
|
||||
|
||||
|
||||
@ -417,7 +417,7 @@ public:
|
||||
SendDiscordMessage(webhook_id, message_prefix + Discord::FormatDiscordMessage(log_category, message));
|
||||
};
|
||||
|
||||
double GetMaxMovementUpdateRange() const { return max_movement_update_range; }
|
||||
double GetMaxUpdateRange() const { return max_movement_update_range; }
|
||||
|
||||
void SetIsHotzone(bool is_hotzone);
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user