diff --git a/Source/Framework/Constants/SharedConst.cs b/Source/Framework/Constants/SharedConst.cs index f61866af4..451c63d1b 100644 --- a/Source/Framework/Constants/SharedConst.cs +++ b/Source/Framework/Constants/SharedConst.cs @@ -241,6 +241,7 @@ namespace Framework.Constants public const float MinMeleeReach = 2.0f; public const float NominalMeleeRange = 5.0f; public const float MeleeRange = NominalMeleeRange - MinMeleeReach * 2; //center to center for players + public const float ExtraCellSearchRadius = 40.0f; // We need in some cases increase search radius. Allow to find creatures with huge combat reach in a different nearby cell. public const float InspectDistance = 28.0f; public const float ContactDistance = 0.5f; public const float InteractionDistance = 5.0f; diff --git a/Source/Game/AI/CoreAI/TotemAI.cs b/Source/Game/AI/CoreAI/TotemAI.cs index e31b767af..80bf44345 100644 --- a/Source/Game/AI/CoreAI/TotemAI.cs +++ b/Source/Game/AI/CoreAI/TotemAI.cs @@ -54,9 +54,10 @@ namespace Game.AI // Search victim if no, not attackable, or out of range, or friendly (possible in case duel end) if (victim == null || !victim.IsTargetableForAttack() || !me.IsWithinDistInMap(victim, max_range) || me.IsFriendlyTo(victim) || !me.CanSeeOrDetect(victim)) { + float extraSearchRadius = max_range > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f; var u_check = new NearestAttackableUnitInObjectRangeCheck(me, me.GetCharmerOrOwnerOrSelf(), max_range); var checker = new UnitLastSearcher(me, u_check); - Cell.VisitAllObjects(me, checker, max_range); + Cell.VisitAllObjects(me, checker, max_range + extraSearchRadius); victim = checker.GetTarget(); } diff --git a/Source/Game/Spells/Auras/Aura.cs b/Source/Game/Spells/Auras/Aura.cs index b8615c024..2dbfcbba0 100644 --- a/Source/Game/Spells/Auras/Aura.cs +++ b/Source/Game/Spells/Auras/Aura.cs @@ -2712,6 +2712,8 @@ namespace Game.Spells var condList = spellEffectInfo.ImplicitTargetConditions; float radius = spellEffectInfo.CalcRadius(refe); + float extraSearchRadius = 0.0f; + SpellTargetCheckTypes selectionType = SpellTargetCheckTypes.Default; switch (spellEffectInfo.Effect) { @@ -2727,6 +2729,7 @@ namespace Game.Spells break; case SpellEffectName.ApplyAreaAuraEnemy: selectionType = SpellTargetCheckTypes.Enemy; + extraSearchRadius = radius > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f; break; case SpellEffectName.ApplyAreaAuraPet: if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(GetUnitOwner(), refe, condList)) @@ -2763,7 +2766,7 @@ namespace Game.Spells { WorldObjectSpellAreaTargetCheck check = new(radius, GetUnitOwner(), refe, GetUnitOwner(), GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit); UnitListSearcher searcher = new(GetUnitOwner(), units, check); - Cell.VisitAllObjects(GetUnitOwner(), searcher, radius); + Cell.VisitAllObjects(GetUnitOwner(), searcher, radius + extraSearchRadius); // by design WorldObjectSpellAreaTargetCheck allows not-in-world units (for spells) but for auras it is not acceptable units.RemoveAll(unit => !unit.IsSelfOrInSameMap(GetUnitOwner())); diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index b93f4de7f..aadf1d7bd 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -740,9 +740,10 @@ namespace Game.Spells GridMapTypeMask containerTypeMask = GetSearcherTypeMask(objectType, condList); if (containerTypeMask != 0) { + float extraSearchRadius = radius > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f; var spellCone = new WorldObjectSpellConeTargetCheck(coneSrc, MathFunctions.DegToRad(coneAngle), m_spellInfo.Width != 0 ? m_spellInfo.Width : m_caster.GetCombatReach(), radius, m_caster, m_spellInfo, selectionType, condList, objectType); var searcher = new WorldObjectListSearcher(m_caster, targets, spellCone, containerTypeMask); - SearchTargets(searcher, containerTypeMask, m_caster, m_caster.GetPosition(), radius); + SearchTargets(searcher, containerTypeMask, m_caster, m_caster.GetPosition(), radius + extraSearchRadius); CallScriptObjectAreaTargetSelectHandlers(targets, spellEffectInfo.EffectIndex, targetType); @@ -1644,9 +1645,11 @@ namespace Game.Spells var containerTypeMask = GetSearcherTypeMask(objectType, condList); if (containerTypeMask == 0) return; + + float extraSearchRadius = range > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f; var check = new WorldObjectSpellAreaTargetCheck(range, position, m_caster, referer, m_spellInfo, selectionType, condList, objectType); var searcher = new WorldObjectListSearcher(m_caster, targets, check, containerTypeMask); - SearchTargets(searcher, containerTypeMask, m_caster, position, range); + SearchTargets(searcher, containerTypeMask, m_caster, position, range + extraSearchRadius); } void SearchChainTargets(List targets, uint chainTargets, WorldObject target, SpellTargetObjectTypes objectType, SpellTargetCheckTypes selectType, SpellEffectInfo spellEffectInfo, bool isChainHeal)