diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 7514f34a1..fc1dd36f2 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -111,6 +111,7 @@ namespace Logs { AIYellForHelp, AICastBeneficialClose, AoeCast, + EntityManagement, MaxCategoryID /* Don't Remove this */ }; @@ -181,6 +182,7 @@ namespace Logs { "AI Yell For Help", "AI Cast Beneficial Close", "AOE Cast", + "Entity Management", }; } diff --git a/common/eqemu_logsys_log_aliases.h b/common/eqemu_logsys_log_aliases.h index 5b9b249ba..24abfdfc9 100644 --- a/common/eqemu_logsys_log_aliases.h +++ b/common/eqemu_logsys_log_aliases.h @@ -531,6 +531,16 @@ OutF(LogSys, Logs::Detail, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) +#define LogEntityManagement(message, ...) do {\ + if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogEntityManagementDetail(message, ...) do {\ + if (LogSys.log_settings[Logs::EntityManagement].is_category_enabled == 1)\ + OutF(LogSys, Logs::Detail, Logs::EntityManagement, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + #define Log(debug_level, log_category, message, ...) do {\ if (LogSys.log_settings[log_category].is_category_enabled == 1)\ LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ diff --git a/zone/attack.cpp b/zone/attack.cpp index 3f1bb6ebd..cd68f5d57 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -5488,4 +5488,4 @@ int32 Mob::GetHPRegen() const int32 Mob::GetManaRegen() const { return mana_regen; -} +} \ No newline at end of file diff --git a/zone/client_process.cpp b/zone/client_process.cpp index e0068d6e9..e75d53d7c 100644 --- a/zone/client_process.cpp +++ b/zone/client_process.cpp @@ -268,10 +268,10 @@ bool Client::Process() { if (mob->IsNPC()) { if (distance <= scan_range) { - close_mobs.insert(std::pair(mob, distance)); + close_mobs.insert(std::pair(mob->GetID(), mob)); } else if ((mob->GetAggroRange() * mob->GetAggroRange()) > scan_range) { - close_mobs.insert(std::pair(mob, distance)); + close_mobs.insert(std::pair(mob->GetID(), mob)); } } } @@ -597,7 +597,7 @@ bool Client::Process() { if (zone->CanDoCombat() && ret && !GetFeigned() && client_scan_npc_aggro_timer.Check()) { int npc_scan_count = 0; for (auto & close_mob : close_mobs) { - Mob *mob = close_mob.first; + Mob *mob = close_mob.second; if (!mob) continue; diff --git a/zone/effects.cpp b/zone/effects.cpp index d9292d2e4..5d9730a54 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -761,7 +761,7 @@ void EntityList::AESpell( LogAoeCast("Using close scan mob list"); for (auto &it : caster_mob->close_mobs) { - current_mob = it.first; + current_mob = it.second; if (!current_mob) { continue; diff --git a/zone/entity.cpp b/zone/entity.cpp index 815e703cd..b9756827e 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -62,7 +62,8 @@ extern char errorname[32]; Entity::Entity() { - id = 0; + id = 0; + initial_id = 0; spawn_timestamp = time(nullptr); } @@ -2566,11 +2567,22 @@ bool EntityList::RemoveNPC(uint16 delete_id) */ bool EntityList::RemoveMobFromCloseLists(Mob *mob) { - LogDebug("Removing mob [{}] from close lists", mob->GetCleanName()); + LogEntityManagement( + "Attempting to remove mob [{}] from close lists entity_id ({})", + mob->GetCleanName(), + mob->GetInitialId() + ); auto it = mob_list.begin(); while (it != mob_list.end()) { - it->second->close_mobs.erase(mob); + LogEntityManagement( + "Removing mob [{}] from [{}] close list entity_id ({})", + mob->GetCleanName(), + it->second->GetCleanName(), + mob->GetInitialId() + ); + + it->second->close_mobs.erase(mob->GetInitialId()); ++it; } @@ -2581,7 +2593,7 @@ bool EntityList::RemoveMobFromCloseLists(Mob *mob) * @param close_mobs * @param scanning_mob */ -void EntityList::ScanCloseMobs(std::unordered_map &close_mobs, Mob *scanning_mob) +void EntityList::ScanCloseMobs(std::unordered_map &close_mobs, Mob *scanning_mob) { float scan_range = RuleI(Range, MobCloseScanDistance) * RuleI(Range, MobCloseScanDistance); int list_count = 0; @@ -2590,13 +2602,15 @@ void EntityList::ScanCloseMobs(std::unordered_map &close_mobs, Mob auto it = mob_list.begin(); while (it != mob_list.end()) { + Mob *mob = it->second; + float distance = DistanceSquared(scanning_mob->GetPosition(), it->second->GetPosition()); if (distance <= scan_range) { - close_mobs.insert(std::pair(it->second, distance)); + close_mobs.insert(std::pair(mob->GetID(), mob)); list_count++; } else if (it->second->GetAggroRange() >= scan_range) { - close_mobs.insert(std::pair(it->second, distance)); + close_mobs.insert(std::pair(mob->GetID(), mob)); list_count++; } ++it; diff --git a/zone/entity.h b/zone/entity.h index 94884167c..d251eeb57 100644 --- a/zone/entity.h +++ b/zone/entity.h @@ -109,6 +109,7 @@ public: const Beacon *CastToBeacon() const; const Encounter *CastToEncounter() const; + inline const uint16& GetInitialId() const { return initial_id; } inline const uint16& GetID() const { return id; } inline const time_t& GetSpawnTimeStamp() const { return spawn_timestamp; } @@ -122,10 +123,17 @@ public: protected: friend class EntityList; - inline virtual void SetID(uint16 set_id) { id = set_id; } + inline virtual void SetID(uint16 set_id) { + id = set_id; + + if (initial_id == 0 && set_id > 0) { + initial_id = set_id; + } + } uint32 pDBAsyncWorkID; private: uint16 id; + uint16 initial_id; time_t spawn_timestamp; }; @@ -523,7 +531,7 @@ public: void RefreshAutoXTargets(Client *c); void RefreshClientXTargets(Client *c); void SendAlternateAdvancementStats(); - void ScanCloseMobs(std::unordered_map &close_mobs, Mob *scanning_mob); + void ScanCloseMobs(std::unordered_map &close_mobs, Mob *scanning_mob); void GetTrapInfo(Client* client); bool IsTrapGroupSpawned(uint32 trap_id, uint8 group); diff --git a/zone/mob.cpp b/zone/mob.cpp index c0c2cc092..6a4c12969 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -500,6 +500,7 @@ Mob::~Mob() UninitializeBuffSlots(); entity_list.RemoveMobFromCloseLists(this); + close_mobs.clear(); #ifdef BOTS LeaveHealRotationTargetPool(); @@ -531,16 +532,6 @@ uint32 Mob::GetAppearanceValue(EmuAppearance iAppearance) { return(ANIM_STAND); } -void Mob::GetCloseMobList(std::list> &m_list) -{ - m_list.clear(); - auto it = close_mobs.begin(); - while (it != close_mobs.end()) { - m_list.push_back(std::make_pair(it->first, it->second)); - ++it; - } -} - void Mob::SetInvisible(uint8 state) { invisible = state; diff --git a/zone/mob.h b/zone/mob.h index 5f9dcae03..cdd6f7041 100644 --- a/zone/mob.h +++ b/zone/mob.h @@ -170,12 +170,10 @@ public: void DisplayInfo(Mob *mob); - std::unordered_map close_mobs; + std::unordered_map close_mobs; Timer mob_scan_close; Timer mob_check_moving_timer; - void GetCloseMobList(std::list> &m_list); - //Somewhat sorted: needs documenting! //Attack diff --git a/zone/mob_ai.cpp b/zone/mob_ai.cpp index bb020060d..525948bb2 100644 --- a/zone/mob_ai.cpp +++ b/zone/mob_ai.cpp @@ -1366,8 +1366,7 @@ void Mob::AI_Process() { * NPC to NPC aggro (npc_aggro flag set) */ for (auto &close_mob : close_mobs) { - Mob *mob = close_mob.first; - float distance = close_mob.second; + Mob *mob = close_mob.second; if (mob->IsClient()) { continue; diff --git a/zone/npc.cpp b/zone/npc.cpp index 38de9529a..5325ea836 100644 --- a/zone/npc.cpp +++ b/zone/npc.cpp @@ -3070,21 +3070,22 @@ bool NPC::AICheckCloseBeneficialSpells( * Check through close range mobs */ for (auto & close_mob : close_mobs) { - Mob *mob = close_mob.first; - float cached_close_mob_distance = close_mob.second; + Mob *mob = close_mob.second; if (mob->IsClient()) { continue; } - if (cached_close_mob_distance > in_cast_range) { + float distance = DistanceSquared(mob->GetPosition(), GetPosition()); + + if (distance > in_cast_range) { continue; } LogAICastBeneficialClose( "NPC [{}] Distance [{}] Cast Range [{}] Caster [{}]", mob->GetCleanName(), - cached_close_mob_distance, + distance, in_cast_range, caster->GetCleanName() ); @@ -3133,9 +3134,8 @@ void NPC::AIYellForHelp(Mob *sender, Mob *attacker) GetID() ); - for (auto & close_mob : close_mobs) { - Mob *mob = close_mob.first; - + for (auto &close_mob : close_mobs) { + Mob *mob = close_mob.second; float distance = DistanceSquared(m_Position, mob->GetPosition()); if (mob->IsClient()) {