4 using System.Collections.Generic;
9 partial class CargoManager
11 private List<SoldEntity> SoldEntities {
get; } =
new List<SoldEntity>();
14 private static readonly HashSet<InvSlotType> equipmentSlots =
new HashSet<InvSlotType>()
26 if (character ==
null) {
return new List<Item>(); }
27 var confirmedSoldEntities = GetConfirmedSoldEntities();
30 if (!IsItemSellable(item, confirmedSoldEntities)) {
return false; }
32 if (!item.AllowedSlots.All(s => equipmentSlots.Contains(s)) && IsInEquipmentSlot(item)) {
return false; }
34 if (item.RootContainer is
Item rootContainer && IsInEquipmentSlot(rootContainer)) {
return false; }
36 }, recursive:
true).Distinct();
38 bool IsInEquipmentSlot(
Item item)
48 private IEnumerable<SoldEntity> GetConfirmedSoldEntities()
53 return SoldEntities.Where(se => se.Status != SoldEntity.SellStatus.Unconfirmed);
59 foreach (var entry
in items)
69 foreach (var entry
in items)
76 public void SetSoldItems(Dictionary<Identifier, List<SoldItem>> items)
78 if (
SoldItems.Count == 0 && items.Count == 0) {
return; }
81 foreach (var entry
in items)
85 foreach (var se
in SoldEntities)
87 if (se.Status == SoldEntity.SellStatus.Confirmed) {
continue; }
88 if (
SoldItems.Any(si => si.Value.Any(si => Match(si, se,
true))))
90 se.Status = SoldEntity.SellStatus.Confirmed;
94 se.Status = SoldEntity.SellStatus.Unconfirmed;
97 foreach (var soldItems
in SoldItems.Values)
99 foreach (var si
in soldItems)
102 if (!(SoldEntities.FirstOrDefault(se => se.Item ==
null && Match(si, se,
false)) is SoldEntity soldEntityMatch)) {
continue; }
104 soldEntityMatch.SetItem(item);
105 soldEntityMatch.Status = SoldEntity.SellStatus.Confirmed;
110 static bool Match(
SoldItem soldItem, SoldEntity soldEntity,
bool matchId)
113 if (matchId && (soldEntity.Item ==
null || soldItem.
ID != soldEntity.Item.ID)) {
return false; }
123 item.Quantity += changeInQuantity;
124 if (item.Quantity < 1)
129 else if (changeInQuantity > 0)
138 IEnumerable<Item> sellableItems;
141 sellableItems = sellingMode
switch
145 _ =>
throw new NotImplementedException()
148 catch (NotImplementedException e)
150 DebugConsole.LogError($
"Error selling items: unknown store tab type \"{sellingMode}\".\n{e.StackTrace.CleanupStackTrace()}");
159 DebugConsole.LogError($
"Error selling items at {Location}: no store with identifier \"{storeIdentifier}\" exists.\n{Environment.StackTrace.CleanupStackTrace()}");
162 var storeSpecificSoldItems =
GetSoldItems(storeIdentifier, create:
true);
163 foreach (var item
in itemsToSell)
165 int itemValue = item.Quantity * sellValues[item.ItemPrefab];
167 if (store.Balance < itemValue) {
continue; }
169 var matchingItems = sellableItems.Where(i => i.Prefab == item.ItemPrefab);
170 int count = Math.Min(item.Quantity, matchingItems.Count());
174 for (
int i = 0; i < count; i++)
176 var matchingItem = matchingItems.ElementAt(i);
177 storeSpecificSoldItems.Add(
new SoldItem(matchingItem.Prefab, matchingItem.ID, canAddToRemoveQueue, sellerId, origin));
178 SoldEntities.Add(
new SoldEntity(matchingItem, campaign.
IsSinglePlayer ? SoldEntity.SellStatus.Confirmed : SoldEntity.SellStatus.Local));
185 for (
int i = 0; i < count; i++)
188 SoldEntities.Add(
new SoldEntity(item.ItemPrefab, SoldEntity.SellStatus.Local));
192 store.Balance -= itemValue;
195 campaign.
Bank.Give(itemValue);
197 GameAnalyticsManager.AddMoneyGainedEvent(itemValue, GameAnalyticsManager.MoneySource.Store, item.ItemPrefab.Identifier.Value);
201 if (sellCrate?.Find(pi => pi.ItemPrefab == item.ItemPrefab) is { } itemToSell)
203 itemToSell.Quantity -= item.Quantity;
204 if (itemToSell.Quantity < 1)
206 sellCrate.Remove(itemToSell);
216 SoldEntities.Clear();
List< PurchasedItem > GetSubCrateItems(Identifier identifier, bool create=false)
List< PurchasedItem > GetSellCrateItems(Identifier identifier, bool create=false)
void SetSoldItems(Dictionary< Identifier, List< SoldItem >> items)
void ModifyItemQuantityInSellCrate(Identifier storeIdentifier, ItemPrefab itemPrefab, int changeInQuantity)
void SetItemsInSubSellCrate(Dictionary< Identifier, List< PurchasedItem >> items)
Dictionary< Identifier, List< PurchasedItem > > ItemsInSellFromSubCrate
IEnumerable< Item > GetSellableItemsFromSub()
void SellItems(Identifier storeIdentifier, List< PurchasedItem > itemsToSell, Store.StoreTab sellingMode)
Dictionary< Identifier, List< PurchasedItem > > ItemsInBuyCrate
readonly NamedEvent< CargoManager > OnItemsInSellFromSubCrateChanged
PurchasedItem GetSellCrateItem(Identifier identifier, ItemPrefab prefab)
List< SoldItem > GetSoldItems(Identifier identifier, bool create=false)
void ClearSoldItemsProjSpecific()
readonly NamedEvent< CargoManager > OnSoldItemsChanged
IEnumerable< Item > GetSellableItems(Character character)
Dictionary< Identifier, List< SoldItem > > SoldItems
Dictionary< ItemPrefab, int > GetSellValuesAtCurrentLocation(Identifier storeIdentifier, IEnumerable< ItemPrefab > items)
readonly NamedEvent< CargoManager > OnItemsInSellCrateChanged
readonly NamedEvent< CargoManager > OnItemsInBuyCrateChanged
void SetItemsInBuyCrate(Dictionary< Identifier, List< PurchasedItem >> items)
CharacterInventory Inventory
static Character? Controlled
bool IsInLimbSlot(Item item, InvSlotType limbSlot)
static EntitySpawner Spawner
const ushort NullEntityID
static Entity FindEntityByID(ushort ID)
Find an entity based on the ID
void AddItemToRemoveQueue(Item item)
static bool IsSingleplayer
List< Item > FindAllItems(Func< Item, bool > predicate=null, bool recursive=false, List< Item > list=null)
ItemPrefab(ContentXElement element, ItemFile file)
StoreInfo GetStore(Identifier identifier)