using System.Linq; using Content.Server.Store.Systems; using Content.Server.StoreDiscount.Systems; using Content.Shared.Hands.EntitySystems; using Content.Shared.Inventory; using Content.Shared.PDA; using Content.Shared.FixedPoint; using Content.Shared.Store; using Content.Shared.Store.Components; namespace Content.Server.Traitor.Uplink { public sealed class UplinkSystem : EntitySystem { [Dependency] private readonly InventorySystem _inventorySystem = default!; [Dependency] private readonly SharedHandsSystem _handsSystem = default!; [Dependency] private readonly StoreSystem _store = default!; [ValidatePrototypeId] public const string TelecrystalCurrencyPrototype = "Telecrystal"; /// /// Adds an uplink to the target /// /// The person who is getting the uplink /// The amount of currency on the uplink. If null, will just use the amount specified in the preset. /// The entity that will actually have the uplink functionality. Defaults to the PDA if null. /// Marker that enables discounts for uplink items. /// Whether or not the uplink was added successfully public bool AddUplink( EntityUid user, FixedPoint2? balance, EntityUid? uplinkEntity = null, bool giveDiscounts = false ) { // Try to find target item if none passed uplinkEntity ??= FindUplinkTarget(user); if (uplinkEntity == null) { return false; } EnsureComp(uplinkEntity.Value); var store = EnsureComp(uplinkEntity.Value); store.AccountOwner = user; store.Balance.Clear(); if (balance != null) { store.Balance.Clear(); _store.TryAddCurrency(new Dictionary { { TelecrystalCurrencyPrototype, balance.Value } }, uplinkEntity.Value, store); } var uplinkInitializedEvent = new StoreInitializedEvent( TargetUser: user, Store: uplinkEntity.Value, UseDiscounts: giveDiscounts, Listings: _store.GetAvailableListings(user, uplinkEntity.Value, store) .ToArray() ); RaiseLocalEvent(ref uplinkInitializedEvent); // TODO add BUI. Currently can't be done outside of yaml -_- return true; } /// /// Finds the entity that can hold an uplink for a user. /// Usually this is a pda in their pda slot, but can also be in their hands. (but not pockets or inside bag, etc.) /// public EntityUid? FindUplinkTarget(EntityUid user) { // Try to find PDA in inventory if (_inventorySystem.TryGetContainerSlotEnumerator(user, out var containerSlotEnumerator)) { while (containerSlotEnumerator.MoveNext(out var pdaUid)) { if (!pdaUid.ContainedEntity.HasValue) continue; if (HasComp(pdaUid.ContainedEntity.Value) || HasComp(pdaUid.ContainedEntity.Value)) return pdaUid.ContainedEntity.Value; } } // Also check hands foreach (var item in _handsSystem.EnumerateHeld(user)) { if (HasComp(item) || HasComp(item)) return item; } return null; } } }