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.
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;
/// <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>
/// </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()
{
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)
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);
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))
- {
- return;
- }
-
- if (!_containers.IsInSameOrTransparentContainer(args.User, args.Target, otherContainer: targetContainer))
- {
+ if (_containers.TryGetContainingContainer(args.Target, out var targetContainer) ||
+ !_containers.IsInSameOrTransparentContainer(ent.Owner, args.Target, otherContainer: targetContainer))
return;
- }
args.Accessible = true;
}