DoAfter Refactor (#13225)
Co-authored-by: DrSmugleaf <drsmugleaf@gmail.com>
This commit is contained in:
@@ -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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,4 @@ public sealed class PartExchangerComponent : Component
|
||||
public SoundSpecifier ExchangeSound = new SoundPathSpecifier("/Audio/Items/rped.ogg");
|
||||
|
||||
public IPlayingAudioStream? AudioStream;
|
||||
|
||||
public CancellationTokenSource? Token;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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!;
|
||||
|
||||
@@ -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
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user