diff --git a/Source/Game/Entities/Object/WorldObject.cs b/Source/Game/Entities/Object/WorldObject.cs index e4fee119b..33ed21a49 100644 --- a/Source/Game/Entities/Object/WorldObject.cs +++ b/Source/Game/Entities/Object/WorldObject.cs @@ -3146,18 +3146,43 @@ namespace Game.Entities } } - public void GetNearPoint2D(out float x, out float y, float distance2d, float absAngle) + public void GetNearPoint2D(WorldObject searcher, out float x, out float y, float distance2d, float absAngle) { - x = (float)(GetPositionX() + (GetCombatReach() + distance2d) * Math.Cos(absAngle)); - y = (float)(GetPositionY() + (GetCombatReach() + distance2d) * Math.Sin(absAngle)); + float effectiveReach = GetCombatReach(); + + if (searcher) + { + effectiveReach += searcher.GetCombatReach(); + + if (this != searcher) + { + float myHover = 0.0f; + float searcherHover = 0.0f; + + Unit unit = ToUnit(); + if (unit != null) + myHover = unit.GetHoverOffset(); + + Unit searchUnit = searcher.ToUnit(); + if (searchUnit != null) + searcherHover = searchUnit.GetHoverOffset(); + + float hoverDelta = myHover - searcherHover; + if (hoverDelta != 0.0f) + effectiveReach = MathF.Sqrt(effectiveReach * effectiveReach - hoverDelta * hoverDelta); + } + } + + x = GetPositionX() + (effectiveReach + distance2d) * MathF.Cos(absAngle); + y = GetPositionY() + (effectiveReach + distance2d) * MathF.Sin(absAngle); GridDefines.NormalizeMapCoord(ref x); GridDefines.NormalizeMapCoord(ref y); } - public void GetNearPoint(WorldObject searcher, out float x, out float y, out float z, float searcher_size, float distance2d, float absAngle) + public void GetNearPoint(WorldObject searcher, out float x, out float y, out float z, float distance2d, float absAngle) { - GetNearPoint2D(out x, out y, distance2d + searcher_size, absAngle); + GetNearPoint2D(searcher, out x, out y, distance2d, absAngle); z = GetPositionZ(); (searcher ?? this).UpdateAllowedPositionZ(x, y, ref z); @@ -3177,7 +3202,7 @@ namespace Game.Entities // loop in a circle to look for a point in LoS using small steps for (float angle = MathFunctions.PI / 8; angle < Math.PI * 2; angle += MathFunctions.PI / 8) { - GetNearPoint2D(out x, out y, distance2d + searcher_size, absAngle + angle); + GetNearPoint2D(searcher, out x, out y, distance2d, absAngle + angle); z = GetPositionZ(); (searcher ?? this).UpdateAllowedPositionZ(x, y, ref z); if (IsWithinLOS(x, y, z)) @@ -3193,7 +3218,7 @@ namespace Game.Entities 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() + relAngle); + GetNearPoint(null, out x, out y, out z, distance2d + size, GetOrientation() + relAngle); } public Position GetNearPosition(float dist, float angle) @@ -3220,7 +3245,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, GetAbsoluteAngle(obj)); + GetNearPoint(obj, out x, out y, out z, distance2d, GetAbsoluteAngle(obj)); } public void MovePosition(Position pos, float dist, float angle) diff --git a/Source/Game/Movement/Generators/TargetMovement.cs b/Source/Game/Movement/Generators/TargetMovement.cs index 7283a4f5c..93acf0353 100644 --- a/Source/Game/Movement/Generators/TargetMovement.cs +++ b/Source/Game/Movement/Generators/TargetMovement.cs @@ -141,35 +141,25 @@ namespace Game.Movement float x, y, z; if (updateDestination || _path == null) { - float size = owner.GetCombatReach(); float hoverDiff = Math.Abs(owner.GetHoverOffset() - GetTarget().GetHoverOffset()); if (_offset == 0) { if (GetTarget().IsWithinDistInMap(owner, SharedConst.ContactDistance)) return; - // to nearest contact position - 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().GetAbsoluteAngle(owner)); + GetTarget().GetNearPoint(owner, out x, out y, out z, SharedConst.ContactDistance, GetTarget().GetAbsoluteAngle(owner)); } else { float distance = _offset + 1.0f; if (owner.IsPet() && GetTarget().GetTypeId() == TypeId.Player) - { distance = 1.0f; - size = 1.0f; - } - else if (hoverDiff != 0) - size = size > hoverDiff ? MathF.Sqrt(size * size - hoverDiff * hoverDiff) : 0.0f; if (GetTarget().IsWithinDistInMap(owner, distance)) return; - GetTarget().GetClosePoint(out x, out y, out z, size, _offset, _angle); + GetTarget().GetClosePoint(out x, out y, out z, _offset, _angle); } if (owner.IsHovering()) diff --git a/Source/Game/Movement/MotionMaster.cs b/Source/Game/Movement/MotionMaster.cs index aed086cfd..4523eb5e4 100644 --- a/Source/Game/Movement/MotionMaster.cs +++ b/Source/Game/Movement/MotionMaster.cs @@ -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.GetAbsoluteAngle(srcX, srcY) + MathFunctions.PI); + _owner.GetNearPoint(_owner, out x, out y, out z, dist, _owner.GetAbsoluteAngle(srcX, srcY) + MathFunctions.PI); MoveSplineInit init = new(_owner); init.MoveTo(x, y, z); @@ -381,7 +381,7 @@ namespace Game.Movement float moveTimeHalf = (float)(speedZ / gravity); float dist = 2 * moveTimeHalf * speedXY; - _owner.GetNearPoint2D(out float x, out float y, dist, _owner.GetOrientation() + angle); + _owner.GetNearPoint2D(null, out float x, out float y, dist, _owner.GetOrientation() + angle); float z = _owner.GetPositionZ(); _owner.UpdateAllowedPositionZ(x, y, ref z); MoveJump(x, y, z, 0.0f, speedXY, speedZ);