//
// 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];
}
}