DoAfter Refactor (#13225)

Co-authored-by: DrSmugleaf <drsmugleaf@gmail.com>
This commit is contained in:
keronshb
2023-02-24 19:01:25 -05:00
committed by GitHub
parent 7a9baa79c2
commit 9ebb452a3c
129 changed files with 2624 additions and 4132 deletions

View File

@@ -1,19 +1,16 @@
using System.Threading;
using Content.Server.Administration.Logs;
using Content.Server.Coordinates.Helpers;
using Content.Server.Popups;
using Content.Server.Pulling;
using Content.Server.Tools;
using Content.Shared.Construction.Components;
using Content.Shared.Construction.EntitySystems;
using Content.Shared.Database;
using Content.Shared.Examine;
using Content.Shared.Pulling.Components;
using Content.Shared.Tools;
using Content.Shared.Tools.Components;
using Robust.Shared.Map;
using Robust.Shared.Physics;
using Robust.Shared.Physics.Components;
using Robust.Shared.Player;
namespace Content.Server.Construction
{
@@ -22,16 +19,14 @@ namespace Content.Server.Construction
[Dependency] private readonly IAdminLogManager _adminLogger = default!;
[Dependency] private readonly IMapManager _mapManager = default!;
[Dependency] private readonly PopupSystem _popup = default!;
[Dependency] private readonly ToolSystem _tool = default!;
[Dependency] private readonly SharedToolSystem _tool = default!;
[Dependency] private readonly PullingSystem _pulling = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<AnchorableComponent, TryAnchorCompletedEvent>(OnAnchorComplete);
SubscribeLocalEvent<AnchorableComponent, TryAnchorCancelledEvent>(OnAnchorCancelled);
SubscribeLocalEvent<AnchorableComponent, TryUnanchorCompletedEvent>(OnUnanchorComplete);
SubscribeLocalEvent<AnchorableComponent, TryUnanchorCancelledEvent>(OnUnanchorCancelled);
SubscribeLocalEvent<AnchorableComponent, ExaminedEvent>(OnAnchoredExamine);
}
@@ -42,14 +37,8 @@ namespace Content.Server.Construction
args.PushMarkup(Loc.GetString(messageId, ("target", uid)));
}
private void OnUnanchorCancelled(EntityUid uid, AnchorableComponent component, TryUnanchorCancelledEvent args)
{
component.CancelToken = null;
}
private void OnUnanchorComplete(EntityUid uid, AnchorableComponent component, TryUnanchorCompletedEvent args)
{
component.CancelToken = null;
var xform = Transform(uid);
RaiseLocalEvent(uid, new BeforeUnanchoredEvent(args.User, args.Using));
@@ -65,14 +54,8 @@ namespace Content.Server.Construction
);
}
private void OnAnchorCancelled(EntityUid uid, AnchorableComponent component, TryAnchorCancelledEvent args)
{
component.CancelToken = null;
}
private void OnAnchorComplete(EntityUid uid, AnchorableComponent component, TryAnchorCompletedEvent args)
{
component.CancelToken = null;
var xform = Transform(uid);
if (TryComp<PhysicsComponent>(uid, out var anchorBody) &&
!TileFree(xform.Coordinates, anchorBody))
@@ -144,8 +127,7 @@ namespace Content.Server.Construction
/// <returns>true if it is valid, false otherwise</returns>
private bool Valid(EntityUid uid, EntityUid userUid, EntityUid usingUid, bool anchoring, AnchorableComponent? anchorable = null, ToolComponent? usingTool = null)
{
if (!Resolve(uid, ref anchorable) ||
anchorable.CancelToken != null)
if (!Resolve(uid, ref anchorable))
return false;
if (!Resolve(usingUid, ref usingTool))
@@ -194,10 +176,8 @@ namespace Content.Server.Construction
return;
}
anchorable.CancelToken = new CancellationTokenSource();
_tool.UseTool(usingUid, userUid, uid, 0f, anchorable.Delay, usingTool.Qualities,
new TryAnchorCompletedEvent(userUid, usingUid), new TryAnchorCancelledEvent(userUid, usingUid), uid, cancelToken: anchorable.CancelToken.Token);
var toolEvData = new ToolEventData(new TryAnchorCompletedEvent(userUid, usingUid), targetEntity:uid);
_tool.UseTool(usingUid, userUid, uid, anchorable.Delay, usingTool.Qualities, toolEvData);
}
/// <summary>
@@ -209,18 +189,17 @@ namespace Content.Server.Construction
TransformComponent? transform = null,
ToolComponent? usingTool = null)
{
if (!Resolve(uid, ref anchorable, ref transform) ||
anchorable.CancelToken != null)
if (!Resolve(uid, ref anchorable, ref transform))
return;
if (!Resolve(usingUid, ref usingTool)) return;
if (!Resolve(usingUid, ref usingTool))
return;
if (!Valid(uid, userUid, usingUid, false)) return;
if (!Valid(uid, userUid, usingUid, false))
return;
anchorable.CancelToken = new CancellationTokenSource();
_tool.UseTool(usingUid, userUid, uid, 0f, anchorable.Delay, usingTool.Qualities,
new TryUnanchorCompletedEvent(userUid, usingUid), new TryUnanchorCancelledEvent(userUid, usingUid), uid, cancelToken: anchorable.CancelToken.Token);
var toolEvData = new ToolEventData(new TryUnanchorCompletedEvent(userUid, usingUid), targetEntity:uid);
_tool.UseTool(usingUid, userUid, uid, anchorable.Delay, usingTool.Qualities, toolEvData);
}
/// <summary>
@@ -271,12 +250,6 @@ namespace Content.Server.Construction
}
}
private sealed class TryUnanchorCancelledEvent : AnchorEvent
{
public TryUnanchorCancelledEvent(EntityUid userUid, EntityUid usingUid) : base(userUid, usingUid)
{
}
}
private sealed class TryAnchorCompletedEvent : AnchorEvent
{
@@ -284,12 +257,5 @@ namespace Content.Server.Construction
{
}
}
private sealed class TryAnchorCancelledEvent : AnchorEvent
{
public TryAnchorCancelledEvent(EntityUid userUid, EntityUid usingUid) : base(userUid, usingUid)
{
}
}
}
}

