using System; using Robust.Client.Graphics.Shaders; using Robust.Client.Interfaces.GameObjects; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components; using Robust.Shared.Input; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Maths; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Robust.Client.GameObjects { // Notice: Most actual logic for clicking is done by the game screen. public class ClickableComponent : Component, IClientClickableComponent { #pragma warning disable 649 [Dependency] private readonly IPrototypeManager _prototypeManager; #pragma warning restore 649 private ShaderInstance _selectionShaderInstance; private string _selectionShader; private Box2? _localBounds; public override string Name => "Clickable"; public override uint? NetID => NetIDs.CLICKABLE; public override Type StateType => typeof(ClickableComponentState); [ViewVariables] public Box2? LocalBounds { get => _localBounds; set => _localBounds = value; } [ViewVariables(VVAccess.ReadWrite)] public string SelectionShader => _selectionShader; /// public override void ExposeData(ObjectSerializer serializer) { serializer.DataFieldCached(ref _selectionShader, "selectionshader", "selection_outline"); serializer.DataField(ref _localBounds, "bounds", null); } /// public override void Initialize() { base.Initialize(); _selectionShaderInstance = _prototypeManager.Index(_selectionShader).Instance(); } /// public override void HandleComponentState(ComponentState curState, ComponentState nextState) { var state = (ClickableComponentState)curState; _localBounds = state.LocalBounds; } /// //TODO: This needs to accept MapPosition, not a Vector2 public bool CheckClick(Vector2 worldPos, out int drawdepth) { if (LocalBounds.HasValue) { var worldBounds = LocalBounds.Value.Translated(Owner.Transform.WorldPosition); if (!worldBounds.Contains(worldPos)) { drawdepth = default; return false; } } if (Owner.TryGetComponent(out ISpriteComponent sprite) && !sprite.Visible) { drawdepth = default; return false; } var component = Owner.GetComponent(); drawdepth = (int)component.DrawDepth; return true; } /// public void OnMouseEnter() { if (Owner.TryGetComponent(out ISpriteComponent sprite)) { sprite.PostShader = _selectionShaderInstance; sprite.RenderOrder = Owner.EntityManager.CurrentTick.Value; } } /// public void OnMouseLeave() { if (Owner.TryGetComponent(out ISpriteComponent sprite)) { sprite.PostShader = null; sprite.RenderOrder = 0; } } } }