Core/Spells: fix wrong distance calculations in AoE spells

Port From (https://github.com/TrinityCore/TrinityCore/commit/5d076cfe291980bc5be9d44ffbae887e3dd5ad59)
This commit is contained in:
hondacrx
2020-05-06 14:34:20 -04:00
parent 95cca081de
commit ba885908b7
29 changed files with 202 additions and 118 deletions
+2 -2
View File
@@ -218,9 +218,9 @@ namespace Framework.Constants
/// <summary>
/// Object Const
/// </summary>
public const float DefaultWorldObjectSize = 0.388999998569489f; // player size, also currently used (correctly?) for any non Unit world objects
public const float DefaultPlayerBoundingRadius = 0.388999998569489f; // player size, also currently used (correctly?) for any non Unit world objects
public const float AttackDistance = 5.0f;
public const float DefaultCombatReach = 1.5f;
public const float DefaultPlayerCombatReach = 1.5f;
public const float MinMeleeReach = 2.0f;
public const float NominalMeleeRange = 5.0f;
public const float MeleeRange = NominalMeleeRange - MinMeleeReach * 2; //center to center for players
@@ -2349,7 +2349,7 @@ namespace Framework.Constants
UnitDestAreaParty = 34,
UnitParty = 35,
DestCasterUnk36 = 36,
UnitLastareaParty = 37,
UnitLastAreaParty = 37,
UnitNearbyEntry = 38,
DestCasterFishing = 39,
GameobjectNearbyEntry = 40,
+1 -1
View File
@@ -724,7 +724,7 @@ namespace Game.Chat
return false;
float x, y, z, o = handler.GetSession().GetPlayer().GetOrientation();
handler.GetSession().GetPlayer().GetClosePoint(out x, out y, out z, handler.GetSession().GetPlayer().GetObjectSize());
handler.GetSession().GetPlayer().GetClosePoint(out x, out y, out z, handler.GetSession().GetPlayer().GetCombatReach());
uint id = args.NextUInt32();
if (id == 0)
+1 -1
View File
@@ -115,7 +115,7 @@ namespace Game.Chat
// before GM
float x, y, z;
gmPlayer.GetClosePoint(out x, out y, out z, player.GetObjectSize());
gmPlayer.GetClosePoint(out x, out y, out z, player.GetCombatReach());
player.TeleportTo(gmPlayer.GetMapId(), x, y, z, player.GetOrientation());
}
+1 -1
View File
@@ -712,7 +712,7 @@ namespace Game.Chat
// before GM
float x, y, z;
handler.GetSession().GetPlayer().GetClosePoint(out x, out y, out z, target.GetObjectSize());
handler.GetSession().GetPlayer().GetClosePoint(out x, out y, out z, target.GetCombatReach());
target.TeleportTo(handler.GetSession().GetPlayer().GetMapId(), x, y, z, target.GetOrientation());
PhasingHandler.InheritPhaseShift(target, handler.GetSession().GetPlayer());
target.UpdateObjectVisibility();
+1 -1
View File
@@ -392,7 +392,7 @@ namespace Game.Chat
// place pet before player
float x, y, z;
player.GetClosePoint(out x, out y, out z, creatureTarget.GetObjectSize(), SharedConst.ContactDistance);
player.GetClosePoint(out x, out y, out z, creatureTarget.GetCombatReach(), SharedConst.ContactDistance);
pet.Relocate(x, y, z, MathFunctions.PI - player.GetOrientation());
// set pet to defensive mode by default (some classes can't control controlled pets in fact).
+3 -3
View File
@@ -2094,7 +2094,7 @@ namespace Game.Entities
else
{
// include sizes for huge npcs
dist += GetObjectSize() + victim.GetObjectSize();
dist += GetCombatReach() + victim.GetCombatReach();
// to prevent creatures in air ignore attacks because distance is already too high...
if (GetCreatureTemplate().InhabitType.HasAnyFlag(InhabitType.Air))
@@ -2675,7 +2675,7 @@ namespace Game.Entities
if (minfo != null)
{
SetBoundingRadius((IsPet() ? 1.0f : minfo.BoundingRadius) * scale);
SetCombatReach((IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * scale);
SetCombatReach((IsPet() ? SharedConst.DefaultPlayerCombatReach : minfo.CombatReach) * scale);
}
}
@@ -2687,7 +2687,7 @@ namespace Game.Entities
if (minfo != null)
{
SetBoundingRadius((IsPet() ? 1.0f : minfo.BoundingRadius) * GetObjectScale());
SetCombatReach((IsPet() ? SharedConst.DefaultCombatReach : minfo.CombatReach) * GetObjectScale());
SetCombatReach((IsPet() ? SharedConst.DefaultPlayerCombatReach : minfo.CombatReach) * GetObjectScale());
}
}
@@ -2756,7 +2756,7 @@ namespace Game.Entities
public void RelocateStationaryPosition(float x, float y, float z, float o) { StationaryPosition.Relocate(x, y, z, o); }
//! Object distance/size - overridden from Object._IsWithinDist. Needs to take in account proper GO size.
public override bool _IsWithinDist(WorldObject obj, float dist2compare, bool is3D)
public override bool _IsWithinDist(WorldObject obj, float dist2compare, bool is3D, bool incOwnRadius, bool incTargetRadius)
{
//! Following check does check 3d distance
return IsInRange(obj.GetPositionX(), obj.GetPositionY(), obj.GetPositionZ(), dist2compare);
+7
View File
@@ -271,6 +271,13 @@ namespace Game.Entities
return true;
}
public bool IsWithinDoubleVerticalCylinder(Position center, float radius, float height)
{
float verticalDelta = GetPositionZ() - center.GetPositionZ();
return IsInDist2d(center, radius) && Math.Abs(verticalDelta) <= height;
}
public bool HasInArc(float arc, Position obj, float border = 2.0f)
{
// always have self in arc
+39 -51
View File
@@ -1406,7 +1406,7 @@ namespace Game.Entities
{
if (x == 0.0f && y == 0.0f && z == 0.0f)
{
GetClosePoint(out x, out y, out z, GetObjectSize());
GetClosePoint(out x, out y, out z, GetCombatReach());
ang = GetOrientation();
}
Position pos = new Position();
@@ -1434,7 +1434,7 @@ namespace Game.Entities
{
if (x == 0 && y == 0 && z == 0)
{
GetClosePoint(out x, out y, out z, GetObjectSize());
GetClosePoint(out x, out y, out z, GetCombatReach());
ang = GetOrientation();
}
@@ -1569,20 +1569,12 @@ namespace Game.Entities
return playerList;
}
public float GetObjectSize()
{
Unit thisUnit = ToUnit();
if (thisUnit != null)
return thisUnit.m_unitData.CombatReach;
return SharedConst.DefaultWorldObjectSize;
}
public bool IsInPhase(WorldObject obj)
{
return GetPhaseShift().CanSee(obj.GetPhaseShift());
}
public virtual float GetCombatReach() { return 0.0f; } // overridden (only) in Unit
public PhaseShift GetPhaseShift() { return _phaseShift; }
public void SetPhaseShift(PhaseShift phaseShift) { _phaseShift = new PhaseShift(phaseShift); }
public PhaseShift GetSuppressedPhaseShift() { return _suppressedPhaseShift; }
@@ -1772,39 +1764,32 @@ namespace Game.Entities
public float GetDistanceZ(WorldObject obj)
{
float dz = Math.Abs(GetPositionZ() - obj.GetPositionZ());
float sizefactor = GetObjectSize() + obj.GetObjectSize();
float sizefactor = GetCombatReach() + obj.GetCombatReach();
float dist = dz - sizefactor;
return (dist > 0 ? dist : 0);
}
public virtual bool _IsWithinDist(WorldObject obj, float dist2compare, bool is3D)
public virtual bool _IsWithinDist(WorldObject obj, float dist2compare, bool is3D, bool incOwnRadius = true, bool incTargetRadius = true)
{
float sizefactor = GetObjectSize() + obj.GetObjectSize();
float sizefactor = 0;
sizefactor += incOwnRadius ? GetCombatReach() : 0.0f;
sizefactor += incTargetRadius ? obj.GetCombatReach() : 0.0f;
float maxdist = dist2compare + sizefactor;
Position thisOrTransport = this;
Position objOrObjTransport = obj;
if (GetTransport() && obj.GetTransport() != null && obj.GetTransport().GetGUID() == GetTransport().GetGUID())
{
float dtx = m_movementInfo.transport.pos.posX - obj.m_movementInfo.transport.pos.posX;
float dty = m_movementInfo.transport.pos.posY - obj.m_movementInfo.transport.pos.posY;
float disttsq = dtx * dtx + dty * dty;
if (is3D)
{
float dtz = m_movementInfo.transport.pos.posZ - obj.m_movementInfo.transport.pos.posZ;
disttsq += dtz * dtz;
}
return disttsq < (maxdist * maxdist);
thisOrTransport = m_movementInfo.transport.pos;
objOrObjTransport = obj.m_movementInfo.transport.pos;
}
float dx = GetPositionX() - obj.GetPositionX();
float dy = GetPositionY() - obj.GetPositionY();
float distsq = dx * dx + dy * dy;
if (is3D)
{
float dz = GetPositionZ() - obj.GetPositionZ();
distsq += dz * dz;
}
return distsq < maxdist * maxdist;
return thisOrTransport.IsInDist(objOrObjTransport, maxdist);
else
return thisOrTransport.IsInDist2d(objOrObjTransport, maxdist);
}
public bool IsWithinLOSInMap(WorldObject obj, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
@@ -1823,31 +1808,31 @@ namespace Game.Entities
public float GetDistance(WorldObject obj)
{
float d = GetExactDist(obj.GetPosition()) - GetObjectSize() - obj.GetObjectSize();
float d = GetExactDist(obj.GetPosition()) - GetCombatReach() - obj.GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
public float GetDistance(Position pos)
{
float d = GetExactDist(pos) - GetObjectSize();
float d = GetExactDist(pos) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
public float GetDistance(float x, float y, float z)
{
float d = GetExactDist(x, y, z) - GetObjectSize();
float d = GetExactDist(x, y, z) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
public float GetDistance2d(WorldObject obj)
{
float d = GetExactDist2d(obj.GetPosition()) - GetObjectSize() - obj.GetObjectSize();
float d = GetExactDist2d(obj.GetPosition()) - GetCombatReach() - obj.GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
public float GetDistance2d(float x, float y)
{
float d = GetExactDist2d(x, y) - GetObjectSize();
float d = GetExactDist2d(x, y) - GetCombatReach();
return d > 0.0f ? d : 0.0f;
}
@@ -1868,22 +1853,22 @@ namespace Game.Entities
public bool IsWithinDist3d(float x, float y, float z, float dist)
{
return IsInDist(x, y, z, dist + GetObjectSize());
return IsInDist(x, y, z, dist + GetCombatReach());
}
public bool IsWithinDist3d(Position pos, float dist)
{
return IsInDist(pos, dist + GetObjectSize());
return IsInDist(pos, dist + GetCombatReach());
}
public bool IsWithinDist2d(float x, float y, float dist)
{
return IsInDist2d(x, y, dist + GetObjectSize());
return IsInDist2d(x, y, dist + GetCombatReach());
}
public bool IsWithinDist2d(Position pos, float dist)
{
return IsInDist2d(pos, dist + GetObjectSize());
return IsInDist2d(pos, dist + GetCombatReach());
}
public bool IsWithinDist(WorldObject obj, float dist2compare, bool is3D = true)
@@ -1891,9 +1876,9 @@ namespace Game.Entities
return obj != null && _IsWithinDist(obj, dist2compare, is3D);
}
public bool IsWithinDistInMap(WorldObject obj, float dist2compare, bool is3D = true)
public bool IsWithinDistInMap(WorldObject obj, float dist2compare, bool is3D = true, bool incOwnRadius = true, bool incTargetRadius = true)
{
return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D);
return obj && IsInMap(obj) && IsInPhase(obj) && _IsWithinDist(obj, dist2compare, is3D, incOwnRadius, incTargetRadius);
}
public bool IsWithinLOS(float ox, float oy, float oz, ModelIgnoreFlags ignoreFlags = ModelIgnoreFlags.Nothing)
@@ -1916,7 +1901,7 @@ namespace Game.Entities
{
Vector3 vThis = new Vector3(GetPositionX(), GetPositionY(), GetPositionZ());
Vector3 vObj = new Vector3(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ());
Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * Math.Min(dest.GetExactDist(GetPosition()), GetObjectSize());
Vector3 contactPoint = vThis + (vObj - vThis).directionOrZero() * Math.Min(dest.GetExactDist(GetPosition()), GetCombatReach());
return new Position(contactPoint.X, contactPoint.Y, contactPoint.Z, GetAngle(contactPoint.X, contactPoint.Y));
}
@@ -1963,7 +1948,7 @@ namespace Game.Entities
distsq += dz * dz;
}
float sizefactor = GetObjectSize() + obj.GetObjectSize();
float sizefactor = GetCombatReach() + obj.GetCombatReach();
// check only for real range
if (minRange > 0.0f)
@@ -1977,7 +1962,10 @@ namespace Game.Entities
return distsq < maxdist * maxdist;
}
public bool IsInBetween(WorldObject obj1, WorldObject obj2, float size = 0) { return obj1 && obj2 && IsInBetween(obj1.GetPosition(), obj2.GetPosition(), size); }
public bool IsInBetween(WorldObject obj1, WorldObject obj2, float size = 0)
{
return obj1 && obj2 && IsInBetween(obj1.GetPosition(), obj2.GetPosition(), size);
}
bool IsInBetween(Position pos1, Position pos2, float size)
{
float dist = GetExactDist2d(pos1);
@@ -1987,7 +1975,7 @@ namespace Game.Entities
return false;
if (size == 0)
size = GetObjectSize() / 2;
size = GetCombatReach() / 2;
float angle = pos1.GetAngle(pos2);
@@ -2112,8 +2100,8 @@ namespace Game.Entities
public void GetNearPoint2D(out float x, out float y, float distance2d, float absAngle)
{
x = (float)(GetPositionX() + (GetObjectSize() + distance2d) * Math.Cos(absAngle));
y = (float)(GetPositionY() + (GetObjectSize() + distance2d) * Math.Sin(absAngle));
x = (float)(GetPositionX() + (GetCombatReach() + distance2d) * Math.Cos(absAngle));
y = (float)(GetPositionY() + (GetCombatReach() + distance2d) * Math.Sin(absAngle));
GridDefines.NormalizeMapCoord(ref x);
GridDefines.NormalizeMapCoord(ref y);
@@ -2184,7 +2172,7 @@ namespace Game.Entities
public void GetContactPoint(WorldObject obj, out float x, out float y, out float z, float distance2d = 0.5f)
{
// angle to face `obj` to `this` using distance includes size of `obj`
GetNearPoint(obj, out x, out y, out z, obj.GetObjectSize(), distance2d, GetAngle(obj));
GetNearPoint(obj, out x, out y, out z, obj.GetCombatReach(), distance2d, GetAngle(obj));
}
public void MovePosition(ref Position pos, float dist, float angle)
+2 -2
View File
@@ -180,7 +180,7 @@ namespace Game.Entities
float px, py, pz;
if (IsCritter())
{
owner.GetClosePoint(out px, out py, out pz, GetObjectSize(), SharedConst.PetFollowDist, GetFollowAngle());
owner.GetClosePoint(out px, out py, out pz, GetCombatReach(), SharedConst.PetFollowDist, GetFollowAngle());
Relocate(px, py, pz, owner.GetOrientation());
if (!IsPositionValid())
@@ -233,7 +233,7 @@ namespace Game.Entities
SynchronizeLevelWithOwner();
// Set pet's position after setting level, its size depends on it
owner.GetClosePoint(out px, out py, out pz, GetObjectSize(), SharedConst.PetFollowDist, GetFollowAngle());
owner.GetClosePoint(out px, out py, out pz, GetCombatReach(), SharedConst.PetFollowDist, GetFollowAngle());
Relocate(px, py, pz, owner.GetOrientation());
if (!IsPositionValid())
{
+2 -2
View File
@@ -6528,8 +6528,8 @@ namespace Game.Entities
public override void SetObjectScale(float scale)
{
base.SetObjectScale(scale);
SetBoundingRadius(scale * SharedConst.DefaultWorldObjectSize);
SetCombatReach(scale * SharedConst.DefaultCombatReach);
SetBoundingRadius(scale * SharedConst.DefaultPlayerBoundingRadius);
SetCombatReach(scale * SharedConst.DefaultPlayerCombatReach);
if (IsInWorld)
SendMovementSetCollisionHeight(scale * GetCollisionHeight(IsMounted()));
}
+1 -1
View File
@@ -546,7 +546,7 @@ namespace Game.Entities
return attackerList;
}
public float GetCombatReach() { return m_unitData.CombatReach; }
public override float GetCombatReach() { return m_unitData.CombatReach; }
public void SetCombatReach(float combatReach) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.CombatReach), combatReach); }
public float GetBoundingRadius() { return m_unitData.BoundingRadius; }
public void SetBoundingRadius(float boundingRadius) { SetUpdateFieldValue(m_values.ModifyValue(m_unitData).ModifyValue(m_unitData.BoundingRadius), boundingRadius); }
+1 -1
View File
@@ -603,7 +603,7 @@ namespace Game.Entities
{
float combat_reach = GetCombatReach();
if (combat_reach < 0.1f)
combat_reach = SharedConst.DefaultCombatReach;
combat_reach = SharedConst.DefaultPlayerCombatReach;
int attacker_number = GetAttackers().Count;
if (attacker_number > 0)
+1 -1
View File
@@ -2391,7 +2391,7 @@ namespace Game
}
if (modelInfo.CombatReach < 0.1f)
modelInfo.CombatReach = SharedConst.DefaultCombatReach;
modelInfo.CombatReach = SharedConst.DefaultPlayerCombatReach;
CreatureModelDataRecord modelData = CliDB.CreatureModelDataStorage.LookupByKey(creatureDisplay.ModelID);
if (modelData != null)
+1 -1
View File
@@ -120,7 +120,7 @@ namespace Game.Maps
{
//we should increase search radius by object's radius, otherwise
//we could have problems with huge creatures, which won't attack nearest players etc
Visit(standing_cell, visitor, map, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetObjectSize());
Visit(standing_cell, visitor, map, obj.GetPositionX(), obj.GetPositionY(), radius + obj.GetCombatReach());
}
public void Visit(CellCoord standing_cell, Visitor visitor, Map map, float x_off, float y_off, float radius)
+53 -8
View File
@@ -1610,37 +1610,55 @@ namespace Game.Maps
public class AnyFriendlyUnitInObjectRangeCheck : ICheck<Unit>
{
public AnyFriendlyUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool playerOnly = false)
public AnyFriendlyUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
{
i_obj = obj;
i_funit = funit;
i_range = range;
i_playerOnly = playerOnly;
i_incOwnRadius = incOwnRadius;
i_incTargetRadius = incTargetRadius;
}
public bool Invoke(Unit u)
{
if (u.IsAlive() && i_obj.IsWithinDistInMap(u, i_range) && i_funit.IsFriendlyTo(u) && (!i_playerOnly || u.IsTypeId(TypeId.Player)))
return true;
else
if (!u.IsAlive())
return false;
float searchRadius = i_range;
if (i_incOwnRadius)
searchRadius += i_obj.GetCombatReach();
if (i_incTargetRadius)
searchRadius += u.GetCombatReach();
if (!u.IsInMap(i_obj) || !u.IsInPhase(i_obj) || !u.IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius))
return false;
if (!i_funit.IsFriendlyTo(u))
return false;
return !i_playerOnly || u.GetTypeId() == TypeId.Player;
}
WorldObject i_obj;
Unit i_funit;
float i_range;
bool i_playerOnly;
bool i_incOwnRadius;
bool i_incTargetRadius;
}
public class AnyGroupedUnitInObjectRangeCheck : ICheck<Unit>
{
public AnyGroupedUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool raid, bool playerOnly = false)
public AnyGroupedUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, bool raid, bool playerOnly = false, bool incOwnRadius = true, bool incTargetRadius = true)
{
_source = obj;
_refUnit = funit;
_range = range;
_raid = raid;
_playerOnly = playerOnly;
i_incOwnRadius = incOwnRadius;
i_incTargetRadius = incTargetRadius;
}
public bool Invoke(Unit u)
@@ -1656,7 +1674,19 @@ namespace Game.Maps
else if (!_refUnit.IsInPartyWith(u))
return false;
return !_refUnit.IsHostileTo(u) && u.IsAlive() && _source.IsWithinDistInMap(u, _range);
if (_refUnit.IsHostileTo(u))
return false;
if (!u.IsAlive())
return false;
float searchRadius = _range;
if (i_incOwnRadius)
searchRadius += _source.GetCombatReach();
if (i_incTargetRadius)
searchRadius += u.GetCombatReach();
return u.IsInMap(_source) && u.IsInPhase(_source) && u.IsWithinDoubleVerticalCylinder(_source, searchRadius, searchRadius);
}
WorldObject _source;
@@ -1664,6 +1694,8 @@ namespace Game.Maps
float _range;
bool _raid;
bool _playerOnly;
bool i_incOwnRadius;
bool i_incTargetRadius;
}
public class AnyUnitInObjectRangeCheck : ICheck<Unit>
@@ -1717,12 +1749,14 @@ namespace Game.Maps
public class AnyAoETargetUnitInObjectRangeCheck : ICheck<Unit>
{
public AnyAoETargetUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, SpellInfo spellInfo = null)
public AnyAoETargetUnitInObjectRangeCheck(WorldObject obj, Unit funit, float range, SpellInfo spellInfo = null, bool incOwnRadius = true, bool incTargetRadius = true)
{
i_obj = obj;
i_funit = funit;
_spellInfo = spellInfo;
i_range = range;
i_incOwnRadius = incOwnRadius;
i_incTargetRadius = incTargetRadius;
if (_spellInfo == null)
{
@@ -1741,13 +1775,24 @@ namespace Game.Maps
if (_spellInfo != null && _spellInfo.HasAttribute(SpellAttr3.OnlyTargetPlayers) && !u.IsPlayer())
return false;
return i_funit._IsValidAttackTarget(u, _spellInfo, i_obj.IsTypeId(TypeId.DynamicObject) ? i_obj : null) && i_obj.IsWithinDistInMap(u, i_range);
if (!i_funit._IsValidAttackTarget(u, _spellInfo, i_obj.GetTypeId() == TypeId.DynamicObject ? i_obj : null))
return false;
float searchRadius = i_range;
if (i_incOwnRadius)
searchRadius += i_obj.GetCombatReach();
if (i_incTargetRadius)
searchRadius += u.GetCombatReach();
return u.IsInMap(i_obj) && u.IsInPhase(i_obj) && u.IsWithinDoubleVerticalCylinder(i_obj, searchRadius, searchRadius);
}
WorldObject i_obj;
Unit i_funit;
SpellInfo _spellInfo;
float i_range;
bool i_incOwnRadius;
bool i_incTargetRadius;
}
public class AnyDeadUnitCheck : ICheck<Unit>
@@ -173,7 +173,7 @@ namespace Game.Movement
float size = 0;
// Pets need special handling.
// We need to subtract GetObjectSize() because it gets added back further down the chain
// We need to subtract GetCombatReach() because it gets added back further down the chain
// and that makes pets too far away. Subtracting it allows pets to properly
// be (GetCombatReach() + i_offset) away.
// Only applies when i_target is pet's owner otherwise pets and mobs end up
@@ -181,12 +181,12 @@ namespace Game.Movement
if (owner.IsPet() && Target.IsTypeId(TypeId.Player))
{
dist = 1.0f;// target.GetCombatReach();
size = 1.0f;// target.GetCombatReach() - target.GetObjectSize();
size = 1.0f;// target.GetCombatReach() - target.GetCombatReach();
}
else
{
dist = offset + 1.0f;
size = owner.GetObjectSize();
size = owner.GetCombatReach();
}
if (Target.IsWithinDistInMap(owner, dist))
+2 -2
View File
@@ -359,7 +359,7 @@ namespace Game.Movement
float dist = 2 * moveTimeHalf * speedXY;
float max_height = -MoveSpline.ComputeFallElevation(moveTimeHalf, false, -speedZ);
_owner.GetNearPoint(_owner, out x, out y, out z, _owner.GetObjectSize(), dist, _owner.GetAngle(srcX, srcY) + MathFunctions.PI);
_owner.GetNearPoint(_owner, out x, out y, out z, _owner.GetCombatReach(), dist, _owner.GetAngle(srcX, srcY) + MathFunctions.PI);
MoveSplineInit init = new MoveSplineInit(_owner);
init.MoveTo(x, y, z);
@@ -383,7 +383,7 @@ namespace Game.Movement
float moveTimeHalf = (float)(speedZ / gravity);
float dist = 2 * moveTimeHalf * speedXY;
_owner.GetClosePoint(out x, out y, out z, _owner.GetObjectSize(), dist, angle);
_owner.GetClosePoint(out x, out y, out z, _owner.GetCombatReach(), dist, angle);
MoveJump(x, y, z, 0.0f, speedXY, speedZ);
}
+2 -2
View File
@@ -377,14 +377,14 @@ namespace Game.Scripting
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.SingleFriend - 1);
// Spell targets AoE friends.
if (effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty || effect.TargetA.GetTarget() == Targets.UnitLastareaParty ||
if (effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty || effect.TargetA.GetTarget() == Targets.UnitLastAreaParty ||
effect.TargetA.GetTarget() == Targets.SrcCaster)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AoeFriend - 1);
// Spell targets any friend (or self).
if (effect.TargetA.GetTarget() == Targets.UnitCaster || effect.TargetA.GetTarget() == Targets.UnitAlly ||
effect.TargetA.GetTarget() == Targets.UnitParty || effect.TargetA.GetTarget() == Targets.UnitCasterAreaParty ||
effect.TargetA.GetTarget() == Targets.UnitLastareaParty || effect.TargetA.GetTarget() == Targets.SrcCaster)
effect.TargetA.GetTarget() == Targets.UnitLastAreaParty || effect.TargetA.GetTarget() == Targets.SrcCaster)
spellSummaryStorage[i].Targets |= 1 << ((int)SelectTargetType.AnyFriend - 1);
// Make sure that this spell includes a damage effect.
+5 -5
View File
@@ -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
View File
@@ -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)
+9 -9
View File
@@ -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
+28
View File
@@ -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;
@@ -102,7 +102,7 @@ namespace Scripts.Northrend.DraktharonKeep.KingDred
DoCastVictim(SpellIds.RaptorCall);
float x, y, z;
me.GetClosePoint(out x, out y, out z, me.GetObjectSize() / 3, 10.0f);
me.GetClosePoint(out x, out y, out z, me.GetCombatReach() / 3, 10.0f);
me.SummonCreature(RandomHelper.RAND(DTKCreatureIds.DrakkariGutripper, DTKCreatureIds.DrakkariScytheclaw), x, y, z, 0, TempSummonType.DeadDespawn, 1000);
task.Repeat();
});
@@ -137,7 +137,7 @@ namespace Scripts.Northrend.FrozenHalls.ForgeOfSouls.Bronjahm
{
summons.Summon(summon);
summon.SetReactState(ReactStates.Passive);
summon.GetMotionMaster().MoveFollow(me, me.GetObjectSize(), 0.0f);
summon.GetMotionMaster().MoveFollow(me, me.GetCombatReach(), 0.0f);
summon.CastSpell(summon, SpellIds.PurpleBanishVisual, true);
}
}
@@ -359,7 +359,7 @@ namespace Scripts.Northrend.IcecrownCitadel
{
float ang = Position.NormalizeOrientation(pos.GetAngle(me));
me.SetOrientation(ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 5.0f - owner.GetObjectSize(), ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 5.0f - owner.GetCombatReach(), ang);
}
else
{
@@ -372,7 +372,7 @@ namespace Scripts.Northrend.IcecrownCitadel
float ang = Position.NormalizeOrientation(pos.GetAngle(target));
me.SetOrientation(ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 15.0f - owner.GetObjectSize(), ang);
owner.GetNearPoint2D(out pos.posX, out pos.posY, 15.0f - owner.GetCombatReach(), ang);
}
me.NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me.GetPositionZ(), me.GetOrientation());
@@ -471,7 +471,7 @@ namespace Scripts.Northrend.IcecrownCitadel
{
targets.Clear();
// select any unit but not the tank (by owners threatlist)
Unit target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 1, -GetCaster().GetObjectSize(), true, -(int)Spells.Impaled);
Unit target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 1, -GetCaster().GetCombatReach(), true, -(int)Spells.Impaled);
if (!target)
target = GetCaster().GetAI().SelectTarget(SelectAggroTarget.Random, 0, 0.0f, true); // or the tank if its solo
if (!target)
+1 -1
View File
@@ -452,7 +452,7 @@ namespace Scripts.World
uint BirdEntry = 0;
float fX, fY, fZ;
go.GetClosePoint(out fX, out fY, out fZ, go.GetObjectSize(), SharedConst.InteractionDistance);
go.GetClosePoint(out fX, out fY, out fZ, go.GetCombatReach(), SharedConst.InteractionDistance);
switch (go.GetEntry())
{
+1 -1
View File
@@ -250,7 +250,7 @@ namespace Scripts.World
return true;
float x, y, z;
go.GetClosePoint(out x, out y, out z, go.GetObjectSize() / 3, 7.0f);
go.GetClosePoint(out x, out y, out z, go.GetCombatReach() / 3, 7.0f);
go.SummonGameObject(ItemScriptConst.GoHighQualityFur, go, Quaternion.fromEulerAnglesZYX(go.GetOrientation(), 0.0f, 0.0f), 1);
TempSummon summon = player.SummonCreature(ItemScriptConst.NpcNesingwaryTrapper, x, y, z, go.GetOrientation(), TempSummonType.DeadDespawn, 1000);
if (summon)