diff --git a/Content.Server/Storage/EntitySystems/StorageSystem.cs b/Content.Server/Storage/EntitySystems/StorageSystem.cs
index 4939f99cec..5fa4b1d706 100644
--- a/Content.Server/Storage/EntitySystems/StorageSystem.cs
+++ b/Content.Server/Storage/EntitySystems/StorageSystem.cs
@@ -48,6 +48,7 @@ namespace Content.Server.Storage.EntitySystems
[Dependency] private readonly UserInterfaceSystem _uiSystem = default!;
[Dependency] private readonly ActionBlockerSystem _actionBlockerSystem = default!;
[Dependency] private readonly SharedAudioSystem _audio = default!;
+ [Dependency] private readonly SharedTransformSystem _transform = default!;
///
public override void Initialize()
@@ -67,12 +68,64 @@ namespace Content.Server.Storage.EntitySystems
SubscribeLocalEvent(OnBoundUIClosed);
SubscribeLocalEvent(OnStorageItemRemoved);
+ SubscribeLocalEvent(OnAreaPickupComplete);
+ SubscribeLocalEvent(OnAreaPickupCancelled);
+
SubscribeLocalEvent>(AddToggleOpenVerb);
SubscribeLocalEvent(OnRelayMovement);
SubscribeLocalEvent(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();
+ var successfullyInsertedPositions = new List();
+ var itemQuery = GetEntityQuery();
+ var xformQuery = GetEntityQuery();
+ 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();
@@ -130,14 +183,16 @@ namespace Content.Server.Storage.EntitySystems
return;
// Get the session for the user
- if (!TryComp(args.User, out var actor) || actor?.PlayerSession == null)
+ if (!TryComp(args.User, out var actor))
return;
// Does this player currently have the storage UI open?
bool uiOpen = _uiSystem.SessionHasOpenUi(uid, StorageUiKey.Key, actor.PlayerSession);
- ActivationVerb verb = new();
- verb.Act = () => OpenStorageUI(uid, args.User, component);
+ ActivationVerb verb = new()
+ {
+ Act = () => OpenStorageUI(uid, args.User, component)
+ };
if (uiOpen)
{
verb.Text = Loc.GetString("verb-common-close-ui");
@@ -178,8 +233,6 @@ namespace Content.Server.Storage.EntitySystems
}
}
-
-
///
/// Inserts storable entities into this storage container if possible, otherwise return to the hand of the user
///
@@ -210,9 +263,6 @@ namespace Content.Server.Storage.EntitySystems
///
private void OnActivate(EntityUid uid, ServerStorageComponent storageComp, ActivateInWorldEvent args)
{
- if (!TryComp(args.User, out var actor))
- return;
-
if (TryComp(uid, out LockComponent? lockComponent) && lockComponent.Locked)
return;
@@ -224,27 +274,27 @@ namespace Content.Server.Storage.EntitySystems
/// around a click.
///
///
- private async void AfterInteract(EntityUid uid, ServerStorageComponent storageComp, AfterInteractEvent eventArgs)
+ private async void AfterInteract(EntityUid uid, ServerStorageComponent storageComp, AfterInteractEvent args)
{
- if (!eventArgs.CanReach) return;
+ if (!args.CanReach) return;
if (storageComp.CancelToken != null)
{
- storageComp.CancelToken.Cancel();
- storageComp.CancelToken = null;
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
- if (storageComp.AreaInsert && (eventArgs.Target == null || !HasComp(eventArgs.Target.Value)))
+ if (storageComp.AreaInsert && (args.Target == null || !HasComp(args.Target.Value)))
{
var validStorables = new List();
- foreach (var entity in _entityLookupSystem.GetEntitiesInRange(eventArgs.ClickLocation, storageComp.AreaInsertRadius, LookupFlags.None))
+ var itemQuery = GetEntityQuery();
+
+ foreach (var entity in _entityLookupSystem.GetEntitiesInRange(args.ClickLocation, storageComp.AreaInsertRadius, LookupFlags.None))
{
- if (entity == eventArgs.User
- || !HasComp(entity)
- || !_interactionSystem.InRangeUnobstructed(eventArgs.User, entity))
+ if (entity == args.User
+ || !itemQuery.HasComponent(entity)
+ || !_interactionSystem.InRangeUnobstructed(args.User, entity))
continue;
validStorables.Add(entity);
@@ -254,57 +304,30 @@ namespace Content.Server.Storage.EntitySystems
if (validStorables.Count > 1)
{
storageComp.CancelToken = new CancellationTokenSource();
- var doAfterArgs = new DoAfterEventArgs(eventArgs.User, 0.2f * validStorables.Count, storageComp.CancelToken.Token, uid)
+ var doAfterArgs = new DoAfterEventArgs(args.User, 0.2f * validStorables.Count, storageComp.CancelToken.Token, target: uid)
{
BreakOnStun = true,
BreakOnDamage = true,
BreakOnUserMove = true,
NeedHand = true,
+ TargetCancelledEvent = new AreaPickupCancelledEvent(),
+ TargetFinishedEvent = new AreaPickupCompleteEvent(args.User, validStorables),
};
- await _doAfterSystem.WaitDoAfter(doAfterArgs);
+ _doAfterSystem.DoAfter(doAfterArgs);
}
- // TODO: Make it use the event DoAfter
- var successfullyInserted = new List();
- var successfullyInsertedPositions = new List();
- foreach (var entity in 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 == eventArgs.User
- || !HasComp(entity))
- continue;
-
- if (TryComp(uid, out var transformOwner) && TryComp(entity, out var transformEnt))
- {
- var position = EntityCoordinates.FromMap(transformOwner.Parent?.Owner ?? uid, transformEnt.MapPosition);
-
- if (PlayerInsertEntityInWorld(uid, eventArgs.User, entity, storageComp))
- {
- 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)
- {
- if (storageComp.StorageInsertSound is not null)
- SoundSystem.Play(storageComp.StorageInsertSound.GetSound(), Filter.Pvs(uid, entityManager: EntityManager), uid, AudioParams.Default);
- RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid, successfullyInserted, successfullyInsertedPositions));
- }
return;
}
+
// Pick up the clicked entity
- else if (storageComp.QuickInsert)
+ if (storageComp.QuickInsert)
{
- if (eventArgs.Target is not {Valid: true} target)
+ if (args.Target is not {Valid: true} target)
return;
if (_containerSystem.IsEntityInContainer(target)
- || target == eventArgs.User
+ || target == args.User
|| !HasComp(target))
return;
@@ -313,9 +336,10 @@ namespace Content.Server.Storage.EntitySystems
var parent = transformOwner.ParentUid;
var position = EntityCoordinates.FromMap(
- parent.IsValid() ? parent : uid,
- transformEnt.MapPosition);
- if (PlayerInsertEntityInWorld(uid, eventArgs.User, target, storageComp))
+ parent.IsValid() ? parent : uid,
+ transformEnt.MapPosition);
+
+ if (PlayerInsertEntityInWorld(uid, args.User, target, storageComp))
{
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(uid,
new List { target },
@@ -323,7 +347,6 @@ namespace Content.Server.Storage.EntitySystems
}
}
}
- return;
}
private void OnDestroy(EntityUid uid, ServerStorageComponent storageComp, DestructionEventArgs args)
@@ -679,5 +702,25 @@ namespace Content.Server.Storage.EntitySystems
_popupSystem.PopupEntity(Loc.GetString(message), player, Filter.Entities(player));
}
+
+ ///
+ /// Raised on storage if it successfully completes area pickup.
+ ///
+ private sealed class AreaPickupCompleteEvent : EntityEventArgs
+ {
+ public EntityUid User;
+ public List ValidStorables;
+
+ public AreaPickupCompleteEvent(EntityUid user, List validStorables)
+ {
+ User = user;
+ ValidStorables = validStorables;
+ }
+ }
+
+ private sealed class AreaPickupCancelledEvent : EntityEventArgs
+ {
+
+ }
}
}