View File

@@ -27,6 +27,4 @@ public sealed class PartExchangerComponent : Component
public SoundSpecifier ExchangeSound = new SoundPathSpecifier("/Audio/Items/rped.ogg");
public IPlayingAudioStream? AudioStream;
public CancellationTokenSource? Token;
}

View File

@@ -11,6 +11,7 @@ using Content.Shared.Construction.Prototypes;
using Content.Shared.Construction.Steps;
using Content.Shared.Coordinates;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Hands.EntitySystems;
using Content.Shared.Interaction;
using Content.Shared.Inventory;

View File

@@ -1,15 +1,15 @@
using Content.Server.Administration.Logs;
using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Server.Temperature.Components;
using Content.Server.Temperature.Systems;
using Content.Shared.Construction;
using Content.Shared.Construction.EntitySystems;
using Content.Shared.Construction.Steps;
using Content.Shared.Database;
using Content.Shared.DoAfter;
using Content.Shared.Interaction;
using Content.Shared.Tools.Components;
using Robust.Shared.Containers;
#if EXCEPTION_TOLERANCE
// ReSharper disable once RedundantUsingDirective
using Robust.Shared.Exceptions;
#endif
@@ -36,6 +36,7 @@ namespace Content.Server.Construction
SubscribeLocalEvent<ConstructionDoAfterCancelled>(OnDoAfterCancelled);
SubscribeLocalEvent<ConstructionComponent, ConstructionDoAfterComplete>(EnqueueEvent);
SubscribeLocalEvent<ConstructionComponent, ConstructionDoAfterCancelled>(EnqueueEvent);
SubscribeLocalEvent<ConstructionComponent, DoAfterEvent<ConstructionData>>(OnDoAfter);
#endregion
@@ -300,20 +301,19 @@ namespace Content.Server.Construction
// If we still haven't completed this step's DoAfter...
if (doAfterState == DoAfterState.None && insertStep.DoAfter > 0)
{
_doAfterSystem.DoAfter(
new DoAfterEventArgs(interactUsing.User, step.DoAfter, default, interactUsing.Target)
{
BreakOnDamage = false,
BreakOnStun = true,
BreakOnTargetMove = true,
BreakOnUserMove = true,
NeedHand = true,
// These events will be broadcast and handled by this very same system, that will
// raise them directed to the target. These events wrap the original event.
var constructionData = new ConstructionData(new ConstructionDoAfterComplete(uid, ev), new ConstructionDoAfterCancelled(uid, ev));
var doAfterEventArgs = new DoAfterEventArgs(interactUsing.User, step.DoAfter, target: interactUsing.Target)
{
BreakOnDamage = false,
BreakOnStun = true,
BreakOnTargetMove = true,
BreakOnUserMove = true,
NeedHand = true
};
// These events will be broadcast and handled by this very same system, that will
// raise them directed to the target. These events wrap the original event.
BroadcastFinishedEvent = new ConstructionDoAfterComplete(uid, ev),
BroadcastCancelledEvent = new ConstructionDoAfterCancelled(uid, ev)
});
_doAfterSystem.DoAfter(doAfterEventArgs, constructionData);
// To properly signal that we're waiting for a DoAfter, we have to set the flag on the component
// and then also return the DoAfter HandleResult.
@@ -375,9 +375,9 @@ namespace Content.Server.Construction
if (doAfterState != DoAfterState.None)
return doAfterState == DoAfterState.Completed ? HandleResult.True : HandleResult.False;
if (!_toolSystem.UseTool(interactUsing.Used, interactUsing.User,
uid, toolInsertStep.Fuel, toolInsertStep.DoAfter, toolInsertStep.Tool,
new ConstructionDoAfterComplete(uid, ev), new ConstructionDoAfterCancelled(uid, ev)))
var toolEvData = new ToolEventData(new ConstructionDoAfterComplete(uid, ev), toolInsertStep.Fuel, new ConstructionDoAfterCancelled(uid, ev));
if(!_toolSystem.UseTool(interactUsing.Used, interactUsing.User, uid, toolInsertStep.DoAfter, new [] {toolInsertStep.Tool}, toolEvData))
return HandleResult.False;
// In the case we're not waiting for a doAfter, then this step is complete!
@@ -546,6 +546,21 @@ namespace Content.Server.Construction
_constructionUpdateQueue.Add(uid);
}
private void OnDoAfter(EntityUid uid, ConstructionComponent component, DoAfterEvent<ConstructionData> args)
{
if (!Exists(args.Args.Target) || args.Handled)
return;
if (args.Cancelled)
{
RaiseLocalEvent(args.Args.Target.Value, args.AdditionalData.CancelEvent);
args.Handled = true;
}
RaiseLocalEvent(args.Args.Target.Value, args.AdditionalData.CompleteEvent);
args.Handled = true;
}
private void OnDoAfterComplete(ConstructionDoAfterComplete ev)
{
// Make extra sure the target entity exists...
@@ -570,6 +585,18 @@ namespace Content.Server.Construction
#region Event Definitions
private sealed class ConstructionData
{
public readonly object CompleteEvent;
public readonly object CancelEvent;
public ConstructionData(object completeEvent, object cancelEvent)
{
CompleteEvent = completeEvent;
CancelEvent = cancelEvent;
}
}
/// <summary>
/// This event signals that a construction interaction's DoAfter has completed successfully.
/// This wraps the original event and also keeps some custom data that event handlers might need.

View File

@@ -1,8 +1,8 @@
using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Server.Stack;
using Content.Server.Tools;
using Content.Shared.Construction;
using Content.Shared.Tools;
using JetBrains.Annotations;
using Robust.Server.Containers;
using Robust.Shared.Prototypes;
@@ -22,7 +22,7 @@ namespace Content.Server.Construction
[Dependency] private readonly DoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly ContainerSystem _container = default!;
[Dependency] private readonly StackSystem _stackSystem = default!;
[Dependency] private readonly ToolSystem _toolSystem = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
private const string SawmillName = "Construction";
private ISawmill _sawmill = default!;

View File

@@ -1,15 +1,14 @@
using System.Linq;
using System.Threading;
using Content.Server.Construction.Components;
using Content.Server.DoAfter;
using Content.Server.Storage.Components;
using Content.Server.Storage.EntitySystems;
using Content.Server.Wires;
using Content.Shared.DoAfter;
using Content.Shared.Construction.Components;
using Content.Shared.Interaction;
using Content.Shared.Popups;
using Robust.Shared.Containers;
using Robust.Shared.Player;
using Robust.Shared.Utility;
namespace Content.Server.Construction;
@@ -27,16 +26,20 @@ public sealed class PartExchangerSystem : EntitySystem
public override void Initialize()
{
SubscribeLocalEvent<PartExchangerComponent, AfterInteractEvent>(OnAfterInteract);
SubscribeLocalEvent<PartExchangerComponent, RpedExchangeFinishedEvent>(OnFinished);
SubscribeLocalEvent<PartExchangerComponent, RpedExchangeCancelledEvent>(OnCancelled);
SubscribeLocalEvent<PartExchangerComponent, DoAfterEvent>(OnDoAfter);
}
private void OnFinished(EntityUid uid, PartExchangerComponent component, RpedExchangeFinishedEvent args)
private void OnDoAfter(EntityUid uid, PartExchangerComponent component, DoAfterEvent args)
{
component.Token = null;
if (args.Cancelled || args.Handled || args.Args.Target == null)
{
component.AudioStream?.Stop();
return;
}
component.AudioStream?.Stop();
if (!TryComp<MachineComponent>(args.Target, out var machine))
if (!TryComp<MachineComponent>(args.Args.Target.Value, out var machine))
return;
if (!TryComp<ServerStorageComponent>(uid, out var storage) || storage.Storage == null)
@@ -59,7 +62,7 @@ public sealed class PartExchangerSystem : EntitySystem
if (TryComp<MachinePartComponent>(ent, out var part))
{
machineParts.Add(part);
_container.RemoveEntity(machine.Owner, ent);
_container.RemoveEntity(args.Args.Target.Value, ent);
}
}
@@ -85,19 +88,12 @@ public sealed class PartExchangerSystem : EntitySystem
_storage.Insert(uid, unused.Owner, null, false);
}
_construction.RefreshParts(machine);
}
private void OnCancelled(EntityUid uid, PartExchangerComponent component, RpedExchangeCancelledEvent args)
{
component.Token = null;
component.AudioStream?.Stop();
args.Handled = true;
}
private void OnAfterInteract(EntityUid uid, PartExchangerComponent component, AfterInteractEvent args)
{
if (component.Token != null)
return;
if (component.DoDistanceCheck && !args.CanReach)
return;
@@ -116,28 +112,11 @@ public sealed class PartExchangerSystem : EntitySystem
component.AudioStream = _audio.PlayPvs(component.ExchangeSound, uid);
component.Token = new CancellationTokenSource();
_doAfter.DoAfter(new DoAfterEventArgs(args.User, component.ExchangeDuration, component.Token.Token, args.Target, args.Used)
_doAfter.DoAfter(new DoAfterEventArgs(args.User, component.ExchangeDuration, target:args.Target, used:args.Used)
{
BreakOnDamage = true,
BreakOnStun = true,
BreakOnUserMove = true,
UsedFinishedEvent = new RpedExchangeFinishedEvent(args.Target.Value),
UsedCancelledEvent = new RpedExchangeCancelledEvent()
BreakOnUserMove = true
});
}
}
public sealed class RpedExchangeFinishedEvent : EntityEventArgs
{
public readonly EntityUid Target;
public RpedExchangeFinishedEvent(EntityUid target)
{
Target = target;
}
}
public readonly struct RpedExchangeCancelledEvent
{
}

View File

@@ -1,15 +1,15 @@
using Content.Server.Construction.Components;
using Content.Server.Tools;
using Content.Server.Stack;
using Content.Shared.Interaction;
using Content.Shared.Stacks;
using Content.Shared.Tools;
using Content.Shared.Tools.Components;
namespace Content.Server.Construction
{
public sealed class RefiningSystem : EntitySystem
{
[Dependency] private readonly ToolSystem _toolSystem = default!;
[Dependency] private readonly SharedToolSystem _toolSystem = default!;
[Dependency] private readonly StackSystem _stackSystem = default!;
public override void Initialize()
{
@@ -29,7 +29,9 @@ namespace Content.Server.Construction
component.BeingWelded = true;
if (!await _toolSystem.UseTool(args.Used, args.User, uid, component.RefineFuel, component.RefineTime, component.QualityNeeded))
var toolEvData = new ToolEventData(null);
if (!_toolSystem.UseTool(args.Used, args.User, uid, component.RefineTime, component.QualityNeeded, toolEvData, component.RefineFuel))
{
// failed to veld - abort refine
component.BeingWelded = false;