From e6bfc452286306e63577a6177dcc8f0ce0c08bdb Mon Sep 17 00:00:00 2001 From: Kamron Batman <3953314+kamronbatman@users.noreply.github.com> Date: Sat, 6 Jul 2024 12:41:45 -0700 Subject: [PATCH] fix: Consolidates and fixes movement/direction checks (#1861) --- Projects/Server/Items/Item.cs | 29 ++-- Projects/Server/Mobiles/Mobile.cs | 74 ++------ Projects/Server/Mobiles/Movement.cs | 39 +++-- .../UOContent/Engines/Pathing/Movement.cs | 58 +------ .../UOContent/Engines/Pathing/PathFollower.cs | 7 +- .../Items/Construction/Doors/BaseDoor.cs | 49 +----- .../Items/Weapons/Knives/ThrowingDagger.cs | 164 ++++++------------ Projects/UOContent/Mobiles/AI/BaseAI.cs | 3 +- Projects/UOContent/Mobiles/PlayerMobile.cs | 5 +- Projects/UOContent/Multis/Boats/BaseBoat.cs | 21 ++- Projects/UOContent/Spells/Base/SpellHelper.cs | 17 +- 11 files changed, 146 insertions(+), 320 deletions(-) diff --git a/Projects/Server/Items/Item.cs b/Projects/Server/Items/Item.cs index 5c73f91a3..228e5b6eb 100644 --- a/Projects/Server/Items/Item.cs +++ b/Projects/Server/Items/Item.cs @@ -3836,24 +3836,27 @@ public class Item : IHued, IComparable, ISpawnable, IObjectPropertyListEnt // return root == null ? m_Location : new Point3D( (IPoint3D) root ); } - public Point3D GetSurfaceTop() + public IPoint3D GetSurfaceTop() { var root = RootParent; - if (root == null) - { - return new Point3D( - m_Location.m_X, - m_Location.m_Y, - m_Location.m_Z + (ItemData.Surface ? ItemData.CalcHeight : 0) - ); - } - - return root.Location; + return (root as Item)?.GetSurfaceTop() ?? (ItemData.Surface ? new Point3D( + m_Location.m_X, + m_Location.m_Y, + m_Location.m_Z + ItemData.CalcHeight + ) : this); } - public Point3D GetWorldTop() => RootParent?.Location ?? - new Point3D(m_Location.m_X, m_Location.m_Y, m_Location.m_Z + ItemData.CalcHeight); + public Point3D GetWorldTop() + { + var root = RootParent; + + return (root as Item)?.GetWorldTop() ?? new Point3D( + m_Location.m_X, + m_Location.m_Y, + m_Location.m_Z + ItemData.CalcHeight + ); + } public void SendLocalizedMessageTo(Mobile to, int number, string args = "") { diff --git a/Projects/Server/Mobiles/Mobile.cs b/Projects/Server/Mobiles/Mobile.cs index a45413655..3349817f5 100644 --- a/Projects/Server/Mobiles/Mobile.cs +++ b/Projects/Server/Mobiles/Mobile.cs @@ -4089,10 +4089,12 @@ public partial class Mobile : IHued, IComparable, ISpawnable, IObjectPro return true; } - public virtual bool CheckMovement(Direction d, out int newZ) => Movement.Movement.CheckMovement(this, d, out newZ); + public virtual bool CheckMovement(Direction d, out int newZ) => CalcMoves.CheckMovement(this, d, out newZ); - private bool CanMove(Direction d, Point3D oldLocation, ref Point3D newLocation) + private bool CanMove(Direction d, Point3D oldLocation, out Point3D newLocation) { + newLocation = oldLocation; + if (m_Spell?.OnCasterMoving(d) == false) { return false; @@ -4110,61 +4112,13 @@ public partial class Mobile : IHued, IComparable, ISpawnable, IObjectPro return false; } - int x = oldLocation.m_X, y = oldLocation.m_Y; - int oldX = x, oldY = y; + var oldX = oldLocation.m_X; + var oldY = oldLocation.m_Y; var oldZ = oldLocation.m_Z; - - switch (d & Direction.Mask) - { - case Direction.North: - { - --y; - break; - } - case Direction.Right: - { - ++x; - --y; - break; - } - case Direction.East: - { - ++x; - break; - } - case Direction.Down: - { - ++x; - ++y; - break; - } - case Direction.South: - { - ++y; - break; - } - case Direction.Left: - { - --x; - ++y; - break; - } - case Direction.West: - { - --x; - break; - } - case Direction.Up: - { - --x; - --y; - break; - } - } - - newLocation.m_X = x; - newLocation.m_Y = y; - newLocation.m_Z = newZ; + var x = oldX; + var y = oldY; + CalcMoves.Offset(d, ref x, ref y); + newLocation = new Point3D(x, y, newZ); Pushing = false; @@ -4344,18 +4298,22 @@ public partial class Mobile : IHued, IComparable, ISpawnable, IObjectPro } var oldLocation = m_Location; - Point3D newLocation = oldLocation; + Point3D newLocation; if ((m_Direction & Direction.Mask) == (d & Direction.Mask)) { // We are actually moving (not just a direction change) - if (!CanMove(d, oldLocation, ref newLocation)) + if (!CanMove(d, oldLocation, out newLocation)) { return false; } DisruptiveAction(); } + else + { + newLocation = oldLocation; + } if (m_NetState != null) { diff --git a/Projects/Server/Mobiles/Movement.cs b/Projects/Server/Mobiles/Movement.cs index def0c5020..f3f509bfb 100644 --- a/Projects/Server/Mobiles/Movement.cs +++ b/Projects/Server/Mobiles/Movement.cs @@ -13,6 +13,8 @@ * along with this program. If not, see . * *************************************************************************/ +using System.Runtime.CompilerServices; + namespace Server.Movement; public static class Movement @@ -56,52 +58,63 @@ public static class Movement return false; } - public static void Offset(Direction d, ref int x, ref int y) + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Offset(Direction d, ref Point3D p, int count = 1) + { + var x = p.m_X; + var y = p.m_Y; + Offset(d, ref x, ref y, count); + p = new Point3D(x, y, p.m_Z); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + public static void Offset(Direction d, ref int x, ref int y, int count = 1) { switch (d & Direction.Mask) { case Direction.North: { - --y; + y -= count; break; } case Direction.South: { - ++y; + y += count; break; } case Direction.West: { - --x; + x -= count; break; } case Direction.East: { - ++x; + x += count; break; } case Direction.Right: { - ++x; - --y; + x += count; + y -= count; break; } case Direction.Left: { - --x; - ++y; + x -= count; + y += count; break; } case Direction.Down: { - ++x; - ++y; + x += count; + y += count; + break; } case Direction.Up: { - --x; - --y; + x -= count; + y -= count; break; } } diff --git a/Projects/UOContent/Engines/Pathing/Movement.cs b/Projects/UOContent/Engines/Pathing/Movement.cs index b1919369e..3f1b263f2 100644 --- a/Projects/UOContent/Engines/Pathing/Movement.cs +++ b/Projects/UOContent/Engines/Pathing/Movement.cs @@ -54,9 +54,9 @@ namespace Server.Movement var checkDiagonals = ((int)d & 0x1) == 0x1; - Offset(d, ref xForward, ref yForward); - Offset((Direction)(((int)d - 1) & 0x7), ref xLeft, ref yLeft); - Offset((Direction)(((int)d + 1) & 0x7), ref xRight, ref yRight); + Movement.Offset(d, ref xForward, ref yForward); + Movement.Offset((Direction)(((int)d - 1) & 0x7), ref xLeft, ref yLeft); + Movement.Offset((Direction)(((int)d + 1) & 0x7), ref xRight, ref yRight); if (xForward < 0 || yForward < 0 || xForward >= map.Width || yForward >= map.Height) { @@ -578,57 +578,5 @@ namespace Server.Movement zTop = loc.Z; } } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static void Offset(Direction d, ref int x, ref int y) - { - switch (d & Direction.Mask) - { - case Direction.North: - { - --y; - break; - } - case Direction.South: - { - ++y; - break; - } - case Direction.West: - { - --x; - break; - } - case Direction.East: - { - ++x; - break; - } - case Direction.Right: - { - ++x; - --y; - break; - } - case Direction.Left: - { - --x; - ++y; - break; - } - case Direction.Down: - { - ++x; - ++y; - break; - } - case Direction.Up: - { - --x; - --y; - break; - } - } - } } } diff --git a/Projects/UOContent/Engines/Pathing/PathFollower.cs b/Projects/UOContent/Engines/Pathing/PathFollower.cs index 1bce5e6d8..fa2557f48 100644 --- a/Projects/UOContent/Engines/Pathing/PathFollower.cs +++ b/Projects/UOContent/Engines/Pathing/PathFollower.cs @@ -42,12 +42,7 @@ namespace Server if (index >= 0 && index < dirs.Length) { - int x = p.X, y = p.Y; - - CalcMoves.Offset(dirs[index], ref x, ref y); - - p.X = x; - p.Y = y; + CalcMoves.Offset(dirs[index], ref p); } } } diff --git a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs index b5608bf40..5997ab735 100644 --- a/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs +++ b/Projects/UOContent/Items/Construction/Doors/BaseDoor.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Runtime.CompilerServices; using ModernUO.Serialization; using Server.Targeting; +using CalcMoves = Server.Movement.Movement; namespace Server.Items; @@ -233,53 +234,7 @@ public abstract partial class BaseDoor : Item, ILockable, ITelekinesisable int x = m.X; int y = m.Y; - switch (m.Direction & Direction.Mask) - { - case Direction.North: - { - --y; - break; - } - case Direction.Right: - { - ++x; - --y; - break; - } - case Direction.East: - { - ++x; - break; - } - case Direction.Down: - { - ++x; - ++y; - break; - } - case Direction.South: - { - ++y; - break; - } - case Direction.Left: - { - --x; - ++y; - break; - } - case Direction.West: - { - --x; - break; - } - case Direction.Up: - { - --x; - --y; - break; - } - } + CalcMoves.Offset(m.Direction, ref x, ref y); foreach (var item in m.Map.GetItemsAt(x, y)) { diff --git a/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs b/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs index c4ccc45f0..f6a00ddbc 100644 --- a/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs +++ b/Projects/UOContent/Items/Weapons/Knives/ThrowingDagger.cs @@ -1,132 +1,82 @@ using System; using ModernUO.Serialization; using Server.Targeting; +using CalcMoves = Server.Movement.Movement; -namespace Server.Items +namespace Server.Items; + +[Flippable(0xF52, 0xF51)] +[SerializationGenerator(0, false)] +public partial class ThrowingDagger : Item { - [Flippable(0xF52, 0xF51)] - [SerializationGenerator(0, false)] - public partial class ThrowingDagger : Item + [Constructible] + public ThrowingDagger() : base(0xF52) { - [Constructible] - public ThrowingDagger() : base(0xF52) + Weight = 1.0; + Layer = Layer.OneHanded; + } + + public override string DefaultName => "a throwing dagger"; + + public override void OnDoubleClick(Mobile from) + { + if (from.Items.Contains(this)) { - Weight = 1.0; - Layer = Layer.OneHanded; + var t = new InternalTarget(this); + from.Target = t; } - - public override string DefaultName => "a throwing dagger"; - - public override void OnDoubleClick(Mobile from) + else { - if (from.Items.Contains(this)) + from.SendMessage("You must be holding that weapon to use it."); + } + } + + private class InternalTarget : Target + { + private readonly ThrowingDagger m_Dagger; + + public InternalTarget(ThrowingDagger dagger) : base(10, false, TargetFlags.Harmful) => m_Dagger = dagger; + + protected override void OnTarget(Mobile from, object targeted) + { + if (m_Dagger.Deleted) { - var t = new InternalTarget(this); - from.Target = t; + return; } - else + + if (!from.Items.Contains(m_Dagger)) { from.SendMessage("You must be holding that weapon to use it."); } - } - - private class InternalTarget : Target - { - private readonly ThrowingDagger m_Dagger; - - public InternalTarget(ThrowingDagger dagger) : base(10, false, TargetFlags.Harmful) => m_Dagger = dagger; - - protected override void OnTarget(Mobile from, object targeted) + else if (targeted is Mobile m && m != from && from.HarmfulCheck(m)) { - if (m_Dagger.Deleted) + var to = from.GetDirectionTo(m); + + from.Direction = to; + + from.Animate(from.Mounted ? 26 : 9, 7, 1, true, false, 0); + + if (Utility.RandomDouble() >= Math.Sqrt(m.Dex / 100.0) * 0.8) { - return; + from.MovingEffect(m, 0x1BFE, 7, 1, false, false, 0x481, 0); + + AOS.Damage(m, from, Utility.Random(5, from.Str / 10), 100, 0, 0, 0, 0); + + m_Dagger.MoveToWorld(m.Location, m.Map); } - - if (!from.Items.Contains(m_Dagger)) + else { - from.SendMessage("You must be holding that weapon to use it."); - } - else if (targeted is Mobile m && m != from && from.HarmfulCheck(m)) - { - var to = from.GetDirectionTo(m); + var p = m.Location; + CalcMoves.Offset(to, ref p); - from.Direction = to; + p.X += Utility.Random(-1, 3); + p.Y += Utility.Random(-1, 3); - from.Animate(from.Mounted ? 26 : 9, 7, 1, true, false, 0); + m_Dagger.MoveToWorld(p, m.Map); - if (Utility.RandomDouble() >= Math.Sqrt(m.Dex / 100.0) * 0.8) - { - from.MovingEffect(m, 0x1BFE, 7, 1, false, false, 0x481, 0); + from.MovingEffect(m_Dagger, 0x1BFE, 7, 1, false, false, 0x481, 0); - AOS.Damage(m, from, Utility.Random(5, from.Str / 10), 100, 0, 0, 0, 0); - - m_Dagger.MoveToWorld(m.Location, m.Map); - } - else - { - int x = 0, y = 0; - - switch (to & Direction.Mask) - { - case Direction.North: - { - --y; - break; - } - case Direction.South: - { - ++y; - break; - } - case Direction.West: - { - --x; - break; - } - case Direction.East: - { - ++x; - break; - } - case Direction.Up: - { - --x; - --y; - break; - } - case Direction.Down: - { - ++x; - ++y; - break; - } - case Direction.Left: - { - --x; - ++y; - break; - } - case Direction.Right: - { - ++x; - --y; - break; - } - } - - x += Utility.Random(-1, 3); - y += Utility.Random(-1, 3); - - x += m.X; - y += m.Y; - - m_Dagger.MoveToWorld(new Point3D(x, y, m.Z), m.Map); - - from.MovingEffect(m_Dagger, 0x1BFE, 7, 1, false, false, 0x481, 0); - - from.SendMessage("You miss."); - } + from.SendMessage("You miss."); } } } diff --git a/Projects/UOContent/Mobiles/AI/BaseAI.cs b/Projects/UOContent/Mobiles/AI/BaseAI.cs index 530e5e70d..5f0fdd0ec 100644 --- a/Projects/UOContent/Mobiles/AI/BaseAI.cs +++ b/Projects/UOContent/Mobiles/AI/BaseAI.cs @@ -2182,7 +2182,8 @@ public abstract class BaseAI if (map != null) { - int x = m_Mobile.X, y = m_Mobile.Y; + var x = m_Mobile.X; + var y = m_Mobile.Y; Movement.Movement.Offset(d, ref x, ref y); using var queue = PooledRefQueue.Create(); diff --git a/Projects/UOContent/Mobiles/PlayerMobile.cs b/Projects/UOContent/Mobiles/PlayerMobile.cs index 43aefed97..50956bc8c 100644 --- a/Projects/UOContent/Mobiles/PlayerMobile.cs +++ b/Projects/UOContent/Mobiles/PlayerMobile.cs @@ -1763,8 +1763,9 @@ namespace Server.Mobiles newZ = foundation.Z + HouseFoundation.GetLevelZ(context.Level, context.Foundation); - int newX = X, newY = Y; - Movement.Movement.Offset(d, ref newX, ref newY); + var newX = X; + var newY = Y; + CalcMoves.Offset(d, ref newX, ref newY); var startX = foundation.X + foundation.Components.Min.X + 1; var startY = foundation.Y + foundation.Components.Min.Y + 1; diff --git a/Projects/UOContent/Multis/Boats/BaseBoat.cs b/Projects/UOContent/Multis/Boats/BaseBoat.cs index e1fbcbe72..7ebe612fc 100644 --- a/Projects/UOContent/Multis/Boats/BaseBoat.cs +++ b/Projects/UOContent/Multis/Boats/BaseBoat.cs @@ -282,14 +282,15 @@ namespace Server.Multis SPlank.SetFacing(_facing); } - int xOffset = 0, yOffset = 0; + var xOffset = X; + var yOffset = Y; Movement.Movement.Offset(_facing, ref xOffset, ref yOffset); if (TillerMan != null) { TillerMan.Location = new Point3D( - X + xOffset * TillerManDistance + (_facing == Direction.North ? 1 : 0), - Y + yOffset * TillerManDistance, + xOffset * TillerManDistance + (_facing == Direction.North ? 1 : 0), + yOffset * TillerManDistance, TillerMan.Z ); TillerMan.SetFacing(_facing); @@ -298,7 +299,7 @@ namespace Server.Multis if (Hold != null) { - Hold.Location = new Point3D(X + xOffset * HoldDistance, Y + yOffset * HoldDistance, Hold.Z); + Hold.Location = new Point3D(xOffset * HoldDistance, yOffset * HoldDistance, Hold.Z); Hold.SetFacing(_facing); } } @@ -1722,7 +1723,8 @@ namespace Server.Multis return false; } - int rx = 0, ry = 0; + var rx = 0; + var ry = 0; var d = (Direction)(((int)_facing + (int)dir) & 0x7); Movement.Movement.Offset(d, ref rx, ref ry); @@ -2083,7 +2085,8 @@ namespace Server.Multis PPlank?.SetFacing(facing); SPlank?.SetFacing(facing); - int xOffset = 0, yOffset = 0; + var xOffset = X; + var yOffset = Y; Movement.Movement.Offset(facing, ref xOffset, ref yOffset); var count = ((_facing - old) & 0x7) / 2; @@ -2109,15 +2112,15 @@ namespace Server.Multis if (TillerMan != null) { TillerMan.Location = new Point3D( - X + xOffset * TillerManDistance + (facing == Direction.North ? 1 : 0), - Y + yOffset * TillerManDistance, + xOffset * TillerManDistance + (facing == Direction.North ? 1 : 0), + yOffset * TillerManDistance, TillerMan.Z ); } if (Hold != null) { - Hold.Location = new Point3D(X + xOffset * HoldDistance, Y + yOffset * HoldDistance, Hold.Z); + Hold.Location = new Point3D(xOffset * HoldDistance, yOffset * HoldDistance, Hold.Z); } if (PPlank != null) diff --git a/Projects/UOContent/Spells/Base/SpellHelper.cs b/Projects/UOContent/Spells/Base/SpellHelper.cs index 76c9acd4b..14eb566a2 100644 --- a/Projects/UOContent/Spells/Base/SpellHelper.cs +++ b/Projects/UOContent/Spells/Base/SpellHelper.cs @@ -176,23 +176,22 @@ namespace Server.Spells return false; } - public static void Turn(Mobile from, object to) + public static void Turn(Mobile from, IPoint3D to) { - if (to is not IPoint3D target) + if (from == null) { return; } - if (target is Item item) + var root = (to as Item)?.RootParent; + if (from != root) { - if (item.RootParent != from) - { - from.Direction = from.GetDirectionTo(item.GetWorldLocation()); - } + to = root; } - else if (!from.Equals(target)) + + if (!from.Equals(to)) { - from.Direction = from.GetDirectionTo(target); + from.Direction = from.GetDirectionTo(to); } }