Core/Auras: Use UnitListSearcher instead of WorldObjectListSearcher when searching for area aura targets

Port From (https://github.com/TrinityCore/TrinityCore/commit/84b0eca4476faa68d9cf06431bc60c9a61c6152f)
This commit is contained in:
Hondacrx
2025-06-03 21:23:23 -04:00
parent 52952deee3
commit e68519679e
2 changed files with 39 additions and 36 deletions
+1 -1
View File
@@ -1667,7 +1667,7 @@ namespace Game.Maps
public class UnitListSearcher : Notifier public class UnitListSearcher : Notifier
{ {
PhaseShift i_phaseShift; public PhaseShift i_phaseShift;
List<Unit> i_objects; List<Unit> i_objects;
ICheck<Unit> i_check; ICheck<Unit> i_check;
+38 -35
View File
@@ -2759,30 +2759,31 @@ namespace Game.Spells
public override void FillTargetMap(ref Dictionary<Unit, uint> targets, Unit caster) public override void FillTargetMap(ref Dictionary<Unit, uint> targets, Unit caster)
{ {
if (GetSpellInfo().HasAttribute(SpellAttr7.DisableAuraWhileDead) && !GetUnitOwner().IsAlive()) Unit unitOwner = GetUnitOwner();
if (GetSpellInfo().HasAttribute(SpellAttr7.DisableAuraWhileDead) && !unitOwner.IsAlive())
return; return;
Unit refe = caster; Unit refe = caster;
if (refe == null) if (refe == null)
refe = GetUnitOwner(); refe = unitOwner;
// add non area aura targets // add non area aura targets
// static applications go through spell system first, so we assume they meet conditions // static applications go through spell system first, so we assume they meet conditions
foreach (var targetPair in _staticApplications) foreach (var (targetGuid, effectMask) in _staticApplications)
{ {
Unit target = Global.ObjAccessor.GetUnit(GetUnitOwner(), targetPair.Key); Unit target = Global.ObjAccessor.GetUnit(unitOwner, targetGuid);
if (target == null && targetPair.Key == GetUnitOwner().GetGUID()) if (target == null && targetGuid == unitOwner.GetGUID())
target = GetUnitOwner(); target = unitOwner;
if (target != null) if (target != null)
targets.Add(target, targetPair.Value); targets.Add(target, effectMask);
} }
// skip area update if owner is not in world! // skip area update if owner is not in world!
if (!GetUnitOwner().IsInWorld) if (!unitOwner.IsInWorld)
return; return;
if (GetUnitOwner().HasAuraState(AuraStateType.Banished, GetSpellInfo(), caster)) if (unitOwner.HasAuraState(AuraStateType.Banished, GetSpellInfo(), caster))
return; return;
foreach (var spellEffectInfo in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
@@ -2794,7 +2795,7 @@ namespace Game.Spells
if (spellEffectInfo.Effect == SpellEffectName.ApplyAura) if (spellEffectInfo.Effect == SpellEffectName.ApplyAura)
continue; continue;
List<WorldObject> units = new(); List<Unit> units = new();
var condList = spellEffectInfo.ImplicitTargetConditions; var condList = spellEffectInfo.ImplicitTargetConditions;
float radius = spellEffectInfo.CalcRadius(refe); float radius = spellEffectInfo.CalcRadius(refe);
@@ -2818,22 +2819,22 @@ namespace Game.Spells
extraSearchRadius = radius > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f; extraSearchRadius = radius > 0.0f ? SharedConst.ExtraCellSearchRadius : 0.0f;
break; break;
case SpellEffectName.ApplyAreaAuraPet: case SpellEffectName.ApplyAreaAuraPet:
if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(GetUnitOwner(), refe, condList)) if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(unitOwner, refe, condList))
units.Add(GetUnitOwner()); units.Add(unitOwner);
goto case SpellEffectName.ApplyAreaAuraOwner; goto case SpellEffectName.ApplyAreaAuraOwner;
/* fallthrough */ /* fallthrough */
case SpellEffectName.ApplyAreaAuraOwner: case SpellEffectName.ApplyAreaAuraOwner:
{ {
Unit owner = GetUnitOwner().GetCharmerOrOwner(); Unit owner = unitOwner.GetCharmerOrOwner();
if (owner != null) if (owner != null)
if (GetUnitOwner().IsWithinDistInMap(owner, radius)) if (unitOwner.IsWithinDistInMap(owner, radius))
if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(owner, refe, condList)) if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(owner, refe, condList))
units.Add(owner); units.Add(owner);
break; break;
} }
case SpellEffectName.ApplyAuraOnPet: case SpellEffectName.ApplyAuraOnPet:
{ {
Unit pet = Global.ObjAccessor.GetUnit(GetUnitOwner(), GetUnitOwner().GetPetGUID()); Unit pet = Global.ObjAccessor.GetUnit(unitOwner, unitOwner.GetPetGUID());
if (pet != null) if (pet != null)
if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(pet, refe, condList)) if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(pet, refe, condList))
units.Add(pet); units.Add(pet);
@@ -2841,8 +2842,8 @@ namespace Game.Spells
} }
case SpellEffectName.ApplyAreaAuraSummons: case SpellEffectName.ApplyAreaAuraSummons:
{ {
if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(GetUnitOwner(), refe, condList)) if (condList == null || Global.ConditionMgr.IsObjectMeetToConditions(unitOwner, refe, condList))
units.Add(GetUnitOwner()); units.Add(unitOwner);
selectionType = SpellTargetCheckTypes.Summoned; selectionType = SpellTargetCheckTypes.Summoned;
break; break;
} }
@@ -2853,22 +2854,22 @@ namespace Game.Spells
var containerTypeMask = Spell.GetSearcherTypeMask(GetSpellInfo(), spellEffectInfo, SpellTargetObjectTypes.Unit, condList); var containerTypeMask = Spell.GetSearcherTypeMask(GetSpellInfo(), spellEffectInfo, SpellTargetObjectTypes.Unit, condList);
if (containerTypeMask != 0) if (containerTypeMask != 0)
{ {
WorldObjectSpellAreaTargetCheck check = new(radius, GetUnitOwner(), refe, GetUnitOwner(), GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit); WorldObjectSpellAreaTargetCheck check = new(radius, unitOwner, refe, unitOwner, GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit);
WorldObjectListSearcher searcher = new(GetUnitOwner(), units, check, containerTypeMask); UnitListSearcher searcher = new(unitOwner, units, check);
searcher.i_phaseShift = PhasingHandler.GetAlwaysVisiblePhaseShift(); searcher.i_phaseShift = PhasingHandler.GetAlwaysVisiblePhaseShift();
Spell.SearchTargets(searcher, containerTypeMask, GetUnitOwner(), GetUnitOwner(), radius + extraSearchRadius); Spell.SearchTargets(searcher, containerTypeMask, unitOwner, unitOwner, radius + extraSearchRadius);
// by design WorldObjectSpellAreaTargetCheck allows not-in-world units (for spells) but for auras it is not acceptable // by design WorldObjectSpellAreaTargetCheck allows not-in-world units (for spells) but for auras it is not acceptable
units.RemoveAll(unit => !unit.IsSelfOrInSameMap(GetUnitOwner())); units.RemoveAll(unit => !unit.IsSelfOrInSameMap(unitOwner));
} }
} }
foreach (WorldObject unit in units) foreach (Unit unit in units)
{ {
if (!targets.ContainsKey(unit.ToUnit())) if (!targets.ContainsKey(unit))
targets[unit.ToUnit()] = 0; targets[unit] = 0;
targets[unit.ToUnit()] |= 1u << (int)spellEffectInfo.EffectIndex; targets[unit] |= 1u << (int)spellEffectInfo.EffectIndex;
} }
} }
} }
@@ -2929,11 +2930,12 @@ namespace Game.Spells
public DynObjAura(AuraCreateInfo createInfo) : base(createInfo) public DynObjAura(AuraCreateInfo createInfo) : base(createInfo)
{ {
LoadScripts(); LoadScripts();
Cypher.Assert(GetDynobjOwner() != null); DynamicObject dynObjOwner = GetDynobjOwner();
Cypher.Assert(GetDynobjOwner().IsInWorld); Cypher.Assert(dynObjOwner != null);
Cypher.Assert(GetDynobjOwner().GetMap() == createInfo.Caster.GetMap()); Cypher.Assert(dynObjOwner.IsInWorld);
Cypher.Assert(dynObjOwner.GetMap() == createInfo.Caster.GetMap());
_InitEffects(createInfo._auraEffectMask, createInfo.Caster, createInfo.BaseAmount); _InitEffects(createInfo._auraEffectMask, createInfo.Caster, createInfo.BaseAmount);
GetDynobjOwner().SetAura(this); dynObjOwner.SetAura(this);
} }
@@ -2946,8 +2948,9 @@ namespace Game.Spells
public override void FillTargetMap(ref Dictionary<Unit, uint> targets, Unit caster) public override void FillTargetMap(ref Dictionary<Unit, uint> targets, Unit caster)
{ {
Unit dynObjOwnerCaster = GetDynobjOwner().GetCaster(); DynamicObject dynObjOwner = GetDynobjOwner();
float radius = GetDynobjOwner().GetRadius(); Unit dynObjOwnerCaster = dynObjOwner.GetCaster();
float radius = dynObjOwner.GetRadius();
foreach (var spellEffectInfo in GetSpellInfo().GetEffects()) foreach (var spellEffectInfo in GetSpellInfo().GetEffects())
{ {
@@ -2962,12 +2965,12 @@ namespace Game.Spells
List<Unit> targetList = new(); List<Unit> targetList = new();
var condList = spellEffectInfo.ImplicitTargetConditions; var condList = spellEffectInfo.ImplicitTargetConditions;
WorldObjectSpellAreaTargetCheck check = new(radius, GetDynobjOwner(), dynObjOwnerCaster, dynObjOwnerCaster, GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit); WorldObjectSpellAreaTargetCheck check = new(radius, dynObjOwner, dynObjOwnerCaster, dynObjOwnerCaster, GetSpellInfo(), selectionType, condList, SpellTargetObjectTypes.Unit);
UnitListSearcher searcher = new(GetDynobjOwner(), targetList, check); UnitListSearcher searcher = new(dynObjOwner, targetList, check);
Cell.VisitAllObjects(GetDynobjOwner(), searcher, radius); Cell.VisitAllObjects(dynObjOwner, searcher, radius);
// by design WorldObjectSpellAreaTargetCheck allows not-in-world units (for spells) but for auras it is not acceptable // by design WorldObjectSpellAreaTargetCheck allows not-in-world units (for spells) but for auras it is not acceptable
targetList.RemoveAll(unit => !unit.IsSelfOrInSameMap(GetDynobjOwner())); targetList.RemoveAll(unit => !unit.IsSelfOrInSameMap(dynObjOwner));
foreach (var unit in targetList) foreach (var unit in targetList)
{ {