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);
}
}
}