Client LuaCsForBarotrauma
CharacterAbilityApplyStatusEffects.cs
1 using System.Collections.Generic;
2 
3 namespace Barotrauma.Abilities
4 {
6  {
7  public override bool AppliesEffectOnIntervalUpdate => true;
8  public override bool AllowClientSimulation => true;
9 
10  protected readonly List<StatusEffect> statusEffects;
11 
12  private readonly bool applyToSelf;
13  private readonly bool nearbyCharactersAppliesToSelf;
14  private readonly bool nearbyCharactersAppliesToAllies;
15  private readonly bool nearbyCharactersAppliesToEnemies;
16  private readonly bool applyToSelected;
17 
18  readonly List<ISerializableEntity> targets = new List<ISerializableEntity>();
19 
20  private bool effectBeingApplied;
21 
22  public CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement) : base(characterAbilityGroup, abilityElement)
23  {
25  applyToSelf = abilityElement.GetAttributeBool("applytoself", false);
26  applyToSelected = abilityElement.GetAttributeBool("applytoselected", false);
27  nearbyCharactersAppliesToSelf = abilityElement.GetAttributeBool("nearbycharactersappliestoself", true);
28  nearbyCharactersAppliesToAllies = abilityElement.GetAttributeBool("nearbycharactersappliestoallies", true);
29  nearbyCharactersAppliesToEnemies = abilityElement.GetAttributeBool("nearbycharactersappliestoenemies", true);
30  }
31 
32  protected void ApplyEffectSpecific(Character targetCharacter, Limb targetLimb = null)
33  {
34  //prevent an infinite loop if an effect triggers itself
35  //(e.g. a talent that triggers when an affliction is applied, and applies that same affliction)
36  if (effectBeingApplied) { return; }
37 
38  effectBeingApplied = true;
39 
40  try
41  {
42  foreach (var statusEffect in statusEffects)
43  {
44  if (statusEffect.HasTargetType(StatusEffect.TargetType.UseTarget))
45  {
46  // currently used to spawn items on the targeted character
47  statusEffect.SetUser(targetCharacter);
48  statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targetCharacter);
49  }
50  else if (statusEffect.HasTargetType(StatusEffect.TargetType.NearbyCharacters))
51  {
52  targets.Clear();
53  statusEffect.AddNearbyTargets(targetCharacter.WorldPosition, targets);
54  if (!nearbyCharactersAppliesToSelf)
55  {
56  targets.RemoveAll(c => c == Character);
57  }
58  if (!nearbyCharactersAppliesToAllies)
59  {
60  targets.RemoveAll(c => c is Character otherCharacter && HumanAIController.IsFriendly(otherCharacter, Character));
61  }
62  if (!nearbyCharactersAppliesToEnemies)
63  {
64  targets.RemoveAll(c => c is Character otherCharacter && !HumanAIController.IsFriendly(otherCharacter, Character));
65  }
66  statusEffect.SetUser(Character);
67  statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, targetCharacter, targets);
68  }
69  else if (statusEffect.HasTargetType(StatusEffect.TargetType.Limb) && targetLimb != null)
70  {
71  statusEffect.SetUser(Character);
72  statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetLimb);
73  }
74  else if (statusEffect.HasTargetType(StatusEffect.TargetType.Character))
75  {
76  statusEffect.SetUser(Character);
77  statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, targetCharacter);
78  }
79  else
80  {
81  statusEffect.SetUser(Character);
82  statusEffect.Apply(ActionType.OnAbility, EffectDeltaTime, Character, Character);
83  }
84  }
85  }
86  finally
87  {
88  effectBeingApplied = false;
89  }
90  }
91  protected override void ApplyEffect()
92  {
93  if (applyToSelected && Character.SelectedCharacter is Character selectedCharacter)
94  {
95  ApplyEffectSpecific(selectedCharacter);
96  }
97  else
98  {
100  }
101  }
102 
103  protected override void ApplyEffect(AbilityObject abilityObject)
104  {
105  if ((abilityObject as IAbilityCharacter)?.Character is Character targetCharacter && !applyToSelf)
106  {
107  ApplyEffectSpecific(targetCharacter, targetLimb: (abilityObject as AbilityApplyTreatment)?.TargetLimb);
108  }
109  else
110  {
111  ApplyEffect();
112  }
113  }
114  }
115 }
CharacterAbilityApplyStatusEffects(CharacterAbilityGroup characterAbilityGroup, ContentXElement abilityElement)
void ApplyEffectSpecific(Character targetCharacter, Limb targetLimb=null)
static List< StatusEffect > ParseStatusEffects(CharacterTalent characterTalent, ContentXElement statusEffectElements)
float EffectDeltaTime
Used primarily for StatusEffects. Default to constant outside interval abilities.
ContentXElement? GetChildElement(string name)
bool GetAttributeBool(string key, bool def)
virtual Vector2 WorldPosition
Definition: Entity.cs:49
static bool IsFriendly(Character me, Character other, bool onlySameTeam=false)
StatusEffects can be used to execute various kinds of effects: modifying the state of some entity in ...
ActionType
ActionTypes define when a StatusEffect is executed.
Definition: Enums.cs:26