2 using System.Collections.Generic;
4 using System.Reflection;
14 public bool IsActive {
get;
private set; } =
true;
29 fallbackAbilities =
new List<CharacterAbility>();
34 CharacterTalent = characterTalent ??
throw new ArgumentNullException(nameof(characterTalent));
37 foreach (var subElement
in abilityElementGroup.Elements())
39 switch (subElement.Name.ToString().ToLowerInvariant())
42 LoadAbilities(subElement);
44 case "fallbackabilities":
45 LoadFallbackAbilities(subElement);
52 DebugConsole.ThrowError($
"Error in talent {characterTalent.Prefab.Identifier}: unrecognized xml element \"{subElement.Name}\".");
57 switch (abilityEffectType)
62 DebugConsole.AddWarning($
"Potential error in talent {characterTalent}: an ability group has the type {AbilityEffectType.OnDieToCharacter}, but includes abilities that require the character to be alive, meaning they will never execute.",
63 characterTalent.Prefab.ContentPackage);
71 if (!CheckActivatingCondition()) {
return; }
75 characterAbility.InitializeAbility(addingFirstTime);
78 foreach (var characterAbility
in fallbackAbilities)
80 characterAbility.InitializeAbility(addingFirstTime);
84 private bool CheckActivatingCondition()
87 return !
abilityConditions.Any(
static abilityCondition => !abilityCondition.MatchesCondition());
96 if (newCondition ==
null)
98 DebugConsole.ThrowError($
"AbilityCondition was not found in talent {CharacterTalent.DebugIdentifier}!",
114 if (characterAbility ==
null)
116 DebugConsole.ThrowError($
"Trying to add null ability for talent {CharacterTalent.DebugIdentifier}!",
126 if (characterAbility ==
null)
128 DebugConsole.ThrowError($
"Trying to add null ability for talent {CharacterTalent.DebugIdentifier}!",
133 fallbackAbilities.Add(characterAbility);
140 string type = conditionElement.
Name.ToString().ToLowerInvariant();
143 conditionType = ReflectionUtils.GetTypeWithBackwardsCompatibility(
"Barotrauma.Abilities", type,
false,
true);
144 if (conditionType ==
null)
148 DebugConsole.ThrowError(
"Could not find the component \"" + type +
"\" (" + characterTalent.
DebugIdentifier +
")",
158 DebugConsole.ThrowError(
"Could not find the component \"" + type +
"\" (" + characterTalent.
DebugIdentifier +
")", e,
164 object[] args = { characterTalent, conditionElement };
166 AbilityCondition newCondition;
169 newCondition = (AbilityCondition)Activator.CreateInstance(conditionType, args);
171 catch (TargetInvocationException e)
173 DebugConsole.ThrowError(
"Error while creating an instance of an ability condition of the type " + conditionType +
".", e.InnerException,
178 if (newCondition ==
null)
180 DebugConsole.ThrowError(
"Error while creating an instance of an ability condition of the type " + conditionType +
", instance was null",
188 private void LoadAbilities(ContentXElement abilityElements)
190 foreach (var abilityElementGroup
in abilityElements.Elements())
196 private void LoadFallbackAbilities(ContentXElement abilityElements)
198 foreach (var abilityElementGroup
in abilityElements.Elements())
204 private CharacterAbility ConstructAbility(ContentXElement abilityElement,
CharacterTalent characterTalent)
206 CharacterAbility newAbility = CharacterAbility.Load(abilityElement,
this);
208 if (newAbility ==
null)
210 DebugConsole.ThrowError($
"Unable to create an ability for {characterTalent.DebugIdentifier}!",
211 contentPackage: characterTalent.Prefab.ContentPackage);
220 if (statusEffectElements ==
null)
222 DebugConsole.ThrowError(
"StatusEffect list was not found in talent " + characterTalent.
DebugIdentifier,
227 List<StatusEffect> statusEffects =
new List<StatusEffect>();
229 foreach (var statusEffectElement
in statusEffectElements.Elements())
231 var statusEffect =
StatusEffect.
Load(statusEffectElement, characterTalent.DebugIdentifier);
232 statusEffects.Add(statusEffect);
235 return statusEffects;
241 if (statTypeString.Equals(
"MedicalItemDurationMultiplier", StringComparison.OrdinalIgnoreCase))
243 statTypeString =
"BuffItemApplyingMultiplier";
245 if (!Enum.TryParse(statTypeString,
true, out
StatTypes statType))
247 DebugConsole.ThrowError(
"Invalid stat type type \"" + statTypeString +
"\" in CharacterTalent (" + debugIdentifier +
")");
254 if (afflictionElements ==
null)
256 DebugConsole.ThrowError(
"Affliction list was not found in talent " + characterTalent.
DebugIdentifier,
261 List<Affliction> afflictions =
new List<Affliction>();
266 foreach (var afflictionElement
in afflictionElements.Elements())
268 Identifier afflictionIdentifier = afflictionElement.GetAttributeIdentifier(
"identifier",
"");
270 if (afflictionPrefab ==
null)
272 DebugConsole.ThrowError(
"Error in CharacterTalent (" + characterTalent.DebugIdentifier +
") - Affliction prefab with the identifier \"" + afflictionIdentifier +
"\" not found.",
273 contentPackage: characterTalent.Prefab.ContentPackage);
277 Affliction afflictionInstance = afflictionPrefab.
Instantiate(afflictionElement.GetAttributeFloat(1.0f,
"amount",
"strength"));
278 afflictionInstance.
Probability = afflictionElement.GetAttributeFloat(1.0f,
"probability");
279 afflictions.Add(afflictionInstance);
287 if (!Enum.TryParse(flagTypeString,
true, out
AbilityFlags flagType))
289 DebugConsole.ThrowError(
"Invalid flag type type \"" + flagTypeString +
"\" in CharacterTalent (" + debugIdentifier +
")");
virtual bool AllowClientSimulation
CharacterAbilityGroup(AbilityEffectType abilityEffectType, CharacterTalent characterTalent, ContentXElement abilityElementGroup)
CharacterTalent CharacterTalent
readonly AbilityEffectType AbilityEffectType
void LoadConditions(ContentXElement conditionElements)
void AddAbility(CharacterAbility characterAbility)
readonly List< AbilityCondition > abilityConditions
void ActivateAbilityGroup(bool addingFirstTime)
static StatTypes ParseStatType(string statTypeString, string debugIdentifier)
static List< Affliction > ParseAfflictions(CharacterTalent characterTalent, ContentXElement afflictionElements)
readonly List< CharacterAbility > characterAbilities
List of abilities that are triggered by this group. Fallback abilities are triggered if the condition...
static AbilityFlags ParseFlagType(string flagTypeString, string debugIdentifier)
void AddFallbackAbility(CharacterAbility characterAbility)
readonly int maxTriggerCount
static List< StatusEffect > ParseStatusEffects(CharacterTalent characterTalent, ContentXElement statusEffectElements)
AfflictionPrefab is a prefab that defines a type of affliction that can be applied to a character....
Affliction Instantiate(float strength, Character source=null)
static IEnumerable< AfflictionPrefab > List
readonly TalentPrefab Prefab
ContentPackage? ContentPackage
IEnumerable< ContentXElement > Elements()
int GetAttributeInt(string key, int def)
static NetworkMember NetworkMember
ContentPackage? ContentPackage
StatusEffects can be used to execute various kinds of effects: modifying the state of some entity in ...
static StatusEffect Load(ContentXElement element, string parentDebugName)
AbilityFlags
AbilityFlags are a set of toggleable flags that can be applied to characters.
StatTypes
StatTypes are used to alter several traits of a character. They are mostly used by talents.