fix: Block EntityStorage from inserting into mechs (#37942)

This additionally moves the hard-coded check for HandsComp that
previously did this, and moves it into an event which now both
HandsSystem and MechSystem subscribe to.
This commit is contained in:
Perry Fraser
2025-08-26 06:29:12 -04:00
committed by GitHub
parent ceda478ae2
commit fd4a0a29b4
4 changed files with 42 additions and 7 deletions

View File

@@ -14,6 +14,7 @@ using Content.Shared.Mech.Equipment.Components;
using Content.Shared.Movement.Components;
using Content.Shared.Movement.Systems;
using Content.Shared.Popups;
using Content.Shared.Storage.Components;
using Content.Shared.Weapons.Melee;
using Content.Shared.Whitelist;
using Robust.Shared.Containers;
@@ -48,6 +49,7 @@ public abstract partial class SharedMechSystem : EntitySystem
SubscribeLocalEvent<MechComponent, UserActivateInWorldEvent>(RelayInteractionEvent);
SubscribeLocalEvent<MechComponent, ComponentStartup>(OnStartup);
SubscribeLocalEvent<MechComponent, DestructionEventArgs>(OnDestruction);
SubscribeLocalEvent<MechComponent, EntityStorageIntoContainerAttemptEvent>(OnEntityStorageDump);
SubscribeLocalEvent<MechComponent, GetAdditionalAccessEvent>(OnGetAdditionalAccess);
SubscribeLocalEvent<MechComponent, DragDropTargetEvent>(OnDragDrop);
SubscribeLocalEvent<MechComponent, CanDropTargetEvent>(OnCanDragDrop);
@@ -104,6 +106,12 @@ public abstract partial class SharedMechSystem : EntitySystem
BreakMech(uid, component);
}
private void OnEntityStorageDump(Entity<MechComponent> entity, ref EntityStorageIntoContainerAttemptEvent args)
{
// There's no reason we should dump into /any/ of the mech's containers.
args.Cancelled = true;
}
private void OnGetAdditionalAccess(EntityUid uid, MechComponent component, ref GetAdditionalAccessEvent args)
{
var pilot = component.PilotSlot.ContainedEntity;
@@ -147,7 +155,7 @@ public abstract partial class SharedMechSystem : EntitySystem
}
/// <summary>
/// Destroys the mech, removing the user and ejecting all installed equipment.
/// Destroys the mech, removing the user and ejecting anything contained.
/// </summary>
/// <param name="uid"></param>
/// <param name="component"></param>
@@ -237,14 +245,19 @@ public abstract partial class SharedMechSystem : EntitySystem
/// <param name="toRemove"></param>
/// <param name="component"></param>
/// <param name="equipmentComponent"></param>
/// <param name="forced">Whether or not the removal can be cancelled</param>
/// <param name="forced">
/// Whether or not the removal can be cancelled, and if non-mech equipment should be ejected.
/// </param>
public void RemoveEquipment(EntityUid uid, EntityUid toRemove, MechComponent? component = null,
MechEquipmentComponent? equipmentComponent = null, bool forced = false)
{
if (!Resolve(uid, ref component))
return;
if (!Resolve(toRemove, ref equipmentComponent))
// When forced, we also want to handle the possibility that the "equipment" isn't actually equipment.
// This /shouldn't/ be possible thanks to OnEntityStorageDump, but there's been quite a few regressions
// with entities being hardlock stuck inside mechs.
if (!Resolve(toRemove, ref equipmentComponent) && !forced)
return;
if (!forced)
@@ -261,7 +274,9 @@ public abstract partial class SharedMechSystem : EntitySystem
if (component.CurrentSelectedEquipment == toRemove)
CycleEquipment(uid, component);
equipmentComponent.EquipmentOwner = null;
if (forced && equipmentComponent != null)
equipmentComponent.EquipmentOwner = null;
_container.Remove(toRemove, component.EquipmentContainer);
UpdateUserInterface(uid, component);
}