diff --git a/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleComponent.cs b/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleComponent.cs deleted file mode 100644 index 2afd4714f2..0000000000 --- a/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleComponent.cs +++ /dev/null @@ -1,55 +0,0 @@ -using Content.Shared.Whitelist; -using Robust.Shared.Containers; -using Robust.Shared.GameStates; -using Robust.Shared.Prototypes; - -namespace Content.Shared._NF.Silicons.Borgs; - -/// -/// Uses placeholder entities to give borgs "hands" that are whitelisted for a certain kind of item. -/// The items in it can be dropped and picked up if they match its whitelist. -/// -[RegisterComponent, NetworkedComponent, Access(typeof(DroppableBorgModuleSystem))] -public sealed partial class DroppableBorgModuleComponent : Component -{ - /// - /// The items to spawn in borg hands. - /// - [DataField(required: true)] - public List Items = new(); - - /// - /// The ID of the container to add that stores items when not in hands. - /// - [DataField] - public string ContainerId = "nf-droppable-items"; - - /// - /// The ID of the container to add that stores item placeholders when not in hands. - /// - [DataField] - public string PlaceholderContainerId = "nf-item-placeholders"; - - /// - /// The ID to check for module equivalence. - /// - [DataField(required: true)] - public string ModuleId = default!; -} - -[DataDefinition] -public sealed partial class DroppableBorgItem -{ - /// - /// The entity to spawn and use for the placeholder sprite. - /// - [DataField(required: true)] - public EntProtoId Id; - - /// - /// A whitelist that items must match to be picked up by the placeholder. - /// Regardless of this whitelist entities must have ItemComponent to be picked up. - /// - [DataField(required: true)] - public EntityWhitelist Whitelist; -} diff --git a/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleSystem.cs b/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleSystem.cs deleted file mode 100644 index 53e5cd7ca5..0000000000 --- a/Content.Shared/_NF/Silicons/Borgs/DroppableBorgModuleSystem.cs +++ /dev/null @@ -1,155 +0,0 @@ -using Content.Shared._NF.Interaction.Systems; -using Content.Shared.Hands.Components; -using Content.Shared.Hands.EntitySystems; -using Content.Shared.Interaction; -using Content.Shared.Popups; -using Content.Shared.Silicons.Borgs.Components; -using Robust.Shared.Containers; -using Robust.Shared.Map; -using Robust.Shared.Network; -using Robust.Shared.Utility; - -namespace Content.Shared._NF.Silicons.Borgs; - -public sealed class DroppableBorgModuleSystem : EntitySystem -{ - [Dependency] private readonly HandPlaceholderSystem _placeholder = default!; - [Dependency] private readonly SharedContainerSystem _container = default!; - [Dependency] private readonly SharedHandsSystem _hands = default!; - [Dependency] private readonly SharedInteractionSystem _interaction = default!; - [Dependency] private readonly SharedPopupSystem _popup = default!; - - public override void Initialize() - { - base.Initialize(); - - SubscribeLocalEvent(OnMapInit); - SubscribeLocalEvent(OnCanInsertModule); - SubscribeLocalEvent(OnModuleSelected); - SubscribeLocalEvent(OnModuleUnselected); - } - - private void OnMapInit(Entity ent, ref MapInitEvent args) - { - _container.EnsureContainer(ent, ent.Comp.ContainerId); - var placeholders = _container.EnsureContainer(ent, ent.Comp.PlaceholderContainerId); - - foreach (var slot in ent.Comp.Items) - { - // only the server runs mapinit, this wont make clientside entities - var successful = TrySpawnInContainer(slot.Id, ent, ent.Comp.ContainerId, out var item); - // this would only fail if the current entity is being terminated, which is impossible for mapinit - DebugTools.Assert(successful, $"Somehow failed to insert {ToPrettyString(item)} into {ToPrettyString(ent)}"); - _placeholder.SpawnPlaceholder(placeholders, item!.Value, slot.Id, slot.Whitelist); - } - - Dirty(ent); - } - - private void OnCanInsertModule(Entity ent, ref BorgCanInsertModuleEvent args) - { - if (args.Cancelled) - return; - - foreach (var module in args.Chassis.Comp.ModuleContainer.ContainedEntities) - { - if (!TryComp(module, out var comp)) - continue; - - if (comp.ModuleId != ent.Comp.ModuleId) - continue; - - if (args.User is { } user) - _popup.PopupEntity(Loc.GetString("borg-module-duplicate"), args.Chassis, user); // event is only raised by server so not using PopupClient - args.Cancelled = true; - return; - } - } - - private void OnModuleSelected(Entity ent, ref BorgModuleSelectedEvent args) - { - var chassis = args.Chassis; - if (!TryComp(chassis, out var hands)) - return; - - var container = _container.GetContainer(ent, ent.Comp.ContainerId); - var items = container.ContainedEntities; - for (int i = 0; i < ent.Comp.Items.Count; i++) - { - var item = items[0]; // the contained items will gradually go to 0 - var handId = HandId(ent, i); - _hands.AddHand((chassis, hands), handId, HandLocation.Middle); - var hand = hands.Hands[handId]; - _hands.DoPickup(chassis, handId, item, hands); - if (_hands.TryGetHeldItem((chassis, hands), handId, out var heldIdtem) - && heldIdtem != item) - { - Log.Error($"Failed to pick up {ToPrettyString(item)} into hand {handId} of {ToPrettyString(chassis)}, it holds {ToPrettyString(heldIdtem)}"); - // If we didn't pick up our expected item, delete the hand. No free hands! - _hands.RemoveHand((chassis, hands), handId); - } - else - { - _interaction.DoContactInteraction(chassis, item); // for potential forensics or other systems (why does hands system not do this) - _placeholder.SetEnabled(item, true); - } - } - } - - private void OnModuleUnselected(Entity ent, ref BorgModuleUnselectedEvent args) - { - var chassis = args.Chassis; - if (!TryComp(chassis, out var hands)) - return; - - if (TerminatingOrDeleted(ent)) - { - for (int i = 0; i < ent.Comp.Items.Count; i++) - { - var handId = HandId(ent, i); - _hands.TryGetHand((chassis, hands), handId, out var hand); - if (_hands.TryGetHeldItem((chassis, hands), handId, out var item) - && item != null) - QueueDel(item); - else if (!TerminatingOrDeleted(chassis) && Transform(chassis).MapID != MapId.Nullspace) // don't care if its empty if the server is shutting down - Log.Warning($"Borg {ToPrettyString(chassis)} terminated with empty hand {i} in {ToPrettyString(ent)}"); - _hands.RemoveHand((chassis, hands), handId); - } - return; - } - - var container = _container.GetContainer(ent, ent.Comp.ContainerId); - for (int i = 0; i < ent.Comp.Items.Count; i++) - { - var handId = HandId(ent, i); - _hands.TryGetHand((chassis, hands), handId, out var hand); - if (_hands.TryGetHeldItem((chassis, hands), handId, out var item) - && item != null) - { - _placeholder.SetEnabled(item.Value, false); - _container.Insert(item.Value, container, force: true); - } - else - { - Log.Error($"Borg {ToPrettyString(chassis)} had an empty hand in the slot for {ent.Comp.Items[i].Id}"); - } - - _hands.RemoveHand((chassis, hands), handId); - } - } - - /// - /// Format the hand ID for a given module and item number. - /// - private static string HandId(EntityUid uid, int i) - { - return $"nf-{uid}-item-{i}"; - } -} - -/// -/// Event raised on a module to check if it can be installed. -/// This should exist upstream but doesn't. -/// -[ByRefEvent] -public record struct BorgCanInsertModuleEvent(Entity Chassis, EntityUid? User, bool Cancelled = false);