Save Space Station 14 from the Toilet Gibber Forever (#35587)
* The evil is defeated
* Tag body bags
* uwu, cwush me cwusher-chan
* absolute 18+ sloggery
* botos binted? 👽
This commit is contained in:
committed by
GitHub
parent
184edfe71d
commit
78b2b361e8
@@ -1,3 +1,4 @@
|
|||||||
|
using Content.Shared.Body.Components;
|
||||||
using Content.Shared.Buckle;
|
using Content.Shared.Buckle;
|
||||||
using Content.Shared.Buckle.Components;
|
using Content.Shared.Buckle.Components;
|
||||||
using Content.Shared.Storage.Components;
|
using Content.Shared.Storage.Components;
|
||||||
@@ -23,7 +24,7 @@ public sealed class FoldableSystem : EntitySystem
|
|||||||
|
|
||||||
SubscribeLocalEvent<FoldableComponent, ComponentInit>(OnFoldableInit);
|
SubscribeLocalEvent<FoldableComponent, ComponentInit>(OnFoldableInit);
|
||||||
SubscribeLocalEvent<FoldableComponent, ContainerGettingInsertedAttemptEvent>(OnInsertEvent);
|
SubscribeLocalEvent<FoldableComponent, ContainerGettingInsertedAttemptEvent>(OnInsertEvent);
|
||||||
SubscribeLocalEvent<FoldableComponent, StoreMobInItemContainerAttemptEvent>(OnStoreThisAttempt);
|
SubscribeLocalEvent<FoldableComponent, InsertIntoEntityStorageAttemptEvent>(OnStoreThisAttempt);
|
||||||
SubscribeLocalEvent<FoldableComponent, StorageOpenAttemptEvent>(OnFoldableOpenAttempt);
|
SubscribeLocalEvent<FoldableComponent, StorageOpenAttemptEvent>(OnFoldableOpenAttempt);
|
||||||
|
|
||||||
SubscribeLocalEvent<FoldableComponent, StrapAttemptEvent>(OnStrapAttempt);
|
SubscribeLocalEvent<FoldableComponent, StrapAttemptEvent>(OnStrapAttempt);
|
||||||
@@ -45,10 +46,8 @@ public sealed class FoldableSystem : EntitySystem
|
|||||||
args.Cancelled = true;
|
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)
|
if (comp.IsFolded)
|
||||||
args.Cancelled = true;
|
args.Cancelled = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,12 +64,6 @@ public abstract partial class SharedEntityStorageComponent : Component
|
|||||||
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
[DataField, ViewVariables(VVAccess.ReadWrite)]
|
||||||
public float EnteringRange = 0.18f;
|
public float EnteringRange = 0.18f;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// If true, there may be mobs inside the container, even if the container is an Item
|
|
||||||
/// </summary>
|
|
||||||
[DataField]
|
|
||||||
public bool ItemCanStoreMobs = false;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether or not to show the contents when the storage is closed
|
/// Whether or not to show the contents when the storage is closed
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -153,10 +147,7 @@ public sealed class EntityStorageComponentState : ComponentState
|
|||||||
}
|
}
|
||||||
|
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct InsertIntoEntityStorageAttemptEvent(bool Cancelled = false);
|
public record struct InsertIntoEntityStorageAttemptEvent(EntityUid ItemToInsert, bool Cancelled = false);
|
||||||
|
|
||||||
[ByRefEvent]
|
|
||||||
public record struct StoreMobInItemContainerAttemptEvent(bool Handled, bool Cancelled = false);
|
|
||||||
|
|
||||||
[ByRefEvent]
|
[ByRefEvent]
|
||||||
public record struct StorageOpenAttemptEvent(EntityUid User, bool Silent, bool Cancelled = false);
|
public record struct StorageOpenAttemptEvent(EntityUid User, bool Silent, bool Cancelled = false);
|
||||||
|
|||||||
@@ -241,26 +241,27 @@ public abstract class SharedEntityStorageSystem : EntitySystem
|
|||||||
component.Open = false;
|
component.Open = false;
|
||||||
Dirty(uid, component);
|
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);
|
RaiseLocalEvent(uid, ref ev);
|
||||||
var count = 0;
|
|
||||||
foreach (var entity in ev.Contents)
|
foreach (var entity in ev.Contents)
|
||||||
{
|
{
|
||||||
if (!ev.BypassChecks.Contains(entity))
|
if (!ev.BypassChecks.Contains(entity) && !CanInsert(entity, uid, component))
|
||||||
{
|
|
||||||
if (!CanInsert(entity, uid, component))
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
if (!AddToContents(entity, uid, component))
|
if (!AddToContents(entity, uid, component))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
count++;
|
if (component.Contents.ContainedEntities.Count >= component.Capacity)
|
||||||
if (count >= component.Capacity)
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,7 +332,23 @@ public abstract class SharedEntityStorageSystem : EntitySystem
|
|||||||
if (component.Contents.ContainedEntities.Count >= component.Capacity)
|
if (component.Contents.ContainedEntities.Count >= component.Capacity)
|
||||||
return false;
|
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)
|
public bool TryOpenStorage(EntityUid user, EntityUid target, bool silent = false)
|
||||||
@@ -412,60 +429,9 @@ public abstract class SharedEntityStorageSystem : EntitySystem
|
|||||||
if (toAdd == container)
|
if (toAdd == container)
|
||||||
return false;
|
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);
|
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)
|
private void ModifyComponents(EntityUid uid, SharedEntityStorageComponent? component = null)
|
||||||
{
|
{
|
||||||
if (!ResolveStorage(uid, ref component))
|
if (!ResolveStorage(uid, ref component))
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
breakOnAccessBreaker: false
|
breakOnAccessBreaker: false
|
||||||
- type: EntityStorage
|
- type: EntityStorage
|
||||||
capacity: 1 # Its smol.
|
capacity: 1 # Its smol.
|
||||||
itemCanStoreMobs: false # just leaving this here explicitly since I know at some point someone will want to use this to hold a mob. This also prevents it from becoming His Grace.
|
|
||||||
# - type: StorageFill
|
# - type: StorageFill
|
||||||
# contents:
|
# contents:
|
||||||
# - id: PuddleSparkle # Ha! Cute. Unfortunately it despawns before the container is likely to open.
|
# - id: PuddleSparkle # Ha! Cute. Unfortunately it despawns before the container is likely to open.
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
- type: entity
|
- type: entity
|
||||||
id: PetCarrier
|
id: PetCarrier
|
||||||
name: big pet carrier
|
name: big pet carrier
|
||||||
description: Allows large animals to be carried comfortably.
|
description: Allows large animals to be carried comfortably. It smells vaguely of toilet water and explosives.
|
||||||
parent: BaseStructureDynamic
|
parent: BaseStructureDynamic
|
||||||
components:
|
components:
|
||||||
- type: Sprite
|
- type: Sprite
|
||||||
@@ -36,7 +36,9 @@
|
|||||||
- type: EntityStorage
|
- type: EntityStorage
|
||||||
capacity: 1
|
capacity: 1
|
||||||
airtight: false
|
airtight: false
|
||||||
itemCanStoreMobs: true
|
whitelist:
|
||||||
|
tags:
|
||||||
|
- VimPilot # If it can fit in a Vim it can fit in a pet carrier.
|
||||||
- type: Weldable
|
- type: Weldable
|
||||||
- type: ResistLocker
|
- type: ResistLocker
|
||||||
- type: PlaceableSurface
|
- type: PlaceableSurface
|
||||||
|
|||||||
@@ -44,6 +44,10 @@
|
|||||||
- type: EntityStorage
|
- type: EntityStorage
|
||||||
capacity: 1
|
capacity: 1
|
||||||
isCollidableWhenOpen: true
|
isCollidableWhenOpen: true
|
||||||
|
whitelist: # Use a tag whitelist rather than filtering for PerishableComponent to avoid chefs using body bags for food preservation
|
||||||
|
tags:
|
||||||
|
- VimPilot # Pets
|
||||||
|
- CanPilot # People
|
||||||
closeSound:
|
closeSound:
|
||||||
path: /Audio/Misc/zip.ogg
|
path: /Audio/Misc/zip.ogg
|
||||||
openSound:
|
openSound:
|
||||||
|
|||||||
@@ -128,6 +128,9 @@
|
|||||||
whitelist:
|
whitelist:
|
||||||
components:
|
components:
|
||||||
- Artifact
|
- Artifact
|
||||||
|
tags:
|
||||||
|
- CanPilot # People
|
||||||
|
- VimPilot # Pets
|
||||||
- type: Appearance
|
- type: Appearance
|
||||||
- type: GenericVisualizer
|
- type: GenericVisualizer
|
||||||
visuals:
|
visuals:
|
||||||
|
|||||||
Reference in New Issue
Block a user