mirror of
https://github.com/space-wizards/RobustToolbox.git
synced 2026-09-03 02:27:08 +02:00
* Move MapManager queries to SharedMapSystem Moves all variants of FindGridsIntersecting/TryFindGridAt to SharedMapSystem Hollows out the MapManager methods and converts them into relays to SharedMapSystem * Move CreateGrid to SharedMapSystem Moves the functionality for CreateGrid and its variants to SharedMapSystem Hollows out the MapManager methods and converts them into relays for the SharedMapSystem methods Obsoletes them too Also moves over the GetAllMapGrids and GetAllGrids methods * Move RaiseOnTileChanged to SharedMapSystem Also moves the SuppressOnTileChanged flag member to SharedMapSystem Hollows out and obsoletes the MapManager versions * Move default value constants to SharedMapSystem * Converts map pausing events into LocalizedEntityCommands * Move MapManager related delegates/structs to SharedMapSystem Moves the GridCreationOptions struct to the same namespace as SharedMapSystem and converts it into a record struct Move the GridCallback delegates to the same namespace as SharedMapSystem * Move CullDeletionHistory to SharedMapSystem Well, that was less painful than I thought it would be * Actually obsolete the NetworkedMapManager method * Rename file * Doc comments for new SharedMapSystem methods * Doc comment * Doc comments * Fix access * Purge all references to IMapManagerInternal * Cull easy IMapManager references * The rest * Purge IMapManager * Private internal FindGridsIntersecting method * please die * 41 * notes --------- Co-authored-by: ArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
400 lines
16 KiB
C#
400 lines
16 KiB
C#
using System;
|
|
using System.Numerics;
|
|
using JetBrains.Annotations;
|
|
using Robust.Shared.GameObjects;
|
|
using Robust.Shared.IoC;
|
|
using Robust.Shared.Map.Components;
|
|
using Robust.Shared.Maths;
|
|
using Robust.Shared.Serialization.Manager.Attributes;
|
|
using Robust.Shared.Utility;
|
|
|
|
namespace Robust.Shared.Map
|
|
{
|
|
/// <summary>
|
|
/// A set of coordinates relative to another entity.
|
|
/// </summary>
|
|
[PublicAPI, DataRecord]
|
|
public readonly partial record struct EntityCoordinates : ISpanFormattable
|
|
{
|
|
public static readonly EntityCoordinates Invalid = new(EntityUid.Invalid, Vector2.Zero);
|
|
|
|
/// <summary>
|
|
/// ID of the entity that this position is relative to.
|
|
/// </summary>
|
|
public readonly EntityUid EntityId;
|
|
|
|
/// <summary>
|
|
/// Position in the entity's local space.
|
|
/// </summary>
|
|
public readonly Vector2 Position;
|
|
|
|
/// <summary>
|
|
/// Location of the X axis local to the entity.
|
|
/// </summary>
|
|
public float X => Position.X;
|
|
|
|
/// <summary>
|
|
/// Location of the Y axis local to the entity.
|
|
/// </summary>
|
|
public float Y => Position.Y;
|
|
|
|
public EntityCoordinates()
|
|
{
|
|
EntityId = EntityUid.Invalid;
|
|
Position = Vector2.Zero;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Constructs a new instance of <see cref="EntityCoordinates"/>.
|
|
/// </summary>
|
|
/// <param name="entityId">ID of the entity that this position is relative to.</param>
|
|
/// <param name="position">Position in the entity's local space.</param>
|
|
public EntityCoordinates(EntityUid entityId, Vector2 position)
|
|
{
|
|
EntityId = entityId;
|
|
Position = position;
|
|
}
|
|
|
|
public EntityCoordinates(EntityUid entityId, float x, float y)
|
|
{
|
|
EntityId = entityId;
|
|
Position = new Vector2(x, y);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Verifies that this set of coordinates can be currently resolved to a location.
|
|
/// </summary>
|
|
/// <param name="entityManager">Entity Manager containing the entity Id.</param>
|
|
/// <returns><see langword="true" /> if this set of coordinates can be currently resolved to a location, otherwise <see langword="false" />.</returns>
|
|
public bool IsValid(IEntityManager entityManager)
|
|
{
|
|
if (!EntityId.IsValid() || !entityManager.EntityExists(EntityId))
|
|
return false;
|
|
|
|
if (!float.IsFinite(Position.X) || !float.IsFinite(Position.Y))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
[Obsolete("Use SharedTransformSystem.ToMapCoordinates()")]
|
|
public MapCoordinates ToMap(IEntityManager entityManager, SharedTransformSystem transformSystem)
|
|
{
|
|
return transformSystem.ToMapCoordinates(this);
|
|
}
|
|
|
|
[Obsolete("Use SharedTransformSystem.ToMapCoordinates()")]
|
|
public Vector2 ToMapPos(IEntityManager entityManager, SharedTransformSystem transformSystem)
|
|
{
|
|
return ToMap(entityManager, transformSystem).Position;
|
|
}
|
|
|
|
[Obsolete("Use SharedTransformSystem.ToCoordinates()")]
|
|
public static EntityCoordinates FromMap(EntityUid entity, MapCoordinates coordinates, SharedTransformSystem transformSystem, IEntityManager? entMan = null)
|
|
{
|
|
return transformSystem.ToCoordinates(entity, coordinates);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Converts this set of coordinates to Vector2i.
|
|
/// </summary>
|
|
public Vector2i ToVector2i(
|
|
IEntityManager entityManager,
|
|
SharedTransformSystem transformSystem)
|
|
{
|
|
if(!IsValid(entityManager))
|
|
return new Vector2i();
|
|
|
|
var mapSystem = entityManager.System<SharedMapSystem>();
|
|
var gridIdOpt = transformSystem.GetGrid(this);
|
|
if (gridIdOpt is { } gridId && gridId.IsValid())
|
|
{
|
|
var grid = entityManager.GetComponent<MapGridComponent>(gridId);
|
|
return mapSystem.GetTileRef(gridId, grid, this).GridIndices;
|
|
}
|
|
|
|
var vec = transformSystem.ToMapCoordinates(this);
|
|
|
|
return new Vector2i((int)MathF.Floor(vec.X), (int)MathF.Floor(vec.Y));
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns an new set of EntityCoordinates with the same <see cref="EntityId"/>
|
|
/// but on a different position.
|
|
/// </summary>
|
|
/// <param name="newPosition">The position the new EntityCoordinates will be in</param>
|
|
/// <returns>A new set of EntityCoordinates with the specified position and same <see cref="EntityId"/> as this one.</returns>
|
|
public EntityCoordinates WithPosition(Vector2 newPosition)
|
|
{
|
|
return new(EntityId, newPosition);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a new set of EntityCoordinates local to a new entity.
|
|
/// </summary>
|
|
/// <param name="entityManager">The Entity Manager holding this entity</param>
|
|
/// <param name="entityId">The entity that the new coordinates will be local to</param>
|
|
/// <returns>A new set of EntityCoordinates local to a new entity.</returns>
|
|
[Obsolete("Use SharedTransformSystem.WithEntityId()")]
|
|
public EntityCoordinates WithEntityId(IEntityManager entityManager, EntityUid entityId)
|
|
{
|
|
if (!entityManager.EntityExists(entityId))
|
|
return new EntityCoordinates(entityId, Vector2.Zero);
|
|
|
|
return WithEntityId(entityId);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a new set of EntityCoordinates local to a new entity.
|
|
/// </summary>
|
|
/// <param name="entity">The entity that the new coordinates will be local to</param>
|
|
/// <returns>A new set of EntityCoordinates local to a new entity.</returns>
|
|
[Obsolete("Use SharedTransformSystem.WithEntityId()")]
|
|
public EntityCoordinates WithEntityId(EntityUid entity, IEntityManager? entMan = null)
|
|
{
|
|
IoCManager.Resolve(ref entMan);
|
|
return WithEntityId(entity, entMan.System<SharedTransformSystem>(), entMan);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns a new set of EntityCoordinates local to a new entity.
|
|
/// </summary>
|
|
/// <param name="entity">The entity that the new coordinates will be local to</param>
|
|
/// <returns>A new set of EntityCoordinates local to a new entity.</returns>
|
|
[Obsolete("Use SharedTransformSystem.WithEntityId()")]
|
|
public EntityCoordinates WithEntityId(
|
|
EntityUid entity,
|
|
SharedTransformSystem transformSystem,
|
|
IEntityManager? entMan = null)
|
|
{
|
|
return transformSystem.WithEntityId(this, entity);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the Grid EntityUid these coordinates are on.
|
|
/// If none of the ancestors are a grid, returns null instead.
|
|
/// </summary>
|
|
/// <param name="entityManager"></param>
|
|
/// <returns>Grid EntityUid this entity is on or null</returns>
|
|
[Obsolete("Use SharedTransformSystem.GetGrid()")]
|
|
public EntityUid? GetGridUid(IEntityManager entityManager)
|
|
{
|
|
return !IsValid(entityManager) ? null : entityManager.GetComponent<TransformComponent>(EntityId).GridUid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the Map Id these coordinates are on.
|
|
/// If the relative entity is not valid, returns <see cref="MapId.Nullspace"/> instead.
|
|
/// </summary>
|
|
/// <param name="entityManager"></param>
|
|
/// <returns>Map Id these coordinates are on or <see cref="MapId.Nullspace"/></returns>
|
|
[Obsolete("Use SharedTransformSystem.GetMapId()")]
|
|
public MapId GetMapId(IEntityManager entityManager)
|
|
{
|
|
return !IsValid(entityManager) ? MapId.Nullspace : entityManager.GetComponent<TransformComponent>(EntityId).MapID;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the Map Id these coordinates are on.
|
|
/// If the relative entity is not valid, returns null instead.
|
|
/// </summary>
|
|
/// <param name="entityManager"></param>
|
|
/// <returns>Map Id these coordinates are on or null</returns>
|
|
[Obsolete("Use SharedTransformSystem.GetMap()")]
|
|
public EntityUid? GetMapUid(IEntityManager entityManager)
|
|
{
|
|
return !IsValid(entityManager) ? null : entityManager.GetComponent<TransformComponent>(EntityId).MapUid;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Offsets the position by a given vector. This happens in local space.
|
|
/// </summary>
|
|
/// <param name="position">The vector to offset by local to the entity.</param>
|
|
/// <returns>Newly offset coordinates.</returns>
|
|
[Pure]
|
|
public EntityCoordinates Offset(Vector2 position)
|
|
{
|
|
return new(EntityId, Position + position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Compares two sets of coordinates to see if they are in range of each other.
|
|
/// </summary>
|
|
/// <param name="entityManager">Entity Manager containing the two entity Ids.</param>
|
|
/// <param name="otherCoordinates">Other set of coordinates to use.</param>
|
|
/// <param name="range">maximum distance between the two sets of coordinates.</param>
|
|
/// <returns>True if the two points are within a given range.</returns>
|
|
[Obsolete("Use TransformSystem.InRange()")]
|
|
public bool InRange(IEntityManager entityManager, EntityCoordinates otherCoordinates, float range)
|
|
{
|
|
return InRange(entityManager, entityManager.System<SharedTransformSystem>(), otherCoordinates, range);
|
|
}
|
|
|
|
[Obsolete("Use TransformSystem.InRange()")]
|
|
public bool InRange(
|
|
IEntityManager entityManager,
|
|
SharedTransformSystem transformSystem,
|
|
EntityCoordinates otherCoordinates,
|
|
float range)
|
|
{
|
|
return transformSystem.InRange(this, otherCoordinates, range);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to calculate the distance between two sets of coordinates.
|
|
/// </summary>
|
|
/// <param name="entityManager"></param>
|
|
/// <param name="otherCoordinates"></param>
|
|
/// <param name="distance"></param>
|
|
/// <returns>True if it was possible to calculate the distance</returns>
|
|
public bool TryDistance(IEntityManager entityManager, EntityCoordinates otherCoordinates, out float distance)
|
|
{
|
|
return TryDistance(
|
|
entityManager,
|
|
entityManager.System<SharedTransformSystem>(),
|
|
otherCoordinates,
|
|
out distance);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to calculate the distance between two sets of coordinates.
|
|
/// </summary>
|
|
/// <returns>True if it was possible to calculate the distance</returns>
|
|
public bool TryDistance(
|
|
IEntityManager entityManager,
|
|
SharedTransformSystem transformSystem,
|
|
EntityCoordinates otherCoordinates,
|
|
out float distance)
|
|
{
|
|
if (TryDelta(entityManager, transformSystem, otherCoordinates, out var delta))
|
|
{
|
|
distance = delta.Length();
|
|
return true;
|
|
}
|
|
|
|
distance = 0f;
|
|
return false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Tries to calculate the distance vector between two sets of coordinates.
|
|
/// </summary>
|
|
/// <returns>True if it was possible to calculate the distance</returns>
|
|
public bool TryDelta(
|
|
IEntityManager entityManager,
|
|
SharedTransformSystem transformSystem,
|
|
EntityCoordinates otherCoordinates,
|
|
out Vector2 delta)
|
|
{
|
|
delta = Vector2.Zero;
|
|
|
|
if (!IsValid(entityManager) || !otherCoordinates.IsValid(entityManager))
|
|
return false;
|
|
|
|
if (EntityId == otherCoordinates.EntityId)
|
|
{
|
|
delta = Position - otherCoordinates.Position;
|
|
return true;
|
|
}
|
|
|
|
var mapCoordinates = transformSystem.ToMapCoordinates(this);
|
|
var otherMapCoordinates = transformSystem.ToMapCoordinates(otherCoordinates);
|
|
|
|
if (mapCoordinates.MapId != otherMapCoordinates.MapId)
|
|
return false;
|
|
|
|
delta = mapCoordinates.Position - otherMapCoordinates.Position;
|
|
return true;
|
|
}
|
|
|
|
#region Operators
|
|
|
|
/// <summary>
|
|
/// Returns the sum for both coordinates but only if they have the same relative entity.
|
|
/// </summary>
|
|
/// <exception cref="ArgumentException">Thrown when the relative entities aren't the same</exception>
|
|
public static EntityCoordinates operator +(EntityCoordinates left, EntityCoordinates right)
|
|
{
|
|
if(left.EntityId != right.EntityId)
|
|
throw new ArgumentException("Can't sum EntityCoordinates with different relative entities.");
|
|
|
|
return new EntityCoordinates(left.EntityId, left.Position + right.Position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the difference for both coordinates but only if they have the same relative entity.
|
|
/// </summary>
|
|
/// <exception cref="ArgumentException">Thrown when the relative entities aren't the same</exception>
|
|
public static EntityCoordinates operator -(EntityCoordinates left, EntityCoordinates right)
|
|
{
|
|
if(left.EntityId != right.EntityId)
|
|
throw new ArgumentException("Can't subtract EntityCoordinates with different relative entities.");
|
|
|
|
return new EntityCoordinates(left.EntityId, left.Position - right.Position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the multiplication of both coordinates but only if they have the same relative entity.
|
|
/// </summary>
|
|
/// <exception cref="ArgumentException">When the relative entities aren't the same</exception>
|
|
public static EntityCoordinates operator *(EntityCoordinates left, EntityCoordinates right)
|
|
{
|
|
if(left.EntityId != right.EntityId)
|
|
throw new ArgumentException("Can't multiply EntityCoordinates with different relative entities.");
|
|
|
|
return new EntityCoordinates(left.EntityId, left.Position * right.Position);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scales the coordinates by a given factor.
|
|
/// </summary>
|
|
/// <exception cref="ArgumentException">When the relative entities aren't the same</exception>
|
|
public static EntityCoordinates operator *(EntityCoordinates left, float right)
|
|
{
|
|
return new(left.EntityId, left.Position * right);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Scales the coordinates by a given factor.
|
|
/// </summary>
|
|
/// <exception cref="ArgumentException">When the relative entities aren't the same</exception>
|
|
public static EntityCoordinates operator *(EntityCoordinates left, int right)
|
|
{
|
|
return new(left.EntityId, left.Position * right);
|
|
}
|
|
|
|
#endregion
|
|
|
|
/// <summary>
|
|
/// Deconstructs the object into it's fields.
|
|
/// </summary>
|
|
/// <param name="entId">ID of the entity that this position is relative to.</param>
|
|
/// <param name="localPos">Position in the entity's local space.</param>
|
|
public void Deconstruct(out EntityUid entId, out Vector2 localPos)
|
|
{
|
|
entId = EntityId;
|
|
localPos = Position;
|
|
}
|
|
|
|
/// <inheritdoc />
|
|
public override string ToString()
|
|
{
|
|
return $"EntId={EntityId}, X={Position.X:N2}, Y={Position.Y:N2}";
|
|
}
|
|
|
|
public string ToString(string? format, IFormatProvider? formatProvider) => ToString();
|
|
|
|
public bool TryFormat(
|
|
Span<char> destination,
|
|
out int charsWritten,
|
|
ReadOnlySpan<char> format,
|
|
IFormatProvider? provider)
|
|
{
|
|
return FormatHelpers.TryFormatInto(
|
|
destination,
|
|
out charsWritten,
|
|
$"EntId={EntityId}, X={Position.X:N2}, Y={Position.Y:N2}");
|
|
}
|
|
}
|
|
}
|