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

@@ -2,7 +2,6 @@ using System.Linq;
using Content.Server.Hands.Components;
using Content.Server.Storage.Components;
using Content.Shared.Interaction;
using Content.Shared.Movement;
using Content.Shared.Storage;
using Content.Shared.Verbs;
using JetBrains.Annotations;
@@ -30,6 +29,7 @@ using static Content.Shared.Storage.SharedStorageComponent;
using Content.Shared.ActionBlocker;
using Content.Shared.CombatMode;
using Content.Shared.Containers.ItemSlots;
using Content.Shared.DoAfter;
using Content.Shared.Implants.Components;
using Content.Shared.Lock;
using Content.Shared.Movement.Events;
@@ -75,8 +75,7 @@ namespace Content.Server.Storage.EntitySystems
SubscribeLocalEvent<ServerStorageComponent, BoundUIClosedEvent>(OnBoundUIClosed);
SubscribeLocalEvent<ServerStorageComponent, EntRemovedFromContainerMessage>(OnStorageItemRemoved);
SubscribeLocalEvent<ServerStorageComponent, AreaPickupCompleteEvent>(OnAreaPickupComplete);
SubscribeLocalEvent<ServerStorageComponent, AreaPickupCancelledEvent>(OnAreaPickupCancelled);
SubscribeLocalEvent<ServerStorageComponent, DoAfterEvent<StorageData>>(OnDoAfter);
SubscribeLocalEvent<EntityStorageComponent, GetVerbsEvent<InteractionVerb>>(AddToggleOpenVerb);
SubscribeLocalEvent<EntityStorageComponent, ContainerRelayMovementEntityEvent>(OnRelayMovement);
@@ -84,55 +83,6 @@ namespace Content.Server.Storage.EntitySystems
SubscribeLocalEvent<StorageFillComponent, MapInitEvent>(OnStorageFillMapInit);
}
private void OnAreaPickupCancelled(EntityUid uid, ServerStorageComponent component, AreaPickupCancelledEvent args)
{
component.CancelToken = null;
}
private void OnAreaPickupComplete(EntityUid uid, ServerStorageComponent component, AreaPickupCompleteEvent args)
{
component.CancelToken = null;
var successfullyInserted = new List<EntityUid>();
var successfullyInsertedPositions = new List<EntityCoordinates>();
var itemQuery = GetEntityQuery<ItemComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
xformQuery.TryGetComponent(uid, out var xform);
foreach (var entity in args.ValidStorables)
{
// Check again, situation may have changed for some entities, but we'll still pick up any that are valid
if (_containerSystem.IsEntityInContainer(entity)
|| entity == args.User
|| !itemQuery.HasComponent(entity))
continue;
if (xform == null ||
!xformQuery.TryGetComponent(entity, out var targetXform) ||
targetXform.MapID != xform.MapID)
{
continue;
}
var position = EntityCoordinates.FromMap(
xform.ParentUid.IsValid() ? xform.ParentUid : uid,
new MapCoordinates(_transform.GetWorldPosition(targetXform, xformQuery),
targetXform.MapID), EntityManager);
if (PlayerInsertEntityInWorld(uid, args.User, entity, component))
{
successfullyInserted.Add(entity);
successfullyInsertedPositions.Add(position);
}
}
// If we picked up atleast one thing, play a sound and do a cool animation!
if (successfullyInserted.Count > 0)
{
_audio.PlayPvs(component.StorageInsertSound, uid);
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid, successfullyInserted, successfullyInsertedPositions));
}
}
private void OnComponentInit(EntityUid uid, ServerStorageComponent storageComp, ComponentInit args)
{
base.Initialize();
@@ -147,10 +97,7 @@ namespace Content.Server.Storage.EntitySystems
private void OnRelayMovement(EntityUid uid, EntityStorageComponent component, ref ContainerRelayMovementEntityEvent args)
{
if (!EntityManager.HasComponent<HandsComponent>(args.Entity))
return;
if (_gameTiming.CurTime < component.LastInternalOpenAttempt + EntityStorageComponent.InternalOpenAttemptDelay)
if (!EntityManager.HasComponent<HandsComponent>(args.Entity) || _gameTiming.CurTime < component.LastInternalOpenAttempt + EntityStorageComponent.InternalOpenAttemptDelay)
return;
component.LastInternalOpenAttempt = _gameTiming.CurTime;
@@ -163,10 +110,7 @@ namespace Content.Server.Storage.EntitySystems
private void AddToggleOpenVerb(EntityUid uid, EntityStorageComponent component, GetVerbsEvent<InteractionVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
if (!_entityStorage.CanOpen(args.User, args.Target, silent: true, component))
if (!args.CanAccess || !args.CanInteract || !_entityStorage.CanOpen(args.User, args.Target, silent: true, component))
return;
InteractionVerb verb = new();
@@ -186,10 +130,7 @@ namespace Content.Server.Storage.EntitySystems
private void AddOpenUiVerb(EntityUid uid, ServerStorageComponent component, GetVerbsEvent<ActivationVerb> args)
{
if (!args.CanAccess || !args.CanInteract)
return;
if (TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
if (!args.CanAccess || !args.CanInteract || TryComp<LockComponent>(uid, out var lockComponent) && lockComponent.Locked)
return;
// Get the session for the user
@@ -222,10 +163,7 @@ namespace Content.Server.Storage.EntitySystems
return;
var entities = component.Storage?.ContainedEntities;
if (entities == null || entities.Count == 0)
return;
if (TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
if (entities == null || entities.Count == 0 || TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
return;
// if the target is storage, add a verb to transfer storage.
@@ -249,13 +187,7 @@ namespace Content.Server.Storage.EntitySystems
/// <returns>true if inserted, false otherwise</returns>
private void OnInteractUsing(EntityUid uid, ServerStorageComponent storageComp, InteractUsingEvent args)
{
if (args.Handled)
return;
if (!storageComp.ClickInsert)
return;
if (TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
if (args.Handled || !storageComp.ClickInsert || TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
return;
Logger.DebugS(storageComp.LoggerName, $"Storage (UID {uid}) attacked by user (UID {args.User}) with entity (UID {args.Used}).");
@@ -273,10 +205,7 @@ namespace Content.Server.Storage.EntitySystems
/// <returns></returns>
private void OnActivate(EntityUid uid, ServerStorageComponent storageComp, ActivateInWorldEvent args)
{
if (args.Handled || _combatMode.IsInCombatMode(args.User))
return;
if (TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
if (args.Handled || _combatMode.IsInCombatMode(args.User) || TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
return;
OpenStorageUI(uid, args.User, storageComp);
@@ -300,12 +229,8 @@ namespace Content.Server.Storage.EntitySystems
/// <returns></returns>
private async void AfterInteract(EntityUid uid, ServerStorageComponent storageComp, AfterInteractEvent args)
{
if (!args.CanReach) return;
if (storageComp.CancelToken != null)
{
if (!args.CanReach)
return;
}
// Pick up all entities in a radius around the clicked location.
// The last half of the if is because carpets exist and this is terrible
@@ -328,18 +253,16 @@ namespace Content.Server.Storage.EntitySystems
//If there's only one then let's be generous
if (validStorables.Count > 1)
{
storageComp.CancelToken = new CancellationTokenSource();
var doAfterArgs = new DoAfterEventArgs(args.User, 0.2f * validStorables.Count, storageComp.CancelToken.Token, target: uid)
var storageData = new StorageData(validStorables);
var doAfterArgs = new DoAfterEventArgs(args.User, 0.2f * validStorables.Count, target: uid)
{
BreakOnStun = true,
BreakOnDamage = true,
BreakOnUserMove = true,
NeedHand = true,
TargetCancelledEvent = new AreaPickupCancelledEvent(),
TargetFinishedEvent = new AreaPickupCompleteEvent(args.User, validStorables),
NeedHand = true
};
_doAfterSystem.DoAfter(doAfterArgs);
_doAfterSystem.DoAfter(doAfterArgs, storageData);
}
return;
@@ -374,6 +297,54 @@ namespace Content.Server.Storage.EntitySystems
}
}
private void OnDoAfter(EntityUid uid, ServerStorageComponent component, DoAfterEvent<StorageData> args)
{
if (args.Handled || args.Cancelled)
return;
var successfullyInserted = new List<EntityUid>();
var successfullyInsertedPositions = new List<EntityCoordinates>();
var itemQuery = GetEntityQuery<ItemComponent>();
var xformQuery = GetEntityQuery<TransformComponent>();
xformQuery.TryGetComponent(uid, out var xform);
foreach (var entity in args.AdditionalData.ValidStorables)
{
// Check again, situation may have changed for some entities, but we'll still pick up any that are valid
if (_containerSystem.IsEntityInContainer(entity)
|| entity == args.Args.User
|| !itemQuery.HasComponent(entity))
continue;
if (xform == null ||
!xformQuery.TryGetComponent(entity, out var targetXform) ||
targetXform.MapID != xform.MapID)
{
continue;
}
var position = EntityCoordinates.FromMap(
xform.ParentUid.IsValid() ? xform.ParentUid : uid,
new MapCoordinates(_transform.GetWorldPosition(targetXform, xformQuery),
targetXform.MapID), EntityManager);
if (PlayerInsertEntityInWorld(uid, args.Args.User, entity, component))
{
successfullyInserted.Add(entity);
successfullyInsertedPositions.Add(position);
}
}
// If we picked up atleast one thing, play a sound and do a cool animation!
if (successfullyInserted.Count > 0)
{
_audio.PlayPvs(component.StorageInsertSound, uid);
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid, successfullyInserted, successfullyInsertedPositions));
}
args.Handled = true;
}
private void OnDestroy(EntityUid uid, ServerStorageComponent storageComp, DestructionEventArgs args)
{
var storedEntities = storageComp.StoredEntities?.ToList();
@@ -404,10 +375,7 @@ namespace Content.Server.Storage.EntitySystems
return;
}
if (!_actionBlockerSystem.CanInteract(player, args.InteractedItemUID))
return;
if (storageComp.Storage == null || !storageComp.Storage.Contains(args.InteractedItemUID))
if (!_actionBlockerSystem.CanInteract(player, args.InteractedItemUID) || storageComp.Storage == null || !storageComp.Storage.Contains(args.InteractedItemUID))
return;
// Does the player have hands?
@@ -419,7 +387,7 @@ namespace Content.Server.Storage.EntitySystems
{
if (_sharedHandsSystem.TryPickupAnyHand(player, args.InteractedItemUID, handsComp: hands)
&& storageComp.StorageRemoveSound != null)
SoundSystem.Play(storageComp.StorageRemoveSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, AudioParams.Default);
_audio.Play(storageComp.StorageRemoveSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, AudioParams.Default);
return;
}
@@ -457,7 +425,7 @@ namespace Content.Server.Storage.EntitySystems
UpdateStorageVisualization(uid, storageComp);
if (storageComp.StorageCloseSound is not null)
SoundSystem.Play(storageComp.StorageCloseSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, storageComp.StorageCloseSound.Params);
_audio.Play(storageComp.StorageCloseSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, storageComp.StorageCloseSound.Params);
}
}
@@ -473,10 +441,10 @@ namespace Content.Server.Storage.EntitySystems
return;
_appearance.SetData(uid, StorageVisuals.Open, storageComp.IsOpen, appearance);
_appearance.SetData(uid, SharedBagOpenVisuals.BagState, storageComp.IsOpen ? SharedBagState.Open : SharedBagState.Closed, appearance);
_appearance.SetData(uid, SharedBagOpenVisuals.BagState, storageComp.IsOpen ? SharedBagState.Open : SharedBagState.Closed);
if (HasComp<ItemCounterComponent>(uid))
_appearance.SetData(uid, StackVisuals.Hide, !storageComp.IsOpen, appearance);
_appearance.SetData(uid, StackVisuals.Hide, !storageComp.IsOpen);
}
private void RecalculateStorageUsed(ServerStorageComponent storageComp)
@@ -581,16 +549,11 @@ namespace Content.Server.Storage.EntitySystems
/// <returns>true if the entity was inserted, false otherwise</returns>
public bool Insert(EntityUid uid, EntityUid insertEnt, ServerStorageComponent? storageComp = null, bool playSound = true)
{
if (!Resolve(uid, ref storageComp))
return false;
if (!CanInsert(uid, insertEnt, out _, storageComp) || storageComp.Storage?.Insert(insertEnt) == false)
if (!Resolve(uid, ref storageComp) || !CanInsert(uid, insertEnt, out _, storageComp) || storageComp.Storage?.Insert(insertEnt) == false)
return false;
if (playSound && storageComp.StorageInsertSound is not null)
{
_audio.PlayPvs(storageComp.StorageInsertSound, uid);
}
RecalculateStorageUsed(storageComp);
UpdateStorageUI(uid, storageComp);
@@ -617,11 +580,7 @@ namespace Content.Server.Storage.EntitySystems
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertHeldEntity(EntityUid uid, EntityUid player, ServerStorageComponent? storageComp = null)
{
if (!Resolve(uid, ref storageComp))
return false;
if (!TryComp(player, out HandsComponent? hands) ||
hands.ActiveHandEntity == null)
if (!Resolve(uid, ref storageComp) || !TryComp(player, out HandsComponent? hands) || hands.ActiveHandEntity == null)
return false;
var toInsert = hands.ActiveHandEntity;
@@ -643,10 +602,7 @@ namespace Content.Server.Storage.EntitySystems
/// <returns>true if inserted, false otherwise</returns>
public bool PlayerInsertEntityInWorld(EntityUid uid, EntityUid player, EntityUid toInsert, ServerStorageComponent? storageComp = null)
{
if (!Resolve(uid, ref storageComp))
return false;
if (!_sharedInteractionSystem.InRangeUnobstructed(player, uid, popup: storageComp.ShowPopup))
if (!Resolve(uid, ref storageComp) || !_sharedInteractionSystem.InRangeUnobstructed(player, uid, popup: storageComp.ShowPopup))
return false;
if (!Insert(uid, toInsert, storageComp))
@@ -663,18 +619,17 @@ namespace Content.Server.Storage.EntitySystems
/// <param name="entity">The entity to open the UI for</param>
public void OpenStorageUI(EntityUid uid, EntityUid entity, ServerStorageComponent? storageComp = null)
{
if (!Resolve(uid, ref storageComp))
return;
if (!TryComp(entity, out ActorComponent? player))
if (!Resolve(uid, ref storageComp) || !TryComp(entity, out ActorComponent? player))
return;
if (storageComp.StorageOpenSound is not null)
SoundSystem.Play(storageComp.StorageOpenSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, storageComp.StorageOpenSound.Params);
_audio.Play(storageComp.StorageOpenSound, Filter.Pvs(uid, entityManager: EntityManager), uid, true, storageComp.StorageOpenSound.Params);
Logger.DebugS(storageComp.LoggerName, $"Storage (UID {uid}) \"used\" by player session (UID {player.PlayerSession.AttachedEntity}).");
_uiSystem.GetUiOrNull(uid, StorageUiKey.Key)?.Open(player.PlayerSession);
var bui = _uiSystem.GetUiOrNull(uid, StorageUiKey.Key);
if (bui != null)
_uiSystem.OpenUi(bui, player.PlayerSession);
}
/// <summary>
@@ -683,10 +638,7 @@ namespace Content.Server.Storage.EntitySystems
/// <param name="session"></param>
public void CloseNestedInterfaces(EntityUid uid, IPlayerSession session, ServerStorageComponent? storageComp = null)
{
if (!Resolve(uid, ref storageComp))
return;
if (storageComp.StoredEntities == null)
if (!Resolve(uid, ref storageComp) || storageComp.StoredEntities == null)
return;
// for each containing thing
@@ -697,9 +649,7 @@ namespace Content.Server.Storage.EntitySystems
foreach (var entity in storageComp.StoredEntities)
{
if (TryComp(entity, out ServerStorageComponent? storedStorageComp))
{
DebugTools.Assert(storedStorageComp != storageComp, $"Storage component contains itself!? Entity: {uid}");
}
if (!TryComp(entity, out ServerUserInterfaceComponent? ui))
continue;
@@ -718,34 +668,22 @@ namespace Content.Server.Storage.EntitySystems
var state = new StorageBoundUserInterfaceState((List<EntityUid>) storageComp.Storage.ContainedEntities, storageComp.StorageUsed, storageComp.StorageCapacityMax);
_uiSystem.GetUiOrNull(uid, StorageUiKey.Key)?.SetState(state);
var bui = _uiSystem.GetUiOrNull(uid, StorageUiKey.Key);
if (bui != null)
_uiSystem.SetUiState(bui, state);
}
private void Popup(EntityUid uid, EntityUid player, string message, ServerStorageComponent storageComp)
{
if (!storageComp.ShowPopup) return;
if (!storageComp.ShowPopup)
return;
_popupSystem.PopupEntity(Loc.GetString(message), player, player);
}
/// <summary>
/// Raised on storage if it successfully completes area pickup.
/// </summary>
private sealed class AreaPickupCompleteEvent : EntityEventArgs
private record struct StorageData(List<EntityUid> validStorables)
{
public EntityUid User;
public List<EntityUid> ValidStorables;
public AreaPickupCompleteEvent(EntityUid user, List<EntityUid> validStorables)
{
User = user;
ValidStorables = validStorables;
}
}
private sealed class AreaPickupCancelledEvent : EntityEventArgs
{
public List<EntityUid> ValidStorables = validStorables;
}
}
}