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 
52  public Identifier RequiredFaction { get; private set; }
53 
54  private readonly Dictionary<Identifier, float> minReputation = new Dictionary<Identifier, float>();
55 
59  public IReadOnlyDictionary<Identifier, float> MinReputation => minReputation;
60 
66  public PriceInfo(XElement element)
67  {
68  Price = element.GetAttributeInt("buyprice", 0);
69  MinLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
70  BuyingPriceMultiplier = element.GetAttributeFloat("buyingpricemultiplier", 1f);
71  CanBeBought = true;
72  MinAvailableAmount = Math.Min(GetMinAmount(element, defaultValue: DefaultAmount), CargoManager.MaxQuantity);
73  MaxAvailableAmount = MathHelper.Clamp(GetMaxAmount(element, defaultValue: (int)(MinAvailableAmount * DefaultMaxAvailabilityRelativeToMin)), MinAvailableAmount, CargoManager.MaxQuantity);
74  RequiresUnlock = element.GetAttributeBool("requiresunlock", false);
75  RequiredFaction = element.GetAttributeIdentifier(nameof(RequiredFaction), Identifier.Empty);
76  System.Diagnostics.Debug.Assert(MaxAvailableAmount >= MinAvailableAmount);
77  }
78 
79  public PriceInfo(int price, bool canBeBought,
80  int minAmount = 0, int maxAmount = 0, bool canBeSpecial = true, int minLevelDifficulty = 0, float buyingPriceMultiplier = 1f,
81  bool displayNonEmpty = false, bool requiresUnlock = false, string storeIdentifier = null)
82  {
83  Price = price;
84  CanBeBought = canBeBought;
85  MinAvailableAmount = Math.Min(minAmount, CargoManager.MaxQuantity);
86  MaxAvailableAmount = Math.Max(Math.Min(maxAmount, CargoManager.MaxQuantity), minAmount);
87  BuyingPriceMultiplier = buyingPriceMultiplier;
88  MinLevelDifficulty = minLevelDifficulty;
89  CanBeSpecial = canBeSpecial;
90  DisplayNonEmpty = displayNonEmpty;
91  StoreIdentifier = new Identifier(storeIdentifier);
92  RequiresUnlock = requiresUnlock;
93 
94  System.Diagnostics.Debug.Assert(MaxAvailableAmount >= MinAvailableAmount);
95  }
96 
97  private void LoadReputationRestrictions(XElement priceInfoElement)
98  {
99  foreach (XElement childElement in priceInfoElement.GetChildElements("reputation"))
100  {
101  Identifier factionId = childElement.GetAttributeIdentifier("faction", Identifier.Empty);
102  float rep = childElement.GetAttributeFloat("min", 0.0f);
103  if (!factionId.IsEmpty && rep > 0)
104  {
105  minReputation.Add(factionId, rep);
106  }
107  }
108  }
109 
110  public static List<PriceInfo> CreatePriceInfos(XElement element, out PriceInfo defaultPrice)
111  {
112  var priceInfos = new List<PriceInfo>();
113  defaultPrice = null;
114  int basePrice = element.GetAttributeInt("baseprice", 0);
115  int minAmount = GetMinAmount(element, defaultValue: DefaultAmount);
116  int maxAmount = GetMaxAmount(element, defaultValue: (int)(DefaultAmount * DefaultMaxAvailabilityRelativeToMin));
117  int minLevelDifficulty = element.GetAttributeInt("minleveldifficulty", 0);
118  bool canBeSpecial = element.GetAttributeBool("canbespecial", true);
119  float buyingPriceMultiplier = element.GetAttributeFloat("buyingpricemultiplier", 1f);
120  bool displayNonEmpty = element.GetAttributeBool("displaynonempty", false);
121  bool soldByDefault = element.GetAttributeBool("sold", element.GetAttributeBool("soldbydefault", true));
122  bool requiresUnlock = element.GetAttributeBool("requiresunlock", false);
123  Identifier requiredFactionByDefault = element.GetAttributeIdentifier(nameof(RequiredFaction), Identifier.Empty);
124  foreach (XElement childElement in element.GetChildElements("price"))
125  {
126  float priceMultiplier = childElement.GetAttributeFloat("multiplier", 1.0f);
127  bool sold = childElement.GetAttributeBool("sold", soldByDefault);
128  int storeMinLevelDifficulty = childElement.GetAttributeInt("minleveldifficulty", minLevelDifficulty);
129  float storeBuyingMultiplier = childElement.GetAttributeFloat("buyingpricemultiplier", buyingPriceMultiplier);
130  string backwardsCompatibleIdentifier = childElement.GetAttributeString("locationtype", "");
131  if (!string.IsNullOrEmpty(backwardsCompatibleIdentifier))
132  {
133  backwardsCompatibleIdentifier = $"merchant{backwardsCompatibleIdentifier}";
134  }
135  string storeIdentifier = childElement.GetAttributeString("storeidentifier", backwardsCompatibleIdentifier);
136  // TODO: Add some error messages if we have defined the min or max amount while the item is not sold
137  var priceInfo = new PriceInfo(price: (int)(priceMultiplier * basePrice),
138  canBeBought: sold,
139  minAmount: sold ? GetMinAmount(childElement, minAmount) : 0,
140  maxAmount: sold ? GetMaxAmount(childElement, maxAmount) : 0,
141  canBeSpecial: canBeSpecial,
142  minLevelDifficulty: storeMinLevelDifficulty,
143  buyingPriceMultiplier: storeBuyingMultiplier,
144  displayNonEmpty: displayNonEmpty,
145  requiresUnlock: requiresUnlock,
146  storeIdentifier: storeIdentifier)
147  {
148  RequiredFaction = childElement.GetAttributeIdentifier(nameof(RequiredFaction), requiredFactionByDefault)
149  };
150  priceInfo.LoadReputationRestrictions(childElement);
151  priceInfos.Add(priceInfo);
152  }
153  bool soldElsewhere = soldByDefault && element.GetAttributeBool("soldelsewhere", element.GetAttributeBool("soldeverywhere", false));
154  defaultPrice = new PriceInfo(price: basePrice,
155  canBeBought: soldElsewhere,
156  minAmount: soldElsewhere ? minAmount : 0,
157  maxAmount: soldElsewhere ? maxAmount : 0,
158  canBeSpecial: canBeSpecial,
159  minLevelDifficulty: minLevelDifficulty,
160  buyingPriceMultiplier: buyingPriceMultiplier,
161  displayNonEmpty: displayNonEmpty,
162  requiresUnlock: requiresUnlock)
163  {
164  RequiredFaction = requiredFactionByDefault
165  };
166  defaultPrice.LoadReputationRestrictions(element);
167  return priceInfos;
168  }
169 
170  private static int GetMinAmount(XElement element, int defaultValue) => element != null ?
171  element.GetAttributeInt("minamount", element.GetAttributeInt("minavailable", defaultValue)) :
172  defaultValue;
173 
174  private static int GetMaxAmount(XElement element, int defaultValue) => element != null ?
175  element.GetAttributeInt("maxamount", element.GetAttributeInt("maxavailable", defaultValue)) :
176  defaultValue;
177  }
178 }
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:66
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:79
IReadOnlyDictionary< Identifier, float > MinReputation
Minimum reputation needed to buy the item (Key = faction ID, Value = min rep)
Definition: PriceInfo.cs:59
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:110
Identifier RequiredFaction
If set, the item is only available in outposts with this faction.
Definition: PriceInfo.cs:52