[STAGING/HOTFIX] Butcher entities in containers. (#40299)

* Kitchen spike and sharp system

* Use transform and parent

* A

* Works

* A

---------

Co-authored-by: Princess Cheeseballs <66055347+Pronana@users.noreply.github.com>
This commit is contained in:
Princess Cheeseballs
2025-09-14 13:41:42 -07:00
committed by GitHub
parent 9e204c3023
commit d8e818283c
4 changed files with 58 additions and 27 deletions

View File

@@ -102,19 +102,25 @@ public sealed class SharpSystem : EntitySystem
component.Butchering.Remove(args.Args.Target.Value);
if (_containerSystem.IsEntityInContainer(args.Args.Target.Value))
{
args.Handled = true;
return;
}
var spawnEntities = EntitySpawnCollection.GetSpawns(butcher.SpawnedEntities, _robustRandom);
var coords = _transform.GetMapCoordinates(args.Args.Target.Value);
EntityUid popupEnt = default!;
foreach (var proto in spawnEntities)
if (_containerSystem.TryGetContainingContainer(args.Args.Target.Value, out var container))
{
// distribute the spawned items randomly in a small radius around the origin
popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f)));
foreach (var proto in spawnEntities)
{
// distribute the spawned items randomly in a small radius around the origin
popupEnt = SpawnInContainerOrDrop(proto, container.Owner, container.ID);
}
}
else
{
foreach (var proto in spawnEntities)
{
// distribute the spawned items randomly in a small radius around the origin
popupEnt = Spawn(proto, coords.Offset(_robustRandom.NextVector2(0.25f)));
}
}
// only show a big popup when butchering living things.

View File

@@ -1303,10 +1303,17 @@ namespace Content.Shared.Interaction
var ev = new AccessibleOverrideEvent(user, target);
RaiseLocalEvent(user, ref ev);
RaiseLocalEvent(target, ref ev);
// If either has handled it and neither has said we can't access it then we can access it.
if (ev.Handled)
return ev.Accessible;
return CanAccess(user, target);
}
public bool CanAccess(EntityUid user, EntityUid target)
{
if (_containerSystem.IsInSameOrParentContainer(user, target, out _, out var container))
return true;
@@ -1511,16 +1518,16 @@ namespace Content.Shared.Interaction
/// <summary>
/// Override event raised directed on the user to say the target is accessible.
/// </summary>
/// <param name="User"></param>
/// <param name="Target"></param>
/// <param name="Target">Entity we're targeting</param>
[ByRefEvent]
public record struct AccessibleOverrideEvent(EntityUid User, EntityUid Target)
{
public readonly EntityUid User = User;
public readonly EntityUid Target = Target;
// We set it to true by default for easier validation later.
public bool Handled;
public bool Accessible = false;
public bool Accessible;
}
/// <summary>

View File

@@ -32,18 +32,19 @@ namespace Content.Shared.Kitchen;
/// </summary>
public sealed class SharedKitchenSpikeSystem : EntitySystem
{
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly ISharedAdminLogManager _logger = default!;
[Dependency] private readonly DamageableSystem _damageableSystem = default!;
[Dependency] private readonly ExamineSystemShared _examineSystem = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
[Dependency] private readonly MetaDataSystem _metaDataSystem = default!;
[Dependency] private readonly ISharedAdminLogManager _logger = default!;
[Dependency] private readonly MobStateSystem _mobStateSystem = default!;
[Dependency] private readonly SharedAppearanceSystem _appearanceSystem = default!;
[Dependency] private readonly SharedAudioSystem _audioSystem = default!;
[Dependency] private readonly SharedBodySystem _bodySystem = default!;
[Dependency] private readonly IGameTiming _gameTiming = default!;
[Dependency] private readonly SharedContainerSystem _containerSystem = default!;
[Dependency] private readonly SharedDoAfterSystem _doAfterSystem = default!;
[Dependency] private readonly SharedInteractionSystem _interaction = default!;
[Dependency] private readonly SharedPopupSystem _popupSystem = default!;
public override void Initialize()
{
@@ -76,6 +77,9 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
SubscribeLocalEvent<KitchenSpikeHookedComponent, PickupAttemptEvent>(OnAttempt);
SubscribeLocalEvent<KitchenSpikeHookedComponent, IsEquippingAttemptEvent>(OnAttempt);
SubscribeLocalEvent<KitchenSpikeHookedComponent, IsUnequippingAttemptEvent>(OnAttempt);
// Container Jank
SubscribeLocalEvent<KitchenSpikeHookedComponent, AccessibleOverrideEvent>(OnAccessibleOverride);
}
private void OnInit(Entity<KitchenSpikeComponent> ent, ref ComponentInit args)
@@ -382,6 +386,21 @@ public sealed class SharedKitchenSpikeSystem : EntitySystem
args.Cancel();
}
private void OnAccessibleOverride(Entity<KitchenSpikeHookedComponent> ent, ref AccessibleOverrideEvent args)
{
// Check if the entity is the target to avoid giving the hooked entity access to everything.
// If we already have access we don't need to run more code.
if (args.Accessible || args.Target != ent.Owner)
return;
var xform = Transform(ent);
if (!_interaction.CanAccess(args.User, xform.ParentUid))
return;
args.Accessible = true;
args.Handled = true;
}
public override void Update(float frameTime)
{
base.Update(frameTime);

View File

@@ -145,18 +145,17 @@ public abstract partial class SharedStationAiSystem : EntitySystem
private void OnAiAccessible(Entity<StationAiOverlayComponent> ent, ref AccessibleOverrideEvent args)
{
// We don't want to allow entities to access the AI just because the eye is nearby.
// Only let the AI access entities through the eye.
if (args.Accessible || args.User != ent.Owner)
return;
args.Handled = true;
// Hopefully AI never needs storage
if (_containers.TryGetContainingContainer(args.Target, out var targetContainer))
{
if (_containers.TryGetContainingContainer(args.Target, out var targetContainer) ||
!_containers.IsInSameOrTransparentContainer(ent.Owner, args.Target, otherContainer: targetContainer))
return;
}
if (!_containers.IsInSameOrTransparentContainer(args.User, args.Target, otherContainer: targetContainer))
{
return;
}
args.Accessible = true;
}