Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 48 additions & 18 deletions Robust.Client/Placement/PlacementManager.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
using System;
using System.Collections.Generic;
using System.Numerics;
using Robust.Client.GameObjects;
using Robust.Client.Graphics;
using Robust.Client.Input;
Expand All @@ -11,38 +8,43 @@
using Robust.Shared.Input;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Map;
using Robust.Shared.Map.Components;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Network.Messages;
using Robust.Shared.Placement;
using Robust.Shared.Prototypes;
using Robust.Shared.Reflection;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
using Robust.Shared.Log;
using Direction = Robust.Shared.Maths.Direction;
using Robust.Shared.Map.Components;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Numerics;
using Direction = Robust.Shared.Maths.Direction;

namespace Robust.Client.Placement
{
public sealed partial class PlacementManager : IPlacementManager, IDisposable, IEntityEventSubscriber
{
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IBaseClient _baseClient = default!;
[Dependency] private readonly IClientNetManager _networkManager = default!;
[Dependency] internal readonly IPlayerManager PlayerManager = default!;
[Dependency] internal readonly IResourceCache ResourceCache = default!;
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IGameTiming _time = default!;
[Dependency] internal readonly IClyde Clyde = default!;
[Dependency] private readonly IComponentFactory _componentFactory = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IEyeManager _eyeManager = default!;
[Dependency] private readonly IGameTiming _time = default!;
[Dependency] internal readonly IInputManager InputManager = default!;
[Dependency] private readonly IEntitySystemManager _entitySystemManager = default!;
[Dependency] private readonly IEntityManager _entityManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IBaseClient _baseClient = default!;
[Dependency] private readonly ILogManager _logManager = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly IOverlayManager _overlayManager = default!;
[Dependency] internal readonly IClyde Clyde = default!;
[Dependency] internal readonly IPlayerManager PlayerManager = default!;
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
[Dependency] private readonly IReflectionManager _reflectionManager = default!;
[Dependency] internal readonly IResourceCache ResourceCache = default!;

private static readonly ProtoId<ShaderPrototype> UnshadedShader = "unshaded";

Expand Down Expand Up @@ -743,7 +745,16 @@ private void PreparePlacement(string templateName)
CurrentPrototype = prototype;
IsActive = true;

CurrentPlacementOverlayEntity = EntityManager.SpawnEntity(templateName, MapCoordinates.Nullspace);
if (prototype.TryGetComponent<PlacementOverlayComponent>(out var placementOverlay, _componentFactory))
{
CurrentPlacementOverlayEntity = EntityManager.SpawnEntity(null, MapCoordinates.Nullspace);
SetPlacementOverlaySprite(placementOverlay);
}
else
{
CurrentPlacementOverlayEntity = EntityManager.SpawnEntity(templateName, MapCoordinates.Nullspace);
}

EntityManager.RunMapInit(
CurrentPlacementOverlayEntity.Value,
EntityManager.GetComponent<MetaDataComponent>(CurrentPlacementOverlayEntity.Value));
Expand Down Expand Up @@ -860,6 +871,25 @@ private void RequestPlacement(EntityCoordinates coordinates)
_networkManager.ClientSendMessage(message);
}

private void SetPlacementOverlaySprite(PlacementOverlayComponent placementOverlay)
{
if (CurrentPlacementOverlayEntity == null)
return;

if (Sprite.RsiStateLike(placementOverlay.Sprite) is not RSI.State overlayRSI)
{
//Fallback
Sprite.AddTextureLayer(CurrentPlacementOverlayEntity.Value, Sprite.RsiStateLike(placementOverlay.Sprite).Default);
return;
}

EntityManager.EnsureComponent<SpriteComponent>(CurrentPlacementOverlayEntity.Value, out var overlaySprite);
Sprite.AddRsiLayer(CurrentPlacementOverlayEntity.Value, overlayRSI.StateId, overlayRSI.RSI);

overlaySprite.NoRotation = placementOverlay.NoRotation;
Sprite.SetScale(CurrentPlacementOverlayEntity.Value, placementOverlay.Scale);
}

public enum PlacementTypes : byte
{
None = 0,
Expand Down
28 changes: 28 additions & 0 deletions Robust.Shared/Placement/PlacementOverlayComponent.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
using Robust.Shared.GameObjects;
using Robust.Shared.Serialization.Manager.Attributes;
using Robust.Shared.Utility;
using System.Numerics;

namespace Robust.Shared.Placement;

/// <summary>
/// That component allows modifying the overlay used by the placement system.
/// </summary>
[RegisterComponent]
public sealed partial class PlacementOverlayComponent : Component
{
/// <summary>
/// Specific sprite for the placement overlay.
/// </summary>
[DataField(readOnly: true, required: true)] public SpriteSpecifier Sprite;

/// <summary>
/// Whether the placement overlay should rotate (default: false).
/// </summary>
[DataField(readOnly: true)] public bool NoRotation;

/// <summary>
/// Scaling vector for the placement overlay (default: Vector2.One).
/// </summary>
[DataField(readOnly: true)] public Vector2 Scale = Vector2.One;
}
Loading