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)); } } }