+using Content.Shared.Body.Components;
using Content.Shared.Buckle;
using Content.Shared.Buckle.Components;
using Content.Shared.Storage.Components;
SubscribeLocalEvent<FoldableComponent, ComponentInit>(OnFoldableInit);
SubscribeLocalEvent<FoldableComponent, ContainerGettingInsertedAttemptEvent>(OnInsertEvent);
- SubscribeLocalEvent<FoldableComponent, StoreMobInItemContainerAttemptEvent>(OnStoreThisAttempt);
+ SubscribeLocalEvent<FoldableComponent, InsertIntoEntityStorageAttemptEvent>(OnStoreThisAttempt);
SubscribeLocalEvent<FoldableComponent, StorageOpenAttemptEvent>(OnFoldableOpenAttempt);
SubscribeLocalEvent<FoldableComponent, StrapAttemptEvent>(OnStrapAttempt);
args.Cancelled = true;
}
- public void OnStoreThisAttempt(EntityUid uid, FoldableComponent comp, ref StoreMobInItemContainerAttemptEvent args)
+ public void OnStoreThisAttempt(EntityUid uid, FoldableComponent comp, ref InsertIntoEntityStorageAttemptEvent args)
{
- args.Handled = true;
-
if (comp.IsFolded)
args.Cancelled = true;
}
component.Open = false;
Dirty(uid, component);
- var targetCoordinates = new EntityCoordinates(uid, component.EnteringOffset);
+ var entities = _lookup.GetEntitiesInRange(
+ new EntityCoordinates(uid, component.EnteringOffset),
+ component.EnteringRange,
+ LookupFlags.Approximate | LookupFlags.Dynamic | LookupFlags.Sundries
+ );
- var entities = _lookup.GetEntitiesInRange(targetCoordinates, component.EnteringRange, LookupFlags.Approximate | LookupFlags.Dynamic | LookupFlags.Sundries);
+ // Don't insert the container into itself.
+ entities.Remove(uid);
- var ev = new StorageBeforeCloseEvent(entities, new());
+ var ev = new StorageBeforeCloseEvent(entities, []);
RaiseLocalEvent(uid, ref ev);
- var count = 0;
+
foreach (var entity in ev.Contents)
{
- if (!ev.BypassChecks.Contains(entity))
- {
- if (!CanInsert(entity, uid, component))
- continue;
- }
+ if (!ev.BypassChecks.Contains(entity) && !CanInsert(entity, uid, component))
+ continue;
if (!AddToContents(entity, uid, component))
continue;
- count++;
- if (count >= component.Capacity)
+ if (component.Contents.ContainedEntities.Count >= component.Capacity)
break;
}
if (component.Contents.ContainedEntities.Count >= component.Capacity)
return false;
- return CanFit(toInsert, container, component);
+ var aabb = _lookup.GetAABBNoContainer(toInsert, Vector2.Zero, 0);
+ if (component.MaxSize < aabb.Size.X || component.MaxSize < aabb.Size.Y)
+ return false;
+
+ // Allow other systems to prevent inserting the item: e.g. the item is actually a ghost.
+ var attemptEvent = new InsertIntoEntityStorageAttemptEvent(toInsert);
+ RaiseLocalEvent(toInsert, ref attemptEvent);
+
+ if (attemptEvent.Cancelled)
+ return false;
+
+ // Consult the whitelist. The whitelist ignores the default assumption about how entity storage works.
+ if (component.Whitelist != null)
+ return _whitelistSystem.IsValid(component.Whitelist, toInsert);
+
+ // The inserted entity must be a mob or an item.
+ return HasComp<BodyComponent>(toInsert) || HasComp<ItemComponent>(toInsert);
}
public bool TryOpenStorage(EntityUid user, EntityUid target, bool silent = false)
if (toAdd == container)
return false;
- var aabb = _lookup.GetAABBNoContainer(toAdd, Vector2.Zero, 0);
- if (component.MaxSize < aabb.Size.X || component.MaxSize < aabb.Size.Y)
- return false;
-
return Insert(toAdd, container, component);
}
- private bool CanFit(EntityUid toInsert, EntityUid container, SharedEntityStorageComponent? component = null)
- {
- if (!Resolve(container, ref component))
- return false;
-
- // conditions are complicated because of pizzabox-related issues, so follow this guide
- // 0. Accomplish your goals at all costs.
- // 1. AddToContents can block anything
- // 2. maximum item count can block anything
- // 3. ghosts can NEVER be eaten
- // 4. items can always be eaten unless a previous law prevents it
- // 5. if this is NOT AN ITEM, then mobs can always be eaten unless a previous
- // law prevents it
- // 6. if this is an item, then mobs must only be eaten if some other component prevents
- // pick-up interactions while a mob is inside (e.g. foldable)
- var attemptEvent = new InsertIntoEntityStorageAttemptEvent();
- RaiseLocalEvent(toInsert, ref attemptEvent);
- if (attemptEvent.Cancelled)
- return false;
-
- var targetIsMob = HasComp<BodyComponent>(toInsert);
- var storageIsItem = HasComp<ItemComponent>(container);
- var allowedToEat = component.Whitelist == null ? HasComp<ItemComponent>(toInsert) : _whitelistSystem.IsValid(component.Whitelist, toInsert);
-
- // BEFORE REPLACING THIS WITH, I.E. A PROPERTY:
- // Make absolutely 100% sure you have worked out how to stop people ending up in backpacks.
- // Seriously, it is insanely hacky and weird to get someone out of a backpack once they end up in there.
- // And to be clear, they should NOT be in there.
- // For the record, what you need to do is empty the backpack onto a PlacableSurface (table, rack)
- if (targetIsMob)
- {
- if (!storageIsItem)
- allowedToEat = true;
- else
- {
- var storeEv = new StoreMobInItemContainerAttemptEvent();
- RaiseLocalEvent(container, ref storeEv);
- allowedToEat = storeEv is { Handled: true, Cancelled: false };
-
- if (component.ItemCanStoreMobs)
- allowedToEat = true;
- }
- }
-
- return allowedToEat;
- }
-
private void ModifyComponents(EntityUid uid, SharedEntityStorageComponent? component = null)
{
if (!ResolveStorage(uid, ref component))