diff --git a/Source/Game/AI/CoreAI/CreatureAI.cs b/Source/Game/AI/CoreAI/CreatureAI.cs index 4fadcfc91..3e5e86ba2 100644 --- a/Source/Game/AI/CoreAI/CreatureAI.cs +++ b/Source/Game/AI/CoreAI/CreatureAI.cs @@ -158,7 +158,7 @@ namespace Game.AI // Face the unit (stealthed player) and set distracted state for 5 seconds me.GetMotionMaster().MoveDistract(5 * Time.InMilliseconds); me.StopMoving(); - me.SetFacingTo(me.GetAngle(who)); + me.SetFacingTo(me.GetAbsoluteAngle(who)); } // Called for reaction at stopping attack at no attackers or targets diff --git a/Source/Game/AI/PlayerAI/PlayerAI.cs b/Source/Game/AI/PlayerAI/PlayerAI.cs index 0bbe7ec92..41e89d06a 100644 --- a/Source/Game/AI/PlayerAI/PlayerAI.cs +++ b/Source/Game/AI/PlayerAI/PlayerAI.cs @@ -1296,7 +1296,7 @@ namespace Game.AI if (me.IsStopped() && !me.HasUnitState(UnitState.CannotTurn)) { - float targetAngle = me.GetAngle(target); + float targetAngle = me.GetAbsoluteAngle(target); if (_forceFacing || Math.Abs(me.GetOrientation() - targetAngle) > 0.4f) { me.SetFacingTo(targetAngle); diff --git a/Source/Game/Chat/Commands/MiscCommands.cs b/Source/Game/Chat/Commands/MiscCommands.cs index d48fc5082..17896839e 100644 --- a/Source/Game/Chat/Commands/MiscCommands.cs +++ b/Source/Game/Chat/Commands/MiscCommands.cs @@ -366,7 +366,7 @@ namespace Game.Chat float x, y, z; target.GetContactPoint(_player, out x, out y, out z); - _player.TeleportTo(target.GetMapId(), x, y, z, _player.GetAngle(target), TeleportToOptions.GMMode); + _player.TeleportTo(target.GetMapId(), x, y, z, _player.GetAbsoluteAngle(target), TeleportToOptions.GMMode); PhasingHandler.InheritPhaseShift(_player, target); _player.UpdateObjectVisibility(); } diff --git a/Source/Game/Chat/Commands/NPCCommands.cs b/Source/Game/Chat/Commands/NPCCommands.cs index 35c4c11d1..fb62bacf9 100644 --- a/Source/Game/Chat/Commands/NPCCommands.cs +++ b/Source/Game/Chat/Commands/NPCCommands.cs @@ -806,7 +806,7 @@ namespace Game.Chat return false; Player chr = handler.GetSession().GetPlayer(); - float followAngle = (creature.GetAngle(chr) - chr.GetOrientation()) * 180.0f / MathF.PI; + float followAngle = (creature.GetAbsoluteAngle(chr) - chr.GetOrientation()) * 180.0f / MathF.PI; float followDist = MathF.Sqrt(MathF.Pow(chr.GetPositionX() - creature.GetPositionX(), 2f) + MathF.Pow(chr.GetPositionY() - creature.GetPositionY(), 2f)); uint groupAI = 0; FormationMgr.AddFormationMember(lowguid, followAngle, followDist, leaderGUID, groupAI); diff --git a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs index 40fe34fb0..4b3991b2a 100644 --- a/Source/Game/Entities/AreaTrigger/AreaTrigger.cs +++ b/Source/Game/Entities/AreaTrigger/AreaTrigger.cs @@ -889,7 +889,7 @@ namespace Game.Entities if (GetTemplate() != null && GetTemplate().HasFlag(AreaTriggerFlags.HasFaceMovementDir)) { Vector3 nextPoint = _spline.GetPoint(lastPositionIndex + 1); - orientation = GetAngle(nextPoint.X, nextPoint.Y); + orientation = GetAbsoluteAngle(nextPoint.X, nextPoint.Y); } GetMap().AreaTriggerRelocation(this, currentPosition.X, currentPosition.Y, currentPosition.Z, orientation); diff --git a/Source/Game/Entities/Object/Position.cs b/Source/Game/Entities/Object/Position.cs index 5b64e932e..a96734b86 100644 --- a/Source/Game/Entities/Object/Position.cs +++ b/Source/Game/Entities/Object/Position.cs @@ -107,13 +107,19 @@ namespace Game.Entities return GridDefines.IsValidMapCoord(posX, posY, posZ, Orientation); } + float ToRelativeAngle(float absAngle) + { + return NormalizeOrientation(absAngle - Orientation); + } + public float GetRelativeAngle(Position pos) { - return GetAngle(pos) - Orientation; + return ToRelativeAngle(GetAbsoluteAngle(pos)); } + public float GetRelativeAngle(float x, float y) { - return GetAngle(x, y) - Orientation; + return ToRelativeAngle(GetAbsoluteAngle(x, y)); } public void GetPosition(out float x, out float y) @@ -214,7 +220,7 @@ namespace Game.Entities return dx * dx + dy * dy; } - public float GetAngle(float x, float y) + public float GetAbsoluteAngle(float x, float y) { float dx = x - GetPositionX(); float dy = y - GetPositionY(); @@ -223,18 +229,24 @@ namespace Game.Entities ang = ang >= 0 ? ang : 2 * MathFunctions.PI + ang; return ang; } - public float GetAngle(Position pos) + public float GetAbsoluteAngle(Position pos) { if (pos == null) return 0; - return GetAngle(pos.GetPositionX(), pos.GetPositionY()); + return GetAbsoluteAngle(pos.GetPositionX(), pos.GetPositionY()); } + float ToAbsoluteAngle(float relAngle) + { + return NormalizeOrientation(relAngle + Orientation); + } + public bool IsInDist(float x, float y, float z, float dist) { return GetExactDistSq(x, y, z) < dist * dist; } + public bool IsInDist(Position pos, float dist) { return GetExactDistSq(pos) < dist * dist; @@ -286,7 +298,7 @@ namespace Game.Entities return IsInDist2d(center, radius) && Math.Abs(verticalDelta) <= height; } - public bool HasInArc(float arc, Position obj, float border = 2.0f, float? orientation = null) + public bool HasInArc(float arc, Position obj, float border = 2.0f) { // always have self in arc if (obj == this) @@ -295,11 +307,8 @@ namespace Game.Entities // move arc to range 0.. 2*pi arc = NormalizeOrientation(arc); - float angle = GetAngle(obj); - angle -= orientation.HasValue ? orientation.Value : GetOrientation(); - // move angle to range -pi ... +pi - angle = NormalizeOrientation(angle); + float angle = GetRelativeAngle(obj); if (angle > MathFunctions.PI) angle -= 2.0f * MathFunctions.PI; @@ -308,13 +317,13 @@ namespace Game.Entities return ((angle >= lborder) && (angle <= rborder)); } - public bool HasInLine(Position pos, float objSize, float width, float? orientation = null) + public bool HasInLine(Position pos, float objSize, float width) { - if (!HasInArc(MathFunctions.PI, pos, 2.0f, orientation)) + if (!HasInArc(MathFunctions.PI, pos, 2.0f)) return false; width += objSize; - float angle = GetAngle(pos) - (orientation.HasValue ? orientation.Value : GetOrientation()); + float angle = GetRelativeAngle(pos); return Math.Abs(Math.Sin(angle)) * GetExactDist2d(pos.GetPositionX(), pos.GetPositionY()) < width; } diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index bf0529987..e4fee119b 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -2973,7 +2973,7 @@ namespace Game.Entities Vector3 vObj = new(dest.GetPositionX(), dest.GetPositionY(), dest.GetPositionZ()); 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)); + return new Position(contactPoint.X, contactPoint.Y, contactPoint.Z, GetAbsoluteAngle(contactPoint.X, contactPoint.Y)); } void GetHitSpherePointFor(Position dest, out float x, out float y, out float z) @@ -3047,7 +3047,7 @@ namespace Game.Entities if (size == 0) size = GetCombatReach() / 2; - float angle = pos1.GetAngle(pos2); + float angle = pos1.GetAbsoluteAngle(pos2); // not using sqrt() for performance return (size * size) >= GetExactDist2dSq(pos1.GetPositionX() + (float)Math.Cos(angle) * dist, pos1.GetPositionY() + (float)Math.Sin(angle) * dist); @@ -3159,7 +3159,7 @@ namespace Game.Entities { GetNearPoint2D(out x, out y, distance2d + searcher_size, absAngle); z = GetPositionZ(); - UpdateAllowedPositionZ(x, y, ref z); + (searcher ?? this).UpdateAllowedPositionZ(x, y, ref z); // if detection disabled, return first point if (!WorldConfig.GetBoolValue(WorldCfg.DetectPosCollision)) @@ -3179,7 +3179,7 @@ namespace Game.Entities { GetNearPoint2D(out x, out y, distance2d + searcher_size, absAngle + angle); z = GetPositionZ(); - UpdateAllowedPositionZ(x, y, ref z); + (searcher ?? this).UpdateAllowedPositionZ(x, y, ref z); if (IsWithinLOS(x, y, z)) return; } @@ -3190,10 +3190,10 @@ namespace Game.Entities z = first_z; } - public void GetClosePoint(out float x, out float y, out float z, float size, float distance2d = 0, float angle = 0) + public void GetClosePoint(out float x, out float y, out float z, float size, float distance2d = 0, float relAngle = 0) { // angle calculated from current orientation - GetNearPoint(null, out x, out y, out z, size, distance2d, GetOrientation() + angle); + GetNearPoint(null, out x, out y, out z, size, distance2d, GetOrientation() + relAngle); } public Position GetNearPosition(float dist, float angle) @@ -3220,7 +3220,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.GetCombatReach(), distance2d, GetAngle(obj)); + GetNearPoint(obj, out x, out y, out z, obj.GetCombatReach(), distance2d, GetAbsoluteAngle(obj)); } public void MovePosition(Position pos, float dist, float angle) diff --git a/Source/Game/Entities/Player/CinematicManager.cs b/Source/Game/Entities/Player/CinematicManager.cs index bc7344cc3..49b5f6723 100644 --- a/Source/Game/Entities/Player/CinematicManager.cs +++ b/Source/Game/Entities/Player/CinematicManager.cs @@ -136,7 +136,7 @@ namespace Game.Entities lastPosition = new Position(cam.locations.X, cam.locations.Y, cam.locations.Z, cam.locations.W); lastTimestamp = cam.timeStamp; } - float angle = lastPosition.GetAngle(nextPosition); + float angle = lastPosition.GetAbsoluteAngle(nextPosition); angle -= lastPosition.GetOrientation(); if (angle < 0) angle += 2 * MathFunctions.PI; diff --git a/Source/Game/Entities/Unit/Unit.Movement.cs b/Source/Game/Entities/Unit/Unit.Movement.cs index 485f3e3c6..d24096664 100644 --- a/Source/Game/Entities/Unit/Unit.Movement.cs +++ b/Source/Game/Entities/Unit/Unit.Movement.cs @@ -188,7 +188,7 @@ namespace Game.Entities public void SetInFront(WorldObject target) { if (!HasUnitState(UnitState.CannotTurn)) - Orientation = GetAngle(target.GetPosition()); + Orientation = GetAbsoluteAngle(target.GetPosition()); } public void SetFacingTo(float ori, bool force = true) @@ -210,7 +210,7 @@ namespace Game.Entities return; // @todo figure out under what conditions creature will move towards object instead of facing it where it currently is. - SetFacingTo(GetAngle(obj)); + SetFacingTo(GetAbsoluteAngle(obj)); } public void MonsterMoveWithSpeed(float x, float y, float z, float speed, bool generatePath = false, bool forceDestination = false) @@ -387,7 +387,7 @@ namespace Game.Entities float x, y, z; obj.GetContactPoint(this, out x, out y, out z); float speedXY = GetExactDist2d(x, y) * 10.0f / speedZ; - GetMotionMaster().MoveJump(x, y, z, GetAngle(obj), speedXY, speedZ, EventId.Jump, withOrientation); + GetMotionMaster().MoveJump(x, y, z, GetAbsoluteAngle(obj), speedXY, speedZ, EventId.Jump, withOrientation); } public void UpdateSpeed(UnitMoveType mtype) @@ -631,19 +631,6 @@ namespace Game.Entities return IsInDist(obj, objBoundaryRadius); } - public void GetRandomContactPoint(Unit obj, out float x, out float y, out float z, float distance2dMin, float distance2dMax) - { - float combat_reach = GetCombatReach(); - if (combat_reach < 0.1f) - combat_reach = SharedConst.DefaultPlayerCombatReach; - - int attacker_number = GetAttackers().Count; - if (attacker_number > 0) - --attacker_number; - GetNearPoint(obj, out x, out y, out z, obj.GetCombatReach(), distance2dMin + (distance2dMax - distance2dMin) * (float)RandomHelper.NextDouble() - , GetAngle(obj.GetPosition()) + (attacker_number != 0 ? MathFunctions.PiOver2 - MathFunctions.PI * (float)RandomHelper.NextDouble() * (float)attacker_number / combat_reach * 0.3f : 0.0f)); - } - public bool SetDisableGravity(bool disable) { if (disable == IsLevitating()) diff --git a/Source/Game/Movement/Generators/FleeingGenerator.cs b/Source/Game/Movement/Generators/FleeingGenerator.cs index b4e3e2863..bf21758ff 100644 --- a/Source/Game/Movement/Generators/FleeingGenerator.cs +++ b/Source/Game/Movement/Generators/FleeingGenerator.cs @@ -135,7 +135,7 @@ namespace Game.Movement { casterDistance = fleeTarget.GetDistance(owner); if (casterDistance > 0.2f) - casterAngle = fleeTarget.GetAngle(owner); + casterAngle = fleeTarget.GetAbsoluteAngle(owner); else casterAngle = RandomHelper.FRand(0.0f, 2.0f * MathF.PI); } diff --git a/Source/Game/Movement/Generators/TargetMovement.cs b/Source/Game/Movement/Generators/TargetMovement.cs index bd015e093..7283a4f5c 100644 --- a/Source/Game/Movement/Generators/TargetMovement.cs +++ b/Source/Game/Movement/Generators/TargetMovement.cs @@ -152,7 +152,7 @@ namespace Game.Movement if (hoverDiff != 0f) size = size > hoverDiff ? MathF.Sqrt(size * size - hoverDiff * hoverDiff) : 0.0f; - GetTarget().GetNearPoint(owner, out x, out y, out z, size, SharedConst.ContactDistance, GetTarget().GetAngle(owner)); + GetTarget().GetNearPoint(owner, out x, out y, out z, size, SharedConst.ContactDistance, GetTarget().GetAbsoluteAngle(owner)); } else { diff --git a/Source/Game/Movement/MotionMaster.cs b/Source/Game/Movement/MotionMaster.cs index 5b1bf650d..aed086cfd 100644 --- a/Source/Game/Movement/MotionMaster.cs +++ b/Source/Game/Movement/MotionMaster.cs @@ -277,7 +277,7 @@ namespace Game.Movement float distanceToTravel = _owner.GetExactDist2d(target) - distance; if (distanceToTravel > 0.0f) { - float angle = _owner.GetAngle(target); + float angle = _owner.GetAbsoluteAngle(target); float destx = _owner.GetPositionX() + distanceToTravel * (float)Math.Cos(angle); float desty = _owner.GetPositionY() + distanceToTravel * (float)Math.Sin(angle); MovePoint(id, destx, desty, target.GetPositionZ()); @@ -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.GetCombatReach(), dist, _owner.GetAngle(srcX, srcY) + MathFunctions.PI); + _owner.GetNearPoint(_owner, out x, out y, out z, _owner.GetCombatReach(), dist, _owner.GetAbsoluteAngle(srcX, srcY) + MathFunctions.PI); MoveSplineInit init = new(_owner); init.MoveTo(x, y, z); @@ -427,7 +427,7 @@ namespace Game.Movement { float step = 2 * MathFunctions.PI / stepCount * (clockwise ? -1.0f : 1.0f); Position pos = new(x, y, z, 0.0f); - float angle = pos.GetAngle(_owner.GetPositionX(), _owner.GetPositionY()); + float angle = pos.GetAbsoluteAngle(_owner.GetPositionX(), _owner.GetPositionY()); MoveSplineInit init = new(_owner); init.args.path = new Vector3[stepCount]; diff --git a/Source/Game/Movement/MoveSplineInit.cs b/Source/Game/Movement/MoveSplineInit.cs index 60043af78..729464ac4 100644 --- a/Source/Game/Movement/MoveSplineInit.cs +++ b/Source/Game/Movement/MoveSplineInit.cs @@ -192,7 +192,7 @@ namespace Game.Movement public void SetFacing(Unit target) { - args.facing.angle = unit.GetAngle(target); + args.facing.angle = unit.GetAbsoluteAngle(target); args.facing.target = target.GetGUID(); args.facing.type = MonsterMoveType.FacingTarget; } diff --git a/Source/Game/Spells/Spell.cs b/Source/Game/Spells/Spell.cs index e0f856a8a..7edc7fb0a 100644 --- a/Source/Game/Spells/Spell.cs +++ b/Source/Game/Spells/Spell.cs @@ -8332,25 +8332,22 @@ namespace Game.Spells public class WorldObjectSpellLineTargetCheck : WorldObjectSpellAreaTargetCheck { - Position _srcPosition; - Position _dstPosition; + Position _position; float _lineWidth; public WorldObjectSpellLineTargetCheck(Position srcPosition, Position dstPosition, float lineWidth, float range, WorldObject caster, SpellInfo spellInfo, SpellTargetCheckTypes selectionType, List condList, SpellTargetObjectTypes objectType) : base(range, caster, caster, caster, spellInfo, selectionType, condList, objectType) { - _srcPosition = srcPosition; - _dstPosition = dstPosition; + _position = srcPosition; _lineWidth = lineWidth; + + if (dstPosition != null && srcPosition != dstPosition) + _position.SetOrientation(srcPosition.GetAbsoluteAngle(dstPosition)); } public override bool Invoke(WorldObject target) { - float angle = _caster.GetOrientation(); - if (_srcPosition != _dstPosition) - angle = _srcPosition.GetAngle(_dstPosition); - - if (!_caster.HasInLine(target, target.GetCombatReach(), _lineWidth, angle)) + if (!_position.HasInLine(target, target.GetCombatReach(), _lineWidth)) return false; return base.Invoke(target); diff --git a/Source/Game/Spells/SpellEffects.cs b/Source/Game/Spells/SpellEffects.cs index bf56c83b8..1f67e5615 100644 --- a/Source/Game/Spells/SpellEffects.cs +++ b/Source/Game/Spells/SpellEffects.cs @@ -1927,7 +1927,7 @@ namespace Game.Spells unitTarget.GetMotionMaster().MoveDistract((uint)(damage * Time.InMilliseconds)); unitTarget.StopMoving(); - unitTarget.SetFacingTo(unitTarget.GetAngle(destTarget)); + unitTarget.SetFacingTo(unitTarget.GetAbsoluteAngle(destTarget)); } [SpellEffectHandler(SpellEffectName.Pickpocket)] @@ -4863,7 +4863,7 @@ namespace Game.Spells summon.SetFaction(unitCaster.GetFaction()); if (summon.HasUnitTypeMask(UnitTypeMask.Minion) && m_targets.HasDst()) - ((Minion)summon).SetFollowAngle(unitCaster.GetAngle(summon.GetPosition())); + ((Minion)summon).SetFollowAngle(unitCaster.GetAbsoluteAngle(summon.GetPosition())); if (summon.GetEntry() == 27893) { diff --git a/Source/Scripts/World/GameObject.cs b/Source/Scripts/World/GameObject.cs index 5f1bbb2c3..2ac85806b 100644 --- a/Source/Scripts/World/GameObject.cs +++ b/Source/Scripts/World/GameObject.cs @@ -431,7 +431,7 @@ namespace Scripts.World.GameObjects me.UseDoorOrButton(); int Random = (int)(RandomHelper.Rand32() % (CreatureIds.PrisonEntry.Length / sizeof(uint))); - Creature creature = player.SummonCreature(CreatureIds.PrisonEntry[Random], me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetAngle(player), TempSummonType.TimedDespawnOutOfCombat, 30000); + Creature creature = player.SummonCreature(CreatureIds.PrisonEntry[Random], me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetAbsoluteAngle(player), TempSummonType.TimedDespawnOutOfCombat, 30000); if (creature) { if (!creature.IsHostileTo(player)) @@ -485,7 +485,7 @@ namespace Scripts.World.GameObjects me.UseDoorOrButton(); int Random = (int)(RandomHelper.Rand32() % CreatureIds.StasisEntry.Length / sizeof(uint)); - player.SummonCreature(CreatureIds.StasisEntry[Random], me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetAngle(player), TempSummonType.TimedDespawnOutOfCombat, 30000); + player.SummonCreature(CreatureIds.StasisEntry[Random], me.GetPositionX(), me.GetPositionY(), me.GetPositionZ(), me.GetAbsoluteAngle(player), TempSummonType.TimedDespawnOutOfCombat, 30000); return false; } @@ -953,8 +953,8 @@ namespace Scripts.World.GameObjects public override bool GossipHello(Player player) { player.SendLoot(me.GetGUID(), LootType.Corpse); - me.SummonCreature(CreatureIds.HiveAmbusher, me.GetPositionX() + 1, me.GetPositionY(), me.GetPositionZ(), me.GetAngle(player), TempSummonType.TimedOrDeadDespawn, 60000); - me.SummonCreature(CreatureIds.HiveAmbusher, me.GetPositionX(), me.GetPositionY() + 1, me.GetPositionZ(), me.GetAngle(player), TempSummonType.TimedOrDeadDespawn, 60000); + me.SummonCreature(CreatureIds.HiveAmbusher, me.GetPositionX() + 1, me.GetPositionY(), me.GetPositionZ(), me.GetAbsoluteAngle(player), TempSummonType.TimedOrDeadDespawn, 60000); + me.SummonCreature(CreatureIds.HiveAmbusher, me.GetPositionX(), me.GetPositionY() + 1, me.GetPositionZ(), me.GetAbsoluteAngle(player), TempSummonType.TimedOrDeadDespawn, 60000); return true; } } diff --git a/Source/Scripts/World/NpcSpecial.cs b/Source/Scripts/World/NpcSpecial.cs index 60dcdb038..e4cf719e9 100644 --- a/Source/Scripts/World/NpcSpecial.cs +++ b/Source/Scripts/World/NpcSpecial.cs @@ -2099,7 +2099,7 @@ namespace Scripts.World.NpcSpecial _isSearching = false; _target = target.GetGUID(); me.SetWalk(true); - me.GetMotionMaster().MovePoint(TrainWrecker.MoveidChase, target.GetNearPosition(3.0f, target.GetAngle(me))); + me.GetMotionMaster().MovePoint(TrainWrecker.MoveidChase, target.GetNearPosition(3.0f, target.GetAbsoluteAngle(me))); } else _timer = 3 * Time.InMilliseconds;