Client LuaCsForBarotrauma
Reputation.cs
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Linq;
4 
5 namespace Barotrauma
6 {
7  class Reputation
8  {
9  public const float HostileThreshold = 0.2f;
10  public const float ReputationLossPerNPCDamage = 0.025f;
11  public const float ReputationLossPerWallDamage = 0.025f;
12  public const float ReputationLossPerStolenItemPrice = 0.0025f;
13  public const float MinReputationLossPerStolenItem = 0.025f;
14  public const float MaxReputationLossPerStolenItem = 0.5f;
15 
19  public const float MaxReputationLossFromNPCDamage = 20.0f;
23  public const float MaxReputationLossFromWallDamage = 10.0f;
24 
25  public Identifier Identifier { get; }
26  public int MinReputation { get; }
27  public int MaxReputation { get; }
28  public int InitialReputation { get; }
29  public CampaignMetadata Metadata { get; }
30 
31  public float ReputationAtRoundStart { get; set; }
32 
33  private readonly Identifier metaDataIdentifier;
34 
38  public float NormalizedValue
39  {
40  get { return MathUtils.InverseLerp(MinReputation, MaxReputation, Value); }
41  }
42 
43  public float Value
44  {
45  get => Metadata == null ? 0 : Math.Min(MaxReputation, Metadata.GetFloat(metaDataIdentifier, InitialReputation));
46  private set
47  {
48  if (MathUtils.NearlyEqual(Value, value) || Metadata == null) { return; }
49 
50  float prevValue = Value;
51 
52  Metadata.SetValue(metaDataIdentifier, Math.Clamp(value, MinReputation, MaxReputation));
53  OnReputationValueChanged?.Invoke(this);
54  OnAnyReputationValueChanged?.Invoke(this);
55 #if CLIENT
56  int increase = (int)Value - (int)prevValue;
57  if (increase != 0 && Character.Controlled != null)
58  {
60  TextManager.GetWithVariable("reputationgainnotification", "[reputationname]", Location?.DisplayName ?? Faction.Prefab.Name).Value,
61  increase > 0 ? GUIStyle.Green : GUIStyle.Red,
62  playSound: true, Identifier, increase, lifetime: 5.0f);
63  }
64 #endif
65  }
66  }
67 
68  public void SetReputation(float newReputation)
69  {
70  Value = newReputation;
71  }
72 
73  public float GetReputationChangeMultiplier(float reputationChange)
74  {
75  return reputationChange switch
76  {
77  > 0f => GetMultiplierForStatType(StatTypes.ReputationGainMultiplier, Identifier),
78  < 0f => GetMultiplierForStatType(StatTypes.ReputationLossMultiplier, Identifier),
79  _ => 1.0f
80  };
81 
82  static float GetMultiplierForStatType(StatTypes statTypes, Identifier identifier)
83  {
84  float multiplier = 1f;
86  if (crew != null && crew.Any())
87  {
88  multiplier *= 1f + crew.Max(c => c.GetStatValue(statTypes, includeSaved: false));
89  multiplier *= 1f + crew.Max(c => c.Info?.GetSavedStatValue(statTypes, identifier) ?? 0);
90  }
91  return multiplier;
92  }
93  }
94 
95  public void AddReputation(float reputationChange, float maxReputationChangePerRound = float.MaxValue)
96  {
97  float prevValue = Value;
98  //if we're already over the limit, do nothing (assuming the change is in the "same direction" that we've gone over the limit)
99  if (doesReputationChangeGoOverLimit(prevValue, reputationChange))
100  {
101  return;
102  }
103 
104  float newValue = Value + reputationChange * GetReputationChangeMultiplier(reputationChange);
105  if (doesReputationChangeGoOverLimit(newValue, newValue - prevValue))
106  {
107  newValue = ReputationAtRoundStart + maxReputationChangePerRound * Math.Sign(reputationChange);
108  }
109 
110  Value = newValue;
111 
112  bool doesReputationChangeGoOverLimit(float newValue, float change)
113  {
114  float totalReputationChange = newValue - ReputationAtRoundStart;
115  return
116  Math.Abs(totalReputationChange) > maxReputationChangePerRound &&
117  Math.Sign(totalReputationChange) == Math.Sign(change);
118  }
119  }
120 
121  public readonly NamedEvent<Reputation> OnReputationValueChanged = new NamedEvent<Reputation>();
122  public static readonly NamedEvent<Reputation> OnAnyReputationValueChanged = new NamedEvent<Reputation>();
123 
124  public readonly Faction Faction;
125  public readonly Location Location;
126 
127 
128  public Reputation(CampaignMetadata metadata, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation)
129  : this(metadata, null, location, identifier, minReputation, maxReputation, initialReputation)
130  {
131  }
132 
133  public Reputation(CampaignMetadata metadata, Faction faction, int minReputation, int maxReputation, int initialReputation)
134  : this(metadata, faction, null, $"faction.{faction.Prefab.Identifier}".ToIdentifier(), minReputation, maxReputation, initialReputation)
135  {
136  }
137 
138  private Reputation(CampaignMetadata metadata, Faction faction, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation)
139  {
140  System.Diagnostics.Debug.Assert(faction != null || location != null);
141  Metadata = metadata;
142  Identifier = identifier;
143  metaDataIdentifier = $"reputation.{Identifier}".ToIdentifier();
144  MinReputation = minReputation;
145  MaxReputation = maxReputation;
146  ReputationAtRoundStart = initialReputation;
147  InitialReputation = initialReputation;
148  Faction = faction;
149  Location = location;
150  }
151 
153  {
155  }
156 
157  public static LocalizedString GetReputationName(float normalizedValue)
158  {
159  if (normalizedValue < HostileThreshold)
160  {
161  return TextManager.Get("reputationverylow");
162  }
163  else if (normalizedValue < 0.4f)
164  {
165  return TextManager.Get("reputationlow");
166  }
167  else if (normalizedValue < 0.6f)
168  {
169  return TextManager.Get("reputationneutral");
170  }
171  else if (normalizedValue < 0.8f)
172  {
173  return TextManager.Get("reputationhigh");
174  }
175  return TextManager.Get("reputationveryhigh");
176  }
177 
178 #if CLIENT
179  public static Color GetReputationColor(float normalizedValue)
180  {
181  if (normalizedValue < HostileThreshold)
182  {
183  return GUIStyle.ColorReputationVeryLow;
184  }
185  else if (normalizedValue < 0.4f)
186  {
187  return GUIStyle.ColorReputationLow;
188  }
189  else if (normalizedValue < 0.6f)
190  {
191  return GUIStyle.ColorReputationNeutral;
192  }
193  else if (normalizedValue < 0.8f)
194  {
195  return GUIStyle.ColorReputationHigh;
196  }
197  return GUIStyle.ColorReputationVeryHigh;
198  }
199  public LocalizedString GetFormattedReputationText(bool addColorTags = false)
200  {
201  return GetFormattedReputationText(NormalizedValue, Value, addColorTags);
202  }
203 
204  public static LocalizedString GetFormattedReputationText(float normalizedValue, float value, bool addColorTags = false)
205  {
206  LocalizedString reputationName = GetReputationName(normalizedValue);
207  LocalizedString formattedReputation = TextManager.GetWithVariables("reputationformat",
208  ("[reputationname]", reputationName),
209  ("[reputationvalue]", ((int)Math.Round(value)).ToString()));
210  if (addColorTags)
211  {
212  formattedReputation = $"‖color:{XMLExtensions.ToStringHex(GetReputationColor(normalizedValue))}‖{formattedReputation}‖end‖";
213  }
214  return formattedReputation;
215  }
216 #endif
217  }
218 }
void AddMessage(string rawText, Color color, bool playSound, Identifier identifier=default, int? value=null, float lifetime=3.0f)
FactionPrefab Prefab
Definition: Factions.cs:18
static ImmutableHashSet< Character > GetSessionCrewCharacters(CharacterType type)
Returns a list of crew characters currently in the game with a given filter.
LocalizedString DisplayName
Definition: Location.cs:59
float??????? Value
Definition: Reputation.cs:44
Reputation(CampaignMetadata metadata, Location location, Identifier identifier, int minReputation, int maxReputation, int initialReputation)
Definition: Reputation.cs:128
const float HostileThreshold
Definition: Reputation.cs:9
const float MaxReputationLossPerStolenItem
Definition: Reputation.cs:14
const float ReputationLossPerStolenItemPrice
Definition: Reputation.cs:12
float GetReputationChangeMultiplier(float reputationChange)
Definition: Reputation.cs:73
const float MaxReputationLossFromWallDamage
Maximum amount of reputation loss you can get from damaging outpost walls per round
Definition: Reputation.cs:23
const float MinReputationLossPerStolenItem
Definition: Reputation.cs:13
LocalizedString GetReputationName()
Definition: Reputation.cs:152
static LocalizedString GetReputationName(float normalizedValue)
Definition: Reputation.cs:157
static LocalizedString GetFormattedReputationText(float normalizedValue, float value, bool addColorTags=false)
Definition: Reputation.cs:204
Identifier Identifier
Definition: Reputation.cs:25
static readonly NamedEvent< Reputation > OnAnyReputationValueChanged
Definition: Reputation.cs:122
static Color GetReputationColor(float normalizedValue)
Definition: Reputation.cs:179
const float MaxReputationLossFromNPCDamage
Maximum amount of reputation loss you can get from damaging outpost NPCs per round
Definition: Reputation.cs:19
void SetReputation(float newReputation)
Definition: Reputation.cs:68
void AddReputation(float reputationChange, float maxReputationChangePerRound=float.MaxValue)
Definition: Reputation.cs:95
const float ReputationLossPerNPCDamage
Definition: Reputation.cs:10
float ReputationAtRoundStart
Definition: Reputation.cs:31
LocalizedString GetFormattedReputationText(bool addColorTags=false)
Definition: Reputation.cs:199
readonly NamedEvent< Reputation > OnReputationValueChanged
Definition: Reputation.cs:121
readonly Location Location
Definition: Reputation.cs:125
const float ReputationLossPerWallDamage
Definition: Reputation.cs:11
CampaignMetadata Metadata
Definition: Reputation.cs:29
float NormalizedValue
Reputation value normalized to the range of 0-1
Definition: Reputation.cs:39
readonly Faction Faction
Definition: Reputation.cs:124
Reputation(CampaignMetadata metadata, Faction faction, int minReputation, int maxReputation, int initialReputation)
Definition: Reputation.cs:133
CharacterType
Definition: Enums.cs:711
StatTypes
StatTypes are used to alter several traits of a character. They are mostly used by talents.
Definition: Enums.cs:195