1 using Microsoft.Xna.Framework;
3 using System.Collections.Generic;
8 using System.Collections.Immutable;
23 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"References to another species. Define only if the creature is a variant that needs to use a pre-existing translation."),
Editable]
26 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"Overrides the name of the character, shown to the player. If the display name is not defined, the game first tries to find the translated name. If that is not found, the species name will be used."),
Editable]
29 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"If defined, different species of the same group consider each other friendly and do not attack each other."),
Editable]
30 public Identifier
Group {
get;
private set; }
32 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"If enabled, the character is a humanoid and has different animation constraints relative to non-humanoid characters."),
Editable(ReadOnly =
true)]
35 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"If enabled, jobs can be assigned to characters of this species. Should be true for the player characters."),
Editable(ReadOnly =
true)]
42 public bool Husk {
get;
private set; }
47 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Does this character need oxygen to survive? Enabling this also makes the character vulnerable to high pressure when swimming outside of the submarine."),
Editable]
53 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Note: non-humans with a human AI aren't fully supported. Enabling this on a non-human character may lead to issues.")]
56 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Is this creature an artificial creature, like robot or machine that shouldn't be affected by afflictions that affect only organic creatures? Overrides DoesBleed."),
Editable]
65 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Is this character's health shown at the top of the player's screen when they are in an active encounter?"),
Editable]
69 public float Noise {
get;
set; }
86 [
Serialize(
true,
IsPropertySaveable.Yes, description:
"Can the creature eat bodies? Used by player controlled creatures to allow them to eat. Currently applicable only to non-humanoids. To allow an AI controller to eat, just add an ai target with the state \"eat\""),
Editable]
89 [
Serialize(10f,
IsPropertySaveable.Yes, description:
"How effectively/easily the character eats other characters. Affects the forces, the amount of particles, and the time required before the target is eaten away"),
Editable(MinValueFloat = 1, MaxValueFloat = 1000, ValueStep = 1)]
95 [
Serialize(1f,
IsPropertySaveable.Yes,
"Decreases the intensive path finding call frequency. Set to a lower value for insignificant creatures to improve performance."),
Editable(minValue: 0f, maxValue: 1f)]
104 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"If set to a value greater than zero, this character creates disrupting noise on the sonar when within range."),
Editable]
107 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Range at which \"long distance\" blips for this character will appear on the sonar (used on some of the Abyss monsters)."),
Editable]
110 [
Serialize(25000f,
IsPropertySaveable.Yes,
"If the character is farther than this (in pixels) from the sub and the players, it will be disabled. The halved value is used for triggering simple physics where the ragdoll is disabled and only the main collider is updated."),
Editable(MinValueFloat = 10000f, MaxValueFloat = 100000f)]
116 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Should the character be drawn on top of characters that do not have this set? This currently has no effect if the character has no deformable sprites."),
Editable]
119 [
Serialize(1.0f,
IsPropertySaveable.Yes,
"Tells the bots how much they should prefer targeting this character with submarine weapons. Defaults to 1. Set 0 to tell the bots not to target this character at all. Distance to the target affects the decision making."),
Editable]
122 [
Serialize(1.0f,
IsPropertySaveable.Yes,
"Tells the bots how much they should prefer targeting this character with submarine weapons tagged as \"slowturret\", like railguns. The tag is arbitrary and can be added to any turrets, just like the priority. Defaults to 1. Not used if AITurretPriority is 0. Distance to the target affects the decision making."),
Editable]
132 public readonly List<SubParam>
SubParams =
new List<SubParam>();
133 public readonly List<SoundParams>
Sounds =
new List<SoundParams>();
134 public readonly List<ParticleParams>
BloodEmitters =
new List<ParticleParams>();
135 public readonly List<ParticleParams>
GibEmitters =
new List<ParticleParams>();
136 public readonly List<ParticleParams>
DamageEmitters =
new List<ParticleParams>();
137 public readonly List<InventoryParams>
Inventories =
new List<InventoryParams>();
153 protected override string GetName() =>
"Character Config File";
159 if (base.MainElement ==
null) {
return null; }
160 return base.MainElement.
IsOverride() ? base.MainElement.FirstElement() : base.MainElement;
166 XElement newXml = variantXML.CreateVariantXML(baseXML);
167 XElement variantAi = variantXML.GetChildElement(
"ai");
168 XElement baseAi = baseXML.GetChildElement(
"ai");
169 if (baseAi is
null || baseAi.Elements().None()
170 || variantAi is
null || variantAi.Elements().None())
175 var finalAiElement = newXml.GetChildElement(
"ai");
176 var processedTags =
new HashSet<string>();
177 foreach (var aiTarget
in finalAiElement.Elements().ToArray())
179 string tag = aiTarget.GetAttributeString(
"tag",
null);
180 if (tag ==
null) {
continue; }
181 if (processedTags.Contains(tag))
186 processedTags.Add(tag);
187 var matchInSelf = variantAi.Elements().FirstOrDefault(e => e.GetAttributeString(
"tag",
null) == tag);
188 var matchInParent = baseAi.Elements().FirstOrDefault(e => e.GetAttributeString(
"tag",
null) == tag);
189 if (matchInSelf !=
null && matchInParent !=
null)
191 aiTarget.ReplaceWith(
new XElement(matchInSelf));
200 doc = XMLExtensions.TryLoadXml(Path);
203 DebugConsole.ThrowError(
"Main element null! Failed to load character params.");
207 if (!variantOf.IsEmpty)
210 #warning TODO: determine that CreateVariantXML is equipped to do this
213 var parentElement = (XContainer)oldElement.
Parent ??
doc; oldElement.Remove(); parentElement.Add(newRoot);
226 public bool Save(
string fileNameWithoutExtension =
null)
231 return base.Save(fileNameWithoutExtension,
new XmlWriterSettings
234 OmitXmlDeclaration =
true,
235 NewLineOnAttributes =
false
239 public override bool Reset(
bool forceReload =
false)
250 public static bool CompareGroup(Identifier group1, Identifier group2) => group1 != Identifier.Empty && group2 != Identifier.Empty && group1 == group2;
256 DebugConsole.ThrowError(
"Main element null, cannot create sub params!");
261 if (healthElement !=
null)
267 DebugConsole.ThrowError($
"No health parameters defined for character \"{(SpeciesName)}\".");
310 public bool Deserialize(XElement element =
null,
bool alsoChildren =
true,
bool recursive =
true,
bool loadDefaultValues =
true)
312 if (base.Deserialize(element))
317 SpeciesName = element.GetAttributeIdentifier(
"name",
"[NAME NOT GIVEN]");
321 SubParams.ForEach(p => p.Deserialize(recursive));
328 public bool Serialize(XElement element =
null,
bool alsoChildren =
true,
bool recursive =
true)
330 if (base.Serialize(element))
334 SubParams.ForEach(p => p.Serialize(recursive));
344 base.AddToEditor(editor);
347 SubParams.ForEach(s => s.AddToEditor(editor, recursive));
367 private void AddEmitter(
string type)
377 case "damageemitter":
380 default:
throw new NotImplementedException(type);
392 if (subParam ==
null || subParam.Element ==
null || subParam.Element.Parent ==
null) {
return false; }
393 if (collection !=
null && !collection.Contains(subParam)) {
return false; }
394 if (!
SubParams.Contains(subParam)) {
return false; }
395 collection?.Remove(subParam);
397 subParam.Element.Remove();
401 protected bool TryAddSubParam<T>(
ContentXElement element, Func<ContentXElement, CharacterParams, T> constructor, out T subParam, IList<T> collection =
null, Func<IList<T>,
bool> filter =
null) where T :
SubParam
403 subParam = constructor(element,
this);
404 if (collection !=
null && filter !=
null)
406 if (filter(collection)) {
return false; }
410 collection?.Add(subParam);
411 return subParam !=
null;
417 public override string Name =>
"Sound";
420 public string File {
get;
private set; }
424 public SoundType
State {
get;
private set; }
428 public float Range {
get;
private set; }
431 public float Volume {
get;
private set; }
436 get {
return string.Join(
',',
TagSet); }
441 .Where(
id => !
id.IsEmpty)
442 .ToImmutableHashSet();
446 public ImmutableHashSet<Identifier>
TagSet {
get;
private set; }
451 if (genderFallback != Identifier.Empty && genderFallback !=
"None")
465 if (name ==
null &&
Element !=
null)
467 name =
Element.
Name.ToString().FormatCamelCaseWithSpaces();
514 public override string Name =>
"Health";
529 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How easily the character heals from the bleeding wounds. Default 0 (no extra healing)."),
Editable(MinValueFloat = 0, MaxValueFloat = 100, DecimalCount = 2)]
532 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How easily the character heals from the burn wounds. Default 0 (no extra healing)."),
Editable(MinValueFloat = 0, MaxValueFloat = 100, DecimalCount = 2)]
559 private ImmutableHashSet<Identifier> _immunityIdentifiers;
565 return _immunityIdentifiers;
577 float newCrushDepth = -
CrushDepth * Physics.DisplayToRealWorldRatio + 1000;
578 DebugConsole.AddWarning($
"Character \"{character.SpeciesName}\" has a negative crush depth. "+
579 "Previously the crush depths were defined as display units (e.g. -30000 would correspond to 300 meters below the level), "+
580 "but now they're in meters (e.g. 3000 would correspond to a depth of 3000 meters displayed on the nav terminal). "+
581 $
"Changing the crush depth from {CrushDepth} to {newCrushDepth}.",
592 public override string Name =>
"Item";
600 public override string Name =>
"Inventory";
602 [
Serialize(
"Any, Any",
IsPropertySaveable.Yes, description:
"Which slots the inventory holds? Accepted types: None, Any, RightHand, LeftHand, Head, InnerClothes, OuterClothes, Headset, and Card."),
Editable()]
603 public string Slots {
get;
private set; }
611 public List<InventoryItem>
Items {
get;
private set; } =
new List<InventoryItem>();
615 foreach (var itemElement
in element.GetChildElements(
"item"))
625 if (
Element ==
null) {
return; }
627 var element =
CreateElement(
"item",
new XAttribute(
"identifier", identifier));
639 public override string Name =>
"AI";
645 public float Sight {
get;
private set; }
650 [
Serialize(-1.0f,
IsPropertySaveable.Yes, description:
"Hard limit to how far the character can spot targets from, regardless of the sight/hearing or how visible or how much noise the target is making. Not used if set to negative."),
Editable]
653 [
Serialize(100f,
IsPropertySaveable.Yes, description:
"How much the targeting priority increases each time the character takes damage. Works like the greed value, described above. The default value is 100."),
Editable(minValue: -1000f, maxValue: 1000f)]
656 [
Serialize(10f,
IsPropertySaveable.Yes, description:
"How much the targeting priority increases each time the character does damage to the target. The actual priority adjustment is calculated based on the damage percentage multiplied by the greed value. The default value is 10, which means the priority will increase by 1 every time the character does damage 10% of the target's current health. If the damage is 50%, then the priority increase is 5."),
Editable(minValue: 0f, maxValue: 1000f)]
659 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"If the health drops below this threshold, the character flees. In percentages."),
Editable(minValue: 0f, maxValue: 100f)]
662 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Does the character attack when provoked? When enabled, overrides the predefined targeting state with Attack and increases the priority of it."),
Editable()]
668 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How much damage is required for single attack to trigger avoiding/releasing targets."),
Editable(minValue: 0f, maxValue: 1000f)]
671 [
Serialize(3f,
IsPropertySaveable.Yes, description:
"How long the creature avoids gunfire. Also used when the creature is unlatched."),
Editable(minValue: 0f, maxValue: 100f)]
674 [
Serialize(20f,
IsPropertySaveable.Yes, description:
"How long the creature flees before returning to normal state. When the creature sees the target or is being chased, it will always flee, if it's in the flee state."),
Editable(minValue: 0f, maxValue: 100f)]
686 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"If enabled, the character chooses randomly from the available attacks. The priority is used as a weight for weighted random."),
Editable]
689 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Does the creature know how to open doors (still requires a proper ID card). Humans can always open doors (They don't use this AI definition)."),
Editable]
692 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Unlike human AI, monsters normally only use pathfinding when they are inside the submarine. When this is enabled, the monsters can also use pathfinding to get inside the sub. In practice, via doors and hatches."),
Editable]
698 [
Serialize(
true,
IsPropertySaveable.Yes,
"Is the creature allowed to navigate from and into the depths of the abyss? When enabled, the creatures will try to avoid the depths."),
Editable]
710 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Initial aggression used in the circle attack pattern (0-100). The aggression affects how close and how fast to the target the monster circles."),
Editable]
713 [
Serialize(100f,
IsPropertySaveable.Yes, description:
"Maximum aggression used in the circle attack pattern (0-100). The aggression affects how close and how fast to the target the monster circles."),
Editable]
716 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How quickly the aggression level increases from StartAggression to MaxAggression when using the circle attack pattern. Artificial amount, applied once per attack cycle."),
Editable]
724 protected readonly List<TargetParams>
targets =
new List<TargetParams>();
728 if (element ==
null) {
return; }
730 element.
GetChildElements(
"targetpriority").ForEach(t => TryAddTarget(t, out _));
739 DebugConsole.AddWarning($
"Trying to add multiple targets with the same tag ('{tag}') defined! Only the first will be used!",
745 target =
new TargetParams(targetElement,
Character);
755 TryAddNewTarget(tag.ToIdentifier(), state, priority, out targetParams);
765 if (TryAddTarget(element, out targetParams))
780 if (tag ==
null) {
return false; }
781 return targets.Any(t => t.Tag == tag);
791 target =
targets.FirstOrDefault(t => t.Tag == targetTag);
792 return target !=
null;
801 return target !=
null;
807 if (tags ==
null || tags.None()) {
return false; }
809 foreach (var potentialTarget
in targets)
811 if (potentialTarget.Priority > priority)
813 if (tags.Any(t => t == potentialTarget.Tag))
815 target = potentialTarget;
816 priority = target.Priority;
820 return target !=
null;
824 =>
GetTarget(targetTag.ToIdentifier(), throwError);
828 if (targetTag.IsEmpty) {
return null; }
833 DebugConsole.ThrowError($
"Cannot find a target with the tag {targetTag}!");
842 public override string Name =>
"Target";
844 [
Serialize(
"",
IsPropertySaveable.Yes, description:
"Can be an item tag, species name or something else. Examples: decoy, provocative, light, dead, human, crawler, wall, nasonov, sonar, door, stronger, weaker, light, human, room..."),
Editable()]
845 public Identifier
Tag {
get;
private set; }
850 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"What base priority is given to the target?"),
Editable(minValue: 0f, maxValue: 1000f, ValueStep = 1, DecimalCount = 0)]
853 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Generic distance that can be used for different purposes depending on the state. E.g. in Avoid state this defines the distance that the character tries to keep to the target. If the distance is 0, it's not used."),
Editable(MinValueFloat = 0, ValueStep = 10, DecimalCount = 0)]
856 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Used for defining the attack distance for PassiveAggressive and Aggressive states. If the distance is 0, it's not used."),
Editable(MinValueFloat = 0, ValueStep = 10, DecimalCount = 0)]
859 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Generic timer that can be used for different purposes depending on the state. E.g. in Observe state this defines how long the character in general keeps staring the targets (Some random is always applied)."),
Editable]
877 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Should the target be ignored if it's inside a different submarine than us? Normally only some targets are ignored when they are not inside the same sub."),
Editable]
883 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"A generic threshold. For example, how much damage the protected target should take from an attacker before the creature starts defending it."),
Editable]
895 [
Serialize(-1.0f,
IsPropertySaveable.Yes, description:
"Maximum distance at which the monster can perceive the target, regardless of the sight/hearing or how visible or how much noise the target is making. Not used if set to negative."),
Editable]
898 [
Serialize(
"0.0, 0.0",
IsPropertySaveable.Yes, description:
"A generic offset. Used for example for offsetting the react distance (vector length) and for offsetting the target position when a guardian flees to a pod."),
Editable]
899 public Vector2
Offset {
get;
private set; }
904 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"If enabled, the AI will give more priority to targets close to the horizontal middle of the sub. Only applies to walls, hulls, and items like sonar. Circle and Sweep always does this regardless of this property."),
Editable]
908 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"Use to define a distance at which the creature starts the sweeping movement."),
Editable(MinValueFloat = 0, MaxValueFloat = 10000, ValueStep = 1, DecimalCount = 0)]
911 [
Serialize(10f,
IsPropertySaveable.Yes, description:
"How much the sweep affects the steering?"),
Editable(MinValueFloat = 0, MaxValueFloat = 100, ValueStep = 1f, DecimalCount = 1)]
914 [
Serialize(1f,
IsPropertySaveable.Yes, description:
"How quickly the sweep direction changes. Uses the sine wave pattern."),
Editable(MinValueFloat = 0, MaxValueFloat = 10, ValueStep = 0.1f, DecimalCount = 2)]
919 [
Serialize(5000f,
IsPropertySaveable.Yes, description:
"How close to the target the character should be, before they start using the circle pattern instead of directional approaching."),
Editable(MinValueFloat = 0f, MaxValueFloat = 20000f)]
922 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"Normally the target size is taken into account when calculating the distance to the target. Set this true to skip that.")]
925 [
Serialize(1f,
IsPropertySaveable.Yes, description:
"Determines the rate how quickly the target movement position is rotated towards the attack target. The actual rotation is calculated once per each attack cycle, based on the current aggression level."),
Editable(MinValueFloat = 0f, MaxValueFloat = 100f)]
928 [
Serialize(
false,
IsPropertySaveable.Yes, description:
"When enabled, the circle rotation speed can change when the target is far. When this setting is disabled (default), the character will head directly towards the target when it's too far."),
Editable]
931 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How much the turn speed can differ between attack cycles (stays constant during the cycle)"),
Editable(MinValueFloat = 0f, MaxValueFloat = 1f)]
934 [
Serialize(5f,
IsPropertySaveable.Yes, description:
"Affects how close to the target the character has to be before the strike phase of the circle behavior triggers. In the strike phase, the creature moves directly towards the target."),
Editable(MinValueFloat = 0f, MaxValueFloat = 10f)]
937 [
Serialize(0f,
IsPropertySaveable.Yes, description:
"How much the target position is offset at maximum. Low values make the character hit the target earlier/always, higher values make it miss the target when the aggression intensity is low (early in the encounter)."),
Editable(MinValueFloat = 0f, MaxValueFloat = 50f)]
944 public List<PropertyConditional>
Conditionals {
get;
private set; } =
new List<PropertyConditional>();
951 foreach (var subElement
in element.Elements())
953 switch (subElement.Name.ToString().ToLowerInvariant())
967 return new XElement(
"target",
968 new XAttribute(
"tag", tag),
969 new XAttribute(
"state", state),
976 public virtual string Name {
get;
set; }
979 public List<SubParam>
SubParams {
get;
set; } =
new List<SubParam>();
998 SubParams.ForEach(sp => sp.Deserialize(
true));
1008 SubParams.ForEach(sp => sp.Serialize(
true));
1022 if (subParam ==
null || subParam.Element ==
null || subParam.Element.Parent ==
null) {
return false; }
1023 if (collection !=
null && !collection.Contains(subParam)) {
return false; }
1024 if (!
SubParams.Contains(subParam)) {
return false; }
1025 collection?.Remove(subParam);
1027 subParam.Element.Remove();
1038 SubParams.ForEach(sp => sp.AddToEditor(editor,
true, titleFont: titleFont ?? GUIStyle.SmallFont));
1044 CanBeFocused =
false
readonly CharacterParams Params
bool TryAddEmptyTarget(out TargetParams targetParams)
bool HasTag(Identifier tag)
TargetParams GetTarget(Identifier targetTag, bool throwError=true)
float FleeHealthThreshold
readonly List< TargetParams > targets
bool TryGetTarget(string targetTag, out TargetParams target)
bool TryGetTarget(Character targetCharacter, out TargetParams target)
float MaxPerceptionDistance
IEnumerable< TargetParams > Targets
bool EnforceAggressiveBehaviorForMissions
TargetParams GetTarget(string targetTag, bool throwError=true)
bool TryGetTarget(Identifier targetTag, out TargetParams target)
bool TryAddNewTarget(string tag, AIState state, float priority, out TargetParams targetParams)
bool UsePathFindingToGetInside
AIParams(ContentXElement element, CharacterParams character)
bool TryGetTarget(IEnumerable< Identifier > tags, out TargetParams target)
float AggressionCumulation
bool RemoveTarget(TargetParams target)
bool TryAddNewTarget(Identifier tag, AIState state, float priority, out TargetParams targetParams)
float PoisonVulnerability
IEnumerable< Identifier > ImmunityIdentifiers
float ConstantHealthRegeneration
HealthParams(ContentXElement element, CharacterParams character)
bool ApplyAfflictionColors
float HealthRegenerationWhenEating
InventoryItem(ContentXElement element, CharacterParams character)
List< InventoryItem > Items
bool RemoveItem(InventoryItem item)
InventoryParams(ContentXElement element, CharacterParams character)
void AddItem(string identifier=null)
bool HighQualityCollisionDetection
ParticleParams(ContentXElement element, CharacterParams character)
SoundParams(ContentXElement element, CharacterParams character)
ImmutableHashSet< Identifier > TagSet
virtual bool Deserialize(bool recursive=true)
ContentXElement CreateElement(string name, params object[] attrs)
SubParam(ContentXElement element, CharacterParams character)
SerializableEntityEditor SerializableEntityEditor
bool RemoveSubParam< T >(T subParam, IList< T > collection=null)
virtual void AddToEditor(ParamsEditor editor, bool recursive=true, int space=0, GUIFont titleFont=null)
virtual bool Serialize(bool recursive=true)
List< SubParam > SubParams
Dictionary< Identifier, SerializableProperty > SerializableProperties
float CircleRandomRotationFactor
bool DynamicCircleRotationSpeed
float CircleRotationSpeed
TargetParams(string tag, AIState state, float priority, CharacterParams character)
List< PropertyConditional > Conditionals
Conditionals that must be met for the character to be able to use these targeting parameters.
static ContentXElement CreateNewElement(CharacterParams character, string tag, AIState state, float priority)
float CircleMaxRandomOffset
static ContentXElement CreateNewElement(CharacterParams character, Identifier tag, AIState state, float priority)
bool IgnoreIfNotInSameSub
float PerceptionDistanceMultiplier
TargetParams(ContentXElement element, CharacterParams character)
float CircleStartDistance
float MaxPerceptionDistance
float CircleStrikeDistanceMultiplier
Contains character data that should be editable in the character editor.
bool RemoveBloodEmitter(ParticleParams emitter)
bool HideInThermalGoggles
bool RemoveInventory(InventoryParams inventory)
bool RemoveSound(SoundParams soundParams)
bool TryAddSubParam< T >(ContentXElement element, Func< ContentXElement, CharacterParams, T > constructor, out T subParam, IList< T > collection=null, Func< IList< T >, bool > filter=null)
bool RemoveDamageEmitter(ParticleParams emitter)
AIParams AI
Parameters for EnemyAIController. Not used by HumanAIController.
readonly List< ParticleParams > DamageEmitters
override ContentXElement? MainElement
readonly List< SoundParams > Sounds
readonly CharacterFile File
bool Save(string fileNameWithoutExtension=null)
override string GetName()
bool Deserialize(XElement element=null, bool alsoChildren=true, bool recursive=true, bool loadDefaultValues=true)
bool RemoveSubParam< T >(T subParam, IList< T > collection=null)
readonly List< ParticleParams > GibEmitters
Identifier DespawnContainer
void AddToEditor(ParamsEditor editor, bool alsoChildren=true, bool recursive=true, int space=0)
float AISlowTurretPriority
readonly List< ParticleParams > BloodEmitters
CharacterParams(CharacterFile file)
bool Serialize(XElement element=null, bool alsoChildren=true, bool recursive=true)
static bool CompareGroup(Identifier group1, Identifier group2)
float BleedParticleMultiplier
static XElement CreateVariantXml(XElement variantXML, XElement baseXML)
readonly List< InventoryParams > Inventories
string BleedParticleWater
readonly List< SubParam > SubParams
Identifier SpeciesTranslationOverride
override bool Reset(bool forceReload=false)
bool RemoveGibEmitter(ParticleParams emitter)
static CharacterPrefab FindBySpeciesName(Identifier speciesName)
ContentXElement ConfigElement
readonly ContentPackage ContentPackage
void Add(ContentXElement elem)
string? GetAttributeString(string key, string? def)
Identifier[] GetAttributeIdentifierArray(Identifier[] def, params string[] keys)
ContentPackage? ContentPackage
IEnumerable< ContentXElement > GetChildElements(string name)
ContentXElement? GetChildElement(string name)
Identifier GetAttributeIdentifier(string key, string def)
virtual void UpdatePath(ContentPath fullPath)
ContentXElement CreateElement(string name, params object[] attrs)
ContentXElement OriginalElement
RectTransform RectTransform
GUIFrame Content
A frame that contains the contents of the listbox. The frame itself is not rendered.
Conditionals are used by some in-game mechanics to require one or more conditions to be met for those...
static IEnumerable< PropertyConditional > FromXElement(ContentXElement element, Predicate< XAttribute >? predicate=null)
static Dictionary< Identifier, SerializableProperty > DeserializeProperties(object obj, XElement element=null)
static void SerializeProperties(ISerializableEntity obj, XElement element, bool saveIfDefault=false, bool ignoreEditable=false)