using System;
using JetBrains.Annotations;
using Robust.Shared.Maths;
using Robust.Shared.Serialization;
namespace Robust.Shared.Map
{
///
/// Coordinates relative to a specific map.
///
[PublicAPI]
[Serializable, NetSerializable]
public readonly struct MapCoordinates : IEquatable
{
public static readonly MapCoordinates Nullspace = new(Vector2.Zero, MapId.Nullspace);
///
/// World Position coordinates.
///
public readonly Vector2 Position;
///
/// Map identifier relevant to this position.
///
public readonly MapId MapId;
///
/// World position on the X axis.
///
public float X => Position.X;
///
/// World position on the Y axis.
///
public float Y => Position.Y;
///
/// Constructs a new instance of MapCoordinates.
///
/// World position coordinates.
/// Map identifier relevant to this position.
public MapCoordinates(Vector2 position, MapId mapId)
{
Position = position;
MapId = mapId;
}
///
/// Constructs a new instance of MapCoordinates.
///
/// World position coordinate on the X axis.
/// World position coordinate on the Y axis.
/// Map identifier relevant to this position.
public MapCoordinates(float x, float y, MapId mapId)
: this(new Vector2(x, y), mapId) { }
///
public override string ToString()
{
return $"Map={MapId}, X={Position.X:N2}, Y={Position.Y:N2}";
}
///
/// Checks that these coordinates are within a certain distance of another set.
///
/// Other set of coordinates to use.
/// maximum distance between the two sets of coordinates.
/// True if the two points are within a given range.
public bool InRange(MapCoordinates otherCoords, float range)
{
if (otherCoords.MapId != MapId)
{
return false;
}
return (otherCoords.Position - Position).LengthSquared < range * range;
}
///
public bool Equals(MapCoordinates other)
{
return Position.Equals(other.Position) && MapId.Equals(other.MapId);
}
///
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj))
return false;
return obj is MapCoordinates other && Equals(other);
}
///
public override int GetHashCode()
{
unchecked
{
return (Position.GetHashCode() * 397) ^ MapId.GetHashCode();
}
}
///
/// Check for equality by value between two objects.
///
public static bool operator ==(MapCoordinates a, MapCoordinates b)
{
return a.Equals(b);
}
///
/// Check for inequality by value between two objects.
///
public static bool operator !=(MapCoordinates a, MapCoordinates b)
{
return !a.Equals(b);
}
///
/// Used to deconstruct this object into a tuple.
///
/// World position coordinate on the X axis.
/// World position coordinate on the Y axis.
public void Deconstruct(out float x, out float y)
{
x = X;
y = Y;
}
///
/// Used to deconstruct this object into a tuple.
///
/// Map identifier relevant to this position.
/// World position coordinate on the X axis.
/// World position coordinate on the Y axis.
public void Deconstruct(out MapId mapId, out float x, out float y)
{
mapId = MapId;
x = X;
y = Y;
}
///
/// Used to get a copy of the coordinates with an offset.
///
/// Offset to apply to these coordinates
/// A copy of these coordinates, but offset.
public MapCoordinates Offset(Vector2 offset)
{
return new MapCoordinates(Position + offset, MapId);
}
///
/// Used to get a copy of the coordinates with an offset.
///
/// X axis offset to apply to these coordinates
/// Y axis offset to apply to these coordinates
/// A copy of these coordinates, but offset.
public MapCoordinates Offset(float x, float y)
{
return Offset(new Vector2(x, y));
}
}
}