diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index 0d1bc591b..bef5ec52d 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -961,31 +961,28 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa return _invalidSector; } - public bool LineOfSight(Point3D org, Point3D dest) + public bool LineOfSight(Point3D origin, Point3D destination) { if (this == Internal) { return false; } - if (!Utility.InRange(org, dest, MaxLOSDistance)) + if (!Utility.InRange(origin, destination, MaxLOSDistance)) { return false; } - var end = dest; - - if (org.X > dest.X || org.X == dest.X && org.Y > dest.Y || org.X == dest.X && org.Y == dest.Y && org.Z > dest.Z) + if (origin.X > destination.X || origin.X == destination.X && origin.Y > destination.Y || origin.X == destination.X && origin.Y == destination.Y && origin.Z > destination.Z) { - (org, dest) = (dest, org); + (origin, destination) = (destination, origin); } - int height; Point3D p; var path = new Point3DList(); TileFlag flags; - if (org == dest) + if (origin == destination) { return true; } @@ -995,9 +992,9 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa path.Clear(); } - var xd = dest.m_X - org.m_X; - var yd = dest.m_Y - org.m_Y; - var zd = dest.m_Z - org.m_Z; + var xd = destination.X - origin.X; + var yd = destination.Y - origin.Y; + var zd = destination.Z - origin.Z; var zslp = Math.Sqrt(xd * xd + yd * yd); var sq3d = zd != 0 ? Math.Sqrt(zslp * zslp + zd * zd) : zslp; @@ -1005,11 +1002,11 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa var run = xd / sq3d; zslp = zd / sq3d; - double y = org.m_Y; - double z = org.m_Z; - double x = org.m_X; - while (Utility.NumberBetween(x, dest.m_X, org.m_X, 0.5) && Utility.NumberBetween(y, dest.m_Y, org.m_Y, 0.5) && - Utility.NumberBetween(z, dest.m_Z, org.m_Z, 0.5)) + double y = origin.Y; + double z = origin.Z; + double x = origin.X; + while (Utility.NumberBetween(x, destination.X, origin.X, 0.5) && Utility.NumberBetween(y, destination.Y, origin.Y, 0.5) && + Utility.NumberBetween(z, destination.Z, origin.Z, 0.5)) { var ix = (int)Math.Round(x); var iy = (int)Math.Round(y); @@ -1018,7 +1015,7 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa { p = path.Last; - if (p.m_X != ix || p.m_Y != iy || p.m_Z != iz) + if (p.X != ix || p.Y != iy || p.Z != iz) { path.Add(ix, iy, iz); } @@ -1040,27 +1037,27 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa p = path.Last; - if (p != dest) + if (p != destination) { - path.Add(dest); + path.Add(destination); } - Point3D pTop = org, pBottom = dest; + Point3D pTop = origin, pBottom = destination; Utility.FixPoints(ref pTop, ref pBottom); var pathCount = path.Count; - var endTop = end.m_Z + 1; + var endTop = destination.Z + 1; for (var i = 0; i < pathCount; ++i) { var point = path[i]; - var pointTop = point.m_Z + 1; + var pointTop = point.Z + 1; var landTile = Tiles.GetLandTile(point.X, point.Y); - GetAverageZ(point.m_X, point.m_Y, out var landZ, out _, out var landTop); + GetAverageZ(point.X, point.Y, out var landZ, out _, out var landTop); if (landZ <= pointTop && landTop >= point.m_Z && - (point.m_X != end.m_X || point.m_Y != end.m_Y || landZ > endTop || landTop < end.m_Z) && + (point.X != destination.X || point.Y != destination.Y || landZ > endTop || landTop < destination.Z) && !landTile.Ignored) { return false; @@ -1082,22 +1079,22 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa bool foundStatic = false; - foreach (var t in Tiles.GetStaticAndMultiTiles(point.m_X, point.m_Y)) + foreach (var t in Tiles.GetStaticAndMultiTiles(point.X, point.Y)) { foundStatic = true; var id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; flags = id.Flags; - height = id.CalcHeight; - if (t.Z <= pointTop && t.Z + height >= point.Z && (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0) + if ( + t.Z <= pointTop && t.Z + id.CalcHeight >= point.Z && + (flags & (TileFlag.Window | TileFlag.NoShoot)) != 0 && + (point.X != destination.X || + point.Y != destination.Y || + t.Z > endTop || t.Z + id.CalcHeight < destination.Z) + ) { - if (point.m_X == end.m_X && point.m_Y == end.m_Y && t.Z <= endTop && t.Z + height >= end.m_Z) - { - continue; - } - return false; } } @@ -1120,21 +1117,21 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa } } - var rect = new Rectangle2D(pTop.m_X, pTop.m_Y, pBottom.m_X - pTop.m_X + 1, pBottom.m_Y - pTop.m_Y + 1); + var rect = new Rectangle2D(pTop.X, pTop.Y, pBottom.X - pTop.X + 1, pBottom.Y - pTop.Y + 1); - foreach (var i in GetItemsInBounds(rect)) + foreach (var item in GetItemsInBounds(rect)) { - if (!i.Visible) + if (!item.Visible) { continue; } - if (i is BaseMulti || i.ItemID > TileData.MaxItemValue) + if (item is BaseMulti || item.ItemID > TileData.MaxItemValue) { continue; } - var id = i.ItemData; + var id = item.ItemData; flags = id.Flags; if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0) @@ -1142,35 +1139,40 @@ public sealed partial class Map : IComparable, ISpanFormattable, ISpanParsa continue; } - height = id.CalcHeight; - - var found = false; - - var count = path.Count; - - for (var j = 0; j < count; ++j) + for (var i = 0; i < path.Count; ++i) { - var point = path[j]; - var pointTop = point.m_Z + 1; - var loc = i.Location; + var pathPoint = path[i]; + var pointTop = pathPoint.Z + 1; + var itemLocation = item.Location; - // if (t.Z <= point.Z && t.Z+height >= point.Z && ( height != 0 || ( t.Z == dest.Z && zd != 0 ) )) - if (loc.m_X == point.m_X && loc.m_Y == point.m_Y && loc.m_Z <= pointTop && loc.m_Z + height >= point.m_Z) + if ( + // Item is on same tile as this point along the LOS path + itemLocation.X == pathPoint.X && + itemLocation.Y == pathPoint.Y && + itemLocation.Z <= pointTop && + + // Item rests on the same level as the path + itemLocation.Z + id.CalcHeight >= pathPoint.Z && + + // Fix door bugging monsters when door is at the START or END of the LOS path by allowing LOS + !(flags.HasFlag(TileFlag.Door) && + itemLocation.X == origin.X && itemLocation.Y == origin.Y || + itemLocation.X == destination.X && itemLocation.Y == destination.Y) && + + // Item is at some point along the path BEFORE the target + (itemLocation.X != destination.X || + itemLocation.Y != destination.Y || + + // Item is diagonally looking DOWN at the target + itemLocation.Z > endTop || + + // Item is diagonally looking UP at the target + itemLocation.Z + id.CalcHeight < destination.Z) + ) { - if (loc.m_X != end.m_X || loc.m_Y != end.m_Y || loc.m_Z > endTop || loc.m_Z + height < end.m_Z) - { - found = true; - break; - } + return false; } } - - if (!found) - { - continue; - } - - return false; } return true; diff --git a/Projects/UOContent/Gumps/Houses/HouseGumpAOS.cs b/Projects/UOContent/Gumps/Houses/HouseGumpAOS.cs index 1e9ba2428..3a159286f 100644 --- a/Projects/UOContent/Gumps/Houses/HouseGumpAOS.cs +++ b/Projects/UOContent/Gumps/Houses/HouseGumpAOS.cs @@ -111,10 +111,10 @@ namespace Server.Gumps AddImage(10, 10, 100); - if (m_House.Sign != null) - { - var lines = m_House.Sign.GetName().Wrap(10, 6); + var lines = m_House.Sign?.GetName().Wrap(10, 6); + if (lines != null) + { for (int i = 0, y = (114 - lines.Count * 14) / 2; i < lines.Count; ++i, y += 14) { var s = lines[i];