|
|
|
|
@@ -61,6 +61,9 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
|
|
|
|
|
public bool CheckingCanInsert;
|
|
|
|
|
|
|
|
|
|
private List<EntityUid> _entList = new();
|
|
|
|
|
private HashSet<EntityUid> _entSet = new();
|
|
|
|
|
|
|
|
|
|
private readonly List<ItemSizePrototype> _sortedSizes = new();
|
|
|
|
|
private FrozenDictionary<string, ItemSizePrototype> _nextSmallest = FrozenDictionary<string, ItemSizePrototype>.Empty;
|
|
|
|
|
|
|
|
|
|
@@ -262,36 +265,40 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private void AfterInteract(EntityUid uid, StorageComponent storageComp, AfterInteractEvent args)
|
|
|
|
|
{
|
|
|
|
|
if (args.Handled || !args.CanReach)
|
|
|
|
|
if (args.Handled || !args.CanReach || !UseDelay.TryResetDelay(uid, checkDelayed: true))
|
|
|
|
|
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 && (args.Target == null || !HasComp<ItemComponent>(args.Target.Value)))
|
|
|
|
|
{
|
|
|
|
|
var validStorables = new List<EntityUid>();
|
|
|
|
|
_entList.Clear();
|
|
|
|
|
_entSet.Clear();
|
|
|
|
|
_entityLookupSystem.GetEntitiesInRange(args.ClickLocation, storageComp.AreaInsertRadius, _entSet, LookupFlags.Dynamic | LookupFlags.Sundries);
|
|
|
|
|
var delay = 0f;
|
|
|
|
|
|
|
|
|
|
foreach (var entity in _entityLookupSystem.GetEntitiesInRange(args.ClickLocation, storageComp.AreaInsertRadius, LookupFlags.Dynamic | LookupFlags.Sundries))
|
|
|
|
|
foreach (var entity in _entSet)
|
|
|
|
|
{
|
|
|
|
|
if (entity == args.User
|
|
|
|
|
// || !_itemQuery.HasComponent(entity)
|
|
|
|
|
|| !TryComp<ItemComponent>(entity, out var itemComp) // Need comp to get item size to get weight
|
|
|
|
|
|| !_itemQuery.TryGetComponent(entity, out var itemComp) // Need comp to get item size to get weight
|
|
|
|
|
|| !_prototype.TryIndex(itemComp.Size, out var itemSize)
|
|
|
|
|
|| !CanInsert(uid, entity, out _, storageComp)
|
|
|
|
|
|| !CanInsert(uid, entity, out _, storageComp, item: itemComp)
|
|
|
|
|
|| !_interactionSystem.InRangeUnobstructed(args.User, entity))
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
validStorables.Add(entity);
|
|
|
|
|
_entList.Add(entity);
|
|
|
|
|
delay += itemSize.Weight * AreaInsertDelayPerItem;
|
|
|
|
|
|
|
|
|
|
if (_entList.Count >= StorageComponent.AreaPickupLimit)
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//If there's only one then let's be generous
|
|
|
|
|
if (validStorables.Count > 1)
|
|
|
|
|
if (_entList.Count > 1)
|
|
|
|
|
{
|
|
|
|
|
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, delay, new AreaPickupDoAfterEvent(GetNetEntityList(validStorables)), uid, target: uid)
|
|
|
|
|
var doAfterArgs = new DoAfterArgs(EntityManager, args.User, delay, new AreaPickupDoAfterEvent(GetNetEntityList(_entList)), uid, target: uid)
|
|
|
|
|
{
|
|
|
|
|
BreakOnDamage = true,
|
|
|
|
|
BreakOnMove = true,
|
|
|
|
|
@@ -313,7 +320,7 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
|
|
|
|
|
if (_containerSystem.IsEntityInContainer(target)
|
|
|
|
|
|| target == args.User
|
|
|
|
|
|| !HasComp<ItemComponent>(target))
|
|
|
|
|
|| !_itemQuery.HasComponent(target))
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@@ -331,10 +338,10 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
args.Handled = true;
|
|
|
|
|
if (PlayerInsertEntityInWorld((uid, storageComp), args.User, target))
|
|
|
|
|
{
|
|
|
|
|
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid),
|
|
|
|
|
EntityManager.RaiseSharedEvent(new AnimateInsertingEntitiesEvent(GetNetEntity(uid),
|
|
|
|
|
new List<NetEntity> { GetNetEntity(target) },
|
|
|
|
|
new List<NetCoordinates> { GetNetCoordinates(position) },
|
|
|
|
|
new List<Angle> { transformOwner.LocalRotation }));
|
|
|
|
|
new List<Angle> { transformOwner.LocalRotation }), args.User);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -349,20 +356,27 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
var successfullyInserted = new List<EntityUid>();
|
|
|
|
|
var successfullyInsertedPositions = new List<EntityCoordinates>();
|
|
|
|
|
var successfullyInsertedAngles = new List<Angle>();
|
|
|
|
|
_xformQuery.TryGetComponent(uid, out var xform);
|
|
|
|
|
|
|
|
|
|
foreach (var netEntity in args.Entities)
|
|
|
|
|
if (!_xformQuery.TryGetComponent(uid, out var xform))
|
|
|
|
|
{
|
|
|
|
|
var entity = GetEntity(netEntity);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var entCount = Math.Min(StorageComponent.AreaPickupLimit, args.Entities.Count);
|
|
|
|
|
|
|
|
|
|
for (var i = 0; i < entCount; i++)
|
|
|
|
|
{
|
|
|
|
|
var entity = GetEntity(args.Entities[i]);
|
|
|
|
|
|
|
|
|
|
// 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) ||
|
|
|
|
|
if (!_xformQuery.TryGetComponent(entity, out var targetXform) ||
|
|
|
|
|
targetXform.MapID != xform.MapID)
|
|
|
|
|
{
|
|
|
|
|
continue;
|
|
|
|
|
@@ -387,12 +401,12 @@ public abstract class SharedStorageSystem : EntitySystem
|
|
|
|
|
// If we picked up at least one thing, play a sound and do a cool animation!
|
|
|
|
|
if (successfullyInserted.Count > 0)
|
|
|
|
|
{
|
|
|
|
|
Audio.PlayPvs(component.StorageInsertSound, uid);
|
|
|
|
|
RaiseNetworkEvent(new AnimateInsertingEntitiesEvent(
|
|
|
|
|
Audio.PlayPredicted(component.StorageInsertSound, uid, args.User);
|
|
|
|
|
EntityManager.RaiseSharedEvent(new AnimateInsertingEntitiesEvent(
|
|
|
|
|
GetNetEntity(uid),
|
|
|
|
|
GetNetEntityList(successfullyInserted),
|
|
|
|
|
GetNetCoordinatesList(successfullyInsertedPositions),
|
|
|
|
|
successfullyInsertedAngles));
|
|
|
|
|
successfullyInsertedAngles), args.User);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
args.Handled = true;
|
|
|
|
|
|