Client LuaCsForBarotrauma
Affliction.cs
2 using Microsoft.Xna.Framework;
3 using System;
4 using System.Collections.Generic;
5 using System.Linq;
6 using System.Xml.Linq;
7 
8 namespace Barotrauma
9 {
11  {
12  public readonly AfflictionPrefab Prefab;
13 
14  public string Name => ToString();
15 
16  public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; set; }
17 
18  public float PendingGrainEffectStrength { get; set; }
19  public float GrainEffectStrength { get; set; }
20 
21  private float fluctuationTimer;
22 
23  private AfflictionPrefab.Effect activeEffect;
24  private float prevActiveEffectStrength;
25  protected bool activeEffectDirty = true;
26 
27  protected float _strength;
28 
30  public virtual float Strength
31  {
32  get { return _strength; }
33  set
34  {
35  if (!MathUtils.IsValid(value))
36  {
37 #if DEBUG
38  DebugConsole.ThrowError($"Attempted to set an affliction to an invalid strength ({value})\n" + Environment.StackTrace.CleanupStackTrace());
39 #endif
40  return;
41  }
42 
43  if (_nonClampedStrength < 0 && value > 0)
44  {
45  _nonClampedStrength = value;
46  }
47  float newValue = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength);
48  if (newValue > _strength)
49  {
51  Duration = Prefab.Duration;
52  }
53  _strength = newValue;
54  activeEffectDirty = true;
55  }
56  }
57 
58  private float _nonClampedStrength = -1;
59  public float NonClampedStrength => _nonClampedStrength > 0 ? _nonClampedStrength : _strength;
60 
62  public Identifier Identifier { get; private set; }
63 
64  [Serialize(1.0f, IsPropertySaveable.Yes, description: "The probability for the affliction to be applied."), Editable(minValue: 0f, maxValue: 1f)]
65  public float Probability { get; set; } = 1.0f;
66 
67  [Serialize(true, IsPropertySaveable.Yes, description: "Explosion damage is applied per each affected limb. Should this affliction damage be divided by the count of affected limbs (1-15) or applied in full? Default: true. Only affects explosions."), Editable]
68  public bool DivideByLimbCount { get; set; }
69 
70  [Serialize(false, IsPropertySaveable.Yes, description: "Is the damage relative to the max vitality (percentage) or absolute (normal)"), Editable]
71  public bool MultiplyByMaxVitality { get; set; }
72 
73  public float DamagePerSecond;
74  public float DamagePerSecondTimer;
76 
77  public (float Value, Affliction Source) StrengthDiminishMultiplier = (1.0f, null);
78 
79  public readonly Dictionary<AfflictionPrefab.PeriodicEffect, float> PeriodicEffectTimers = new Dictionary<AfflictionPrefab.PeriodicEffect, float>();
80 
81  public double AppliedAsSuccessfulTreatmentTime, AppliedAsFailedTreatmentTime;
82 
83  public float Duration;
84 
88  public Character Source;
89 
90  private readonly static LocalizedString[] strengthTexts = new LocalizedString[]
91  {
92  TextManager.Get("AfflictionStrengthLow"),
93  TextManager.Get("AfflictionStrengthMedium"),
94  TextManager.Get("AfflictionStrengthHigh")
95  };
96 
97  public Affliction(AfflictionPrefab prefab, float strength)
98  {
99 #if CLIENT
100  prefab?.ReloadSoundsIfNeeded();
101 #endif
102  Prefab = prefab;
103  PendingGrainEffectStrength = Prefab.GrainBurst;
104  _strength = strength;
105  Identifier = prefab.Identifier;
106 
107  Duration = prefab.Duration;
108 
109  foreach (var periodicEffect in prefab.PeriodicEffects)
110  {
111  PeriodicEffectTimers[periodicEffect] = Rand.Range(periodicEffect.MinInterval, periodicEffect.MaxInterval);
112  }
113  }
114 
118  public void CopyProperties(Affliction source)
119  {
120  Probability = source.Probability;
123  }
124 
125  public void Serialize(XElement element)
126  {
128  }
129 
130  public void Deserialize(XElement element)
131  {
133  //backwards compatibility
134  if (element.GetAttribute("amount") != null && element.GetAttribute("strength") == null)
135  {
136  Strength = element.GetAttributeFloat("amount", 0.0f);
137  }
138  }
139 
140  public Affliction CreateMultiplied(float multiplier, Affliction affliction)
141  {
142  Affliction instance = Prefab.Instantiate(NonClampedStrength * multiplier, Source);
143  instance.CopyProperties(affliction);
144  return instance;
145  }
146 
147  public override string ToString() => Prefab == null ? "Affliction (Invalid)" : $"Affliction ({Prefab.Name})";
148 
150  {
151  return GetStrengthText(Strength, Prefab.MaxStrength);
152  }
153 
154  public static LocalizedString GetStrengthText(float strength, float maxStrength)
155  {
156  return strengthTexts[
157  MathHelper.Clamp((int)Math.Floor(strength / maxStrength * strengthTexts.Length), 0, strengthTexts.Length - 1)];
158  }
159 
161  {
162  if (activeEffectDirty)
163  {
164  activeEffect = Prefab.GetActiveEffect(_strength);
165  prevActiveEffectStrength = _strength;
166  activeEffectDirty = false;
167  }
168  return activeEffect;
169  }
170 
171  public float GetVitalityDecrease(CharacterHealth characterHealth)
172  {
173  return GetVitalityDecrease(characterHealth, Strength);
174  }
175 
176  public float GetVitalityDecrease(CharacterHealth characterHealth, float strength)
177  {
178  if (strength < Prefab.ActivationThreshold) { return 0.0f; }
179  strength = MathHelper.Clamp(strength, 0.0f, Prefab.MaxStrength);
180  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
181  if (currentEffect == null) { return 0.0f; }
182  if (currentEffect.MaxStrength - currentEffect.MinStrength <= 0.0f) { return 0.0f; }
183 
184  float currVitalityDecrease = MathHelper.Lerp(
185  currentEffect.MinVitalityDecrease,
186  currentEffect.MaxVitalityDecrease,
187  currentEffect.GetStrengthFactor(strength));
188 
189  if (currentEffect.MultiplyByMaxVitality)
190  {
191  currVitalityDecrease *= characterHealth?.MaxVitality ?? 100.0f;
192  }
193 
194  return currVitalityDecrease;
195  }
196 
197 
198  public float GetScreenGrainStrength()
199  {
200  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
201  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
202  if (currentEffect == null) { return 0.0f; }
203  if (MathUtils.NearlyEqual(currentEffect.MaxGrainStrength, 0f)) { return 0.0f; }
204 
205  float amount = MathHelper.Lerp(
206  currentEffect.MinGrainStrength,
207  currentEffect.MaxGrainStrength,
208  currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
209 
210  if (Prefab.GrainBurst > 0 && GrainEffectStrength > amount)
211  {
212  return Math.Min(GrainEffectStrength, 1.0f);
213  }
214 
215  return amount;
216  }
217 
219  {
220  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
221  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
222  if (currentEffect == null) { return 0.0f; }
223  if (currentEffect.MaxScreenDistort - currentEffect.MinScreenDistort < 0.0f) { return 0.0f; }
224 
225  return MathHelper.Lerp(
226  currentEffect.MinScreenDistort,
227  currentEffect.MaxScreenDistort,
228  currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
229  }
230 
232  {
233  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
234  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
235  if (currentEffect == null) { return 0.0f; }
236  if (currentEffect.MaxRadialDistort - currentEffect.MinRadialDistort < 0.0f) { return 0.0f; }
237 
238  return MathHelper.Lerp(
239  currentEffect.MinRadialDistort,
240  currentEffect.MaxRadialDistort,
241  currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
242  }
243 
245  {
246  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
247  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
248  if (currentEffect == null) { return 0.0f; }
249  if (currentEffect.MaxChromaticAberration - currentEffect.MinChromaticAberration < 0.0f) { return 0.0f; }
250 
251  return MathHelper.Lerp(
252  currentEffect.MinChromaticAberration,
253  currentEffect.MaxChromaticAberration,
254  currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
255  }
256 
258  {
259  //If the overlay's alpha progresses linearly, then don't worry about affliction effects.
260  if (Prefab.AfflictionOverlayAlphaIsLinear) { return (Strength / Prefab.MaxStrength); }
261  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
262  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
263  if (currentEffect == null) { return 0.0f; }
264  if (currentEffect.MaxAfflictionOverlayAlphaMultiplier - currentEffect.MinAfflictionOverlayAlphaMultiplier < 0.0f) { return 0.0f; }
265 
266  return MathHelper.Lerp(
267  currentEffect.MinAfflictionOverlayAlphaMultiplier,
268  currentEffect.MaxAfflictionOverlayAlphaMultiplier,
269  currentEffect.GetStrengthFactor(this));
270  }
271 
272  public Color GetFaceTint()
273  {
274  if (Strength < Prefab.ActivationThreshold) { return Color.TransparentBlack; }
275  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
276  if (currentEffect == null) { return Color.TransparentBlack; }
277 
278  return Color.Lerp(
279  currentEffect.MinFaceTint,
280  currentEffect.MaxFaceTint,
281  currentEffect.GetStrengthFactor(this));
282  }
283 
284  public Color GetBodyTint()
285  {
286  if (Strength < Prefab.ActivationThreshold) { return Color.TransparentBlack; }
287  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
288  if (currentEffect == null) { return Color.TransparentBlack; }
289 
290  return Color.Lerp(
291  currentEffect.MinBodyTint,
292  currentEffect.MaxBodyTint,
293  currentEffect.GetStrengthFactor(this));
294  }
295 
296  public float GetScreenBlurStrength()
297  {
298  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
299  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
300  if (currentEffect == null) { return 0.0f; }
301  if (currentEffect.MaxScreenBlur - currentEffect.MinScreenBlur < 0.0f) { return 0.0f; }
302 
303  return MathHelper.Lerp(
304  currentEffect.MinScreenBlur,
305  currentEffect.MaxScreenBlur,
306  currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
307  }
308 
309  private float GetScreenEffectFluctuation(AfflictionPrefab.Effect currentEffect)
310  {
311  if (currentEffect == null || currentEffect.ScreenEffectFluctuationFrequency <= 0.0f) { return 1.0f; }
312  return ((float)Math.Sin(fluctuationTimer * MathHelper.TwoPi) + 1.0f) * 0.5f;
313  }
314 
315  public float GetSkillMultiplier()
316  {
317  if (Strength < Prefab.ActivationThreshold) { return 1.0f; }
318  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
319  if (currentEffect == null) { return 1.0f; }
320 
321  float amount = MathHelper.Lerp(
322  currentEffect.MinSkillMultiplier,
323  currentEffect.MaxSkillMultiplier,
324  currentEffect.GetStrengthFactor(this));
325 
326  return amount;
327  }
328 
329  public void CalculateDamagePerSecond(float currentVitalityDecrease)
330  {
331  DamagePerSecond = Math.Max(DamagePerSecond, currentVitalityDecrease - PreviousVitalityDecrease);
332  if (DamagePerSecondTimer >= 1.0f)
333  {
334  DamagePerSecond = currentVitalityDecrease - PreviousVitalityDecrease;
335  PreviousVitalityDecrease = currentVitalityDecrease;
336  DamagePerSecondTimer = 0.0f;
337  }
338  }
339 
340  public float GetResistance(Identifier afflictionId)
341  {
342  if (Strength < Prefab.ActivationThreshold) { return 0.0f; }
343  var affliction = AfflictionPrefab.Prefabs[afflictionId];
344  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
345  if (currentEffect == null) { return 0.0f; }
346  if (!currentEffect.ResistanceFor.Any(r =>
347  r == affliction.Identifier ||
348  r == affliction.AfflictionType))
349  {
350  return 0.0f;
351  }
352  return MathHelper.Lerp(
353  currentEffect.MinResistance,
354  currentEffect.MaxResistance,
355  currentEffect.GetStrengthFactor(this));
356  }
357 
358  public float GetSpeedMultiplier()
359  {
360  if (Strength < Prefab.ActivationThreshold) { return 1.0f; }
361  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
362  if (currentEffect == null) { return 1.0f; }
363  return MathHelper.Lerp(
364  currentEffect.MinSpeedMultiplier,
365  currentEffect.MaxSpeedMultiplier,
366  currentEffect.GetStrengthFactor(this));
367  }
368 
369  public float GetStatValue(StatTypes statType)
370  {
371  if (GetViableEffect() is not AfflictionPrefab.Effect currentEffect) { return 0.0f; }
372 
373  if (!currentEffect.AfflictionStatValues.TryGetValue(statType, out var appliedStat)) { return 0.0f; }
374 
375  return MathHelper.Lerp(appliedStat.MinValue, appliedStat.MaxValue, currentEffect.GetStrengthFactor(this));
376  }
377 
378  public bool HasFlag(AbilityFlags flagType)
379  {
380  if (GetViableEffect() is not AfflictionPrefab.Effect currentEffect) { return false; }
381  return currentEffect.AfflictionAbilityFlags.HasFlag(flagType);
382  }
383 
384  private AfflictionPrefab.Effect GetViableEffect()
385  {
386  if (Strength < Prefab.ActivationThreshold) { return null; }
387  return GetActiveEffect();
388  }
389 
390  public virtual void Update(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
391  {
392  foreach (AfflictionPrefab.PeriodicEffect periodicEffect in Prefab.PeriodicEffects)
393  {
394  if (Strength <= periodicEffect.MinStrength) { continue; }
395  if (periodicEffect.MaxStrength > 0 && Strength > periodicEffect.MaxStrength) { continue; }
396  PeriodicEffectTimers[periodicEffect] -= deltaTime;
397  if (PeriodicEffectTimers[periodicEffect] <= 0.0f)
398  {
399  if (GameMain.NetworkMember != null && GameMain.NetworkMember.IsClient)
400  {
401  PeriodicEffectTimers[periodicEffect] = 0.0f;
402  }
403  else
404  {
405  foreach (StatusEffect statusEffect in periodicEffect.StatusEffects)
406  {
407  ApplyStatusEffect(ActionType.OnActive, statusEffect, 1.0f, characterHealth, targetLimb);
408  PeriodicEffectTimers[periodicEffect] = Rand.Range(periodicEffect.MinInterval, periodicEffect.MaxInterval);
409  }
410  }
411  }
412  }
413 
414  AfflictionPrefab.Effect currentEffect = GetActiveEffect();
415  if (currentEffect == null) { return; }
416 
417  fluctuationTimer += deltaTime * currentEffect.ScreenEffectFluctuationFrequency;
418  fluctuationTimer %= 1.0f;
419 
420  if (currentEffect.StrengthChange < 0) // Only apply StrengthDiminish.Multiplier if affliction is being weakened
421  {
422  float stat = characterHealth.Character.GetStatValue(
423  Prefab.IsBuff
424  ? StatTypes.BuffDurationMultiplier
425  : StatTypes.DebuffDurationMultiplier);
426 
427  float durationMultiplier = 1f / (1f + stat);
428 
429  _strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier.Value * durationMultiplier;
430  }
431  else if (currentEffect.StrengthChange > 0) // Reduce strengthening of afflictions if resistant
432  {
433  _strength += currentEffect.StrengthChange * deltaTime * (1f - characterHealth.GetResistance(Prefab));
434  }
435  // Don't use the property, because it's virtual and some afflictions like husk overload it for external use.
436  _strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength);
437  activeEffectDirty |= !MathUtils.NearlyEqual(prevActiveEffectStrength, _strength);
438 
439  foreach (StatusEffect statusEffect in currentEffect.StatusEffects)
440  {
441  ApplyStatusEffect(ActionType.OnActive, statusEffect, deltaTime, characterHealth, targetLimb);
442  }
443 
444  float amount = deltaTime;
445  if (Prefab.GrainBurst > 0)
446  {
447  amount /= Prefab.GrainBurst;
448  }
450  {
451  GrainEffectStrength += amount;
452  PendingGrainEffectStrength -= deltaTime;
453  }
454  else if (GrainEffectStrength > 0)
455  {
456  GrainEffectStrength -= amount;
457  }
458  GameMain.LuaCs.Hook.Call("afflictionUpdate", new object[] { this, characterHealth, targetLimb, deltaTime });
459  }
460 
461  public void ApplyStatusEffects(ActionType type, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
462  {
463  var currentEffect = GetActiveEffect();
464  if (currentEffect != null)
465  {
466  foreach (var statusEffect in currentEffect.StatusEffects)
467  {
468  ApplyStatusEffect(type, statusEffect, deltaTime, characterHealth, targetLimb);
469  }
470  }
471  }
472 
473  private readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
474  public void ApplyStatusEffect(ActionType type, StatusEffect statusEffect, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
475  {
476  if (type == ActionType.OnDamaged && !statusEffect.HasRequiredAfflictions(characterHealth.Character.LastDamage)) { return; }
477 
478  statusEffect.SetUser(Source);
479  if (statusEffect.HasTargetType(StatusEffect.TargetType.Character))
480  {
481  statusEffect.Apply(type, deltaTime, characterHealth.Character, characterHealth.Character);
482  }
483  if (targetLimb != null && statusEffect.HasTargetType(StatusEffect.TargetType.Limb))
484  {
485  statusEffect.Apply(type, deltaTime, characterHealth.Character, targetLimb);
486  }
487  if (characterHealth?.Character?.AnimController?.Limbs != null && statusEffect.HasTargetType(StatusEffect.TargetType.AllLimbs))
488  {
489  statusEffect.Apply(type, deltaTime, characterHealth.Character, targets: characterHealth.Character.AnimController.Limbs);
490  }
491  if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyItems) ||
492  statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
493  {
494  targets.Clear();
495  statusEffect.AddNearbyTargets(characterHealth.Character.WorldPosition, targets);
496  statusEffect.Apply(type, deltaTime, characterHealth.Character, targets);
497  }
498  }
499 
504  public void SetStrength(float strength)
505  {
506  if (!MathUtils.IsValid(strength))
507  {
508 #if DEBUG
509  DebugConsole.ThrowError($"Attempted to set an affliction to an invalid strength ({strength})\n" + Environment.StackTrace.CleanupStackTrace());
510 #endif
511  return;
512  }
513  _nonClampedStrength = strength;
514  _strength = _nonClampedStrength;
515  activeEffectDirty |= !MathUtils.NearlyEqual(_strength, prevActiveEffectStrength);
516  }
517 
518  public bool ShouldShowIcon(Character afflictedCharacter)
519  {
520  return Strength >= (afflictedCharacter == Character.Controlled ? Prefab.ShowIconThreshold : Prefab.ShowIconToOthersThreshold);
521  }
522  }
523 }
override string ToString()
static LocalizedString GetStrengthText(float strength, float maxStrength)
Definition: Affliction.cs:154
LocalizedString GetStrengthText()
Definition: Affliction.cs:149
bool ShouldShowIcon(Character afflictedCharacter)
Definition: Affliction.cs:518
void Deserialize(XElement element)
Definition: Affliction.cs:130
float GetRadialDistortStrength()
Definition: Affliction.cs:231
readonly Dictionary< AfflictionPrefab.PeriodicEffect, float > PeriodicEffectTimers
Definition: Affliction.cs:79
float PreviousVitalityDecrease
Definition: Affliction.cs:75
Identifier Identifier
Definition: Affliction.cs:62
float GetChromaticAberrationStrength()
Definition: Affliction.cs:244
float GetVitalityDecrease(CharacterHealth characterHealth)
Definition: Affliction.cs:171
float GetResistance(Identifier afflictionId)
Definition: Affliction.cs:340
void CopyProperties(Affliction source)
Copy properties here instead of using SerializableProperties (with reflection).
Definition: Affliction.cs:118
bool HasFlag(AbilityFlags flagType)
Definition: Affliction.cs:378
float GetAfflictionOverlayMultiplier()
Definition: Affliction.cs:257
Affliction CreateMultiplied(float multiplier, Affliction affliction)
Definition: Affliction.cs:140
float GetStatValue(StatTypes statType)
Definition: Affliction.cs:369
virtual float Strength
Definition: Affliction.cs:31
float GetScreenDistortStrength()
Definition: Affliction.cs:218
void CalculateDamagePerSecond(float currentVitalityDecrease)
Definition: Affliction.cs:329
AfflictionPrefab.Effect GetActiveEffect()
Definition: Affliction.cs:160
void SetStrength(float strength)
Use this method to skip clamping and additional logic of the setters. Ideally we would keep this priv...
Definition: Affliction.cs:504
virtual void Update(CharacterHealth characterHealth, Limb targetLimb, float deltaTime)
Definition: Affliction.cs:390
void Serialize(XElement element)
Definition: Affliction.cs:125
double AppliedAsSuccessfulTreatmentTime
Definition: Affliction.cs:81
float GetSpeedMultiplier()
Definition: Affliction.cs:358
float GetSkillMultiplier()
Definition: Affliction.cs:315
Dictionary< Identifier, SerializableProperty > SerializableProperties
Definition: Affliction.cs:16
Character Source
Which character gave this affliction
Definition: Affliction.cs:88
float PendingGrainEffectStrength
Definition: Affliction.cs:18
Affliction(AfflictionPrefab prefab, float strength)
Definition: Affliction.cs:97
float GetScreenBlurStrength()
Definition: Affliction.cs:296
readonly AfflictionPrefab Prefab
Definition: Affliction.cs:12
float GetVitalityDecrease(CharacterHealth characterHealth, float strength)
Definition: Affliction.cs:176
void ApplyStatusEffect(ActionType type, StatusEffect statusEffect, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
Definition: Affliction.cs:474
void ApplyStatusEffects(ActionType type, float deltaTime, CharacterHealth characterHealth, Limb targetLimb)
Definition: Affliction.cs:461
float GetScreenGrainStrength()
Definition: Affliction.cs:198
Effects are the primary way to add functionality to afflictions.
PeriodicEffect applies StatusEffects to the character periodically.
AfflictionPrefab is a prefab that defines a type of affliction that can be applied to a character....
readonly float Duration
The duration of the affliction, in seconds. If set to 0, the affliction does not expire.
static readonly PrefabCollection< AfflictionPrefab > Prefabs
float GetStatValue(StatTypes statType, bool includeSaved=true)
virtual Vector2 WorldPosition
Definition: Entity.cs:49
static NetworkMember NetworkMember
Definition: GameMain.cs:190
static LuaCsSetup LuaCs
Definition: GameMain.cs:26
object Call(string name, params object[] args)
readonly Identifier Identifier
Definition: Prefab.cs:34
static Dictionary< Identifier, SerializableProperty > DeserializeProperties(object obj, XElement element=null)
static void SerializeProperties(ISerializableEntity obj, XElement element, bool saveIfDefault=false, bool ignoreEditable=false)
StatusEffects can be used to execute various kinds of effects: modifying the state of some entity in ...
void AddNearbyTargets(Vector2 worldPosition, List< ISerializableEntity > targets)
virtual void Apply(ActionType type, float deltaTime, Entity entity, ISerializableEntity target, Vector2? worldPosition=null)
AbilityFlags
AbilityFlags are a set of toggleable flags that can be applied to characters.
Definition: Enums.cs:615
ActionType
ActionTypes define when a StatusEffect is executed.
Definition: Enums.cs:19
StatTypes
StatTypes are used to alter several traits of a character. They are mostly used by talents.
Definition: Enums.cs:180