Fix pulling mispredicts (#22941)

* Fix pulling mispredicts

* Make behaviour consistent

* Good ol terminating entities
This commit is contained in:
Leon Friedrich
2023-12-25 02:33:32 -05:00
committed by GitHub
parent 9eaa4c3a5d
commit 721a445bbd
8 changed files with 42 additions and 77 deletions

View File

@@ -1,25 +1,18 @@
using System.Linq;
using System.Numerics; using System.Numerics;
using Content.Server.Popups;
using Content.Server.Pulling; using Content.Server.Pulling;
using Content.Server.Stack; using Content.Server.Stack;
using Content.Server.Storage.EntitySystems;
using Content.Server.Stunnable; using Content.Server.Stunnable;
using Content.Shared.ActionBlocker; using Content.Shared.ActionBlocker;
using Content.Shared.Body.Part; using Content.Shared.Body.Part;
using Content.Shared.CombatMode; using Content.Shared.CombatMode;
using Content.Shared.Explosion; using Content.Shared.Explosion;
using Content.Shared.Hands;
using Content.Shared.Hands.Components; using Content.Shared.Hands.Components;
using Content.Shared.Hands.EntitySystems; using Content.Shared.Hands.EntitySystems;
using Content.Shared.Input; using Content.Shared.Input;
using Content.Shared.Inventory;
using Content.Shared.Physics.Pull; using Content.Shared.Physics.Pull;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using Content.Shared.Stacks; using Content.Shared.Stacks;
using Content.Shared.Storage;
using Content.Shared.Throwing; using Content.Shared.Throwing;
using Robust.Shared.Containers;
using Robust.Shared.GameStates; using Robust.Shared.GameStates;
using Robust.Shared.Input.Binding; using Robust.Shared.Input.Binding;
using Robust.Shared.Map; using Robust.Shared.Map;
@@ -30,16 +23,12 @@ namespace Content.Server.Hands.Systems
{ {
public sealed class HandsSystem : SharedHandsSystem public sealed class HandsSystem : SharedHandsSystem
{ {
[Dependency] private readonly InventorySystem _inventorySystem = default!;
[Dependency] private readonly StackSystem _stackSystem = default!; [Dependency] private readonly StackSystem _stackSystem = default!;
[Dependency] private readonly HandVirtualItemSystem _virtualItemSystem = default!; [Dependency] private readonly HandVirtualItemSystem _virtualItemSystem = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!; [Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly SharedHandVirtualItemSystem _virtualSystem = default!;
[Dependency] private readonly PopupSystem _popupSystem = default!;
[Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!;
[Dependency] private readonly PullingSystem _pullingSystem = default!; [Dependency] private readonly PullingSystem _pullingSystem = default!;
[Dependency] private readonly ThrowingSystem _throwingSystem = default!; [Dependency] private readonly ThrowingSystem _throwingSystem = default!;
[Dependency] private readonly StorageSystem _storageSystem = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -98,14 +87,6 @@ namespace Content.Server.Hands.Systems
args.Handled = true; // no shove/stun. args.Handled = true; // no shove/stun.
} }
protected override void HandleEntityRemoved(EntityUid uid, HandsComponent hands, EntRemovedFromContainerMessage args)
{
base.HandleEntityRemoved(uid, hands, args);
if (!Deleted(args.Entity) && TryComp(args.Entity, out HandVirtualItemComponent? @virtual))
_virtualSystem.Delete((args.Entity, @virtual), uid);
}
private void HandleBodyPartAdded(EntityUid uid, HandsComponent component, ref BodyPartAddedEvent args) private void HandleBodyPartAdded(EntityUid uid, HandsComponent component, ref BodyPartAddedEvent args)
{ {
if (args.Part.PartType != BodyPartType.Hand) if (args.Part.PartType != BodyPartType.Hand)

View File

@@ -25,6 +25,9 @@ public abstract partial class SharedHandsSystem
var didUnequip = new DidUnequipHandEvent(uid, args.Entity, hand); var didUnequip = new DidUnequipHandEvent(uid, args.Entity, hand);
RaiseLocalEvent(uid, didUnequip); RaiseLocalEvent(uid, didUnequip);
if (TryComp(args.Entity, out HandVirtualItemComponent? @virtual))
_virtualSystem.Delete((args.Entity, @virtual), uid);
} }
/// <summary> /// <summary>
@@ -100,8 +103,14 @@ public abstract partial class SharedHandsSystem
var entity = hand.HeldEntity!.Value; var entity = hand.HeldEntity!.Value;
DoDrop(uid, hand, doDropInteraction: doDropInteraction, handsComp); DoDrop(uid, hand, doDropInteraction: doDropInteraction, handsComp);
var userXform = Transform(uid); if (TerminatingOrDeleted(entity))
return true;
var itemXform = Transform(entity); var itemXform = Transform(entity);
if (itemXform.MapUid == null)
return true;
var userXform = Transform(uid);
var isInContainer = ContainerSystem.IsEntityInContainer(uid); var isInContainer = ContainerSystem.IsEntityInContainer(uid);
if (targetDropLocation == null || isInContainer) if (targetDropLocation == null || isInContainer)

View File

@@ -20,6 +20,7 @@ public abstract partial class SharedHandsSystem
[Dependency] private readonly SharedItemSystem _items = default!; [Dependency] private readonly SharedItemSystem _items = default!;
[Dependency] private readonly SharedStorageSystem _storage = default!; [Dependency] private readonly SharedStorageSystem _storage = default!;
[Dependency] protected readonly SharedTransformSystem TransformSystem = default!; [Dependency] protected readonly SharedTransformSystem TransformSystem = default!;
[Dependency] private readonly SharedHandVirtualItemSystem _virtualSystem = default!;
protected event Action<Entity<HandsComponent>?>? OnHandSetActive; protected event Action<Entity<HandsComponent>?>? OnHandSetActive;

View File

@@ -11,6 +11,7 @@ public abstract class SharedHandVirtualItemSystem : EntitySystem
{ {
[Dependency] private readonly INetManager _net = default!; [Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly SharedHandsSystem _hands = default!; [Dependency] private readonly SharedHandsSystem _hands = default!;
[Dependency] private readonly SharedTransformSystem _transform = default!;
public override void Initialize() public override void Initialize()
{ {
@@ -82,14 +83,16 @@ public abstract class SharedHandVirtualItemSystem : EntitySystem
/// </summary> /// </summary>
public void Delete(Entity<HandVirtualItemComponent> item, EntityUid user) public void Delete(Entity<HandVirtualItemComponent> item, EntityUid user)
{ {
if (_net.IsClient)
return;
var userEv = new VirtualItemDeletedEvent(item.Comp.BlockingEntity, user); var userEv = new VirtualItemDeletedEvent(item.Comp.BlockingEntity, user);
RaiseLocalEvent(user, userEv); RaiseLocalEvent(user, userEv);
var targEv = new VirtualItemDeletedEvent(item.Comp.BlockingEntity, user); var targEv = new VirtualItemDeletedEvent(item.Comp.BlockingEntity, user);
RaiseLocalEvent(item.Comp.BlockingEntity, targEv); RaiseLocalEvent(item.Comp.BlockingEntity, targEv);
if (TerminatingOrDeleted(item))
return;
_transform.DetachParentToNull(item, Transform(item));
if (_net.IsServer)
QueueDel(item); QueueDel(item);
} }
} }

View File

@@ -5,7 +5,7 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Pulling.Components namespace Content.Shared.Pulling.Components
{ {
// Before you try to add another type than SharedPullingStateManagementSystem, consider the can of worms you may be opening! // Before you try to add another type than SharedPullingStateManagementSystem, consider the can of worms you may be opening!
[NetworkedComponent()] [NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedPullingStateManagementSystem))] [Access(typeof(SharedPullingStateManagementSystem))]
[RegisterComponent] [RegisterComponent]
public sealed partial class SharedPullableComponent : Component public sealed partial class SharedPullableComponent : Component
@@ -13,11 +13,13 @@ namespace Content.Shared.Pulling.Components
/// <summary> /// <summary>
/// The current entity pulling this component. /// The current entity pulling this component.
/// </summary> /// </summary>
[DataField, AutoNetworkedField]
public EntityUid? Puller { get; set; } public EntityUid? Puller { get; set; }
/// <summary> /// <summary>
/// The pull joint. /// The pull joint.
/// </summary> /// </summary>
[DataField, AutoNetworkedField]
public string? PullJointId { get; set; } public string? PullJointId { get; set; }
public bool BeingPulled => Puller != null; public bool BeingPulled => Puller != null;
@@ -40,17 +42,6 @@ namespace Content.Shared.Pulling.Components
public bool PrevFixedRotation; public bool PrevFixedRotation;
} }
[Serializable, NetSerializable]
public sealed class PullableComponentState : ComponentState
{
public readonly NetEntity? Puller;
public PullableComponentState(NetEntity? puller)
{
Puller = puller;
}
}
/// <summary> /// <summary>
/// Raised when a request is made to stop pulling an entity. /// Raised when a request is made to stop pulling an entity.
/// </summary> /// </summary>

View File

@@ -1,6 +1,8 @@
namespace Content.Shared.Pulling.Components using Robust.Shared.GameStates;
namespace Content.Shared.Pulling.Components
{ {
[RegisterComponent] [RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
[Access(typeof(SharedPullingStateManagementSystem))] [Access(typeof(SharedPullingStateManagementSystem))]
public sealed partial class SharedPullerComponent : Component public sealed partial class SharedPullerComponent : Component
{ {
@@ -9,7 +11,7 @@
public float SprintSpeedModifier => Pulling == default ? 1.0f : 0.95f; public float SprintSpeedModifier => Pulling == default ? 1.0f : 0.95f;
[ViewVariables] [DataField, AutoNetworkedField]
public EntityUid? Pulling { get; set; } public EntityUid? Pulling { get; set; }
/// <summary> /// <summary>

View File

@@ -1,7 +1,6 @@
using Content.Shared.Physics.Pull; using Content.Shared.Physics.Pull;
using Content.Shared.Pulling.Components; using Content.Shared.Pulling.Components;
using JetBrains.Annotations; using JetBrains.Annotations;
using Robust.Shared.GameStates;
using Robust.Shared.Map; using Robust.Shared.Map;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
@@ -26,43 +25,6 @@ namespace Content.Shared.Pulling
base.Initialize(); base.Initialize();
SubscribeLocalEvent<SharedPullableComponent, ComponentShutdown>(OnShutdown); SubscribeLocalEvent<SharedPullableComponent, ComponentShutdown>(OnShutdown);
SubscribeLocalEvent<SharedPullableComponent, ComponentGetState>(OnGetState);
SubscribeLocalEvent<SharedPullableComponent, ComponentHandleState>(OnHandleState);
}
private void OnGetState(EntityUid uid, SharedPullableComponent component, ref ComponentGetState args)
{
args.State = new PullableComponentState(GetNetEntity(component.Puller));
}
private void OnHandleState(EntityUid uid, SharedPullableComponent component, ref ComponentHandleState args)
{
if (args.Current is not PullableComponentState state)
return;
var puller = EnsureEntity<SharedPullableComponent>(state.Puller, uid);
if (!puller.HasValue)
{
ForceDisconnectPullable(component);
return;
}
if (component.Puller == puller)
{
// don't disconnect and reconnect a puller for no reason
return;
}
if (!TryComp<SharedPullerComponent>(puller, out var comp))
{
Log.Error($"Pullable state for entity {ToPrettyString(uid)} had invalid puller entity {ToPrettyString(puller.Value)}");
// ensure it disconnects from any different puller, still
ForceDisconnectPullable(component);
return;
}
ForceRelationship(comp, component);
} }
private void OnShutdown(EntityUid uid, SharedPullableComponent component, ComponentShutdown args) private void OnShutdown(EntityUid uid, SharedPullableComponent component, ComponentShutdown args)
@@ -111,6 +73,9 @@ namespace Content.Shared.Pulling
public void ForceRelationship(SharedPullerComponent? puller, SharedPullableComponent? pullable) public void ForceRelationship(SharedPullerComponent? puller, SharedPullableComponent? pullable)
{ {
if (_timing.ApplyingState)
return;
;
if (pullable != null && puller != null && (puller.Pulling == pullable.Owner)) if (pullable != null && puller != null && (puller.Pulling == pullable.Owner))
{ {
// Already done // Already done
@@ -187,6 +152,9 @@ namespace Content.Shared.Pulling
public void ForceSetMovingTo(SharedPullableComponent pullable, EntityCoordinates? movingTo) public void ForceSetMovingTo(SharedPullableComponent pullable, EntityCoordinates? movingTo)
{ {
if (_timing.ApplyingState)
return;
if (pullable.MovingTo == movingTo) if (pullable.MovingTo == movingTo)
{ {
return; return;
@@ -200,6 +168,7 @@ namespace Content.Shared.Pulling
} }
pullable.MovingTo = movingTo; pullable.MovingTo = movingTo;
Dirty(pullable);
if (movingTo == null) if (movingTo == null)
{ {

View File

@@ -12,6 +12,8 @@ using Robust.Shared.Map;
using Robust.Shared.Physics; using Robust.Shared.Physics;
using Robust.Shared.Physics.Components; using Robust.Shared.Physics.Components;
using Robust.Shared.Physics.Systems; using Robust.Shared.Physics.Systems;
using Robust.Shared.Timing;
using Robust.Shared.Utility;
namespace Content.Shared.Pulling namespace Content.Shared.Pulling
{ {
@@ -23,6 +25,7 @@ namespace Content.Shared.Pulling
[Dependency] private readonly SharedInteractionSystem _interaction = default!; [Dependency] private readonly SharedInteractionSystem _interaction = default!;
[Dependency] private readonly SharedPhysicsSystem _physics = default!; [Dependency] private readonly SharedPhysicsSystem _physics = default!;
[Dependency] private readonly ISharedAdminLogManager _adminLogger = default!; [Dependency] private readonly ISharedAdminLogManager _adminLogger = default!;
[Dependency] private readonly IGameTiming _timing = default!;
public bool CanPull(EntityUid puller, EntityUid pulled) public bool CanPull(EntityUid puller, EntityUid pulled)
{ {
@@ -90,6 +93,9 @@ namespace Content.Shared.Pulling
public bool TryStopPull(SharedPullableComponent pullable, EntityUid? user = null) public bool TryStopPull(SharedPullableComponent pullable, EntityUid? user = null)
{ {
if (_timing.ApplyingState)
return false;
if (!pullable.BeingPulled) if (!pullable.BeingPulled)
{ {
return false; return false;
@@ -127,6 +133,9 @@ namespace Content.Shared.Pulling
// The main "start pulling" function. // The main "start pulling" function.
public bool TryStartPull(SharedPullerComponent puller, SharedPullableComponent pullable) public bool TryStartPull(SharedPullerComponent puller, SharedPullableComponent pullable)
{ {
if (_timing.ApplyingState)
return false;
if (puller.Pulling == pullable.Owner) if (puller.Pulling == pullable.Owner)
return true; return true;