Unstable 0.17.4.0

This commit is contained in:
Markus Isberg
2022-03-30 00:08:09 +09:00
parent 2968e23ae8
commit c1b8e5a341
177 changed files with 3388 additions and 1977 deletions
@@ -130,7 +130,7 @@ namespace Barotrauma
UISprite newSprite = new UISprite(subElement);
GUIComponent.ComponentState spriteState = GUIComponent.ComponentState.None;
if (subElement.Attribute("state") != null)
if (subElement.GetAttribute("state") != null)
{
string stateStr = subElement.GetAttributeString("state", "None");
Enum.TryParse(stateStr, out spriteState);
@@ -172,7 +172,7 @@ namespace Barotrauma
{
AutoScaleVertical = true,
TextScale = 1.1f,
TextGetter = () => FormatCurrency(campaign.Wallet.Balance)
TextGetter = () => TextManager.FormatCurrency(campaign.Wallet.Balance)
};
var pendingAndCrewGroup = new GUILayoutGroup(new RectTransform(new Vector2(0.9f, 0.95f), anchor: Anchor.Center,
@@ -400,7 +400,7 @@ namespace Barotrauma
if (listBox != crewList)
{
new GUITextBlock(new RectTransform(new Vector2(width, 1.0f), mainGroup.RectTransform),
FormatCurrency(characterInfo.Salary),
TextManager.FormatCurrency(characterInfo.Salary),
textAlignment: Alignment.Center)
{
CanBeFocused = false
@@ -629,7 +629,7 @@ namespace Barotrauma
{
total += ((InfoSkill)c.UserData).CharacterInfo.Salary;
});
totalBlock.Text = FormatCurrency(total);
totalBlock.Text = TextManager.FormatCurrency(total);
bool enoughMoney = campaign == null || campaign.Wallet.CanAfford(total);
totalBlock.TextColor = enoughMoney ? Color.White : Color.Red;
validateHiresButton.Enabled = enoughMoney && pendingList.Content.RectTransform.Children.Any();
@@ -925,7 +925,5 @@ namespace Barotrauma
GameMain.Client.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
}
}
private LocalizedString FormatCurrency(int currency) => TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", currency));
}
}
@@ -40,7 +40,7 @@ namespace Barotrauma
public IEnumerable<T> GetAllChildren<T>() where T : GUIComponent
{
return GetAllChildren().Where(c => c is T).Select(c => c as T);
return GetAllChildren().OfType<T>();
}
/// <summary>
@@ -67,7 +67,7 @@ namespace Barotrauma
{
foreach (GUIComponent child in Children)
{
if (child.UserData == obj || (child.UserData != null && child.UserData.Equals(obj))) { return child; }
if (Equals(child.UserData, obj)) { return child; }
}
return null;
}
@@ -108,7 +108,7 @@ namespace Barotrauma
}
public GUIComponent FindChild(object userData, bool recursive = false)
{
var matchingChild = Children.FirstOrDefault(c => c.UserData == userData);
var matchingChild = Children.FirstOrDefault(c => Equals(c.UserData, userData));
if (recursive && matchingChild == null)
{
foreach (GUIComponent child in Children)
@@ -123,7 +123,7 @@ namespace Barotrauma
public IEnumerable<GUIComponent> FindChildren(object userData)
{
return Children.Where(c => c.UserData == userData);
return Children.Where(c => Equals(c.UserData, userData));
}
public IEnumerable<GUIComponent> FindChildren(Func<GUIComponent, bool> predicate)
@@ -16,8 +16,8 @@ namespace Barotrauma
public LocalizedString Tooltip;
public ContextMenuOption(string labelTag, bool isEnabled, Action onSelected)
: this(TextManager.Get(labelTag), isEnabled, onSelected) { }
public ContextMenuOption(string label, bool isEnabled, Action onSelected)
: this(TextManager.Get(label).Fallback(label), isEnabled, onSelected) { }
public ContextMenuOption(Identifier labelTag, bool isEnabled, Action onSelected)
: this(TextManager.Get(labelTag), isEnabled, onSelected) { }
@@ -314,13 +314,12 @@ namespace Barotrauma
foreach (GUIComponent child in ListBox.Content.Children)
{
var tickBox = child.GetChild<GUITickBox>();
if (obj == child.UserData) { tickBox.Selected = true; }
if (Equals(obj, child.UserData)) { tickBox.Selected = true; }
}
}
else
{
GUITextBlock textBlock = component as GUITextBlock;
if (textBlock == null)
if (!(component is GUITextBlock textBlock))
{
textBlock = component.GetChild<GUITextBlock>();
if (textBlock is null && !AllowNonText) { return false; }
@@ -96,15 +96,11 @@ namespace Barotrauma
switch (child.ScaleBasis)
{
case ScaleBasis.BothHeight:
child.MinSize = new Point(child.Rect.Height, child.MinSize.Y);
break;
case ScaleBasis.Smallest when Rect.Height <= Rect.Width:
case ScaleBasis.Largest when Rect.Height > Rect.Width:
child.MinSize = new Point((int)((child.Rect.Height * child.RelativeSize.X) / child.RelativeSize.Y), child.MinSize.Y);
break;
case ScaleBasis.BothWidth:
child.MinSize = new Point(child.MinSize.X, child.Rect.Width);
break;
case ScaleBasis.Smallest when Rect.Width <= Rect.Height:
case ScaleBasis.Largest when Rect.Width > Rect.Height:
child.MinSize = new Point(child.MinSize.X, (int)((child.Rect.Width * child.RelativeSize.Y) / child.RelativeSize.X));
@@ -402,8 +402,7 @@ namespace Barotrauma
int i = 0;
foreach (GUIComponent child in children)
{
if ((child.UserData != null && child.UserData.Equals(userData)) ||
(child.UserData == null && userData == null))
if (Equals(child.UserData, userData))
{
Select(i, force, autoScroll);
if (!SelectMultiple) { return; }
@@ -1219,6 +1218,20 @@ namespace Barotrauma
i++;
}
if (isDraggingElement && CurrentDragMode == DragMode.DragOutsideBox && HideDraggedElement)
{
Rectangle drawRect = DraggedElement.Rect;
int draggedElementIndex = Content.GetChildIndex(DraggedElement);
CalculateChildrenOffsets((index, point) =>
{
if (draggedElementIndex == index)
{
drawRect.Location = Content.Rect.Location + point;
}
});
GUI.DrawRectangle(spriteBatch, drawRect, Color.White * 0.5f, thickness: 2f);
}
if (HideChildrenOutsideFrame)
{
spriteBatch.End();
@@ -65,7 +65,7 @@ namespace Barotrauma
LoadFont();
}
private void LoadFont()
public void LoadFont()
{
string fontPath = GetFontFilePath(element);
uint size = GetFontSize(element);
@@ -268,7 +268,7 @@ namespace Barotrauma
}
int totalCost = medicalClinic.GetTotalCost();
healList.PriceBlock.Text = UpgradeStore.FormatCurrency(totalCost);
healList.PriceBlock.Text = TextManager.FormatCurrency(totalCost);
healList.PriceBlock.TextColor = GUIStyle.Red;
healList.HealButton.Enabled = false;
if (medicalClinic.GetWallet().CanAfford(totalCost))
@@ -288,7 +288,7 @@ namespace Barotrauma
{
if (element.FindAfflictionElement(affliction) is { } existingAffliction)
{
existingAffliction.Price.Text = UpgradeStore.FormatCurrency(affliction.Strength);
existingAffliction.Price.Text = TextManager.FormatCurrency(affliction.Strength);
continue;
}
@@ -467,7 +467,7 @@ namespace Barotrauma
GUITextBlock moneyLabel = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), balanceLayout.RectTransform), string.Empty, textAlignment: Alignment.TopRight, font: GUIStyle.SubHeadingFont)
{
TextGetter = () => UpgradeStore.FormatCurrency(medicalClinic.GetWallet().Balance),
TextGetter = () => TextManager.FormatCurrency(medicalClinic.GetWallet().Balance),
AutoScaleVertical = true,
TextScale = 1.1f
};
@@ -571,7 +571,7 @@ namespace Barotrauma
GUILayoutGroup priceLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true);
GUITextBlock priceLabelBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.Get("campaignstore.total"));
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), UpgradeStore.FormatCurrency(medicalClinic.GetTotalCost()), font: GUIStyle.SubHeadingFont,
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), priceLayout.RectTransform), TextManager.FormatCurrency(medicalClinic.GetTotalCost()), font: GUIStyle.SubHeadingFont,
textAlignment: Alignment.Right);
GUILayoutGroup buttonLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), footerLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterRight);
@@ -684,7 +684,7 @@ namespace Barotrauma
GUIFrame textContainer = new GUIFrame(new RectTransform(new Vector2(0.6f, 1f), textLayout.RectTransform), style: null);
GUITextBlock afflictionName = new GUITextBlock(new RectTransform(Vector2.One, textContainer.RectTransform), name, font: GUIStyle.SubHeadingFont);
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
GUITextBlock healCost = new GUITextBlock(new RectTransform(new Vector2(0.2f, 1f), textLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), textAlignment: Alignment.Center, font: GUIStyle.LargeFont)
{
Padding = Vector4.Zero
};
@@ -876,7 +876,7 @@ namespace Barotrauma
ToolTip = prefab.Description
};
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), UpgradeStore.FormatCurrency(affliction.Price), font: GUIStyle.LargeFont);
GUITextBlock priceBlock = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), bottomTextLayout.RectTransform), TextManager.FormatCurrency(affliction.Price), font: GUIStyle.LargeFont);
GUIButton buyButton = new GUIButton(new RectTransform(new Vector2(0.2f, 0.75f), bottomLayout.RectTransform), style: "CrewManagementAddButton");
@@ -931,7 +931,7 @@ namespace Barotrauma
});
}
private static void EnsureTextDoesntOverflow(string? text, GUITextBlock textBlock, Rectangle bounds, ImmutableArray<GUILayoutGroup>? layoutGroups = null)
public static void EnsureTextDoesntOverflow(string? text, GUITextBlock textBlock, Rectangle bounds, ImmutableArray<GUILayoutGroup>? layoutGroups = null)
{
if (string.IsNullOrWhiteSpace(text)) { return; }
@@ -44,6 +44,7 @@ namespace Barotrauma
private bool suppressBuySell;
private int buyTotal, sellTotal, sellFromSubTotal;
private GUITextBlock storeNameBlock;
private GUITextBlock merchantBalanceBlock;
private GUITextBlock currentSellValueBlock, newSellValueBlock;
private GUIImage sellValueChangeArrow;
@@ -65,6 +66,7 @@ namespace Barotrauma
private Point resolutionWhenCreated;
private Dictionary<ItemPrefab, ItemQuantity> OwnedItems { get; } = new Dictionary<ItemPrefab, ItemQuantity>();
private Location.StoreInfo ActiveStore { get; set; }
private CargoManager CargoManager => campaignUI.Campaign.CargoManager;
private Location CurrentLocation => campaignUI.Campaign.Map?.CurrentLocation;
@@ -238,6 +240,39 @@ namespace Barotrauma
campaignUI.Campaign.CargoManager.OnItemsInSellFromSubCrateChanged += () => { needsSellingFromSubRefresh = true; };
}
public void SelectStore(Identifier identifier)
{
if (CurrentLocation?.Stores != null)
{
if (CurrentLocation.GetStore(identifier) is { } store)
{
ActiveStore = store;
if (storeNameBlock != null)
{
var storeName = TextManager.Get($"storename.{store.Identifier}");
if (storeName.IsNullOrEmpty())
{
storeName = TextManager.Get("store");
}
storeNameBlock.SetRichText(storeName);
}
}
else
{
ActiveStore = null;
string msg = $"Error selecting store with identifier \"{identifier}\" at {CurrentLocation}: store with the identifier doesn't exist at the location.";
DebugConsole.ShowError(msg);
GameAnalyticsManager.AddErrorEventOnce("Store.SelectStore:StoreDoesntExist", GameAnalyticsManager.ErrorSeverity.Error, msg);
}
}
else
{
ActiveStore = null;
}
RefreshItemsToSell();
Refresh();
}
public void Refresh(bool updateOwned = true)
{
UpdatePermissions();
@@ -321,7 +356,7 @@ namespace Barotrauma
};
var imageWidth = (float)headerGroup.Rect.Height / headerGroup.Rect.Width;
new GUIImage(new RectTransform(new Vector2(imageWidth, 1.0f), headerGroup.RectTransform), "StoreTradingIcon");
new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("store"), font: GUIStyle.LargeFont)
storeNameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f - imageWidth, 1.0f), headerGroup.RectTransform), TextManager.Get("store"), font: GUIStyle.LargeFont)
{
CanBeFocused = false,
ForceUpperCase = ForceUpperCase.Yes
@@ -350,7 +385,7 @@ namespace Barotrauma
TextScale = 1.1f,
TextGetter = () =>
{
merchantBalanceBlock.TextColor = CurrentLocation?.BalanceColor ?? Color.Red;
merchantBalanceBlock.TextColor = ActiveStore?.BalanceColor ?? Color.Red;
return GetMerchantBalanceText();
}
};
@@ -388,17 +423,17 @@ namespace Barotrauma
{
int balanceAfterTransaction = activeTab switch
{
StoreTab.Buy => CurrentLocation.StoreCurrentBalance + buyTotal,
StoreTab.Sell => CurrentLocation.StoreCurrentBalance - sellTotal,
StoreTab.SellSub => CurrentLocation.StoreCurrentBalance - sellFromSubTotal,
StoreTab.Buy => ActiveStore.Balance + buyTotal,
StoreTab.Sell => ActiveStore.Balance - sellTotal,
StoreTab.SellSub => ActiveStore.Balance - sellFromSubTotal,
_ => throw new NotImplementedException(),
};
if (balanceAfterTransaction != CurrentLocation.StoreCurrentBalance)
if (balanceAfterTransaction != ActiveStore.Balance)
{
var newStatus = CurrentLocation.GetStoreBalanceStatus(balanceAfterTransaction);
if (CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier != newStatus.SellPriceModifier)
if (ActiveStore.ActiveBalanceStatus.SellPriceModifier != newStatus.SellPriceModifier)
{
string tooltipTag = newStatus.SellPriceModifier > CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier ?
string tooltipTag = newStatus.SellPriceModifier > ActiveStore.ActiveBalanceStatus.SellPriceModifier ?
"campaingstore.valueincreasetooltip" : "campaingstore.valuedecreasetooltip";
sellValueContainer.ToolTip = TextManager.Get(tooltipTag);
currentSellValueBlock.TextColor = newStatus.Color;
@@ -406,14 +441,14 @@ namespace Barotrauma
sellValueChangeArrow.Visible = true;
newSellValueBlock.TextColor = newStatus.Color;
newSellValueBlock.Text = $"{(newStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
return $"{(CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
return $"{(ActiveStore.ActiveBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
}
}
sellValueContainer.ToolTip = TextManager.Get("campaignstore.sellvaluetooltip");
currentSellValueBlock.TextColor = CurrentLocation.BalanceColor;
currentSellValueBlock.TextColor = ActiveStore.BalanceColor;
sellValueChangeArrow.Visible = false;
newSellValueBlock.Text = null;
return $"{(CurrentLocation.ActiveStoreBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
return $"{(ActiveStore.ActiveBalanceStatus.SellPriceModifier * 100).FormatZeroDecimal()} %";
}
else
{
@@ -698,9 +733,9 @@ namespace Barotrauma
if (!HasActiveTabPermissions()) { return false; }
var itemsToRemove = activeTab switch
{
StoreTab.Buy => new List<PurchasedItem>(CargoManager.ItemsInBuyCrate),
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
StoreTab.Buy => new List<PurchasedItem>(CargoManager.GetBuyCrateItems(ActiveStore)),
StoreTab.Sell => new List<PurchasedItem>(CargoManager.GetSellCrateItems(ActiveStore)),
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.GetSubCrateItems(ActiveStore)),
_ => throw new NotImplementedException(),
};
itemsToRemove.ForEach(i => ClearFromShoppingCrate(i));
@@ -708,14 +743,13 @@ namespace Barotrauma
}
};
Refresh();
ChangeStoreTab(activeTab);
resolutionWhenCreated = new Point(GameMain.GraphicsWidth, GameMain.GraphicsHeight);
}
private LocalizedString GetMerchantBalanceText() => GetCurrencyFormatted(CurrentLocation?.StoreCurrentBalance ?? 0);
private LocalizedString GetMerchantBalanceText() => TextManager.FormatCurrency(ActiveStore?.Balance ?? 0);
private LocalizedString GetPlayerBalanceText() => GetCurrencyFormatted(PlayerWallet.Balance);
private LocalizedString GetPlayerBalanceText() => TextManager.FormatCurrency(PlayerWallet.Balance);
private GUILayoutGroup CreateDealsGroup(GUIListBox parentList, int elementCount = 4)
{
@@ -746,21 +780,25 @@ namespace Barotrauma
private void UpdateLocation(Location prevLocation, Location newLocation)
{
if (prevLocation == newLocation) { return; }
if (prevLocation?.Reputation != null)
{
prevLocation.Reputation.OnReputationValueChanged = null;
prevLocation.Reputation.OnReputationValueChanged -= SetNeedsRefresh;
}
if (ItemPrefab.Prefabs.Any(p => p.CanBeBoughtAtLocation(CurrentLocation, out PriceInfo _)))
if (ItemPrefab.Prefabs.Any(p => p.CanBeBoughtFrom(newLocation)))
{
selectedItemCategory = null;
searchBox.Text = "";
ChangeStoreTab(StoreTab.Buy);
if (newLocation?.Reputation != null)
{
newLocation.Reputation.OnReputationValueChanged += () => { needsRefresh = true; };
newLocation.Reputation.OnReputationValueChanged += SetNeedsRefresh;
}
}
void SetNeedsRefresh()
{
needsRefresh = true;
}
}
private void ChangeStoreTab(StoreTab tab)
@@ -862,9 +900,9 @@ namespace Barotrauma
bool hasPermissions = HasBuyPermissions;
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
int dailySpecialCount = CurrentLocation?.DailySpecials.Count() ?? 3;
int dailySpecialCount = ActiveStore.DailySpecials.Count;
if ((storeDailySpecialsGroup != null) != CurrentLocation.DailySpecials.Any() || dailySpecialCount != prevDailySpecialCount)
if ((storeDailySpecialsGroup != null) != ActiveStore.DailySpecials.Any() || dailySpecialCount != prevDailySpecialCount)
{
if (storeDailySpecialsGroup == null || dailySpecialCount != prevDailySpecialCount)
{
@@ -881,32 +919,32 @@ namespace Barotrauma
prevDailySpecialCount = dailySpecialCount;
}
foreach (PurchasedItem item in CurrentLocation.StoreStock)
foreach (PurchasedItem item in ActiveStore.Stock)
{
CreateOrUpdateItemFrame(item.ItemPrefab, item.Quantity);
}
foreach (ItemPrefab itemPrefab in CurrentLocation.DailySpecials)
foreach (ItemPrefab itemPrefab in ActiveStore.DailySpecials)
{
if (CurrentLocation.StoreStock.Any(pi => pi.ItemPrefab == itemPrefab)) { continue; }
if (ActiveStore.Stock.Any(pi => pi.ItemPrefab == itemPrefab)) { continue; }
CreateOrUpdateItemFrame(itemPrefab, 0);
}
void CreateOrUpdateItemFrame(ItemPrefab itemPrefab, int quantity)
{
if (itemPrefab.CanBeBoughtAtLocation(CurrentLocation, out PriceInfo priceInfo))
if (itemPrefab.CanBeBoughtFrom(ActiveStore, out PriceInfo priceInfo))
{
var isDailySpecial = CurrentLocation.DailySpecials.Contains(itemPrefab);
bool isDailySpecial = ActiveStore.DailySpecials.Contains(itemPrefab);
var itemFrame = isDailySpecial ?
storeDailySpecialsGroup.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab) :
storeBuyList.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab);
if (CargoManager.PurchasedItems.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem purchasedItem)
if (CargoManager.GetPurchasedItem(ActiveStore, itemPrefab) is { } purchasedItem)
{
quantity = Math.Max(quantity - purchasedItem.Quantity, 0);
}
if (CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem itemInBuyCrate)
if (CargoManager.GetBuyCrateItem(ActiveStore, itemPrefab) is { } buyCrateItem)
{
quantity = Math.Max(quantity - itemInBuyCrate.Quantity, 0);
quantity = Math.Max(quantity - buyCrateItem.Quantity, 0);
}
if (itemFrame == null)
{
@@ -945,7 +983,7 @@ namespace Barotrauma
bool hasPermissions = HasTabPermissions(StoreTab.Sell);
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
if ((storeRequestedGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
if ((storeRequestedGoodGroup != null) != ActiveStore.RequestedGoods.Any())
{
if (storeRequestedGoodGroup == null)
{
@@ -965,7 +1003,7 @@ namespace Barotrauma
CreateOrUpdateItemFrame(item.ItemPrefab, item.Quantity);
}
foreach (var requestedGood in CurrentLocation.RequestedGoods)
foreach (var requestedGood in ActiveStore.RequestedGoods)
{
if (itemsToSell.Any(pi => pi.ItemPrefab == requestedGood)) { continue; }
CreateOrUpdateItemFrame(requestedGood, 0);
@@ -973,15 +1011,15 @@ namespace Barotrauma
void CreateOrUpdateItemFrame(ItemPrefab itemPrefab, int itemQuantity)
{
PriceInfo priceInfo = itemPrefab.GetPriceInfo(CurrentLocation);
PriceInfo priceInfo = itemPrefab.GetPriceInfo(ActiveStore);
if (priceInfo == null) { return; }
var isRequestedGood = CurrentLocation.RequestedGoods.Contains(itemPrefab);
var isRequestedGood = ActiveStore.RequestedGoods.Contains(itemPrefab);
var itemFrame = isRequestedGood ?
storeRequestedGoodGroup.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab) :
storeSellList.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab);
if (CargoManager.ItemsInSellCrate.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem itemInSellCrate)
if (CargoManager.GetSellCrateItem(ActiveStore, itemPrefab) is { } sellCrateItem)
{
itemQuantity = Math.Max(itemQuantity - itemInSellCrate.Quantity, 0);
itemQuantity = Math.Max(itemQuantity - sellCrateItem.Quantity, 0);
}
if (itemFrame == null)
{
@@ -1023,7 +1061,7 @@ namespace Barotrauma
bool hasPermissions = HasSellSubPermissions;
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
if ((storeRequestedSubGoodGroup != null) != CurrentLocation.RequestedGoods.Any())
if ((storeRequestedSubGoodGroup != null) != ActiveStore.RequestedGoods.Any())
{
if (storeRequestedSubGoodGroup == null)
{
@@ -1043,7 +1081,7 @@ namespace Barotrauma
CreateOrUpdateItemFrame(item.ItemPrefab, item.Quantity);
}
foreach (var requestedGood in CurrentLocation.RequestedGoods)
foreach (var requestedGood in ActiveStore.RequestedGoods)
{
if (itemsToSellFromSub.Any(pi => pi.ItemPrefab == requestedGood)) { continue; }
CreateOrUpdateItemFrame(requestedGood, 0);
@@ -1051,15 +1089,15 @@ namespace Barotrauma
void CreateOrUpdateItemFrame(ItemPrefab itemPrefab, int itemQuantity)
{
PriceInfo priceInfo = itemPrefab.GetPriceInfo(CurrentLocation);
PriceInfo priceInfo = itemPrefab.GetPriceInfo(ActiveStore);
if (priceInfo == null) { return; }
var isRequestedGood = CurrentLocation.RequestedGoods.Contains(itemPrefab);
bool isRequestedGood = ActiveStore.RequestedGoods.Contains(itemPrefab);
var itemFrame = isRequestedGood ?
storeRequestedSubGoodGroup.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab) :
storeSellFromSubList.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab == itemPrefab);
if (CargoManager.ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == itemPrefab) is PurchasedItem itemInSellFromSubCrate)
if (CargoManager.GetSubCrateItem(ActiveStore, itemPrefab) is { } subCrateItem)
{
itemQuantity = Math.Max(itemQuantity - itemInSellFromSubCrate.Quantity, 0);
itemQuantity = Math.Max(itemQuantity - subCrateItem.Quantity, 0);
}
if (itemFrame == null)
{
@@ -1102,13 +1140,13 @@ namespace Barotrauma
{
if (buying)
{
undiscountedPriceBlock.TextGetter = () => GetCurrencyFormatted(
CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab, considerDailySpecials: false) ?? 0);
undiscountedPriceBlock.TextGetter = () => TextManager.FormatCurrency(
ActiveStore?.GetAdjustedItemBuyPrice(pi.ItemPrefab, considerDailySpecials: false) ?? 0);
}
else
{
undiscountedPriceBlock.TextGetter = () => GetCurrencyFormatted(
CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab, considerRequestedGoods: false) ?? 0);
undiscountedPriceBlock.TextGetter = () => TextManager.FormatCurrency(
ActiveStore?.GetAdjustedItemSellPrice(pi.ItemPrefab, considerRequestedGoods: false) ?? 0);
}
}
@@ -1116,11 +1154,11 @@ namespace Barotrauma
{
if (buying)
{
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemBuyPrice(pi.ItemPrefab) ?? 0);
priceBlock.TextGetter = () => TextManager.FormatCurrency(ActiveStore?.GetAdjustedItemBuyPrice(pi.ItemPrefab) ?? 0);
}
else
{
priceBlock.TextGetter = () => GetCurrencyFormatted(CurrentLocation?.GetAdjustedItemSellPrice(pi.ItemPrefab) ?? 0);
priceBlock.TextGetter = () => TextManager.FormatCurrency(ActiveStore?.GetAdjustedItemSellPrice(pi.ItemPrefab) ?? 0);
}
}
}
@@ -1135,21 +1173,21 @@ namespace Barotrauma
{
item.Quantity += 1;
}
else if (playerItem.Prefab.GetPriceInfo(CurrentLocation) != null)
else if (playerItem.Prefab.GetPriceInfo(ActiveStore) != null)
{
itemsToSell.Add(new PurchasedItem(playerItem.Prefab, 1));
}
}
// Remove items from sell crate if they aren't in player inventory anymore
var itemsInCrate = new List<PurchasedItem>(CargoManager.ItemsInSellCrate);
var itemsInCrate = new List<PurchasedItem>(CargoManager.GetSellCrateItems(ActiveStore));
foreach (PurchasedItem crateItem in itemsInCrate)
{
var playerItem = itemsToSell.Find(i => i.ItemPrefab == crateItem.ItemPrefab);
var playerItemQuantity = playerItem != null ? playerItem.Quantity : 0;
if (crateItem.Quantity > playerItemQuantity)
{
CargoManager.ModifyItemQuantityInSellCrate(crateItem.ItemPrefab, playerItemQuantity - crateItem.Quantity);
CargoManager.ModifyItemQuantityInSellCrate(ActiveStore.Identifier, crateItem.ItemPrefab, playerItemQuantity - crateItem.Quantity);
}
}
needsItemsToSellRefresh = false;
@@ -1165,35 +1203,35 @@ namespace Barotrauma
{
item.Quantity += 1;
}
else if (subItem.Prefab.GetPriceInfo(CurrentLocation) != null)
else if (subItem.Prefab.GetPriceInfo(ActiveStore) != null)
{
itemsToSellFromSub.Add(new PurchasedItem(subItem.Prefab, 1));
}
}
// Remove items from sell crate if they aren't on the sub anymore
var itemsInCrate = new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate);
var itemsInCrate = new List<PurchasedItem>(CargoManager.GetSubCrateItems(ActiveStore));
foreach (PurchasedItem crateItem in itemsInCrate)
{
var subItem = itemsToSellFromSub.Find(i => i.ItemPrefab == crateItem.ItemPrefab);
var subItemQuantity = subItem != null ? subItem.Quantity : 0;
if (crateItem.Quantity > subItemQuantity)
{
CargoManager.ModifyItemQuantityInSellFromSubCrate(crateItem.ItemPrefab, subItemQuantity - crateItem.Quantity);
CargoManager.ModifyItemQuantityInSubSellCrate(ActiveStore.Identifier, crateItem.ItemPrefab, subItemQuantity - crateItem.Quantity);
}
}
sellableItemsFromSubUpdateTimer = 0.0f;
needsItemsToSellFromSubRefresh = false;
}
private void RefreshShoppingCrateList(List<PurchasedItem> items, GUIListBox listBox, StoreTab tab)
private void RefreshShoppingCrateList(IEnumerable<PurchasedItem> items, GUIListBox listBox, StoreTab tab)
{
bool hasPermissions = HasTabPermissions(tab);
HashSet<GUIComponent> existingItemFrames = new HashSet<GUIComponent>();
int totalPrice = 0;
foreach (PurchasedItem item in items)
{
if (!(item.ItemPrefab.GetPriceInfo(CurrentLocation) is { } priceInfo)) { continue; }
if (!(item.ItemPrefab.GetPriceInfo(ActiveStore) is { } priceInfo)) { continue; }
GUINumberInput numInput = null;
if (!(listBox.Content.FindChild(c => c.UserData is PurchasedItem pi && pi.ItemPrefab.Identifier == item.ItemPrefab.Identifier) is { } itemFrame))
{
@@ -1227,9 +1265,9 @@ namespace Barotrauma
{
int price = tab switch
{
StoreTab.Buy => CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo),
StoreTab.Sell => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
StoreTab.SellSub => CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
StoreTab.Buy => ActiveStore.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo),
StoreTab.Sell => ActiveStore.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
StoreTab.SellSub => ActiveStore.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo),
_ => throw new NotImplementedException()
};
totalPrice += item.Quantity * price;
@@ -1265,11 +1303,11 @@ namespace Barotrauma
SetConfirmButtonStatus();
}
private void RefreshShoppingCrateBuyList() => RefreshShoppingCrateList(CargoManager.ItemsInBuyCrate, shoppingCrateBuyList, StoreTab.Buy);
private void RefreshShoppingCrateBuyList() => RefreshShoppingCrateList(CargoManager.GetBuyCrateItems(ActiveStore), shoppingCrateBuyList, StoreTab.Buy);
private void RefreshShoppingCrateSellList() => RefreshShoppingCrateList(CargoManager.ItemsInSellCrate, shoppingCrateSellList, StoreTab.Sell);
private void RefreshShoppingCrateSellList() => RefreshShoppingCrateList(CargoManager.GetSellCrateItems(ActiveStore), shoppingCrateSellList, StoreTab.Sell);
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.ItemsInSellFromSubCrate, shoppingCrateSellFromSubList, StoreTab.SellSub);
private void RefreshShoppingCrateSellFromSubList() => RefreshShoppingCrateList(CargoManager.GetSubCrateItems(ActiveStore), shoppingCrateSellFromSubList, StoreTab.SellSub);
private void SortItems(GUIListBox list, SortingMethod sortingMethod)
{
@@ -1316,8 +1354,8 @@ namespace Barotrauma
{
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
{
var sortResult = CurrentLocation.GetAdjustedItemSellPrice(itemX.ItemPrefab).CompareTo(
CurrentLocation.GetAdjustedItemSellPrice(itemY.ItemPrefab));
int sortResult = ActiveStore.GetAdjustedItemSellPrice(itemX.ItemPrefab).CompareTo(
ActiveStore.GetAdjustedItemSellPrice(itemY.ItemPrefab));
if (sortingMethod == SortingMethod.PriceDesc) { sortResult *= -1; }
return sortResult;
}
@@ -1340,8 +1378,8 @@ namespace Barotrauma
{
if (x.GUIComponent.UserData is PurchasedItem itemX && y.GUIComponent.UserData is PurchasedItem itemY)
{
var sortResult = CurrentLocation.GetAdjustedItemBuyPrice(itemX.ItemPrefab).CompareTo(
CurrentLocation.GetAdjustedItemBuyPrice(itemY.ItemPrefab));
int sortResult = ActiveStore.GetAdjustedItemBuyPrice(itemX.ItemPrefab).CompareTo(
ActiveStore.GetAdjustedItemBuyPrice(itemY.ItemPrefab));
if (sortingMethod == SortingMethod.PriceDesc) { sortResult *= -1; }
return sortResult;
}
@@ -1485,7 +1523,7 @@ namespace Barotrauma
};
bool isSellingRelatedList = containingTab != StoreTab.Buy;
bool locationHasDealOnItem = isSellingRelatedList ?
CurrentLocation.RequestedGoods.Contains(pi.ItemPrefab) : CurrentLocation.DailySpecials.Contains(pi.ItemPrefab);
ActiveStore.RequestedGoods.Contains(pi.ItemPrefab) : ActiveStore.DailySpecials.Contains(pi.ItemPrefab);
GUITextBlock nameBlock = new GUITextBlock(new RectTransform(new Vector2(1.0f, 0.4f), nameAndQuantityGroup.RectTransform),
pi.ItemPrefab.Name, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft)
{
@@ -1673,7 +1711,7 @@ namespace Barotrauma
}
// Add items already purchased
CargoManager?.PurchasedItems?.ForEach(pi => AddNonEmptyOwnedItems(pi));
CargoManager?.GetPurchasedItems(ActiveStore).ForEach(pi => AddNonEmptyOwnedItems(pi));
ownedItemsUpdateTimer = 0.0f;
@@ -1689,7 +1727,7 @@ namespace Barotrauma
void AddOwnedItem(Item item)
{
if (!(item?.Prefab.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)) { return; }
if (!(item?.Prefab.GetPriceInfo(ActiveStore) is PriceInfo priceInfo)) { return; }
bool isNonEmpty = !priceInfo.DisplayNonEmpty || item.ConditionPercentage > 5.0f;
if (OwnedItems.TryGetValue(item.Prefab, out ItemQuantity itemQuantity))
{
@@ -1862,7 +1900,7 @@ namespace Barotrauma
{
list = mode switch
{
StoreTab.Buy => CurrentLocation?.StoreStock,
StoreTab.Buy => ActiveStore?.Stock,
StoreTab.Sell => itemsToSell,
StoreTab.SellSub => itemsToSellFromSub,
_ => throw new NotImplementedException()
@@ -1876,7 +1914,7 @@ namespace Barotrauma
{
if (mode == StoreTab.Buy)
{
var purchasedItem = CargoManager.PurchasedItems.Find(i => i.ItemPrefab == item.ItemPrefab);
var purchasedItem = CargoManager.GetPurchasedItem(ActiveStore, item.ItemPrefab);
if (purchasedItem != null) { return Math.Max(item.Quantity - purchasedItem.Quantity, 0); }
}
return item.Quantity;
@@ -1887,22 +1925,19 @@ namespace Barotrauma
}
}
private LocalizedString GetCurrencyFormatted(int amount) =>
TextManager.GetWithVariable("currencyformat", "[credits]", string.Format(CultureInfo.InvariantCulture, "{0:N0}", amount));
private bool ModifyBuyQuantity(PurchasedItem item, int quantity)
{
if (item?.ItemPrefab == null) { return false; }
if (!HasBuyPermissions) { return false; }
if (quantity > 0)
{
var itemInCrate = CargoManager.ItemsInBuyCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
if (itemInCrate != null && itemInCrate.Quantity >= CargoManager.MaxQuantity) { return false; }
var crateItem = CargoManager.GetBuyCrateItem(ActiveStore, item.ItemPrefab);
if (crateItem != null && crateItem.Quantity >= CargoManager.MaxQuantity) { return false; }
// Make sure there's enough available in the store
var totalQuantityToBuy = itemInCrate != null ? itemInCrate.Quantity + quantity : quantity;
var totalQuantityToBuy = crateItem != null ? crateItem.Quantity + quantity : quantity;
if (totalQuantityToBuy > GetMaxAvailable(item.ItemPrefab, StoreTab.Buy)) { return false; }
}
CargoManager.ModifyItemQuantityInBuyCrate(item.ItemPrefab, quantity);
CargoManager.ModifyItemQuantityInBuyCrate(ActiveStore.Identifier, item.ItemPrefab, quantity);
GameMain.Client?.SendCampaignState();
return true;
}
@@ -1914,11 +1949,11 @@ namespace Barotrauma
if (quantity > 0)
{
// Make sure there's enough available to sell
var itemToSell = CargoManager.ItemsInSellCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
var itemToSell = CargoManager.GetSellCrateItem(ActiveStore, item.ItemPrefab);
var totalQuantityToSell = itemToSell != null ? itemToSell.Quantity + quantity : quantity;
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.Sell)) { return false; }
}
CargoManager.ModifyItemQuantityInSellCrate(item.ItemPrefab, quantity);
CargoManager.ModifyItemQuantityInSellCrate(ActiveStore.Identifier, item.ItemPrefab, quantity);
return true;
}
@@ -1929,11 +1964,11 @@ namespace Barotrauma
if (quantity > 0)
{
// Make sure there's enough available to sell
var itemToSell = CargoManager.ItemsInSellFromSubCrate.Find(i => i.ItemPrefab == item.ItemPrefab);
var itemToSell = CargoManager.GetSubCrateItem(ActiveStore, item.ItemPrefab);
var totalQuantityToSell = itemToSell != null ? itemToSell.Quantity + quantity : quantity;
if (totalQuantityToSell > GetMaxAvailable(item.ItemPrefab, StoreTab.SellSub)) { return false; }
}
CargoManager.ModifyItemQuantityInSellFromSubCrate(item.ItemPrefab, quantity);
CargoManager.ModifyItemQuantityInSubSellCrate(ActiveStore.Identifier, item.ItemPrefab, quantity);
GameMain.Client?.SendCampaignState();
return true;
}
@@ -1981,32 +2016,27 @@ namespace Barotrauma
private bool BuyItems()
{
if (!HasBuyPermissions) { return false; }
var itemsToPurchase = new List<PurchasedItem>(CargoManager.ItemsInBuyCrate);
var itemsToPurchase = new List<PurchasedItem>(CargoManager.GetBuyCrateItems(ActiveStore));
var itemsToRemove = new List<PurchasedItem>();
var totalPrice = 0;
foreach (PurchasedItem item in itemsToPurchase)
int totalPrice = 0;
foreach (var item in itemsToPurchase)
{
if (item?.ItemPrefab == null || !item.ItemPrefab.CanBeBoughtAtLocation(CurrentLocation, out PriceInfo priceInfo))
if (item?.ItemPrefab == null || !item.ItemPrefab.CanBeBoughtFrom(ActiveStore, out var priceInfo))
{
itemsToRemove.Add(item);
continue;
}
totalPrice += item.Quantity * CurrentLocation.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo);
totalPrice += item.Quantity * ActiveStore.GetAdjustedItemBuyPrice(item.ItemPrefab, priceInfo: priceInfo);
}
itemsToRemove.ForEach(i => itemsToPurchase.Remove(i));
if (itemsToPurchase.None() || !PlayerWallet.CanAfford(totalPrice)) { return false; }
CargoManager.PurchaseItems(itemsToPurchase, true);
CargoManager.PurchaseItems(ActiveStore.Identifier, itemsToPurchase, true);
GameMain.Client?.SendCampaignState();
var dialog = new GUIMessageBox(
TextManager.Get("newsupplies"),
TextManager.GetWithVariable("suppliespurchasedmessage", "[location]", campaignUI?.Campaign?.Map?.CurrentLocation?.Name),
new LocalizedString[] { TextManager.Get("Ok") });
dialog.Buttons[0].OnClicked += dialog.Close;
return false;
}
@@ -2018,8 +2048,8 @@ namespace Barotrauma
{
itemsToSell = activeTab switch
{
StoreTab.Sell => new List<PurchasedItem>(CargoManager.ItemsInSellCrate),
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.ItemsInSellFromSubCrate),
StoreTab.Sell => new List<PurchasedItem>(CargoManager.GetSellCrateItems(ActiveStore)),
StoreTab.SellSub => new List<PurchasedItem>(CargoManager.GetSubCrateItems(ActiveStore)),
_ => throw new NotImplementedException()
};
}
@@ -2032,9 +2062,9 @@ namespace Barotrauma
int totalValue = 0;
foreach (PurchasedItem item in itemsToSell)
{
if (item?.ItemPrefab?.GetPriceInfo(CurrentLocation) is PriceInfo priceInfo)
if (item?.ItemPrefab?.GetPriceInfo(ActiveStore) is PriceInfo priceInfo)
{
totalValue += item.Quantity * CurrentLocation.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
totalValue += item.Quantity * ActiveStore.GetAdjustedItemSellPrice(item.ItemPrefab, priceInfo: priceInfo);
}
else
{
@@ -2042,8 +2072,8 @@ namespace Barotrauma
}
}
itemsToRemove.ForEach(i => itemsToSell.Remove(i));
if (itemsToSell.None() || totalValue > CurrentLocation.StoreCurrentBalance) { return false; }
CargoManager.SellItems(itemsToSell, activeTab);
if (itemsToSell.None() || totalValue > ActiveStore.Balance) { return false; }
CargoManager.SellItems(ActiveStore.Identifier, itemsToSell, activeTab);
GameMain.Client?.SendCampaignState();
return false;
}
@@ -2052,7 +2082,7 @@ namespace Barotrauma
{
if (IsBuying)
{
shoppingCrateTotal.Text = GetCurrencyFormatted(buyTotal);
shoppingCrateTotal.Text = TextManager.FormatCurrency(buyTotal);
shoppingCrateTotal.TextColor = !PlayerWallet.CanAfford(buyTotal) ? Color.Red : Color.White;
}
else
@@ -2063,8 +2093,8 @@ namespace Barotrauma
StoreTab.SellSub => sellFromSubTotal,
_ => throw new NotImplementedException(),
};
shoppingCrateTotal.Text = GetCurrencyFormatted(total);
shoppingCrateTotal.TextColor = CurrentLocation != null && total > CurrentLocation.StoreCurrentBalance ? Color.Red : Color.White;
shoppingCrateTotal.Text = TextManager.FormatCurrency(total);
shoppingCrateTotal.TextColor = CurrentLocation != null && total > ActiveStore.Balance ? Color.Red : Color.White;
}
}
@@ -2100,8 +2130,8 @@ namespace Barotrauma
activeTab switch
{
StoreTab.Buy => PlayerWallet.CanAfford(buyTotal),
StoreTab.Sell => CurrentLocation != null && sellTotal <= CurrentLocation.StoreCurrentBalance,
StoreTab.SellSub => CurrentLocation != null && sellFromSubTotal <= CurrentLocation.StoreCurrentBalance,
StoreTab.Sell => CurrentLocation != null && sellTotal <= ActiveStore.Balance,
StoreTab.SellSub => CurrentLocation != null && sellFromSubTotal <= ActiveStore.Balance,
_ => false
};
}
@@ -2124,6 +2154,7 @@ namespace Barotrauma
if (GameMain.GraphicsWidth != resolutionWhenCreated.X || GameMain.GraphicsHeight != resolutionWhenCreated.Y)
{
CreateUI();
needsRefresh = true;
}
else
{
@@ -2131,38 +2162,62 @@ namespace Barotrauma
ownedItemsUpdateTimer += deltaTime;
if (ownedItemsUpdateTimer >= timerUpdateInterval)
{
var prevOwnedItems = new Dictionary<ItemPrefab, ItemQuantity>(OwnedItems);
bool checkForRefresh = !needsItemsToSellRefresh || !needsRefresh;
var prevOwnedItems = checkForRefresh ? new Dictionary<ItemPrefab, ItemQuantity>(OwnedItems) : null;
UpdateOwnedItems();
bool refresh = OwnedItems.Count != prevOwnedItems.Count ||
OwnedItems.Values.Sum(v => v.Total) != prevOwnedItems.Values.Sum(v => v.Total) ||
OwnedItems.Any(kvp => !prevOwnedItems.TryGetValue(kvp.Key, out ItemQuantity v) || kvp.Value.Total != v.Total) ||
prevOwnedItems.Any(kvp => !OwnedItems.ContainsKey(kvp.Key));
if (refresh)
if (checkForRefresh)
{
needsItemsToSellRefresh = true;
needsRefresh = true;
bool refresh = OwnedItems.Count != prevOwnedItems.Count ||
OwnedItems.Values.Sum(v => v.Total) != prevOwnedItems.Values.Sum(v => v.Total) ||
OwnedItems.Any(kvp => !prevOwnedItems.TryGetValue(kvp.Key, out ItemQuantity v) || kvp.Value.Total != v.Total) ||
prevOwnedItems.Any(kvp => !OwnedItems.ContainsKey(kvp.Key));
if (refresh)
{
needsItemsToSellRefresh = true;
needsRefresh = true;
}
}
}
// Update the sellable sub items at short intervals and check if the interface should be refreshed
sellableItemsFromSubUpdateTimer += deltaTime;
if (sellableItemsFromSubUpdateTimer >= timerUpdateInterval)
{
var prevSubItems = new List<PurchasedItem>(itemsToSellFromSub);
bool checkForRefresh = !needsRefresh;
var prevSubItems = checkForRefresh ? new List<PurchasedItem>(itemsToSellFromSub) : null;
RefreshItemsToSellFromSub();
needsRefresh = needsRefresh ||
itemsToSellFromSub.Count != prevSubItems.Count ||
itemsToSellFromSub.Sum(i => i.Quantity) != prevSubItems.Sum(i => i.Quantity) ||
itemsToSellFromSub.Any(i => !(prevSubItems.FirstOrDefault(prev => prev.ItemPrefab == i.ItemPrefab) is PurchasedItem prev) || i.Quantity != prev.Quantity) ||
prevSubItems.Any(prev => itemsToSellFromSub.None(i => i.ItemPrefab == prev.ItemPrefab));
if (checkForRefresh)
{
needsRefresh = itemsToSellFromSub.Count != prevSubItems.Count ||
itemsToSellFromSub.Sum(i => i.Quantity) != prevSubItems.Sum(i => i.Quantity) ||
itemsToSellFromSub.Any(i => !(prevSubItems.FirstOrDefault(prev => prev.ItemPrefab == i.ItemPrefab) is PurchasedItem prev) || i.Quantity != prev.Quantity) ||
prevSubItems.Any(prev => itemsToSellFromSub.None(i => i.ItemPrefab == prev.ItemPrefab));
}
}
}
if (needsItemsToSellRefresh) { RefreshItemsToSell(); }
if (needsItemsToSellFromSubRefresh) { RefreshItemsToSellFromSub(); }
if (needsRefresh || HavePermissionsChanged()) { Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f); }
if (needsBuyingRefresh || HavePermissionsChanged(StoreTab.Buy)) { RefreshBuying(updateOwned: ownedItemsUpdateTimer > 0.0f); }
if (needsSellingRefresh || HavePermissionsChanged(StoreTab.Sell)) { RefreshSelling(updateOwned: ownedItemsUpdateTimer > 0.0f); }
if (needsSellingFromSubRefresh || HavePermissionsChanged(StoreTab.SellSub)) { RefreshSellingFromSub(updateOwned: ownedItemsUpdateTimer > 0.0f, updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f); }
if (needsItemsToSellRefresh)
{
RefreshItemsToSell();
}
if (needsItemsToSellFromSubRefresh)
{
RefreshItemsToSellFromSub();
}
if (needsRefresh || HavePermissionsChanged())
{
Refresh(updateOwned: ownedItemsUpdateTimer > 0.0f);
}
if (needsBuyingRefresh || HavePermissionsChanged(StoreTab.Buy))
{
RefreshBuying(updateOwned: ownedItemsUpdateTimer > 0.0f);
}
if (needsSellingRefresh || HavePermissionsChanged(StoreTab.Sell))
{
RefreshSelling(updateOwned: ownedItemsUpdateTimer > 0.0f);
}
if (needsSellingFromSubRefresh || HavePermissionsChanged(StoreTab.SellSub))
{
RefreshSellingFromSub(updateOwned: ownedItemsUpdateTimer > 0.0f, updateItemsToSellFromSub: sellableItemsFromSubUpdateTimer > 0.0f);
}
updateStopwatch.Stop();
GameMain.PerformanceCounter.AddPartialElapsedTicks("GameSessionUpdate", "StoreUpdate", updateStopwatch.ElapsedTicks);
@@ -31,7 +31,7 @@ namespace Barotrauma
private readonly List<SubmarineInfo> subsToShow;
private readonly SubmarineDisplayContent[] submarineDisplays = new SubmarineDisplayContent[submarinesPerPage];
private SubmarineInfo selectedSubmarine = null;
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyShorthandText, currencyLongText;
private LocalizedString purchaseAndSwitchText, purchaseOnlyText, deliveryText, currentSubText, deliveryFeeText, priceText, switchText, missingPreviewText, currencyName;
private readonly RectTransform parent;
private readonly Action closeAction;
private Sprite pageIndicator;
@@ -99,8 +99,7 @@ namespace Barotrauma
priceText = TextManager.Get("price");
}
currencyShorthandText = TextManager.Get("currencyformat");
currencyLongText = TextManager.Get("credit").Value.ToLowerInvariant();
currencyName = TextManager.Get("credit").Value.ToLowerInvariant();
UpdateSubmarines();
missingPreviewText = TextManager.Get("SubPreviewImageNotFound");
@@ -335,7 +334,7 @@ namespace Barotrauma
if (!GameMain.GameSession.IsSubmarineOwned(subToDisplay))
{
LocalizedString amountString = currencyShorthandText.Replace("[credits]", subToDisplay.Price.ToString());
LocalizedString amountString = TextManager.FormatCurrency(subToDisplay.Price);
submarineDisplays[i].submarineFee.Text = priceText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
}
else
@@ -344,7 +343,7 @@ namespace Barotrauma
{
if (deliveryFee > 0)
{
LocalizedString amountString = currencyShorthandText.Replace("[credits]", deliveryFee.ToString());
LocalizedString amountString = TextManager.FormatCurrency(deliveryFee);
submarineDisplays[i].submarineFee.Text = deliveryFeeText.Replace("[amount]", amountString).Replace("[currencyname]", string.Empty).TrimEnd();
}
else
@@ -584,7 +583,7 @@ namespace Barotrauma
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(deliveryFee) && deliveryFee > 0)
{
new GUIMessageBox(TextManager.Get("deliveryrequestheader"), TextManager.GetWithVariables("notenoughmoneyfordeliverytext",
("[currencyname]", currencyLongText),
("[currencyname]", currencyName),
("[submarinename]", selectedSubmarine.DisplayName),
("[location1]", deliveryLocationName),
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name)));
@@ -601,7 +600,7 @@ namespace Barotrauma
("[location2]", GameMain.GameSession.Map.CurrentLocation.Name),
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName),
("[amount]", deliveryFee.ToString()),
("[currencyname]", currencyLongText)), messageBoxOptions);
("[currencyname]", currencyName)), messageBoxOptions);
}
else
{
@@ -632,7 +631,7 @@ namespace Barotrauma
if (!GameMain.GameSession.Campaign.Wallet.CanAfford(selectedSubmarine.Price))
{
new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("notenoughmoneyforpurchasetext",
("[currencyname]", currencyLongText),
("[currencyname]", currencyName),
("[submarinename]", selectedSubmarine.DisplayName)));
return;
}
@@ -644,7 +643,7 @@ namespace Barotrauma
msgBox = new GUIMessageBox(TextManager.Get("purchaseandswitchsubmarineheader"), TextManager.GetWithVariables("purchaseandswitchsubmarinetext",
("[submarinename1]", selectedSubmarine.DisplayName),
("[amount]", selectedSubmarine.Price.ToString()),
("[currencyname]", currencyLongText),
("[currencyname]", currencyName),
("[submarinename2]", CurrentOrPendingSubmarine().DisplayName)), messageBoxOptions);
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
@@ -667,7 +666,7 @@ namespace Barotrauma
msgBox = new GUIMessageBox(TextManager.Get("purchasesubmarineheader"), TextManager.GetWithVariables("purchasesubmarinetext",
("[submarinename]", selectedSubmarine.DisplayName),
("[amount]", selectedSubmarine.Price.ToString()),
("[currencyname]", currencyLongText)), messageBoxOptions);
("[currencyname]", currencyName)), messageBoxOptions);
msgBox.Buttons[0].OnClicked = (applyButton, obj) =>
{
@@ -218,7 +218,7 @@ namespace Barotrauma
public void AddToGUIUpdateList()
{
infoFrame?.AddToGUIUpdateList();
infoFrame?.AddToGUIUpdateList(order: 1);
NetLobbyScreen.JobInfoFrame?.AddToGUIUpdateList();
}
@@ -379,8 +379,7 @@ namespace Barotrauma
private void CreateCrewListFrame(GUIFrame crewFrame)
{
// FIXME remove TestScreen stuff
crew = GameMain.GameSession?.CrewManager?.GetCharacters() ?? new []{ TestScreen.dummyCharacter };
crew = GameMain.GameSession?.CrewManager?.GetCharacters() ?? Array.Empty<Character>();
teamIDs = crew.Select(c => c.TeamID).Distinct().ToList();
// Show own team first when there's more than one team
@@ -817,8 +816,11 @@ namespace Barotrauma
else if (client != null)
{
GUIComponent preview = CreateClientInfoFrame(background, client, GetPermissionIcon(client));
if (GameMain.NetworkMember != null) { GameMain.Client.SelectCrewClient(client, preview); }
CreateWalletFrame(background, client.Character);
GameMain.Client?.SelectCrewClient(client, preview);
if (client.Character != null)
{
CreateWalletFrame(background, client.Character);
}
}
return true;
@@ -845,22 +847,23 @@ namespace Barotrauma
float relativeX = icon.RectTransform.NonScaledSize.X / (float)icon.Parent.RectTransform.NonScaledSize.X;
GUILayoutGroup headerTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1.0f - relativeX, 1f), headerLayout.RectTransform), isHorizontal: true) { Stretch = true };
new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.Get("crewwallet.wallet"), font: GUIStyle.LargeFont);
GUITextBlock moneyBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), UpgradeStore.FormatCurrency(targetWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
GUITextBlock moneyBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), headerTextLayout.RectTransform), TextManager.FormatCurrency(targetWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
GUILayoutGroup middleLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.66f), walletLayout.RectTransform));
GUILayoutGroup salaryTextLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true);
GUITextBlock salaryTitle = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), TextManager.Get("crewwallet.salary"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.BottomLeft);
GUITextBlock rewardBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), TextManager.GetWithVariable("percentageformat", "[value]", GetSharePercentage()), textAlignment: Alignment.BottomRight);
GUITextBlock rewardBlock = new GUITextBlock(new RectTransform(new Vector2(0.5f, 1f), salaryTextLayout.RectTransform), string.Empty, textAlignment: Alignment.BottomRight);
GUILayoutGroup sliderLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), middleLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.Center);
GUIScrollBar salarySlider = new GUIScrollBar(new RectTransform(new Vector2(0.9f, 1f), sliderLayout.RectTransform), style: "GUISlider", barSize: 0.03f)
{
Range = Vector2.UnitY,
ToolTip = TextManager.Get("crewwallet.salary.tooltip"),
Range = new Vector2(0, 1),
BarScrollValue = targetWallet.RewardDistribution / 100f,
Step = 0.01f,
BarSize = 0.1f,
OnMoved = (bar, scroll) =>
{
rewardBlock.Text = TextManager.GetWithVariable("percentageformat", "[value]", GetSharePercentage());
SetRewardText((int)(scroll * 100), rewardBlock);
return true;
},
OnReleased = (bar, scroll) =>
@@ -871,6 +874,9 @@ namespace Barotrauma
return true;
}
};
SetRewardText(targetWallet.RewardDistribution, rewardBlock);
// @formatter:off
GUIScissorComponent scissorComponent = new GUIScissorComponent(new RectTransform(new Vector2(0.85f, 1.25f), walletFrame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter))
{
@@ -883,7 +889,7 @@ namespace Barotrauma
GUILayoutGroup mainLayout = new GUILayoutGroup(new RectTransform(new Vector2(1f, 0.5f), paddedTransferMenuLayout.RectTransform), isHorizontal: true, childAnchor: Anchor.CenterLeft);
GUILayoutGroup leftLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1f), mainLayout.RectTransform));
GUITextBlock leftName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), leftLayout.RectTransform), character.Name, textAlignment: Alignment.CenterLeft, font: GUIStyle.SubHeadingFont);
GUITextBlock leftBalance = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), leftLayout.RectTransform), UpgradeStore.FormatCurrency(targetWallet.Balance), textAlignment: Alignment.Left) { TextColor = GUIStyle.Blue };
GUITextBlock leftBalance = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), leftLayout.RectTransform), TextManager.FormatCurrency(targetWallet.Balance), textAlignment: Alignment.Left) { TextColor = GUIStyle.Blue };
GUILayoutGroup rightLayout = new GUILayoutGroup(new RectTransform(new Vector2(0.5f, 1f), mainLayout.RectTransform), childAnchor: Anchor.TopRight);
GUITextBlock rightName = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), rightLayout.RectTransform), string.Empty, font: GUIStyle.SubHeadingFont, textAlignment: Alignment.CenterRight);
GUITextBlock rightBalance = new GUITextBlock(new RectTransform(new Vector2(1f, 0.5f), rightLayout.RectTransform), string.Empty, textAlignment: Alignment.Right) { TextColor = GUIStyle.Red };
@@ -902,8 +908,11 @@ namespace Barotrauma
GUIButton confirmButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), centerButtonLayout.RectTransform), TextManager.Get("confirm"), style: "GUIButtonFreeScale") { Enabled = false };
GUIButton resetButton = new GUIButton(new RectTransform(new Vector2(0.5f, 1f), centerButtonLayout.RectTransform), TextManager.Get("reset"), style: "GUIButtonFreeScale") { Enabled = false };
// @formatter:on
ImmutableArray<GUILayoutGroup> layoutGroups = ImmutableArray.Create(transferMenuLayout, paddedTransferMenuLayout, mainLayout, leftLayout, rightLayout);
MedicalClinicUI.EnsureTextDoesntOverflow(character.Name, leftName, leftLayout.Rect, layoutGroups);
transferMenuButton = new GUIButton(new RectTransform(new Vector2(0.5f, 0.2f), walletFrame.RectTransform, Anchor.BottomCenter, Pivot.TopCenter), style: "UIToggleButtonVertical")
{
ToolTip = TextManager.Get("crewwallet.transfer.tooltip"),
OnClicked = (button, o) =>
{
isTransferMenuOpen = !isTransferMenuOpen;
@@ -951,13 +960,15 @@ namespace Barotrauma
break;
}
MedicalClinicUI.EnsureTextDoesntOverflow(rightName.Text.ToString(), rightName, rightLayout.Rect, layoutGroups);
if (!hasPermissions)
{
centerButton.Enabled = centerButton.CanBeFocused = false;
salarySlider.Enabled = salarySlider.CanBeFocused = false;
}
leftBalance.Text = UpgradeStore.FormatCurrency(otherWallet.Balance);
leftBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
UpdateAllInputs();
@@ -983,7 +994,7 @@ namespace Barotrauma
{
if (e.Wallet == targetWallet)
{
moneyBlock.Text = UpgradeStore.FormatCurrency(e.Info.Balance);
moneyBlock.Text = TextManager.FormatCurrency(e.Info.Balance);
salarySlider.BarScrollValue = e.Info.RewardDistribution / 100f;
}
UpdateAllInputs();
@@ -1022,23 +1033,23 @@ namespace Barotrauma
confirmButton.Enabled = resetButton.Enabled = transferAmountInput.IntValue > 0;
if (transferAmountInput.IntValue == 0)
{
rightBalance.Text = UpgradeStore.FormatCurrency(otherWallet.Balance);
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance);
rightBalance.TextColor = GUIStyle.TextColorNormal;
leftBalance.Text = UpgradeStore.FormatCurrency(targetWallet.Balance);
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance);
leftBalance.TextColor = GUIStyle.TextColorNormal;
}
else if (isSending)
{
rightBalance.Text = UpgradeStore.FormatCurrency(otherWallet.Balance + transferAmountInput.IntValue);
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance + transferAmountInput.IntValue);
rightBalance.TextColor = GUIStyle.Blue;
leftBalance.Text = UpgradeStore.FormatCurrency(targetWallet.Balance - transferAmountInput.IntValue);
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance - transferAmountInput.IntValue);
leftBalance.TextColor = GUIStyle.Red;
}
else
{
rightBalance.Text = UpgradeStore.FormatCurrency(otherWallet.Balance - transferAmountInput.IntValue);
rightBalance.Text = TextManager.FormatCurrency(otherWallet.Balance - transferAmountInput.IntValue);
rightBalance.TextColor = GUIStyle.Red;
leftBalance.Text = UpgradeStore.FormatCurrency(targetWallet.Balance + transferAmountInput.IntValue);
leftBalance.Text = TextManager.FormatCurrency(targetWallet.Balance + transferAmountInput.IntValue);
leftBalance.TextColor = GUIStyle.Blue;
}
}
@@ -1073,14 +1084,14 @@ namespace Barotrauma
Receiver = to.Select(option => option.ID),
Amount = amount
};
IWriteMessage msg = new WriteOnlyMessage().WithHeader(ClientPacketHeader.MONEY);
IWriteMessage msg = new WriteOnlyMessage().WithHeader(ClientPacketHeader.TRANSFER_MONEY);
transfer.Write(msg);
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
}
static void SetRewardDistribution(Character character, int newValue)
{
INetSerializableStruct transfer = new NetWalletSalaryUpdate
INetSerializableStruct transfer = new NetWalletSetSalaryUpdate
{
Target = character.ID,
NewRewardDistribution = newValue
@@ -1090,7 +1101,23 @@ namespace Barotrauma
GameMain.Client?.ClientPeer?.Send(msg, DeliveryMethod.Reliable);
}
string GetSharePercentage() => Mission.GetRewardShare(targetWallet.RewardDistribution, salaryCrew, Option<int>.None()).Percentage.ToString();
void SetRewardText(int value, GUITextBlock block)
{
var (_, percentage, sum) = Mission.GetRewardShare(value, salaryCrew, Option<int>.None());
LocalizedString tooltip = string.Empty;
block.TextColor = GUIStyle.TextColorNormal;
if (sum > 100)
{
tooltip = TextManager.GetWithVariables("crewwallet.salary.over100toolitp", ("[sum]", $"{(int)sum}"), ("[newvalue]", $"{percentage}"));
block.TextColor = GUIStyle.Orange;
}
LocalizedString text = TextManager.GetWithVariable("percentageformat", "[value]", $"{value}");
block.Text = text;
block.ToolTip = RichString.Rich(tooltip);
}
}
private GUIComponent CreateClientInfoFrame(GUIFrame frame, Client client, Sprite permissionIcon = null)
@@ -287,7 +287,7 @@ namespace Barotrauma
GUILayoutGroup rightLayout = new GUILayoutGroup(rectT(0.5f, 1, topHeaderLayout), childAnchor: Anchor.TopRight);
GUILayoutGroup priceLayout = new GUILayoutGroup(rectT(1, 0.8f, rightLayout), childAnchor: Anchor.Center) { RelativeSpacing = 0.08f };
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.Get("CampaignStore.Balance"), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right);
new GUITextBlock(rectT(1f, 0f, priceLayout), FormatCurrency(PlayerWallet.Balance, format: true), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => FormatCurrency(PlayerWallet.Balance, format: true) };
new GUITextBlock(rectT(1f, 0f, priceLayout), TextManager.FormatCurrency(PlayerWallet.Balance), font: GUIStyle.SubHeadingFont, textAlignment: Alignment.Right) { TextGetter = () => TextManager.FormatCurrency(PlayerWallet.Balance) };
new GUIFrame(rectT(0.5f, 0.1f, rightLayout, Anchor.BottomRight), style: "HorizontalLine") { IgnoreLayoutGroups = true };
repairButton.OnClicked = upgradeButton.OnClicked = (button, o) =>
@@ -571,7 +571,7 @@ namespace Barotrauma
var repairIcon = new GUIFrame(rectT(new Point(contentLayout.Rect.Height, contentLayout.Rect.Height), contentLayout), style: imageStyle);
GUILayoutGroup textLayout = new GUILayoutGroup(rectT(0.8f - repairIcon.RectTransform.RelativeSize.X, 1, contentLayout)) { Stretch = true };
new GUITextBlock(rectT(1, 0, textLayout), title, font: GUIStyle.SubHeadingFont) { CanBeFocused = false, AutoScaleHorizontal = true };
new GUITextBlock(rectT(1, 0, textLayout), FormatCurrency(price));
new GUITextBlock(rectT(1, 0, textLayout), TextManager.FormatCurrency(price));
GUILayoutGroup buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, contentLayout), childAnchor: Anchor.Center) { UserData = "buybutton" };
new GUIButton(rectT(0.7f, 0.5f, buyButtonLayout), string.Empty, style: "RepairBuyButton") { ClickSound = GUISoundType.HireRepairClick, Enabled = PlayerWallet.Balance >= price && !isDisabled, OnClicked = onPressed };
contentLayout.Recalculate();
@@ -1094,7 +1094,7 @@ namespace Barotrauma
if (addBuyButton)
{
var formattedPrice = FormatCurrency(Math.Abs(price));
var formattedPrice = TextManager.FormatCurrency(Math.Abs(price));
//negative price = refund
if (price < 0) { formattedPrice = "+" + formattedPrice; }
buyButtonLayout = new GUILayoutGroup(rectT(0.2f, 1, prefabLayout), childAnchor: Anchor.TopCenter) { UserData = "buybutton" };
@@ -1577,7 +1577,7 @@ namespace Barotrauma
if (priceLabel != null && !WaitForServerUpdate)
{
priceLabel.Text = FormatCurrency(price);
priceLabel.Text = TextManager.FormatCurrency(price);
if (currentLevel >= prefab.MaxLevel)
{
priceLabel.Text = TextManager.Get("Upgrade.MaxedUpgrade");
@@ -1695,11 +1695,6 @@ namespace Barotrauma
private bool HasPermission => campaignUI.Campaign.AllowedToManageCampaign();
public static LocalizedString FormatCurrency(int money, bool format = true)
{
return TextManager.GetWithVariable("CurrencyFormat", "[credits]", format ? string.Format(CultureInfo.InvariantCulture, "{0:N0}", money) : money.ToString());
}
// just a shortcut to create new RectTransforms since all the new RectTransform and new Vector2 confuses my IDE (and me)
private static RectTransform rectT(float x, float y, GUIComponent parentComponent, Anchor anchor = Anchor.TopLeft, ScaleBasis scaleBasis = ScaleBasis.Normal)
{