diff --git a/Content.Client/Tabletop/Components/TabletopDraggableComponent.cs b/Content.Client/Tabletop/Components/TabletopDraggableComponent.cs deleted file mode 100644 index 35c00de53a..0000000000 --- a/Content.Client/Tabletop/Components/TabletopDraggableComponent.cs +++ /dev/null @@ -1,16 +0,0 @@ -using Content.Shared.Tabletop.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.Network; -using Robust.Shared.ViewVariables; - -namespace Content.Client.Tabletop.Components -{ - [RegisterComponent] - [ComponentReference(typeof(SharedTabletopDraggableComponent))] - public sealed class TabletopDraggableComponent : SharedTabletopDraggableComponent - { - // The player dragging the piece - [ViewVariables] - public NetUserId? DraggingPlayer; - } -} diff --git a/Content.Client/Tabletop/TabletopSystem.cs b/Content.Client/Tabletop/TabletopSystem.cs index 0e1f072e3b..931f2bf8a2 100644 --- a/Content.Client/Tabletop/TabletopSystem.cs +++ b/Content.Client/Tabletop/TabletopSystem.cs @@ -1,7 +1,7 @@ -using Content.Client.Tabletop.Components; using Content.Client.Tabletop.UI; using Content.Client.Viewport; using Content.Shared.Tabletop; +using Content.Shared.Tabletop.Components; using Content.Shared.Tabletop.Events; using JetBrains.Annotations; using Robust.Client.GameObjects; @@ -10,14 +10,10 @@ using Robust.Client.Input; using Robust.Client.Player; using Robust.Client.UserInterface; using Robust.Client.UserInterface.CustomControls; -using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.Input; using Robust.Shared.Input.Binding; -using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.Map; -using Robust.Shared.Maths; using Robust.Shared.Timing; using static Robust.Shared.Input.Binding.PointerInputCmdHandler; using DrawDepth = Content.Shared.DrawDepth.DrawDepth; @@ -51,6 +47,13 @@ namespace Content.Client.Tabletop SubscribeNetworkEvent(OnTabletopPlay); SubscribeLocalEvent(HandleComponentState); + SubscribeLocalEvent(HandleDraggableRemoved); + } + + private void HandleDraggableRemoved(EntityUid uid, TabletopDraggableComponent component, ComponentRemove args) + { + if (_draggedEntity == uid) + StopDragging(false); } public override void Update(float frameTime) @@ -59,13 +62,11 @@ namespace Content.Client.Tabletop if (!_gameTiming.IsFirstTimePredicted) return; - // If there is no player entity, return - if (_playerManager.LocalPlayer is not {ControlledEntity: { } playerEntity}) return; + if (_window == null) + return; - if (StunnedOrNoHands(playerEntity)) - { - StopDragging(); - } + // If there is no player entity, return + if (_playerManager.LocalPlayer is not { ControlledEntity: { } playerEntity }) return; if (!CanSeeTable(playerEntity, _table)) { @@ -77,8 +78,11 @@ namespace Content.Client.Tabletop // If no entity is being dragged or no viewport is clicked, return if (_draggedEntity == null || _viewport == null) return; - // Make sure the dragged entity has a draggable component - if (!EntityManager.TryGetComponent(_draggedEntity.Value, out var draggableComponent)) return; + if (!CanDrag(playerEntity, _draggedEntity.Value, out var draggableComponent)) + { + StopDragging(); + return; + } // If the dragged entity has another dragging player, drop the item // This should happen if the local player is dragging an item, and another player grabs it out of their hand @@ -179,21 +183,7 @@ namespace Content.Client.Tabletop return false; // Return if can not see table or stunned/no hands - if (!CanSeeTable(playerEntity, _table) || StunnedOrNoHands(playerEntity)) - { - return false; - } - - var draggedEntity = args.EntityUid; - - // Set the entity being dragged and the viewport under the mouse - if (!EntityManager.EntityExists(draggedEntity)) - { - return false; - } - - // Make sure that entity can be dragged - if (!EntityManager.HasComponent(draggedEntity)) + if (!CanSeeTable(playerEntity, _table) || !CanDrag(playerEntity, args.EntityUid, out _)) { return false; } @@ -204,7 +194,7 @@ namespace Content.Client.Tabletop return false; } - StartDragging(draggedEntity, viewport); + StartDragging(args.EntityUid, viewport); return true; } diff --git a/Content.Server/Tabletop/Components/TabletopDraggableComponent.cs b/Content.Server/Tabletop/Components/TabletopDraggableComponent.cs deleted file mode 100644 index 9504b46662..0000000000 --- a/Content.Server/Tabletop/Components/TabletopDraggableComponent.cs +++ /dev/null @@ -1,28 +0,0 @@ -using Content.Shared.Tabletop.Components; -using Robust.Shared.GameObjects; -using Robust.Shared.Network; -using Robust.Shared.Players; -using Robust.Shared.ViewVariables; -using static Content.Shared.Tabletop.SharedTabletopSystem; - -namespace Content.Server.Tabletop.Components -{ - [RegisterComponent] - [ComponentReference(typeof(SharedTabletopDraggableComponent))] - public sealed class TabletopDraggableComponent : SharedTabletopDraggableComponent - { - private NetUserId? _draggingPlayer; - - // The player dragging the piece - [ViewVariables] - public NetUserId? DraggingPlayer - { - get => _draggingPlayer; - set - { - _draggingPlayer = value; - Dirty(); - } - } - } -} diff --git a/Content.Server/Tabletop/TabletopSystem.Draggable.cs b/Content.Server/Tabletop/TabletopSystem.Draggable.cs index b96c883639..7db264a841 100644 --- a/Content.Server/Tabletop/TabletopSystem.Draggable.cs +++ b/Content.Server/Tabletop/TabletopSystem.Draggable.cs @@ -1,11 +1,10 @@ using Content.Server.Tabletop.Components; using Content.Shared.Tabletop; +using Content.Shared.Tabletop.Components; using Content.Shared.Tabletop.Events; using Robust.Server.Player; -using Robust.Shared.GameObjects; using Robust.Shared.GameStates; using Robust.Shared.Map; -using Robust.Shared.Maths; using DrawDepth = Content.Shared.DrawDepth.DrawDepth; namespace Content.Server.Tabletop @@ -34,18 +33,7 @@ namespace Content.Server.Tabletop if (!session.Players.ContainsKey(playerSession)) return; - // Return if can not see table or stunned/no hands - if (!EntityManager.EntityExists(msg.TableUid)) - return; - - if (!CanSeeTable(playerEntity, msg.TableUid) || StunnedOrNoHands(playerEntity)) - return; - - // Check if moved entity exists and has tabletop draggable component - if (!EntityManager.EntityExists(msg.MovedEntityUid)) - return; - - if (!EntityManager.HasComponent(msg.MovedEntityUid)) + if (!CanSeeTable(playerEntity, msg.TableUid) || !CanDrag(playerEntity, msg.MovedEntityUid, out _)) return; // TODO: some permission system, disallow movement if you're not permitted to move the item @@ -63,6 +51,7 @@ namespace Content.Server.Tabletop if (!EntityManager.TryGetComponent(dragged, out var draggableComponent)) return; draggableComponent.DraggingPlayer = msg.IsDragging ? args.SenderSession.UserId : null; + Dirty(draggableComponent); if (!EntityManager.TryGetComponent(dragged, out var appearance)) return; diff --git a/Content.Server/Tabletop/TabletopSystem.cs b/Content.Server/Tabletop/TabletopSystem.cs index b80cefedcd..b10f410905 100644 --- a/Content.Server/Tabletop/TabletopSystem.cs +++ b/Content.Server/Tabletop/TabletopSystem.cs @@ -103,11 +103,8 @@ namespace Content.Server.Tabletop var gamerUid = (gamer).Owner; - if (actor.PlayerSession.Status > SessionStatus.Connected || CanSeeTable(gamerUid, gamer.Tabletop) - || !StunnedOrNoHands(gamerUid)) - continue; - - CloseSessionFor(actor.PlayerSession, gamer.Tabletop); + if (actor.PlayerSession.Status != SessionStatus.InGame || !CanSeeTable(gamerUid, gamer.Tabletop)) + CloseSessionFor(actor.PlayerSession, gamer.Tabletop); } } } diff --git a/Content.Shared/Tabletop/Components/SharedTabletopDraggableComponent.cs b/Content.Shared/Tabletop/Components/SharedTabletopDraggableComponent.cs deleted file mode 100644 index d5ab674b3e..0000000000 --- a/Content.Shared/Tabletop/Components/SharedTabletopDraggableComponent.cs +++ /dev/null @@ -1,13 +0,0 @@ -using Robust.Shared.GameObjects; -using Robust.Shared.GameStates; - -namespace Content.Shared.Tabletop.Components -{ - /// - /// Allows an entity to be dragged around by the mouse. The position is updated for all player while dragging. - /// - [NetworkedComponent] - public abstract class SharedTabletopDraggableComponent : Component - { - } -} diff --git a/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs b/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs new file mode 100644 index 0000000000..8bd3754bc7 --- /dev/null +++ b/Content.Shared/Tabletop/Components/TabletopDraggableComponent.cs @@ -0,0 +1,16 @@ +using Robust.Shared.GameStates; +using Robust.Shared.Network; + +namespace Content.Shared.Tabletop.Components; + +/// +/// Allows an entity to be dragged around by the mouse. The position is updated for all player while dragging. +/// +[NetworkedComponent] +[RegisterComponent] +public sealed class TabletopDraggableComponent : Component +{ + // The player dragging the piece + [ViewVariables] + public NetUserId? DraggingPlayer; +} diff --git a/Content.Shared/Tabletop/Events/TabletopMoveEvent.cs b/Content.Shared/Tabletop/Events/TabletopMoveEvent.cs index 6230e12326..10a0d01e27 100644 --- a/Content.Shared/Tabletop/Events/TabletopMoveEvent.cs +++ b/Content.Shared/Tabletop/Events/TabletopMoveEvent.cs @@ -8,7 +8,7 @@ namespace Content.Shared.Tabletop.Events { /// /// An event that is sent to the server every so often by the client to tell where an entity with a - /// has been moved. + /// has been moved. /// [Serializable, NetSerializable] public sealed class TabletopMoveEvent : EntityEventArgs diff --git a/Content.Shared/Tabletop/SharedTabletopSystem.cs b/Content.Shared/Tabletop/SharedTabletopSystem.cs index 7903e999b0..92476333f7 100644 --- a/Content.Shared/Tabletop/SharedTabletopSystem.cs +++ b/Content.Shared/Tabletop/SharedTabletopSystem.cs @@ -2,8 +2,10 @@ using Content.Shared.ActionBlocker; using Content.Shared.Hands.Components; using Content.Shared.Interaction; using Content.Shared.Stunnable; +using Content.Shared.Tabletop.Components; using Robust.Shared.Network; using Robust.Shared.Serialization; +using System.Diagnostics.CodeAnalysis; namespace Content.Shared.Tabletop { @@ -32,15 +34,10 @@ namespace Content.Shared.Tabletop /// The table entity to check. protected bool CanSeeTable(EntityUid playerEntity, EntityUid? table) { - if (table == null) - return false; - - if (EntityManager.GetComponent(table.Value).Parent?.Owner is not { } parent) - { - return false; - } - - if (!EntityManager.HasComponent(parent) && !EntityManager.HasComponent(parent)) + // Table may have been deleted, hence TryComp + if (!TryComp(table, out MetaDataComponent? meta) + || meta.EntityLifeStage >= EntityLifeStage.Terminating + || (meta.Flags & MetaDataFlags.InContainer) == MetaDataFlags.InContainer) { return false; } @@ -48,15 +45,16 @@ namespace Content.Shared.Tabletop return _interactionSystem.InRangeUnobstructed(playerEntity, table.Value) && _actionBlockerSystem.CanInteract(playerEntity, table); } - protected bool StunnedOrNoHands(EntityUid playerEntity) + protected bool CanDrag(EntityUid playerEntity, EntityUid target, [NotNullWhen(true)] out TabletopDraggableComponent? draggable) { - var stunned = EntityManager.HasComponent(playerEntity); - var hasHand = EntityManager.TryGetComponent(playerEntity, out var handsComponent) && - handsComponent.Hands.Count > 0; + if (!TryComp(target, out draggable)) + return false; - return stunned || !hasHand; + // CanSeeTable checks interaction action blockers. So no need to check them here. + // If this ever changes, so that ghosts can spectate games, then the check needs to be moved here. + + return TryComp(playerEntity, out SharedHandsComponent? hands) && hands.Hands.Count > 0; } - #endregion } }