diff --git a/Projects/Server/Geometry/Point3DList.cs b/Projects/Server/Geometry/Point3DList.cs index 244a20defb..3de9410d20 100644 --- a/Projects/Server/Geometry/Point3DList.cs +++ b/Projects/Server/Geometry/Point3DList.cs @@ -9,7 +9,7 @@ public class Point3DList public Point3DList() { - m_List = new Point3D[8]; + m_List = new Point3D[16]; Count = 0; } diff --git a/Projects/Server/Maps/Map.cs b/Projects/Server/Maps/Map.cs index bef5ec52df..26ab156b88 100644 --- a/Projects/Server/Maps/Map.cs +++ b/Projects/Server/Maps/Map.cs @@ -973,25 +973,21 @@ public bool LineOfSight(Point3D origin, Point3D destination) return false; } - 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) - { - (origin, destination) = (destination, origin); - } - - Point3D p; - var path = new Point3DList(); - TileFlag flags; - if (origin == destination) { return true; } - if (path.Count > 0) + var end = destination; + + 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) { - path.Clear(); + (origin, destination) = (destination, origin); } + var path = new Point3DList(); + var xd = destination.X - origin.X; var yd = destination.Y - origin.Y; var zd = destination.Z - origin.Z; @@ -1005,15 +1001,17 @@ public bool LineOfSight(Point3D origin, Point3D destination) 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) && + 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); var iz = (int)Math.Round(z); + if (path.Count > 0) { - p = path.Last; + var p = path.Last; if (p.X != ix || p.Y != iy || p.Z != iz) { @@ -1035,18 +1033,13 @@ public bool LineOfSight(Point3D origin, Point3D destination) return true; // <--should never happen, but to be safe. } - p = path.Last; - - if (p != destination) + if (path.Last != destination) { path.Add(destination); } - Point3D pTop = origin, pBottom = destination; - Utility.FixPoints(ref pTop, ref pBottom); - var pathCount = path.Count; - var endTop = destination.Z + 1; + var endTop = end.Z + 1; for (var i = 0; i < pathCount; ++i) { @@ -1057,7 +1050,7 @@ public bool LineOfSight(Point3D origin, Point3D destination) GetAverageZ(point.X, point.Y, out var landZ, out _, out var landTop); if (landZ <= pointTop && landTop >= point.m_Z && - (point.X != destination.X || point.Y != destination.Y || landZ > endTop || landTop < destination.Z) && + (point.X != end.X || point.Y != end.Y || landZ > endTop || landTop < end.Z) && !landTile.Ignored) { return false; @@ -1085,14 +1078,14 @@ public bool LineOfSight(Point3D origin, Point3D destination) var id = TileData.ItemTable[t.ID & TileData.MaxItemValue]; - flags = id.Flags; + var flags = id.Flags; 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) + (point.X != end.X || + point.Y != end.Y || + t.Z > endTop || t.Z + id.CalcHeight < end.Z) ) { return false; @@ -1117,6 +1110,10 @@ public bool LineOfSight(Point3D origin, Point3D destination) } } + var pTop = origin; + var pBottom = destination; + Utility.FixPoints(ref pTop, ref pBottom); + var rect = new Rectangle2D(pTop.X, pTop.Y, pBottom.X - pTop.X + 1, pBottom.Y - pTop.Y + 1); foreach (var item in GetItemsInBounds(rect)) @@ -1132,7 +1129,7 @@ public bool LineOfSight(Point3D origin, Point3D destination) } var id = item.ItemData; - flags = id.Flags; + var flags = id.Flags; if ((flags & (TileFlag.Window | TileFlag.NoShoot)) == 0) { @@ -1160,14 +1157,14 @@ public bool LineOfSight(Point3D origin, Point3D destination) 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 || + (itemLocation.X != end.X || + itemLocation.Y != end.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) + itemLocation.Z + id.CalcHeight < end.Z) ) { return false;