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,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.