Core/Spells: fix wrong distance calculations in AoE spells
Port From (https://github.com/TrinityCore/TrinityCore/commit/5d076cfe291980bc5be9d44ffbae887e3dd5ad59)
This commit is contained in:
@@ -2583,7 +2583,7 @@ namespace Game.Spells
|
||||
case SpellEffectName.ApplyAreaAuraRaid:
|
||||
{
|
||||
targetList.Add(GetUnitOwner());
|
||||
var u_check = new AnyGroupedUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius, effect.Effect == SpellEffectName.ApplyAreaAuraRaid);
|
||||
var u_check = new AnyGroupedUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius, effect.Effect == SpellEffectName.ApplyAreaAuraRaid, GetSpellInfo().HasAttribute(SpellAttr3.OnlyTargetPlayers), false, true);
|
||||
var searcher = new UnitListSearcher(GetUnitOwner(), targetList, u_check);
|
||||
Cell.VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
@@ -2591,14 +2591,14 @@ namespace Game.Spells
|
||||
case SpellEffectName.ApplyAreaAuraFriend:
|
||||
{
|
||||
targetList.Add(GetUnitOwner());
|
||||
var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius);
|
||||
var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo().HasAttribute(SpellAttr3.OnlyTargetPlayers), false, true);
|
||||
var searcher = new UnitListSearcher(GetUnitOwner(), targetList, u_check);
|
||||
Cell.VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
}
|
||||
case SpellEffectName.ApplyAreaAuraEnemy:
|
||||
{
|
||||
var u_check = new AnyAoETargetUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius);
|
||||
var u_check = new AnyAoETargetUnitInObjectRangeCheck(GetUnitOwner(), GetUnitOwner(), radius, GetSpellInfo(), false, true);
|
||||
var searcher = new UnitListSearcher(GetUnitOwner(), targetList, u_check);
|
||||
Cell.VisitAllObjects(GetUnitOwner(), searcher, radius);
|
||||
break;
|
||||
@@ -2669,13 +2669,13 @@ namespace Game.Spells
|
||||
List<Unit> targetList = new List<Unit>();
|
||||
if (effect.TargetB.GetTarget() == Targets.DestDynobjAlly || effect.TargetB.GetTarget() == Targets.UnitDestAreaAlly)
|
||||
{
|
||||
var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius, GetSpellInfo().HasAttribute(SpellAttr3.OnlyTargetPlayers));
|
||||
var u_check = new AnyFriendlyUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius, GetSpellInfo().HasAttribute(SpellAttr3.OnlyTargetPlayers), false, true);
|
||||
var searcher = new UnitListSearcher(GetDynobjOwner(), targetList, u_check);
|
||||
Cell.VisitAllObjects(GetDynobjOwner(), searcher, radius);
|
||||
}
|
||||
else
|
||||
{
|
||||
var u_check = new AnyAoETargetUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius);
|
||||
var u_check = new AnyAoETargetUnitInObjectRangeCheck(GetDynobjOwner(), dynObjOwnerCaster, radius, null, false, true);
|
||||
var searcher = new UnitListSearcher(GetDynobjOwner(), targetList, u_check);
|
||||
Cell.VisitAllObjects(GetDynobjOwner(), searcher, radius);
|
||||
}
|
||||
|
||||
+28
-12
@@ -735,7 +735,12 @@ namespace Game.Spells
|
||||
SpellEffectInfo effect = GetEffect(effIndex);
|
||||
if (effect == null)
|
||||
return;
|
||||
|
||||
float radius = effect.CalcRadius(m_caster) * m_spellValue.RadiusMod;
|
||||
// if this is a proximity based aoe (Frost Nova, Psychic Scream, ...), include the caster's own combat reach
|
||||
if (targetType.IsProximityBasedAoe())
|
||||
radius += GetCaster().GetCombatReach();
|
||||
|
||||
SearchAreaTargets(targets, radius, center, referer, targetType.GetObjectType(), targetType.GetCheckType(), effect.ImplicitTargetConditions);
|
||||
|
||||
CallScriptObjectAreaTargetSelectHandlers(targets, effIndex, targetType);
|
||||
@@ -797,7 +802,7 @@ namespace Game.Spells
|
||||
float dis = (float)RandomHelper.NextDouble() * (maxDist - minDist) + minDist;
|
||||
float x, y, z;
|
||||
float angle = (float)RandomHelper.NextDouble() * (MathFunctions.PI * 35.0f / 180.0f) - (float)(Math.PI * 17.5f / 180.0f);
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultWorldObjectSize, dis, angle);
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultPlayerBoundingRadius, dis, angle);
|
||||
|
||||
float ground = m_caster.GetMap().GetHeight(m_caster.GetPhaseShift(), x, y, z, true, 50.0f);
|
||||
float liquidLevel = MapConst.VMAPInvalidHeightValue;
|
||||
@@ -830,7 +835,7 @@ namespace Game.Spells
|
||||
{
|
||||
float dist = effect.CalcRadius(m_caster);
|
||||
float angl = targetType.CalcDirectionAngle();
|
||||
float objSize = m_caster.GetObjectSize();
|
||||
float objSize = m_caster.GetCombatReach();
|
||||
|
||||
switch (targetType.GetTarget())
|
||||
{
|
||||
@@ -885,7 +890,7 @@ namespace Game.Spells
|
||||
if (effect != null)
|
||||
{
|
||||
float angle = targetType.CalcDirectionAngle();
|
||||
float objSize = target.GetObjectSize();
|
||||
float objSize = target.GetCombatReach();
|
||||
float dist = effect.CalcRadius(m_caster);
|
||||
if (dist < objSize)
|
||||
dist = objSize;
|
||||
@@ -1108,7 +1113,7 @@ namespace Game.Spells
|
||||
}
|
||||
}
|
||||
|
||||
float size = Math.Max(obj.GetObjectSize(), 1.0f);
|
||||
float size = Math.Max(obj.GetCombatReach(), 1.0f);
|
||||
float objDist2d = srcPos.GetExactDist2d(obj);
|
||||
float dz = obj.GetPositionZ() - srcPos.posZ;
|
||||
|
||||
@@ -4843,12 +4848,12 @@ namespace Game.Spells
|
||||
if (!target.IsWithinLOSInMap(m_caster)) //Do full LoS/Path check. Don't exclude m2
|
||||
return SpellCastResult.LineOfSight;
|
||||
|
||||
float objSize = target.GetObjectSize();
|
||||
float objSize = target.GetCombatReach();
|
||||
float range = m_spellInfo.GetMaxRange(true, m_caster, this) * 1.5f + objSize; // can't be overly strict
|
||||
|
||||
m_preGeneratedPath.SetPathLengthLimit(range);
|
||||
//first try with raycast, if it fails fall back to normal path
|
||||
float targetObjectSize = Math.Min(target.GetObjectSize(), 4.0f);
|
||||
float targetObjectSize = Math.Min(target.GetCombatReach(), 4.0f);
|
||||
bool result = m_preGeneratedPath.CalculatePath(target.GetPositionX(), target.GetPositionY(), target.GetPositionZ() + targetObjectSize, false, true);
|
||||
if (m_preGeneratedPath.GetPathType().HasAnyFlag(PathType.Short))
|
||||
return SpellCastResult.OutOfRange;
|
||||
@@ -7746,8 +7751,7 @@ namespace Game.Spells
|
||||
{
|
||||
float _range;
|
||||
Position _position;
|
||||
public WorldObjectSpellAreaTargetCheck(float range, Position position, Unit caster,
|
||||
Unit referer, SpellInfo spellInfo, SpellTargetCheckTypes selectionType, List<Condition> condList)
|
||||
public WorldObjectSpellAreaTargetCheck(float range, Position position, Unit caster, Unit referer, SpellInfo spellInfo, SpellTargetCheckTypes selectionType, List<Condition> condList)
|
||||
: base(caster, referer, spellInfo, selectionType, condList)
|
||||
{
|
||||
_range = range;
|
||||
@@ -7757,8 +7761,20 @@ namespace Game.Spells
|
||||
|
||||
public override bool Invoke(WorldObject target)
|
||||
{
|
||||
if (!target.IsWithinDist3d(_position, _range) && !(target.IsTypeId(TypeId.GameObject) && target.ToGameObject().IsInRange(_position.posX, _position.posY, _position.posZ, _range)))
|
||||
return false;
|
||||
if (target.ToGameObject())
|
||||
{
|
||||
// isInRange including the dimension of the GO
|
||||
bool isInRange = target.ToGameObject().IsInRange(_position.GetPositionX(), _position.GetPositionY(), _position.GetPositionZ(), _range);
|
||||
if (!isInRange)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isInsideCylinder = target.IsWithinDist2d(_position, _range) && Math.Abs(target.GetPositionZ() - _position.GetPositionZ()) <= _range;
|
||||
if (!isInsideCylinder)
|
||||
return false;
|
||||
}
|
||||
|
||||
return base.Invoke(target);
|
||||
}
|
||||
}
|
||||
@@ -7780,7 +7796,7 @@ namespace Game.Spells
|
||||
}
|
||||
else if (_spellInfo.HasAttribute(SpellCustomAttributes.ConeLine))
|
||||
{
|
||||
if (!_caster.HasInLine(target, target.GetObjectSize(), _caster.GetObjectSize()))
|
||||
if (!_caster.HasInLine(target, target.GetCombatReach(), _caster.GetCombatReach()))
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -7812,7 +7828,7 @@ namespace Game.Spells
|
||||
public override bool Invoke(WorldObject target)
|
||||
{
|
||||
// return all targets on missile trajectory (0 - size of a missile)
|
||||
if (!_caster.HasInLine(target, target.GetObjectSize(), SpellConst.TrajectoryMissileSize))
|
||||
if (!_caster.HasInLine(target, target.GetCombatReach(), SpellConst.TrajectoryMissileSize))
|
||||
return false;
|
||||
|
||||
if (target.GetExactDist2d(_position) > _range)
|
||||
|
||||
@@ -2034,7 +2034,7 @@ namespace Game.Spells
|
||||
float dis = effectInfo.CalcRadius(m_caster);
|
||||
|
||||
float fx, fy, fz;
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, unitTarget.GetObjectSize(), dis);
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, unitTarget.GetCombatReach(), dis);
|
||||
|
||||
unitTarget.NearTeleportTo(fx, fy, fz, -m_caster.GetOrientation(), unitTarget == m_caster);
|
||||
}
|
||||
@@ -2385,7 +2385,7 @@ namespace Game.Spells
|
||||
Cypher.Assert(OldSummon.GetMap() == owner.GetMap());
|
||||
|
||||
float px, py, pz;
|
||||
owner.GetClosePoint(out px, out py, out pz, OldSummon.GetObjectSize());
|
||||
owner.GetClosePoint(out px, out py, out pz, OldSummon.GetCombatReach());
|
||||
|
||||
OldSummon.NearTeleportTo(px, py, pz, OldSummon.GetOrientation());
|
||||
|
||||
@@ -2402,7 +2402,7 @@ namespace Game.Spells
|
||||
}
|
||||
|
||||
float x, y, z;
|
||||
owner.GetClosePoint(out x, out y, out z, owner.GetObjectSize());
|
||||
owner.GetClosePoint(out x, out y, out z, owner.GetCombatReach());
|
||||
Pet pet = owner.SummonPet(petentry, x, y, z, owner.Orientation, PetType.Summon, 0);
|
||||
if (!pet)
|
||||
return;
|
||||
@@ -2791,7 +2791,7 @@ namespace Game.Spells
|
||||
if (m_targets.HasDst())
|
||||
destTarget.GetPosition(out x, out y, out z);
|
||||
else
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultWorldObjectSize);
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultPlayerBoundingRadius);
|
||||
|
||||
Map map = target.GetMap();
|
||||
|
||||
@@ -3790,7 +3790,7 @@ namespace Game.Spells
|
||||
destTarget.GetPosition(out x, out y, out z);
|
||||
// Summon in random point all other units if location present
|
||||
else
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultWorldObjectSize);
|
||||
m_caster.GetClosePoint(out x, out y, out z, SharedConst.DefaultPlayerBoundingRadius);
|
||||
|
||||
Map map = m_caster.GetMap();
|
||||
Position pos = new Position(x, y, z, m_caster.GetOrientation());
|
||||
@@ -4094,7 +4094,7 @@ namespace Game.Spells
|
||||
// Spell is not using explicit target - no generated path
|
||||
if (m_preGeneratedPath.GetPathType() == PathType.Blank)
|
||||
{
|
||||
Position pos = unitTarget.GetFirstCollisionPosition(unitTarget.GetObjectSize(), unitTarget.GetRelativeAngle(m_caster.GetPosition()));
|
||||
Position pos = unitTarget.GetFirstCollisionPosition(unitTarget.GetCombatReach(), unitTarget.GetRelativeAngle(m_caster.GetPosition()));
|
||||
if (MathFunctions.fuzzyGt(m_spellInfo.Speed, 0.0f) && m_spellInfo.HasAttribute(SpellAttr9.SpecialDelayCalculation))
|
||||
speed = pos.GetExactDist(m_caster) / speed;
|
||||
|
||||
@@ -4530,7 +4530,7 @@ namespace Game.Spells
|
||||
else if (effectInfo.HasRadius() && m_spellInfo.Speed == 0)
|
||||
{
|
||||
float dis = effectInfo.CalcRadius(m_originalCaster);
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, SharedConst.DefaultWorldObjectSize, dis);
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, SharedConst.DefaultPlayerBoundingRadius, dis);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -4539,7 +4539,7 @@ namespace Game.Spells
|
||||
float max_dis = m_spellInfo.GetMaxRange(true);
|
||||
float dis = (float)RandomHelper.NextDouble() * (max_dis - min_dis) + min_dis;
|
||||
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, SharedConst.DefaultWorldObjectSize, dis);
|
||||
m_caster.GetClosePoint(out fx, out fy, out fz, SharedConst.DefaultPlayerBoundingRadius, dis);
|
||||
}
|
||||
|
||||
Map cMap = m_caster.GetMap();
|
||||
@@ -4938,7 +4938,7 @@ namespace Game.Spells
|
||||
|
||||
// relocate
|
||||
float px, py, pz;
|
||||
unitTarget.GetClosePoint(out px, out py, out pz, pet.GetObjectSize(), SharedConst.PetFollowDist, pet.GetFollowAngle());
|
||||
unitTarget.GetClosePoint(out px, out py, out pz, pet.GetCombatReach(), SharedConst.PetFollowDist, pet.GetFollowAngle());
|
||||
pet.Relocate(px, py, pz, unitTarget.GetOrientation());
|
||||
|
||||
// add to world
|
||||
|
||||
@@ -4598,6 +4598,34 @@ namespace Game.Spells
|
||||
return GetSelectionCategory() == SpellTargetSelectionCategories.Area || GetSelectionCategory() == SpellTargetSelectionCategories.Cone;
|
||||
}
|
||||
|
||||
public bool IsProximityBasedAoe()
|
||||
{
|
||||
switch (_target)
|
||||
{
|
||||
case Targets.UnitSrcAreaEntry:
|
||||
case Targets.UnitSrcAreaEnemy:
|
||||
case Targets.UnitCasterAreaParty:
|
||||
case Targets.UnitSrcAreaAlly:
|
||||
case Targets.UnitSrcAreaParty:
|
||||
case Targets.UnitLastAreaParty:
|
||||
case Targets.GameobjectSrcArea:
|
||||
case Targets.UnitCasterAreaRaid:
|
||||
case Targets.CorpseSrcAreaEnemy:
|
||||
return true;
|
||||
|
||||
case Targets.UnitDestAreaEntry:
|
||||
case Targets.UnitDestAreaEnemy:
|
||||
case Targets.UnitDestAreaAlly:
|
||||
case Targets.UnitDestAreaParty:
|
||||
case Targets.GameobjectDestArea:
|
||||
case Targets.UnitAreaRaidClass:
|
||||
return false;
|
||||
|
||||
default:
|
||||
Log.outWarn(LogFilter.Spells, "SpellImplicitTargetInfo.IsProximityBasedAoe called a non-aoe spell");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
public SpellTargetSelectionCategories GetSelectionCategory()
|
||||
{
|
||||
return _data[(int)_target].SelectionCategory;
|
||||
|
||||
Reference in New Issue
Block a user