Client LuaCsForBarotrauma
PriceInfo.cs
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Collections.Generic;
4 using System.Xml.Linq;
5 
6 namespace Barotrauma
7 {
8  class PriceInfo
9  {
10  public int Price { get; }
11  public bool CanBeBought { get; }
12 
16  public int MinAvailableAmount { get; }
17 
21  public int MaxAvailableAmount { get; }
25  public bool CanBeSpecial { get; }
29  public int MinLevelDifficulty { get; }
33  public float BuyingPriceMultiplier { get; } = 1f;
34  public bool DisplayNonEmpty { get; } = false;
35  public Identifier StoreIdentifier { get; }
36 
37  public bool RequiresUnlock { get; }
38 
42  private const int DefaultAmount = 5;
43 
47  private const float DefaultMaxAvailabilityRelativeToMin = 1.2f;
48 
49  private readonly Dictionary<Identifier, float> minReputation = new Dictionary<Identifier, float>();
50 
54  public IReadOnlyDictionary<Identifier, float> MinReputation => minReputation;
55 
61  public PriceInfo(XElement element)
62  {
63  Price = element.GetAttributeInt("buyprice", 0);
64  MinLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
65  BuyingPriceMultiplier = element.GetAttributeFloat("buyingpricemultiplier", 1f);
66  CanBeBought = true;
67  MinAvailableAmount = Math.Min(GetMinAmount(element, defaultValue: DefaultAmount), CargoManager.MaxQuantity);
68  MaxAvailableAmount = MathHelper.Clamp(GetMaxAmount(element, defaultValue: (int)(MinAvailableAmount * DefaultMaxAvailabilityRelativeToMin)), MinAvailableAmount, CargoManager.MaxQuantity);
69  RequiresUnlock = element.GetAttributeBool("requiresunlock", false);
70 
71  System.Diagnostics.Debug.Assert(MaxAvailableAmount >= MinAvailableAmount);
72  }
73 
74  public PriceInfo(int price, bool canBeBought,
75  int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true, int minLevelDifficulty = 0, float buyingPriceMultiplier = 1f,
76  bool displayNonEmpty = false, bool requiresUnlock = false, string storeIdentifier = null)
77  {
78  Price = price;
79  CanBeBought = canBeBought;
80  MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity);
81  MaxAvailableAmount = Math.Max(Math.Min(maxAmount, CargoManager.MaxQuantity), minAmount);
82  BuyingPriceMultiplier = buyingPriceMultiplier;
83  MinLevelDifficulty = minLevelDifficulty;
84  CanBeSpecial = canBeSpecial;
85  DisplayNonEmpty = displayNonEmpty;
86  StoreIdentifier = new Identifier(storeIdentifier);
87  RequiresUnlock = requiresUnlock;
88 
89  System.Diagnostics.Debug.Assert(MaxAvailableAmount >= MinAvailableAmount);
90  }
91 
92  private void LoadReputationRestrictions(XElement priceInfoElement)
93  {
94  foreach (XElement childElement in priceInfoElement.GetChildElements("reputation"))
95  {
96  Identifier factionId = childElement.GetAttributeIdentifier("faction", Identifier.Empty);
97  float rep = childElement.GetAttributeFloat("min", 0.0f);
98  if (!factionId.IsEmpty && rep > 0)
99  {
100  minReputation.Add(factionId, rep);
101  }
102  }
103  }
104 
105  public static List<PriceInfo> CreatePriceInfos(XElement element, out PriceInfo defaultPrice)
106  {
107  var priceInfos = new List<PriceInfo>();
108  defaultPrice = null;
109  int basePrice = element.GetAttributeInt("baseprice", 0);
110  int minAmount = GetMinAmount(element, defaultValue: DefaultAmount);
111  int maxAmount = GetMaxAmount(element, defaultValue: (int)(DefaultAmount * DefaultMaxAvailabilityRelativeToMin));
112  int minLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
113  bool canBeSpecial = element.GetAttributeBool("canbespecial", true);
114  float buyingPriceMultiplier = element.GetAttributeFloat("buyingpricemultiplier", 1f);
115  bool displayNonEmpty = element.GetAttributeBool("displaynonempty", false);
116  bool soldByDefault = element.GetAttributeBool("sold", element.GetAttributeBool("soldbydefault", true));
117  bool requiresUnlock = element.GetAttributeBool("requiresunlock", false);
118  foreach (XElement childElement in element.GetChildElements("price"))
119  {
120  float priceMultiplier = childElement.GetAttributeFloat("multiplier", 1.0f);
121  bool sold = childElement.GetAttributeBool("sold", soldByDefault);
122  int storeMinLevelDifficulty = childElement.GetAttributeInt("minleveldifficulty", minLevelDifficulty);
123  float storeBuyingMultiplier = childElement.GetAttributeFloat("buyingpricemultiplier", buyingPriceMultiplier);
124  string backwardsCompatibleIdentifier = childElement.GetAttributeString("locationtype", "");
125  if (!string.IsNullOrEmpty(backwardsCompatibleIdentifier))
126  {
127  backwardsCompatibleIdentifier = $"merchant{backwardsCompatibleIdentifier}";
128  }
129  string storeIdentifier = childElement.GetAttributeString("storeidentifier", backwardsCompatibleIdentifier);
130  // TODO: Add some error messages if we have defined the min or max amount while the item is not sold
131  var priceInfo = new PriceInfo(price: (int)(priceMultiplier * basePrice),
132  canBeBought: sold,
133  minAmount: sold ? GetMinAmount(childElement, minAmount) : 0,
134  maxAmount: sold ? GetMaxAmount(childElement, maxAmount) : 0,
135  canBeSpecial: canBeSpecial,
136  minLevelDifficulty: storeMinLevelDifficulty,
137  buyingPriceMultiplier: storeBuyingMultiplier,
138  displayNonEmpty: displayNonEmpty,
139  requiresUnlock: requiresUnlock,
140  storeIdentifier: storeIdentifier);
141  priceInfo.LoadReputationRestrictions(childElement);
142  priceInfos.Add(priceInfo);
143  }
144  bool soldElsewhere = soldByDefault && element.GetAttributeBool("soldelsewhere", element.GetAttributeBool("soldeverywhere", false));
145  defaultPrice = new PriceInfo(price: basePrice,
146  canBeBought: soldElsewhere,
147  minAmount: soldElsewhere ? minAmount : 0,
148  maxAmount: soldElsewhere ? maxAmount : 0,
149  canBeSpecial: canBeSpecial,
150  minLevelDifficulty: minLevelDifficulty,
151  buyingPriceMultiplier: buyingPriceMultiplier,
152  displayNonEmpty: displayNonEmpty,
153  requiresUnlock: requiresUnlock);
154  defaultPrice.LoadReputationRestrictions(element);
155  return priceInfos;
156  }
157 
158  private static int GetMinAmount(XElement element, int defaultValue) => element != null ?
159  element.GetAttributeInt("minamount", element.GetAttributeInt("minavailable", defaultValue)) :
160  defaultValue;
161 
162  private static int GetMaxAmount(XElement element, int defaultValue) => element != null ?
163  element.GetAttributeInt("maxamount", element.GetAttributeInt("maxavailable", defaultValue)) :
164  defaultValue;
165  }
166 }
int MinAvailableAmount
Minimum number of items available at a given store
Definition: PriceInfo.cs:16
float BuyingPriceMultiplier
The cost of item when sold by the store. Higher modifier means the item costs more to buy from the st...
Definition: PriceInfo.cs:33
int MinLevelDifficulty
The item isn't available in stores unless the level's difficulty is above this value
Definition: PriceInfo.cs:29
PriceInfo(XElement element)
Support for the old style of determining item prices when there were individual Price elements for ea...
Definition: PriceInfo.cs:61
int MaxAvailableAmount
Maximum number of items available at a given store. Defaults to 20% more than the minimum amount.
Definition: PriceInfo.cs:21
PriceInfo(int price, bool canBeBought, int minAmount=0, int maxAmount=0, bool canBeSpecial=true, int minLevelDifficulty=0, float buyingPriceMultiplier=1f, bool displayNonEmpty=false, bool requiresUnlock=false, string storeIdentifier=null)
Definition: PriceInfo.cs:74
IReadOnlyDictionary< Identifier, float > MinReputation
Minimum reputation needed to buy the item (Key = faction ID, Value = min rep)
Definition: PriceInfo.cs:54
Identifier StoreIdentifier
Definition: PriceInfo.cs:35
bool CanBeSpecial
Can the item be a Daily Special or a Requested Good
Definition: PriceInfo.cs:25
static List< PriceInfo > CreatePriceInfos(XElement element, out PriceInfo defaultPrice)
Definition: PriceInfo.cs:105