diff --git a/Content.Client/Decals/DecalPlacementSystem.cs b/Content.Client/Decals/DecalPlacementSystem.cs index 022ad21667..7673378595 100644 --- a/Content.Client/Decals/DecalPlacementSystem.cs +++ b/Content.Client/Decals/DecalPlacementSystem.cs @@ -1,12 +1,13 @@ using Content.Client.Actions; +using Content.Client.Decals.Overlays; using Content.Shared.Actions; using Content.Shared.Actions.ActionTypes; using Content.Shared.Decals; using Robust.Client.GameObjects; +using Robust.Client.Graphics; using Robust.Client.Input; using Robust.Shared.Input; using Robust.Shared.Input.Binding; -using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Serialization.TypeSerializers.Implementations.Custom.Prototype; @@ -17,9 +18,11 @@ namespace Content.Client.Decals; public sealed class DecalPlacementSystem : EntitySystem { [Dependency] private readonly IInputManager _inputManager = default!; - [Dependency] private readonly InputSystem _inputSystem = default!; + [Dependency] private readonly IOverlayManager _overlay = default!; [Dependency] private readonly IPrototypeManager _protoMan = default!; - [Dependency] private readonly IMapManager _mapMan = default!; + [Dependency] private readonly InputSystem _inputSystem = default!; + [Dependency] private readonly SharedTransformSystem _transform = default!; + [Dependency] private readonly SpriteSystem _sprite = default!; private string? _decalId; private Color _decalColor = Color.White; @@ -32,9 +35,17 @@ public sealed class DecalPlacementSystem : EntitySystem private bool _placing; private bool _erasing; + public (DecalPrototype? Decal, bool Snap, Angle Angle, Color Color) GetActiveDecal() + { + return _active && _decalId != null ? + (_protoMan.Index(_decalId), _snap, _decalAngle, _decalColor) : + (null, false, Angle.Zero, Color.Wheat); + } + public override void Initialize() { base.Initialize(); + _overlay.AddOverlay(new DecalPlacementOverlay(this, _transform, _sprite)); CommandBinds.Builder.Bind(EngineKeyFunctions.EditorPlaceObject, new PointerStateInputCmdHandler( (session, coords, uid) => @@ -158,6 +169,7 @@ public sealed class DecalPlacementSystem : EntitySystem { base.Shutdown(); + _overlay.RemoveOverlay(); CommandBinds.Unregister(); } diff --git a/Content.Client/Decals/DecalSystem.cs b/Content.Client/Decals/DecalSystem.cs index 8d599bebdb..fa6066c17b 100644 --- a/Content.Client/Decals/DecalSystem.cs +++ b/Content.Client/Decals/DecalSystem.cs @@ -1,3 +1,4 @@ +using Content.Client.Decals.Overlays; using Content.Shared.Decals; using Robust.Client.GameObjects; using Robust.Client.Graphics; diff --git a/Content.Client/Decals/DecalOverlay.cs b/Content.Client/Decals/Overlays/DecalOverlay.cs similarity index 98% rename from Content.Client/Decals/DecalOverlay.cs rename to Content.Client/Decals/Overlays/DecalOverlay.cs index b360ccec5c..5c6a4570de 100644 --- a/Content.Client/Decals/DecalOverlay.cs +++ b/Content.Client/Decals/Overlays/DecalOverlay.cs @@ -2,11 +2,10 @@ using Content.Shared.Decals; using Robust.Client.GameObjects; using Robust.Client.Graphics; using Robust.Shared.Enums; -using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Utility; -namespace Content.Client.Decals +namespace Content.Client.Decals.Overlays { public sealed class DecalOverlay : Overlay { diff --git a/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs new file mode 100644 index 0000000000..7057187efd --- /dev/null +++ b/Content.Client/Decals/Overlays/DecalPlacementOverlay.cs @@ -0,0 +1,67 @@ +using Robust.Client.GameObjects; +using Robust.Client.Graphics; +using Robust.Client.Input; +using Robust.Shared.Enums; +using Robust.Shared.Map; + +namespace Content.Client.Decals.Overlays; + +public sealed class DecalPlacementOverlay : Overlay +{ + [Dependency] private readonly IEyeManager _eyeManager = default!; + [Dependency] private readonly IInputManager _inputManager = default!; + [Dependency] private readonly IMapManager _mapManager = default!; + private readonly DecalPlacementSystem _placement; + private readonly SharedTransformSystem _transform; + private readonly SpriteSystem _sprite; + + public override OverlaySpace Space => OverlaySpace.WorldSpace; + + public DecalPlacementOverlay(DecalPlacementSystem placement, SharedTransformSystem transform, SpriteSystem sprite) + { + IoCManager.InjectDependencies(this); + _placement = placement; + _transform = transform; + _sprite = sprite; + } + + protected override void Draw(in OverlayDrawArgs args) + { + var (decal, snap, rotation, color) = _placement.GetActiveDecal(); + + if (decal == null) + return; + + var mouseScreenPos = _inputManager.MouseScreenPosition; + var mousePos = _eyeManager.ScreenToMap(mouseScreenPos); + + if (mousePos.MapId != args.MapId) + return; + + // No map support for decals + if (!_mapManager.TryFindGridAt(mousePos, out var grid)) + { + return; + } + + var worldMatrix = _transform.GetWorldMatrix(grid.Owner); + var invMatrix = _transform.GetInvWorldMatrix(grid.Owner); + + var handle = args.WorldHandle; + handle.SetTransform(worldMatrix); + + var localPos = invMatrix.Transform(mousePos.Position); + + if (snap) + { + localPos = (Vector2) localPos.Floored() + grid.TileSize / 2f; + } + + // Nothing uses snap cardinals so probably don't need preview? + var aabb = Box2.UnitCentered.Translated(localPos); + var box = new Box2Rotated(aabb, rotation, localPos); + + handle.DrawTextureRect(_sprite.Frame0(decal.Sprite), box, color); + handle.SetTransform(Matrix3.Identity); + } +} diff --git a/Content.Client/Gameplay/GameplayState.cs b/Content.Client/Gameplay/GameplayState.cs index 67d8b29548..44914c7bee 100644 --- a/Content.Client/Gameplay/GameplayState.cs +++ b/Content.Client/Gameplay/GameplayState.cs @@ -31,10 +31,8 @@ namespace Content.Client.Gameplay [Dependency] private readonly IEyeManager _eyeManager = default!; [Dependency] private readonly IOverlayManager _overlayManager = default!; [Dependency] private readonly IGameTiming _gameTiming = default!; - [Dependency] private readonly IPlayerManager _playerMan = default!; [Dependency] private readonly IUserInterfaceManager _uiManager = default!; [Dependency] private readonly IConfigurationManager _configurationManager = default!; - [Dependency] private readonly IEntityManager _entMan = default!; private FpsCounter _fpsCounter = default!;