// // Licensed under the MIT License. See LICENSE file in the project root for full license information. // namespace MUnique.OpenMU.GameLogic; using MUnique.OpenMU.GameLogic.Attributes; using MUnique.OpenMU.Pathfinding; /// /// Extensions for mu objects. /// public static class LocateableExtensions { /// /// Filters out inactive (non-alive) locateables. /// /// Type of elements. /// The locateables. /// /// All active locateables of the given enumeration. /// public static IEnumerable WhereActive(this IEnumerable locateables) where T : ILocateable { return locateables.Where(l => l.IsActive()); } /// /// Filters out invisible locateables. /// /// Type of elements. /// The locateables. /// /// All visible locateables of the given enumeration. /// public static IEnumerable WhereNotInvisible(this IEnumerable locateables) where T : IAttackable { return locateables.Where(l => l.Attributes[Stats.IsInvisible] == 0); } /// /// Determines whether this instance is active (alive). /// /// The locateable. /// /// true if the specified locateable is active; otherwise, false. /// public static bool IsActive(this ILocateable locateable) { return locateable is not IAttackable attackable || (attackable.IsAlive && !attackable.IsTeleporting); } /// /// Gets the distance to another object. /// /// The object from which the distance is calculated. /// The object to which the distance is calculated. /// The distance between this and another object. public static double GetDistanceTo(this ILocateable objectFrom, ILocateable objectTo) { return objectFrom.GetDistanceTo(objectTo.Position); } /// /// Gets the distance to another point. /// /// The object from which the distance is calculated. /// The point to which the distance is calculated. /// The distance between this and another object. public static double GetDistanceTo(this ILocateable objectFrom, Point objectToPosition) { return objectFrom.Position.EuclideanDistanceTo(objectToPosition); } /// /// Determines whether the specified coordinates are in the specified range of the object. /// /// The object. /// The coordinates. /// The maximum range. /// True, if the specified coordinate is in the specified range of the object; Otherwise, false. public static bool IsInRange(this ILocateable obj, Point point, int range) => obj.IsInRange(point.X, point.Y, range); /// /// Determines whether the specified coordinates are in the specified range of the object. /// /// The object. /// The second object. /// The maximum range. /// True, if the specified coordinate is in the specified range of the object; Otherwise, false. public static bool IsInRange(this ILocateable obj, ILocateable obj2, int range) => obj.IsInRange(obj2.Position, range); /// /// Determines whether the specified coordinate is in the specified range of the object. /// /// The object. /// The x coordinate. /// The y coordinate. /// The maximum range. /// True, if the specified coordinate is in the specified range of the object; Otherwise, false. public static bool IsInRange(this ILocateable locatable, int x, int y, int range) { int xdiff; int ydiff; var point = locatable.Position; if (x < point.X) { xdiff = point.X - x; } else if (x > point.X) { xdiff = x - point.X; } else { xdiff = 0; } if (xdiff > range) { return false; } if (y < point.Y) { ydiff = point.Y - y; } else if (y > point.Y) { ydiff = y - point.Y; } else { ydiff = 0; } return ydiff <= range; } /// /// Gets the direction to another object. /// /// The object from which the direction is calculated. /// The object to which the direction is calculated. /// The direction between this and another object. /// /// The returned values differ a bit, so we first have to analyze which function is correct. /// public static Direction GetDirectionTo(this ILocateable objectFrom, ILocateable objectTo) => objectFrom.Position.GetDirectionTo(objectTo.Position); /// /// Determines whether the object is at the safezone of his current map. /// /// The object. /// True, if it is on the safezone of his current map; Otherwise, false. public static bool IsAtSafezone(this ILocateable obj) { var map = obj.CurrentMap; if (map?.Terrain?.SafezoneMap is null) { return true; } return map.Terrain.SafezoneMap[obj.Position.X, obj.Position.Y]; } }