DoAfter Refactor (#13225)
Co-authored-by: DrSmugleaf <drsmugleaf@gmail.com>
This commit is contained in:
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user