RCD Refactor (#34781)
* fixed prediction (hopefully), removed caching of prototype, sealed the class, removed any and count * erroneus using statement * removed unused timing, removed obsolete method of getting gridUid * nuked mapgriddata * code cleanup * cleanup * this has to be a string without me rewriting more code than i want to in this moment * kill --------- Co-authored-by: metalgearsloth <31366439+metalgearsloth@users.noreply.github.com> Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
This commit is contained in:
@@ -96,20 +96,22 @@ public sealed class AlignRCDConstruction : PlacementMode
|
|||||||
if (!_entityManager.TryGetComponent<RCDComponent>(heldEntity, out var rcd))
|
if (!_entityManager.TryGetComponent<RCDComponent>(heldEntity, out var rcd))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Retrieve the map grid data for the position
|
var gridUid = _transformSystem.GetGrid(position);
|
||||||
if (!_rcdSystem.TryGetMapGridData(position, out var mapGridData))
|
if (!_entityManager.TryGetComponent<MapGridComponent>(gridUid, out var mapGrid))
|
||||||
return false;
|
return false;
|
||||||
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, position);
|
||||||
|
var posVector = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, position);
|
||||||
|
|
||||||
// Determine if the user is hovering over a target
|
// Determine if the user is hovering over a target
|
||||||
var currentState = _stateManager.CurrentState;
|
var currentState = _stateManager.CurrentState;
|
||||||
|
|
||||||
if (currentState is not GameplayStateBase screen)
|
if (currentState is not GameplayStateBase screen)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
var target = screen.GetClickedEntity(_transformSystem.ToMapCoordinates(_unalignedMouseCoords));
|
var target = screen.GetClickedEntity(_transformSystem.ToMapCoordinates(_unalignedMouseCoords));
|
||||||
|
|
||||||
// Determine if the RCD operation is valid or not
|
// Determine if the RCD operation is valid or not
|
||||||
if (!_rcdSystem.IsRCDOperationStillValid(heldEntity.Value, rcd, mapGridData.Value, target, player.Value, false))
|
if (!_rcdSystem.IsRCDOperationStillValid(heldEntity.Value, rcd, gridUid.Value, mapGrid, tile, posVector, target, player.Value, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ using Content.Shared.RCD.Systems;
|
|||||||
using Robust.Client.Placement;
|
using Robust.Client.Placement;
|
||||||
using Robust.Client.Player;
|
using Robust.Client.Player;
|
||||||
using Robust.Shared.Enums;
|
using Robust.Shared.Enums;
|
||||||
|
using Robust.Shared.Prototypes;
|
||||||
|
|
||||||
namespace Content.Client.RCD;
|
namespace Content.Client.RCD;
|
||||||
|
|
||||||
@@ -14,6 +15,7 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
|||||||
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
[Dependency] private readonly IPlayerManager _playerManager = default!;
|
||||||
[Dependency] private readonly RCDSystem _rcdSystem = default!;
|
[Dependency] private readonly RCDSystem _rcdSystem = default!;
|
||||||
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
[Dependency] private readonly IPlacementManager _placementManager = default!;
|
||||||
|
[Dependency] private readonly IPrototypeManager _protoManager = default!;
|
||||||
|
|
||||||
private string _placementMode = typeof(AlignRCDConstruction).Name;
|
private string _placementMode = typeof(AlignRCDConstruction).Name;
|
||||||
private Direction _placementDirection = default;
|
private Direction _placementDirection = default;
|
||||||
@@ -47,6 +49,7 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
|||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var prototype = _protoManager.Index(rcd.ProtoId);
|
||||||
|
|
||||||
// Update the direction the RCD prototype based on the placer direction
|
// Update the direction the RCD prototype based on the placer direction
|
||||||
if (_placementDirection != _placementManager.Direction)
|
if (_placementDirection != _placementManager.Direction)
|
||||||
@@ -56,9 +59,7 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the placer has not changed, exit
|
// If the placer has not changed, exit
|
||||||
_rcdSystem.UpdateCachedPrototype(heldEntity.Value, rcd);
|
if (heldEntity == placerEntity && prototype.Prototype == placerProto)
|
||||||
|
|
||||||
if (heldEntity == placerEntity && rcd.CachedPrototype.Prototype == placerProto)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Create a new placer
|
// Create a new placer
|
||||||
@@ -66,9 +67,9 @@ public sealed class RCDConstructionGhostSystem : EntitySystem
|
|||||||
{
|
{
|
||||||
MobUid = heldEntity.Value,
|
MobUid = heldEntity.Value,
|
||||||
PlacementOption = _placementMode,
|
PlacementOption = _placementMode,
|
||||||
EntityType = rcd.CachedPrototype.Prototype,
|
EntityType = prototype.Prototype,
|
||||||
Range = (int) Math.Ceiling(SharedInteractionSystem.InteractionRange),
|
Range = (int) Math.Ceiling(SharedInteractionSystem.InteractionRange),
|
||||||
IsTile = (rcd.CachedPrototype.Mode == RcdMode.ConstructTile),
|
IsTile = (prototype.Mode == RcdMode.ConstructTile),
|
||||||
UseEditorContext = false,
|
UseEditorContext = false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,25 +33,13 @@ public sealed partial class RCDComponent : Component
|
|||||||
[DataField, AutoNetworkedField]
|
[DataField, AutoNetworkedField]
|
||||||
public ProtoId<RCDPrototype> ProtoId { get; set; } = "Invalid";
|
public ProtoId<RCDPrototype> ProtoId { get; set; } = "Invalid";
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// A cached copy of currently selected RCD prototype
|
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// If the ProtoId is changed, make sure to update the CachedPrototype as well
|
|
||||||
/// </remarks>
|
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
|
||||||
public RCDPrototype CachedPrototype { get; set; } = default!;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The direction constructed entities will face upon spawning
|
/// The direction constructed entities will face upon spawning
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, AutoNetworkedField]
|
[DataField, AutoNetworkedField]
|
||||||
public Direction ConstructionDirection
|
public Direction ConstructionDirection
|
||||||
{
|
{
|
||||||
get
|
get => _constructionDirection;
|
||||||
{
|
|
||||||
return _constructionDirection;
|
|
||||||
}
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
_constructionDirection = value;
|
_constructionDirection = value;
|
||||||
@@ -68,5 +56,5 @@ public sealed partial class RCDComponent : Component
|
|||||||
/// Contains no position data
|
/// Contains no position data
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
public Transform ConstructionTransform { get; private set; } = default!;
|
public Transform ConstructionTransform { get; private set; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,27 +4,16 @@ using Robust.Shared.Serialization;
|
|||||||
namespace Content.Shared.RCD;
|
namespace Content.Shared.RCD;
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class RCDSystemMessage : BoundUserInterfaceMessage
|
public sealed class RCDSystemMessage(ProtoId<RCDPrototype> protoId) : BoundUserInterfaceMessage
|
||||||
{
|
{
|
||||||
public ProtoId<RCDPrototype> ProtoId;
|
public ProtoId<RCDPrototype> ProtoId = protoId;
|
||||||
|
|
||||||
public RCDSystemMessage(ProtoId<RCDPrototype> protoId)
|
|
||||||
{
|
|
||||||
ProtoId = protoId;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed class RCDConstructionGhostRotationEvent : EntityEventArgs
|
public sealed class RCDConstructionGhostRotationEvent(NetEntity netEntity, Direction direction) : EntityEventArgs
|
||||||
{
|
{
|
||||||
public readonly NetEntity NetEntity;
|
public readonly NetEntity NetEntity = netEntity;
|
||||||
public readonly Direction Direction;
|
public readonly Direction Direction = direction;
|
||||||
|
|
||||||
public RCDConstructionGhostRotationEvent(NetEntity netEntity, Direction direction)
|
|
||||||
{
|
|
||||||
NetEntity = netEntity;
|
|
||||||
Direction = direction;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
|
|||||||
@@ -6,10 +6,10 @@ using Robust.Shared.Utility;
|
|||||||
namespace Content.Shared.RCD;
|
namespace Content.Shared.RCD;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Contains the parameters for a RCD construction / operation
|
/// Contains the parameters for an RCD construction / operation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Prototype("rcd")]
|
[Prototype("rcd")]
|
||||||
public sealed partial class RCDPrototype : IPrototype
|
public sealed class RCDPrototype : IPrototype
|
||||||
{
|
{
|
||||||
[IdDataField]
|
[IdDataField]
|
||||||
public string ID { get; private set; } = default!;
|
public string ID { get; private set; } = default!;
|
||||||
@@ -36,13 +36,13 @@ public sealed partial class RCDPrototype : IPrototype
|
|||||||
/// Texture path for this prototypes menu icon
|
/// Texture path for this prototypes menu icon
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||||
public SpriteSpecifier? Sprite { get; private set; } = null;
|
public SpriteSpecifier? Sprite { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The entity prototype that will be constructed (mode dependent)
|
/// The entity prototype that will be constructed (mode dependent)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||||
public string? Prototype { get; private set; } = string.Empty;
|
public string? Prototype { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Number of charges consumed when the operation is completed
|
/// Number of charges consumed when the operation is completed
|
||||||
@@ -60,10 +60,10 @@ public sealed partial class RCDPrototype : IPrototype
|
|||||||
/// The visual effect that plays during this operation
|
/// The visual effect that plays during this operation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("fx"), ViewVariables(VVAccess.ReadOnly)]
|
[DataField("fx"), ViewVariables(VVAccess.ReadOnly)]
|
||||||
public EntProtoId? Effect { get; private set; } = null;
|
public EntProtoId? Effect { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A list of rules that govern where the entity prototype can be contructed
|
/// A list of rules that govern where the entity prototype can be constructed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[DataField("rules"), ViewVariables(VVAccess.ReadOnly)]
|
[DataField("rules"), ViewVariables(VVAccess.ReadOnly)]
|
||||||
public HashSet<RcdConstructionRule> ConstructionRules { get; private set; } = new();
|
public HashSet<RcdConstructionRule> ConstructionRules { get; private set; } = new();
|
||||||
@@ -84,10 +84,7 @@ public sealed partial class RCDPrototype : IPrototype
|
|||||||
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
[DataField, ViewVariables(VVAccess.ReadOnly)]
|
||||||
public Box2? CollisionBounds
|
public Box2? CollisionBounds
|
||||||
{
|
{
|
||||||
get
|
get => _collisionBounds;
|
||||||
{
|
|
||||||
return _collisionBounds;
|
|
||||||
}
|
|
||||||
|
|
||||||
private set
|
private set
|
||||||
{
|
{
|
||||||
@@ -103,13 +100,13 @@ public sealed partial class RCDPrototype : IPrototype
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Box2? _collisionBounds = null;
|
private Box2? _collisionBounds;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The polygon shape associated with the prototype CollisionBounds (if set)
|
/// The polygon shape associated with the prototype CollisionBounds (if set)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[ViewVariables(VVAccess.ReadOnly)]
|
[ViewVariables(VVAccess.ReadOnly)]
|
||||||
public PolygonShape? CollisionPolygon { get; private set; } = null;
|
public PolygonShape? CollisionPolygon { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Governs how the local rotation of the constructed entity will be set
|
/// Governs how the local rotation of the constructed entity will be set
|
||||||
|
|||||||
@@ -22,16 +22,12 @@ using Robust.Shared.Physics.Collision.Shapes;
|
|||||||
using Robust.Shared.Physics.Dynamics;
|
using Robust.Shared.Physics.Dynamics;
|
||||||
using Robust.Shared.Prototypes;
|
using Robust.Shared.Prototypes;
|
||||||
using Robust.Shared.Serialization;
|
using Robust.Shared.Serialization;
|
||||||
using Robust.Shared.Timing;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Content.Shared.RCD.Systems;
|
namespace Content.Shared.RCD.Systems;
|
||||||
|
|
||||||
[Virtual]
|
public sealed class RCDSystem : EntitySystem
|
||||||
public class RCDSystem : EntitySystem
|
|
||||||
{
|
{
|
||||||
[Dependency] private readonly IGameTiming _timing = default!;
|
|
||||||
[Dependency] private readonly INetManager _net = default!;
|
[Dependency] private readonly INetManager _net = default!;
|
||||||
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
|
||||||
[Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
|
[Dependency] private readonly ITileDefinitionManager _tileDefMan = default!;
|
||||||
@@ -47,6 +43,7 @@ public class RCDSystem : EntitySystem
|
|||||||
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
[Dependency] private readonly SharedMapSystem _mapSystem = default!;
|
||||||
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
[Dependency] private readonly SharedTransformSystem _transform = default!;
|
||||||
[Dependency] private readonly TagSystem _tags = default!;
|
[Dependency] private readonly TagSystem _tags = default!;
|
||||||
|
[Dependency] private readonly SharedTransformSystem _transformSystem = default!;
|
||||||
|
|
||||||
private readonly int _instantConstructionDelay = 0;
|
private readonly int _instantConstructionDelay = 0;
|
||||||
private readonly EntProtoId _instantConstructionFx = "EffectRCDConstruct0";
|
private readonly EntProtoId _instantConstructionFx = "EffectRCDConstruct0";
|
||||||
@@ -74,10 +71,9 @@ public class RCDSystem : EntitySystem
|
|||||||
private void OnMapInit(EntityUid uid, RCDComponent component, MapInitEvent args)
|
private void OnMapInit(EntityUid uid, RCDComponent component, MapInitEvent args)
|
||||||
{
|
{
|
||||||
// On init, set the RCD to its first available recipe
|
// On init, set the RCD to its first available recipe
|
||||||
if (component.AvailablePrototypes.Any())
|
if (component.AvailablePrototypes.Count > 0)
|
||||||
{
|
{
|
||||||
component.ProtoId = component.AvailablePrototypes.First();
|
component.ProtoId = component.AvailablePrototypes.ElementAt(0);
|
||||||
UpdateCachedPrototype(uid, component);
|
|
||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@@ -98,7 +94,6 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
// Set the current RCD prototype to the one supplied
|
// Set the current RCD prototype to the one supplied
|
||||||
component.ProtoId = args.ProtoId;
|
component.ProtoId = args.ProtoId;
|
||||||
UpdateCachedPrototype(uid, component);
|
|
||||||
Dirty(uid, component);
|
Dirty(uid, component);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -107,17 +102,16 @@ public class RCDSystem : EntitySystem
|
|||||||
if (!args.IsInDetailsRange)
|
if (!args.IsInDetailsRange)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Update cached prototype if required
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
UpdateCachedPrototype(uid, component);
|
|
||||||
|
|
||||||
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(component.CachedPrototype.SetName)));
|
var msg = Loc.GetString("rcd-component-examine-mode-details", ("mode", Loc.GetString(prototype.SetName)));
|
||||||
|
|
||||||
if (component.CachedPrototype.Mode == RcdMode.ConstructTile || component.CachedPrototype.Mode == RcdMode.ConstructObject)
|
if (prototype.Mode == RcdMode.ConstructTile || prototype.Mode == RcdMode.ConstructObject)
|
||||||
{
|
{
|
||||||
var name = Loc.GetString(component.CachedPrototype.SetName);
|
var name = Loc.GetString(prototype.SetName);
|
||||||
|
|
||||||
if (component.CachedPrototype.Prototype != null &&
|
if (prototype.Prototype != null &&
|
||||||
_protoManager.TryIndex(component.CachedPrototype.Prototype, out var proto))
|
_protoManager.TryIndex(prototype.Prototype, out var proto))
|
||||||
name = proto.Name;
|
name = proto.Name;
|
||||||
|
|
||||||
msg = Loc.GetString("rcd-component-examine-build-details", ("name", name));
|
msg = Loc.GetString("rcd-component-examine-build-details", ("name", name));
|
||||||
@@ -133,32 +127,37 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
var user = args.User;
|
var user = args.User;
|
||||||
var location = args.ClickLocation;
|
var location = args.ClickLocation;
|
||||||
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
|
|
||||||
// Initial validity checks
|
// Initial validity checks
|
||||||
if (!location.IsValid(EntityManager))
|
if (!location.IsValid(EntityManager))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!TryGetMapGridData(location, out var mapGridData))
|
var gridUid = _transformSystem.GetGrid(location);
|
||||||
|
|
||||||
|
if (!TryComp<MapGridComponent>(gridUid, out var mapGrid))
|
||||||
{
|
{
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-no-valid-grid"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-no-valid-grid"), uid, user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Target, args.User))
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Target, args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!_net.IsServer)
|
if (!_net.IsServer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Get the starting cost, delay, and effect from the prototype
|
// Get the starting cost, delay, and effect from the prototype
|
||||||
var cost = component.CachedPrototype.Cost;
|
var cost = prototype.Cost;
|
||||||
var delay = component.CachedPrototype.Delay;
|
var delay = prototype.Delay;
|
||||||
var effectPrototype = component.CachedPrototype.Effect;
|
var effectPrototype = prototype.Effect;
|
||||||
|
|
||||||
#region: Operation modifiers
|
#region: Operation modifiers
|
||||||
|
|
||||||
// Deconstruction modifiers
|
// Deconstruction modifiers
|
||||||
switch (component.CachedPrototype.Mode)
|
switch (prototype.Mode)
|
||||||
{
|
{
|
||||||
case RcdMode.Deconstruct:
|
case RcdMode.Deconstruct:
|
||||||
|
|
||||||
@@ -176,7 +175,7 @@ public class RCDSystem : EntitySystem
|
|||||||
// Deconstructing a tile
|
// Deconstructing a tile
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
var deconstructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location);
|
var deconstructedTile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
var protoName = !deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
|
var protoName = !deconstructedTile.IsSpace() ? _deconstructTileProto : _deconstructLatticeProto;
|
||||||
|
|
||||||
if (_protoManager.TryIndex(protoName, out var deconProto))
|
if (_protoManager.TryIndex(protoName, out var deconProto))
|
||||||
@@ -192,7 +191,7 @@ public class RCDSystem : EntitySystem
|
|||||||
case RcdMode.ConstructTile:
|
case RcdMode.ConstructTile:
|
||||||
|
|
||||||
// If replacing a tile, make the construction instant
|
// If replacing a tile, make the construction instant
|
||||||
var contructedTile = _mapSystem.GetTileRef(mapGridData.Value.GridUid, mapGridData.Value.Component, mapGridData.Value.Location);
|
var contructedTile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
if (!contructedTile.Tile.IsEmpty)
|
if (!contructedTile.Tile.IsEmpty)
|
||||||
{
|
{
|
||||||
@@ -206,8 +205,8 @@ public class RCDSystem : EntitySystem
|
|||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
// Try to start the do after
|
// Try to start the do after
|
||||||
var effect = Spawn(effectPrototype, mapGridData.Value.Location);
|
var effect = Spawn(effectPrototype, location);
|
||||||
var ev = new RCDDoAfterEvent(GetNetCoordinates(mapGridData.Value.Location), component.ConstructionDirection, component.ProtoId, cost, EntityManager.GetNetEntity(effect));
|
var ev = new RCDDoAfterEvent(GetNetCoordinates(location), component.ConstructionDirection, component.ProtoId, cost, EntityManager.GetNetEntity(effect));
|
||||||
|
|
||||||
var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, ev, uid, target: args.Target, used: uid)
|
var doAfterArgs = new DoAfterArgs(EntityManager, user, delay, ev, uid, target: args.Target, used: uid)
|
||||||
{
|
{
|
||||||
@@ -240,37 +239,53 @@ public class RCDSystem : EntitySystem
|
|||||||
// Ensure the RCD operation is still valid
|
// Ensure the RCD operation is still valid
|
||||||
var location = GetCoordinates(args.Event.Location);
|
var location = GetCoordinates(args.Event.Location);
|
||||||
|
|
||||||
if (!TryGetMapGridData(location, out var mapGridData))
|
var gridUid = _transformSystem.GetGrid(location);
|
||||||
|
|
||||||
|
if (!TryComp<MapGridComponent>(gridUid, out var mapGrid))
|
||||||
{
|
{
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Event.Target, args.Event.User))
|
|
||||||
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Event.Target, args.Event.User))
|
||||||
args.Cancel();
|
args.Cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnDoAfter(EntityUid uid, RCDComponent component, RCDDoAfterEvent args)
|
private void OnDoAfter(EntityUid uid, RCDComponent component, RCDDoAfterEvent args)
|
||||||
{
|
{
|
||||||
if (args.Cancelled && _net.IsServer)
|
if (args.Cancelled)
|
||||||
QueueDel(EntityManager.GetEntity(args.Effect));
|
{
|
||||||
|
// Delete the effect entity if the do-after was cancelled (server-side only)
|
||||||
|
if (_net.IsServer)
|
||||||
|
QueueDel(EntityManager.GetEntity(args.Effect));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (args.Handled || args.Cancelled || !_timing.IsFirstTimePredicted)
|
if (args.Handled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
args.Handled = true;
|
args.Handled = true;
|
||||||
|
|
||||||
var location = GetCoordinates(args.Location);
|
var location = GetCoordinates(args.Location);
|
||||||
|
|
||||||
if (!TryGetMapGridData(location, out var mapGridData))
|
var gridUid = _transformSystem.GetGrid(location);
|
||||||
|
|
||||||
|
if (!TryComp<MapGridComponent>(gridUid, out var mapGrid))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
||||||
|
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
||||||
|
|
||||||
// Ensure the RCD operation is still valid
|
// Ensure the RCD operation is still valid
|
||||||
if (!IsRCDOperationStillValid(uid, component, mapGridData.Value, args.Target, args.User))
|
if (!IsRCDOperationStillValid(uid, component, gridUid.Value, mapGrid, tile, position, args.Target, args.User))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Finalize the operation
|
// Finalize the operation (this should handle prediction properly)
|
||||||
FinalizeRCDOperation(uid, component, mapGridData.Value, args.Direction, args.Target, args.User);
|
FinalizeRCDOperation(uid, component, gridUid.Value, mapGrid, tile, position, args.Direction, args.Target, args.User);
|
||||||
|
|
||||||
// Play audio and consume charges
|
// Play audio and consume charges
|
||||||
_audio.PlayPredicted(component.SuccessSound, uid, args.User);
|
_audio.PlayPredicted(component.SuccessSound, uid, args.User);
|
||||||
@@ -301,10 +316,9 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
#region Entity construction/deconstruction rule checks
|
#region Entity construction/deconstruction rule checks
|
||||||
|
|
||||||
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true)
|
public bool IsRCDOperationStillValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, EntityUid? target, EntityUid user, bool popMsgs = true)
|
||||||
{
|
{
|
||||||
// Update cached prototype if required
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
UpdateCachedPrototype(uid, component);
|
|
||||||
|
|
||||||
// Check that the RCD has enough ammo to get the job done
|
// Check that the RCD has enough ammo to get the job done
|
||||||
TryComp<LimitedChargesComponent>(uid, out var charges);
|
TryComp<LimitedChargesComponent>(uid, out var charges);
|
||||||
@@ -318,7 +332,7 @@ public class RCDSystem : EntitySystem
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_charges.HasInsufficientCharges(uid, component.CachedPrototype.Cost, charges))
|
if (_charges.HasInsufficientCharges(uid, prototype.Cost, charges))
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-insufficient-ammo-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-insufficient-ammo-message"), uid, user);
|
||||||
@@ -328,27 +342,31 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
// Exit if the target / target location is obstructed
|
// Exit if the target / target location is obstructed
|
||||||
var unobstructed = (target == null)
|
var unobstructed = (target == null)
|
||||||
? _interaction.InRangeUnobstructed(user, _mapSystem.GridTileToWorld(mapGridData.GridUid, mapGridData.Component, mapGridData.Position), popup: popMsgs)
|
? _interaction.InRangeUnobstructed(user, _mapSystem.GridTileToWorld(gridUid, mapGrid, position), popup: popMsgs)
|
||||||
: _interaction.InRangeUnobstructed(user, target.Value, popup: popMsgs);
|
: _interaction.InRangeUnobstructed(user, target.Value, popup: popMsgs);
|
||||||
|
|
||||||
if (!unobstructed)
|
if (!unobstructed)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Return whether the operation location is valid
|
// Return whether the operation location is valid
|
||||||
switch (component.CachedPrototype.Mode)
|
switch (prototype.Mode)
|
||||||
{
|
{
|
||||||
case RcdMode.ConstructTile: return IsConstructionLocationValid(uid, component, mapGridData, user, popMsgs);
|
case RcdMode.ConstructTile:
|
||||||
case RcdMode.ConstructObject: return IsConstructionLocationValid(uid, component, mapGridData, user, popMsgs);
|
case RcdMode.ConstructObject:
|
||||||
case RcdMode.Deconstruct: return IsDeconstructionStillValid(uid, component, mapGridData, target, user, popMsgs);
|
return IsConstructionLocationValid(uid, component, gridUid, mapGrid, tile, position, user, popMsgs);
|
||||||
|
case RcdMode.Deconstruct:
|
||||||
|
return IsDeconstructionStillValid(uid, tile, target, user, popMsgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsConstructionLocationValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid user, bool popMsgs = true)
|
private bool IsConstructionLocationValid(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, EntityUid user, bool popMsgs = true)
|
||||||
{
|
{
|
||||||
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
|
|
||||||
// Check rule: Must build on empty tile
|
// Check rule: Must build on empty tile
|
||||||
if (component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnEmptyTile) && !mapGridData.Tile.Tile.IsEmpty)
|
if (prototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnEmptyTile) && !tile.Tile.IsEmpty)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-must-build-on-empty-tile-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-must-build-on-empty-tile-message"), uid, user);
|
||||||
@@ -357,7 +375,7 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rule: Must build on non-empty tile
|
// Check rule: Must build on non-empty tile
|
||||||
if (!component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.CanBuildOnEmptyTile) && mapGridData.Tile.Tile.IsEmpty)
|
if (!prototype.ConstructionRules.Contains(RcdConstructionRule.CanBuildOnEmptyTile) && tile.Tile.IsEmpty)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-empty-tile-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-on-empty-tile-message"), uid, user);
|
||||||
@@ -366,7 +384,7 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rule: Must place on subfloor
|
// Check rule: Must place on subfloor
|
||||||
if (component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnSubfloor) && !mapGridData.Tile.Tile.GetContentTileDefinition().IsSubFloor)
|
if (prototype.ConstructionRules.Contains(RcdConstructionRule.MustBuildOnSubfloor) && !tile.Tile.GetContentTileDefinition().IsSubFloor)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-must-build-on-subfloor-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-must-build-on-subfloor-message"), uid, user);
|
||||||
@@ -375,10 +393,10 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Tile specific rules
|
// Tile specific rules
|
||||||
if (component.CachedPrototype.Mode == RcdMode.ConstructTile)
|
if (prototype.Mode == RcdMode.ConstructTile)
|
||||||
{
|
{
|
||||||
// Check rule: Tile placement is valid
|
// Check rule: Tile placement is valid
|
||||||
if (!_floors.CanPlaceTile(mapGridData.GridUid, mapGridData.Component, out var reason))
|
if (!_floors.CanPlaceTile(gridUid, mapGrid, out var reason))
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(reason, uid, user);
|
_popup.PopupClient(reason, uid, user);
|
||||||
@@ -387,7 +405,7 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check rule: Tiles can't be identical
|
// Check rule: Tiles can't be identical
|
||||||
if (mapGridData.Tile.Tile.GetContentTileDefinition().ID == component.CachedPrototype.Prototype)
|
if (tile.Tile.GetContentTileDefinition().ID == prototype.Prototype)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-cannot-build-identical-tile"), uid, user);
|
||||||
@@ -402,11 +420,11 @@ public class RCDSystem : EntitySystem
|
|||||||
// Entity specific rules
|
// Entity specific rules
|
||||||
|
|
||||||
// Check rule: The tile is unoccupied
|
// Check rule: The tile is unoccupied
|
||||||
var isWindow = component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.IsWindow);
|
var isWindow = prototype.ConstructionRules.Contains(RcdConstructionRule.IsWindow);
|
||||||
var isCatwalk = component.CachedPrototype.ConstructionRules.Contains(RcdConstructionRule.IsCatwalk);
|
var isCatwalk = prototype.ConstructionRules.Contains(RcdConstructionRule.IsCatwalk);
|
||||||
|
|
||||||
_intersectingEntities.Clear();
|
_intersectingEntities.Clear();
|
||||||
_lookup.GetLocalEntitiesIntersecting(mapGridData.GridUid, mapGridData.Position, _intersectingEntities, -0.05f, LookupFlags.Uncontained);
|
_lookup.GetLocalEntitiesIntersecting(gridUid, position, _intersectingEntities, -0.05f, LookupFlags.Uncontained);
|
||||||
|
|
||||||
foreach (var ent in _intersectingEntities)
|
foreach (var ent in _intersectingEntities)
|
||||||
{
|
{
|
||||||
@@ -421,17 +439,17 @@ public class RCDSystem : EntitySystem
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (component.CachedPrototype.CollisionMask != CollisionGroup.None && TryComp<FixturesComponent>(ent, out var fixtures))
|
if (prototype.CollisionMask != CollisionGroup.None && TryComp<FixturesComponent>(ent, out var fixtures))
|
||||||
{
|
{
|
||||||
foreach (var fixture in fixtures.Fixtures.Values)
|
foreach (var fixture in fixtures.Fixtures.Values)
|
||||||
{
|
{
|
||||||
// Continue if no collision is possible
|
// Continue if no collision is possible
|
||||||
if (!fixture.Hard || fixture.CollisionLayer <= 0 || (fixture.CollisionLayer & (int) component.CachedPrototype.CollisionMask) == 0)
|
if (!fixture.Hard || fixture.CollisionLayer <= 0 || (fixture.CollisionLayer & (int) prototype.CollisionMask) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Continue if our custom collision bounds are not intersected
|
// Continue if our custom collision bounds are not intersected
|
||||||
if (component.CachedPrototype.CollisionPolygon != null &&
|
if (prototype.CollisionPolygon != null &&
|
||||||
!DoesCustomBoundsIntersectWithFixture(component.CachedPrototype.CollisionPolygon, component.ConstructionTransform, ent, fixture))
|
!DoesCustomBoundsIntersectWithFixture(prototype.CollisionPolygon, component.ConstructionTransform, ent, fixture))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Collision was detected
|
// Collision was detected
|
||||||
@@ -446,13 +464,13 @@ public class RCDSystem : EntitySystem
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool IsDeconstructionStillValid(EntityUid uid, RCDComponent component, MapGridData mapGridData, EntityUid? target, EntityUid user, bool popMsgs = true)
|
private bool IsDeconstructionStillValid(EntityUid uid, TileRef tile, EntityUid? target, EntityUid user, bool popMsgs = true)
|
||||||
{
|
{
|
||||||
// Attempt to deconstruct a floor tile
|
// Attempt to deconstruct a floor tile
|
||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
// The tile is empty
|
// The tile is empty
|
||||||
if (mapGridData.Tile.Tile.IsEmpty)
|
if (tile.Tile.IsEmpty)
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-nothing-to-deconstruct-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-nothing-to-deconstruct-message"), uid, user);
|
||||||
@@ -461,7 +479,7 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The tile has a structure sitting on it
|
// The tile has a structure sitting on it
|
||||||
if (_turf.IsTileBlocked(mapGridData.Tile, CollisionGroup.MobMask))
|
if (_turf.IsTileBlocked(tile, CollisionGroup.MobMask))
|
||||||
{
|
{
|
||||||
if (popMsgs)
|
if (popMsgs)
|
||||||
_popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user);
|
_popup.PopupClient(Loc.GetString("rcd-component-tile-obstructed-message"), uid, user);
|
||||||
@@ -470,7 +488,7 @@ public class RCDSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
|
|
||||||
// The tile cannot be destroyed
|
// The tile cannot be destroyed
|
||||||
var tileDef = (ContentTileDefinition) _tileDefMan[mapGridData.Tile.Tile.TypeId];
|
var tileDef = (ContentTileDefinition) _tileDefMan[tile.Tile.TypeId];
|
||||||
|
|
||||||
if (tileDef.Indestructible)
|
if (tileDef.Indestructible)
|
||||||
{
|
{
|
||||||
@@ -501,25 +519,27 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
#region Entity construction/deconstruction
|
#region Entity construction/deconstruction
|
||||||
|
|
||||||
private void FinalizeRCDOperation(EntityUid uid, RCDComponent component, MapGridData mapGridData, Direction direction, EntityUid? target, EntityUid user)
|
private void FinalizeRCDOperation(EntityUid uid, RCDComponent component, EntityUid gridUid, MapGridComponent mapGrid, TileRef tile, Vector2i position, Direction direction, EntityUid? target, EntityUid user)
|
||||||
{
|
{
|
||||||
if (!_net.IsServer)
|
if (!_net.IsServer)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (component.CachedPrototype.Prototype == null)
|
var prototype = _protoManager.Index(component.ProtoId);
|
||||||
|
|
||||||
|
if (prototype.Prototype == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
switch (component.CachedPrototype.Mode)
|
switch (prototype.Mode)
|
||||||
{
|
{
|
||||||
case RcdMode.ConstructTile:
|
case RcdMode.ConstructTile:
|
||||||
_mapSystem.SetTile(mapGridData.GridUid, mapGridData.Component, mapGridData.Position, new Tile(_tileDefMan[component.CachedPrototype.Prototype].TileId));
|
_mapSystem.SetTile(gridUid, mapGrid, position, new Tile(_tileDefMan[prototype.Prototype].TileId));
|
||||||
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {mapGridData.GridUid} {mapGridData.Position} to {component.CachedPrototype.Prototype}");
|
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {gridUid} {position} to {prototype.Prototype}");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RcdMode.ConstructObject:
|
case RcdMode.ConstructObject:
|
||||||
var ent = Spawn(component.CachedPrototype.Prototype, _mapSystem.GridTileToLocal(mapGridData.GridUid, mapGridData.Component, mapGridData.Position));
|
var ent = Spawn(prototype.Prototype, _mapSystem.GridTileToLocal(gridUid, mapGrid, position));
|
||||||
|
|
||||||
switch (component.CachedPrototype.Rotation)
|
switch (prototype.Rotation)
|
||||||
{
|
{
|
||||||
case RcdRotation.Fixed:
|
case RcdRotation.Fixed:
|
||||||
Transform(ent).LocalRotation = Angle.Zero;
|
Transform(ent).LocalRotation = Angle.Zero;
|
||||||
@@ -532,7 +552,7 @@ public class RCDSystem : EntitySystem
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to spawn {ToPrettyString(ent)} at {mapGridData.Position} on grid {mapGridData.GridUid}");
|
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to spawn {ToPrettyString(ent)} at {position} on grid {gridUid}");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RcdMode.Deconstruct:
|
case RcdMode.Deconstruct:
|
||||||
@@ -540,9 +560,9 @@ public class RCDSystem : EntitySystem
|
|||||||
if (target == null)
|
if (target == null)
|
||||||
{
|
{
|
||||||
// Deconstruct tile (either converts the tile to lattice, or removes lattice)
|
// Deconstruct tile (either converts the tile to lattice, or removes lattice)
|
||||||
var tile = (mapGridData.Tile.Tile.GetContentTileDefinition().ID != "Lattice") ? new Tile(_tileDefMan["Lattice"].TileId) : Tile.Empty;
|
var tileDef = (tile.Tile.GetContentTileDefinition().ID != "Lattice") ? new Tile(_tileDefMan["Lattice"].TileId) : Tile.Empty;
|
||||||
_mapSystem.SetTile(mapGridData.GridUid, mapGridData.Component, mapGridData.Position, tile);
|
_mapSystem.SetTile(gridUid, mapGrid, position, tileDef);
|
||||||
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {mapGridData.GridUid} tile: {mapGridData.Position} open to space");
|
_adminLogger.Add(LogType.RCD, LogImpact.High, $"{ToPrettyString(user):user} used RCD to set grid: {gridUid} tile: {position} open to space");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -559,28 +579,6 @@ public class RCDSystem : EntitySystem
|
|||||||
|
|
||||||
#region Utility functions
|
#region Utility functions
|
||||||
|
|
||||||
public bool TryGetMapGridData(EntityCoordinates location, [NotNullWhen(true)] out MapGridData? mapGridData)
|
|
||||||
{
|
|
||||||
mapGridData = null;
|
|
||||||
var gridUid = _transform.GetGrid(location);
|
|
||||||
|
|
||||||
if (!TryComp<MapGridComponent>(gridUid, out var mapGrid))
|
|
||||||
{
|
|
||||||
location = location.AlignWithClosestGridTile(1.75f, EntityManager);
|
|
||||||
gridUid = _transform.GetGrid(location);
|
|
||||||
|
|
||||||
// Check if we got a grid ID the second time round
|
|
||||||
if (!TryComp(gridUid, out mapGrid))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var tile = _mapSystem.GetTileRef(gridUid.Value, mapGrid, location);
|
|
||||||
var position = _mapSystem.TileIndicesFor(gridUid.Value, mapGrid, location);
|
|
||||||
mapGridData = new MapGridData(gridUid.Value, mapGrid, location, tile, position);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private bool DoesCustomBoundsIntersectWithFixture(PolygonShape boundingPolygon, Transform boundingTransform, EntityUid fixtureOwner, Fixture fixture)
|
private bool DoesCustomBoundsIntersectWithFixture(PolygonShape boundingPolygon, Transform boundingTransform, EntityUid fixtureOwner, Fixture fixture)
|
||||||
{
|
{
|
||||||
var entXformComp = Transform(fixtureOwner);
|
var entXformComp = Transform(fixtureOwner);
|
||||||
@@ -589,50 +587,26 @@ public class RCDSystem : EntitySystem
|
|||||||
return boundingPolygon.ComputeAABB(boundingTransform, 0).Intersects(fixture.Shape.ComputeAABB(entXform, 0));
|
return boundingPolygon.ComputeAABB(boundingTransform, 0).Intersects(fixture.Shape.ComputeAABB(entXform, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateCachedPrototype(EntityUid uid, RCDComponent component)
|
|
||||||
{
|
|
||||||
if (component.ProtoId.Id != component.CachedPrototype?.Prototype)
|
|
||||||
component.CachedPrototype = _protoManager.Index(component.ProtoId);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
|
|
||||||
public struct MapGridData
|
|
||||||
{
|
|
||||||
public EntityUid GridUid;
|
|
||||||
public MapGridComponent Component;
|
|
||||||
public EntityCoordinates Location;
|
|
||||||
public TileRef Tile;
|
|
||||||
public Vector2i Position;
|
|
||||||
|
|
||||||
public MapGridData(EntityUid gridUid, MapGridComponent component, EntityCoordinates location, TileRef tile, Vector2i position)
|
|
||||||
{
|
|
||||||
GridUid = gridUid;
|
|
||||||
Component = component;
|
|
||||||
Location = location;
|
|
||||||
Tile = tile;
|
|
||||||
Position = position;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[Serializable, NetSerializable]
|
[Serializable, NetSerializable]
|
||||||
public sealed partial class RCDDoAfterEvent : DoAfterEvent
|
public sealed partial class RCDDoAfterEvent : DoAfterEvent
|
||||||
{
|
{
|
||||||
[DataField(required: true)]
|
[DataField(required: true)]
|
||||||
public NetCoordinates Location { get; private set; } = default!;
|
public NetCoordinates Location { get; private set; }
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public Direction Direction { get; private set; } = default!;
|
public Direction Direction { get; private set; }
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public ProtoId<RCDPrototype> StartingProtoId { get; private set; } = default!;
|
public ProtoId<RCDPrototype> StartingProtoId { get; private set; }
|
||||||
|
|
||||||
[DataField]
|
[DataField]
|
||||||
public int Cost { get; private set; } = 1;
|
public int Cost { get; private set; } = 1;
|
||||||
|
|
||||||
[DataField("fx")]
|
[DataField("fx")]
|
||||||
public NetEntity? Effect { get; private set; } = null;
|
public NetEntity? Effect { get; private set; }
|
||||||
|
|
||||||
private RCDDoAfterEvent() { }
|
private RCDDoAfterEvent() { }
|
||||||
|
|
||||||
@@ -645,5 +619,8 @@ public sealed partial class RCDDoAfterEvent : DoAfterEvent
|
|||||||
Effect = effect;
|
Effect = effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override DoAfterEvent Clone() => this;
|
public override DoAfterEvent Clone()
|
||||||
|
{
|
||||||
|
return this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user