Client LuaCsForBarotrauma
BarotraumaShared/SharedSource/Characters/Health/DamageModifier.cs
1 using Microsoft.Xna.Framework;
2 using System;
3 using System.Xml.Linq;
4 using System.Collections.Generic;
5 using System.Collections.Immutable;
6 using System.Linq;
7 
8 namespace Barotrauma
9 {
11  {
12  public string Name => "Damage Modifier";
13 
14  public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; private set; }
15 
16  [Serialize(1.0f, IsPropertySaveable.No), Editable(DecimalCount = 2)]
17  public float DamageMultiplier
18  {
19  get;
20  private set;
21  }
22 
23  [Serialize(1.0f, IsPropertySaveable.No), Editable(DecimalCount = 2, MinValueFloat = 0, MaxValueFloat = 1)]
24  public float ProbabilityMultiplier
25  {
26  get;
27  private set;
28  }
29 
30  [Serialize("0.0,360", IsPropertySaveable.No), Editable]
31  public Vector2 ArmorSector
32  {
33  get;
34  private set;
35  }
36 
37  public Vector2 ArmorSectorInRadians => new Vector2(MathHelper.ToRadians(ArmorSector.X), MathHelper.ToRadians(ArmorSector.Y));
38 
40  public bool DeflectProjectiles
41  {
42  get;
43  private set;
44  }
45 
47  public string AfflictionIdentifiers
48  {
49  get
50  {
51  return rawAfflictionIdentifierString;
52  }
53  private set
54  {
55  rawAfflictionIdentifierString = value;
56  ParseAfflictionIdentifiers();
57  }
58  }
59 
61  public string AfflictionTypes
62  {
63  get
64  {
65  return rawAfflictionTypeString;
66  }
67  private set
68  {
69  rawAfflictionTypeString = value;
70  ParseAfflictionTypes();
71  }
72  }
73 
74  private string rawAfflictionIdentifierString;
75  private string rawAfflictionTypeString;
76  private ImmutableArray<Identifier> parsedAfflictionIdentifiers;
77  private ImmutableArray<Identifier> parsedAfflictionTypes;
78  public ref readonly ImmutableArray<Identifier> ParsedAfflictionIdentifiers => ref parsedAfflictionIdentifiers;
79 
80  public ref readonly ImmutableArray<Identifier> ParsedAfflictionTypes => ref parsedAfflictionTypes;
81 
82  public DamageModifier(ContentXElement element, string parentDebugName, bool checkErrors = true)
83  {
84  Deserialize(element);
85  if (element.GetAttribute("afflictionnames") != null)
86  {
87  DebugConsole.ThrowError("Error in DamageModifier config (" + parentDebugName + ") - define afflictions using identifiers or types instead of names.",
88  contentPackage: element.ContentPackage);
89  }
90  if (checkErrors)
91  {
92  foreach (var afflictionType in parsedAfflictionTypes)
93  {
94  if (!AfflictionPrefab.Prefabs.Any(p => p.AfflictionType == afflictionType))
95  {
96  createWarningOrError($"Potentially invalid damage modifier in \"{parentDebugName}\". Could not find any afflictions of the type \"{afflictionType}\". Did you mean to use an affliction identifier instead?");
97  }
98  }
99  foreach (var afflictionIdentifier in parsedAfflictionIdentifiers)
100  {
101  if (!AfflictionPrefab.Prefabs.ContainsKey(afflictionIdentifier))
102  {
103  createWarningOrError($"Potentially invalid damage modifier in \"{parentDebugName}\". Could not find any afflictions with the identifier \"{afflictionIdentifier}\". Did you mean to use an affliction type instead?");
104  }
105  }
106  if (!parsedAfflictionTypes.Any() && !parsedAfflictionIdentifiers.Any())
107  {
108  createWarningOrError($"Potentially invalid damage modifier in \"{parentDebugName}\". Neither affliction types of identifiers defined.");
109  }
110  }
111 
112  void createWarningOrError(string msg)
113  {
114 #if DEBUG
115  DebugConsole.ThrowError(msg, contentPackage: element.ContentPackage);
116 #else
117  DebugConsole.AddWarning(msg, contentPackage: element.ContentPackage);
118 #endif
119  }
120  }
121 
122  private void ParseAfflictionTypes()
123  {
124  if (string.IsNullOrWhiteSpace(rawAfflictionTypeString))
125  {
126  parsedAfflictionTypes = Enumerable.Empty<Identifier>().ToImmutableArray();
127  return;
128  }
129 
130  parsedAfflictionTypes = rawAfflictionTypeString.Split(',', ',')
131  .Select(s => s.Trim()).ToIdentifiers().ToImmutableArray();
132  }
133 
134  private void ParseAfflictionIdentifiers()
135  {
136  if (string.IsNullOrWhiteSpace(rawAfflictionIdentifierString))
137  {
138  parsedAfflictionIdentifiers = Enumerable.Empty<Identifier>().ToImmutableArray();
139  return;
140  }
141 
142  parsedAfflictionIdentifiers = rawAfflictionIdentifierString.Split(',', ',')
143  .Select(s => s.Trim()).ToIdentifiers().ToImmutableArray();
144  }
145 
146  public bool MatchesAfflictionIdentifier(string identifier) =>
147  MatchesAfflictionIdentifier(identifier.ToIdentifier());
148 
149  public bool MatchesAfflictionIdentifier(Identifier identifier)
150  {
151  //if no identifiers have been defined, the damage modifier affects all afflictions
152  if (AfflictionIdentifiers.Length == 0) { return true; }
153  return parsedAfflictionIdentifiers.Any(id => id == identifier);
154  }
155 
156  public bool MatchesAfflictionType(string type) =>
157  MatchesAfflictionType(type.ToIdentifier());
158 
159  public bool MatchesAfflictionType(Identifier type)
160  {
161  //if no types have been defined, the damage modifier affects all afflictions
162  if (AfflictionTypes.Length == 0) { return true; }
163  return parsedAfflictionTypes.Any(t => t == type);
164  }
165 
169  public bool MatchesAffliction(string identifier, string type) =>
170  MatchesAffliction(identifier.ToIdentifier(), type.ToIdentifier());
171 
172  public bool MatchesAffliction(Identifier identifier, Identifier type)
173  {
174  //if no identifiers or types have been defined, the damage modifier affects all afflictions
175  if (AfflictionIdentifiers.Length == 0 && AfflictionTypes.Length == 0) { return true; }
176  return parsedAfflictionIdentifiers.Any(id => id == identifier)
177  || parsedAfflictionTypes.Any(t => t == type);
178  }
179 
180  public bool MatchesAffliction(Affliction affliction) => MatchesAffliction(affliction.Identifier, affliction.Prefab.AfflictionType);
181 
182  public void Serialize(XElement element)
183  {
184  if (element == null) { return; }
186  }
187 
188  public void Deserialize(XElement element)
189  {
190  if (element == null) { return; }
192  }
193  }
194 }
AfflictionPrefab is a prefab that defines a type of affliction that can be applied to a character....
static readonly PrefabCollection< AfflictionPrefab > Prefabs
ContentPackage? ContentPackage
XAttribute? GetAttribute(string name)
bool MatchesAfflictionType(string type)
bool MatchesAfflictionIdentifier(string identifier)
Dictionary< Identifier, SerializableProperty > SerializableProperties
DamageModifier(ContentXElement element, string parentDebugName, bool checkErrors=true)
bool MatchesAffliction(Affliction affliction)
bool MatchesAffliction(string identifier, string type)
Returns true if the type or the identifier matches the defined types/identifiers.
ref readonly ImmutableArray< Identifier > ParsedAfflictionIdentifiers
static Dictionary< Identifier, SerializableProperty > DeserializeProperties(object obj, XElement element=null)
static void SerializeProperties(ISerializableEntity obj, XElement element, bool saveIfDefault=false, bool ignoreEditable=false)