diff --git a/common/eqemu_logsys.h b/common/eqemu_logsys.h index 460ff2fef..7514f34a1 100644 --- a/common/eqemu_logsys.h +++ b/common/eqemu_logsys.h @@ -110,6 +110,7 @@ namespace Logs { AIScanClose, AIYellForHelp, AICastBeneficialClose, + AoeCast, MaxCategoryID /* Don't Remove this */ }; @@ -179,6 +180,7 @@ namespace Logs { "AI Scan Close", "AI Yell For Help", "AI Cast Beneficial Close", + "AOE Cast", }; } diff --git a/common/eqemu_logsys_log_aliases.h b/common/eqemu_logsys_log_aliases.h index d569fba77..5b9b249ba 100644 --- a/common/eqemu_logsys_log_aliases.h +++ b/common/eqemu_logsys_log_aliases.h @@ -521,6 +521,16 @@ OutF(LogSys, Logs::Detail, Logs::AICastBeneficialClose, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ } while (0) +#define LogAoeCast(message, ...) do {\ + if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\ + OutF(LogSys, Logs::General, Logs::AoeCast, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\ +} while (0) + +#define LogAoeCastDetail(message, ...) do {\ + if (LogSys.log_settings[Logs::AoeCast].is_category_enabled == 1)\ + OutF(LogSys, Logs::Detail, Logs::AoeCast, __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/common/ruletypes.h b/common/ruletypes.h index 6933b00e4..5aeaa3021 100644 --- a/common/ruletypes.h +++ b/common/ruletypes.h @@ -568,7 +568,7 @@ RULE_INT(Range, ClientPositionUpdates, 300, "") RULE_INT(Range, ClientForceSpawnUpdateRange, 1000, "") RULE_INT(Range, CriticalDamage, 80, "") RULE_INT(Range, ClientNPCScan, 300, "") -RULE_INT(Range, MobCloseScanDistance, 300, "") +RULE_INT(Range, MobCloseScanDistance, 600, "") RULE_CATEGORY_END() diff --git a/zone/attack.cpp b/zone/attack.cpp index 78aecd22d..3f1bb6ebd 100644 --- a/zone/attack.cpp +++ b/zone/attack.cpp @@ -850,11 +850,12 @@ int Mob::ACSum() auto over_cap = ac - softcap; ac = softcap + (over_cap * returns); } - LogCombat("ACSum ac [{}] softcap [{}] returns [{}]", ac, softcap, returns); + LogCombatDetail("ACSum ac [{}] softcap [{}] returns [{}]", ac, softcap, returns); } else { - LogCombat("ACSum ac [{}]", ac); + LogCombatDetail("ACSum ac [{}]", ac); } + return ac; } @@ -2153,8 +2154,6 @@ bool NPC::Death(Mob* killer_mob, int32 damage, uint16 spell, EQEmu::skills::Skil LogCombat("Fatal blow dealt by [{}] with [{}] damage, spell [{}], skill [{}]", ((killer_mob) ? (killer_mob->GetName()) : ("[nullptr]")), damage, spell, attack_skill); - entity_list.RemoveMobFromCloseLists(CastToMob()); - Mob *oos = nullptr; if (killer_mob) { oos = killer_mob->GetOwnerOrSelf(); diff --git a/zone/effects.cpp b/zone/effects.cpp index 4b908cec6..d9292d2e4 100644 --- a/zone/effects.cpp +++ b/zone/effects.cpp @@ -748,37 +748,77 @@ void EntityList::AESpell( int target_hit_counter = 0; float distance_to_target = 0; + float distance = caster_mob->GetAOERange(spell_id); - for (auto &it : caster_mob->close_mobs) { - current_mob = it.first; + LogAoeCast( + "Close scan distance [{}] cast distance [{}]", + RuleI(Range, MobCloseScanDistance), + distance + ); - if (!current_mob) { - continue; + if (distance <= RuleI(Range, MobCloseScanDistance)) { + + LogAoeCast("Using close scan mob list"); + + for (auto &it : caster_mob->close_mobs) { + current_mob = it.first; + + if (!current_mob) { + continue; + } + + LogAoeCast("Checking against close scan mob [{}]", current_mob->GetCleanName()); + + if (!AESpellFilterCriteria( + current_mob, + caster_mob, + center_mob, + spell_id, + max_targets, + max_targets_allowed, + target_hit_counter, + distance_to_target, + cast_target_position, + affect_caster, + resist_adjust + )) { + continue; + } + + current_mob->CalcSpellPowerDistanceMod(spell_id, distance_to_target); + caster_mob->SpellOnTarget(spell_id, current_mob, false, true, resist_adjust); } + } else { - LogDebug("iterating [{}]", current_mob->GetCleanName()); + LogAoeCast("Using full entity mob list"); - if (!AESpellFilterCriteria( - current_mob, - caster_mob, - center_mob, - spell_id, - max_targets, - max_targets_allowed, - target_hit_counter, - distance_to_target, - cast_target_position, - affect_caster, - resist_adjust - )) { - continue; + for (auto &it : mob_list) { + current_mob = it.second; + + LogAoeCast("Checking against full zone scan mob [{}]", current_mob->GetCleanName()); + + if (!AESpellFilterCriteria( + current_mob, + caster_mob, + center_mob, + spell_id, + max_targets, + max_targets_allowed, + target_hit_counter, + distance_to_target, + cast_target_position, + affect_caster, + resist_adjust + )) { + continue; + } + + current_mob->CalcSpellPowerDistanceMod(spell_id, distance_to_target); + caster_mob->SpellOnTarget(spell_id, current_mob, false, true, resist_adjust); } - - current_mob->CalcSpellPowerDistanceMod(spell_id, distance_to_target); - caster_mob->SpellOnTarget(spell_id, current_mob, false, true, resist_adjust); } - LogDebug("Done iterating [{}]", caster_mob->GetCleanName()); + LogAoeCast("Done iterating [{}]", caster_mob->GetCleanName()); if (max_targets && max_targets_allowed) { *max_targets = *max_targets - target_hit_counter; diff --git a/zone/entity.cpp b/zone/entity.cpp index c7ecb0f80..815e703cd 100644 --- a/zone/entity.cpp +++ b/zone/entity.cpp @@ -2498,9 +2498,6 @@ bool EntityList::RemoveMob(uint16 delete_id) auto it = mob_list.find(delete_id); if (it != mob_list.end()) { - - RemoveMobFromCloseLists(it->second); - if (npc_list.count(delete_id)) { entity_list.RemoveNPC(delete_id); } @@ -2530,8 +2527,6 @@ bool EntityList::RemoveMob(Mob *delete_mob) auto it = mob_list.begin(); while (it != mob_list.end()) { if (it->second == delete_mob) { - RemoveMobFromCloseLists(it->second); - safe_delete(it->second); if (!corpse_list.count(it->first)) { free_ids.push(it->first); @@ -2554,7 +2549,6 @@ bool EntityList::RemoveNPC(uint16 delete_id) if (it != npc_list.end()) { NPC *npc = it->second; RemoveProximity(delete_id); - RemoveMobFromCloseLists(npc->CastToMob()); npc_list.erase(it); if (npc_limit_list.count(delete_id)) { diff --git a/zone/mob.cpp b/zone/mob.cpp index 6c04d2c13..c0c2cc092 100644 --- a/zone/mob.cpp +++ b/zone/mob.cpp @@ -467,35 +467,40 @@ Mob::~Mob() AI_Stop(); if (GetPet()) { - if (GetPet()->Charmed()) + if (GetPet()->Charmed()) { GetPet()->BuffFadeByEffect(SE_Charm); - else + } + else { SetPet(0); + } } EQApplicationPacket app; CreateDespawnPacket(&app, !IsCorpse()); - Corpse* corpse = entity_list.GetCorpseByID(GetID()); - if(!corpse || (corpse && !corpse->IsPlayerCorpse())) + Corpse *corpse = entity_list.GetCorpseByID(GetID()); + if (!corpse || (corpse && !corpse->IsPlayerCorpse())) { entity_list.QueueClients(this, &app, true); + } entity_list.RemoveFromTargets(this, true); - if(trade) { + if (trade) { Mob *with = trade->With(); - if(with && with->IsClient()) { + if (with && with->IsClient()) { with->CastToClient()->FinishTrade(with); with->trade->Reset(); } delete trade; } - if(HasTempPetsActive()){ + if (HasTempPetsActive()) { entity_list.DestroyTempPets(this); } entity_list.UnMarkNPC(GetID()); UninitializeBuffSlots(); + entity_list.RemoveMobFromCloseLists(this); + #ifdef BOTS LeaveHealRotationTargetPool(); #endif