using System.Linq; using Content.Shared.FixedPoint; using Content.Shared.PDA.Ringer; using Content.Shared.Store.Components; using Robust.Shared.Player; using Robust.Shared.Prototypes; namespace Content.Shared.Store; /// /// This handles... /// public abstract partial class SharedStoreSystem { /// /// Toggles the store Ui open and closed /// /// the person doing the toggling /// the store being toggled /// /// The entity remotely accessing the store, if any. /// The remote access component, if any. public void ToggleUi(EntityUid user, EntityUid storeEnt, StoreComponent? component = null, EntityUid? remoteAccess = null, RemoteStoreComponent? remoteComponent = null) { if (!Resolve(storeEnt, ref component)) return; if (remoteAccess != null && !Resolve(remoteAccess.Value, ref remoteComponent) && remoteComponent!.Store != storeEnt) return; if (!TryComp(user, out var actor)) return; if (!UI.TryToggleUi(remoteAccess != null ? remoteAccess.Value : storeEnt, StoreUiKey.Key, actor.PlayerSession)) return; UpdateUserInterface(user, storeEnt, component); } /// /// Closes the store UI for everyone, if it's open /// public void CloseUi(EntityUid uid, StoreComponent? component = null) { if (!Resolve(uid, ref component)) return; UI.CloseUi(uid, StoreUiKey.Key); } /// /// Updates the user interface for a store and refreshes the listings /// /// The person who if opening the store ui. Listings are filtered based on this. /// The store entity itself /// The store component being refreshed. public void UpdateUserInterface(EntityUid? user, EntityUid store, StoreComponent? component = null) { if (!Resolve(store, ref component)) return; //this is the person who will be passed into logic for all listing filtering. if (user != null) //if we have no "buyer" for this update, then don't update the listings { component.LastAvailableListings = GetAvailableListings(component.AccountOwner ?? user.Value, store, component).ToHashSet(); } //dictionary for all currencies, including 0 values for currencies on the whitelist Dictionary, FixedPoint2> allCurrency = new(); foreach (var supported in component.CurrencyWhitelist) { allCurrency.Add(supported, FixedPoint2.Zero); if (component.Balance.TryGetValue(supported, out var value)) allCurrency[supported] = value; } // TODO: if multiple users are supposed to be able to interact with a single BUI & see different // stores/listings, this needs to use session specific BUI states. // only tell operatives to lock their uplink if it can be locked var showFooter = HasComp(store); var state = new StoreUpdateState(component.LastAvailableListings, allCurrency, showFooter, component.RefundAllowed); UpdateRemoteStores(store, state); UI.SetUiState(store, StoreUiKey.Key, state); } /// /// Updates any remote store connections to a specific store. /// /// The store being updated. /// The state being applied. public void UpdateRemoteStores(EntityUid store, StoreUpdateState state) { var query = EntityQueryEnumerator(); while (query.MoveNext(out var uid, out var remote, out var ui)) { if (remote.Store != store) continue; UI.SetUiState((uid, ui), StoreUiKey.Key, state); } } }