Fix some tabletop prediction jank (#12758)
This commit is contained in:
@@ -2,7 +2,11 @@ using Content.Shared.ActionBlocker;
|
||||
using Content.Shared.Hands.Components;
|
||||
using Content.Shared.Interaction;
|
||||
using Content.Shared.Tabletop.Components;
|
||||
using Content.Shared.Tabletop.Events;
|
||||
using Robust.Shared.GameStates;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Network;
|
||||
using Robust.Shared.Players;
|
||||
using Robust.Shared.Serialization;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
@@ -10,8 +14,66 @@ namespace Content.Shared.Tabletop
|
||||
{
|
||||
public abstract class SharedTabletopSystem : EntitySystem
|
||||
{
|
||||
[Dependency] protected readonly ActionBlockerSystem _actionBlockerSystem = default!;
|
||||
[Dependency] protected readonly ActionBlockerSystem ActionBlockerSystem = default!;
|
||||
[Dependency] private readonly SharedInteractionSystem _interactionSystem = default!;
|
||||
[Dependency] private readonly SharedAppearanceSystem _appearance = default!;
|
||||
[Dependency] private readonly SharedTransformSystem _transforms = default!;
|
||||
[Dependency] private readonly IMapManager _mapMan = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
SubscribeLocalEvent<TabletopDraggableComponent, ComponentGetState>(GetDraggableState);
|
||||
SubscribeAllEvent<TabletopDraggingPlayerChangedEvent>(OnDraggingPlayerChanged);
|
||||
SubscribeAllEvent<TabletopMoveEvent>(OnTabletopMove);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Move an entity which is dragged by the user, but check if they are allowed to do so and to these coordinates
|
||||
/// </summary>
|
||||
protected virtual void OnTabletopMove(TabletopMoveEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
if (args.SenderSession is not { AttachedEntity: { } playerEntity } playerSession)
|
||||
return;
|
||||
|
||||
if (!CanSeeTable(playerEntity, msg.TableUid) || !CanDrag(playerEntity, msg.MovedEntityUid, out _))
|
||||
return;
|
||||
|
||||
// Move the entity and dirty it (we use the map ID from the entity so noone can try to be funny and move the item to another map)
|
||||
var transform = EntityManager.GetComponent<TransformComponent>(msg.MovedEntityUid);
|
||||
_transforms.SetParent(transform, _mapMan.GetMapEntityId(transform.MapID));
|
||||
_transforms.SetLocalPositionNoLerp(transform, msg.Coordinates.Position);
|
||||
}
|
||||
|
||||
private void GetDraggableState(EntityUid uid, TabletopDraggableComponent component, ref ComponentGetState args)
|
||||
{
|
||||
args.State = new TabletopDraggableComponentState(component.DraggingPlayer);
|
||||
}
|
||||
|
||||
private void OnDraggingPlayerChanged(TabletopDraggingPlayerChangedEvent msg, EntitySessionEventArgs args)
|
||||
{
|
||||
var dragged = msg.DraggedEntityUid;
|
||||
|
||||
if (!TryComp(dragged, out TabletopDraggableComponent? draggableComponent))
|
||||
return;
|
||||
|
||||
draggableComponent.DraggingPlayer = msg.IsDragging ? args.SenderSession.UserId : null;
|
||||
Dirty(draggableComponent);
|
||||
|
||||
if (!TryComp(dragged, out AppearanceComponent? appearance))
|
||||
return;
|
||||
|
||||
if (draggableComponent.DraggingPlayer != null)
|
||||
{
|
||||
_appearance.SetData(dragged, TabletopItemVisuals.Scale, new Vector2(1.25f, 1.25f), appearance);
|
||||
_appearance.SetData(dragged, TabletopItemVisuals.DrawDepth, (int) DrawDepth.DrawDepth.Items + 1, appearance);
|
||||
}
|
||||
else
|
||||
{
|
||||
_appearance.SetData(dragged, TabletopItemVisuals.Scale, Vector2.One, appearance);
|
||||
_appearance.SetData(dragged, TabletopItemVisuals.DrawDepth, (int) DrawDepth.DrawDepth.Items, appearance);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Serializable, NetSerializable]
|
||||
public sealed class TabletopDraggableComponentState : ComponentState
|
||||
@@ -41,7 +103,7 @@ namespace Content.Shared.Tabletop
|
||||
return false;
|
||||
}
|
||||
|
||||
return _interactionSystem.InRangeUnobstructed(playerEntity, table.Value) && _actionBlockerSystem.CanInteract(playerEntity, table);
|
||||
return _interactionSystem.InRangeUnobstructed(playerEntity, table.Value) && ActionBlockerSystem.CanInteract(playerEntity, table);
|
||||
}
|
||||
|
||||
protected bool CanDrag(EntityUid playerEntity, EntityUid target, [NotNullWhen(true)] out TabletopDraggableComponent? draggable)
|
||||
@@ -51,7 +113,7 @@ namespace Content.Shared.Tabletop
|
||||
|
||||
// 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
|
||||
|
||||
Reference in New Issue
Block a user