v1.6.17.0 (Unto the Breach update)

This commit is contained in:
Regalis11
2024-10-22 17:29:04 +03:00
parent e74b3cdb17
commit 6e6c17e100
417 changed files with 17166 additions and 5870 deletions
@@ -44,9 +44,6 @@ namespace Barotrauma
[Serialize(0f, IsPropertySaveable.Yes, description: "How much the body raises when taking a step."), Editable(MinValueFloat = 0, MaxValueFloat = 100, ValueStep = 0.1f)]
public float StepLiftAmount { get; set; }
[Serialize(true, IsPropertySaveable.Yes), Editable]
public bool MultiplyByDir { get; set; }
[Serialize(0.5f, IsPropertySaveable.Yes, description: "When does the body raise when taking a step. The default (0.5) is in the middle of the step."), Editable(MinValueFloat = -1, MaxValueFloat = 1, DecimalCount = 2, ValueStep = 0.1f)]
public float StepLiftOffset { get; set; }
@@ -56,6 +53,48 @@ namespace Barotrauma
[Header("Movement")]
[Serialize(0.75f, IsPropertySaveable.Yes, description: "The character's movement speed is multiplied with this value when moving backwards."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 0.99f, DecimalCount = 2)]
public float BackwardsMovementMultiplier { get; set; }
[Serialize(1.0f, IsPropertySaveable.Yes, description: "Adjusts the maximum speed while climbing. The actual speed is affected by the MovementSpeed."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 10f, DecimalCount = 2)]
public float ClimbSpeed { get; set; }
[Serialize(2.0f, IsPropertySaveable.Yes, description: "Used instead of ClimbSpeed when descending ladders while moving fast (running). Not used if lower than ClimbSpeed."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 10f, DecimalCount = 2)]
public float SlideSpeed { get; set; }
[Serialize(10.5f, IsPropertySaveable.Yes, description: "Force applied to the main collider, torso and head, when climbing ladders."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 100f, DecimalCount = 1)]
public float ClimbBodyMoveForce { get; set; }
[Serialize(5.2f, IsPropertySaveable.Yes, description: "Force applied to the hands when climbing ladders."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 100f, DecimalCount = 1)]
public float ClimbHandMoveForce { get; set; }
[Serialize(10.0f, IsPropertySaveable.Yes, description: "Force applied to the feet when climbing ladders."), Editable(MinValueFloat = 0.1f, MaxValueFloat = 100f, DecimalCount = 1)]
public float ClimbFootMoveForce { get; set; }
[Serialize(30.0f, IsPropertySaveable.Yes), Editable(MinValueFloat = 0.1f, MaxValueFloat = 100f, DecimalCount = 1)]
public float ClimbStepHeight { get; set; }
protected override bool Deserialize(XElement element = null)
{
if (element.GetAttributeEnum(nameof(AnimationType), AnimationType.NotDefined) is AnimationType.Run)
{
// These values were previously hard-coded when running, so we need to set different default values for the run animations, when they are not defined.
const string climbSpeedName = nameof(ClimbSpeed);
if (element.GetAttribute(climbSpeedName) == null)
{
element.SetAttribute(climbSpeedName, 2.0f);
}
const string climbStepName = nameof(ClimbStepHeight);
if (element.GetAttribute(climbStepName) == null)
{
element.SetAttribute(climbStepName, 60.0f);
}
const string slideSpeedName = nameof(SlideSpeed);
if (element.GetAttribute(slideSpeedName) == null)
{
element.SetAttribute(slideSpeedName, 4.0f);
}
}
return base.Deserialize(element);
}
}
abstract class SwimParams : AnimationParams
@@ -92,7 +131,7 @@ namespace Barotrauma
/// <summary>
/// In degrees.
/// </summary>
[Header("Standing")]
[Header("Orientation")]
[Serialize(float.NaN, IsPropertySaveable.Yes), Editable(-360f, 360f)]
public float HeadAngle
{
@@ -19,6 +19,16 @@ namespace Barotrauma
{
[Serialize("", IsPropertySaveable.Yes), Editable]
public Identifier SpeciesName { get; private set; }
[Serialize("", IsPropertySaveable.Yes), Editable]
public string Tags
{
get => tags.ConvertToString();
set => tags = value.ToIdentifiers().ToHashSet();
}
private HashSet<Identifier> tags = new HashSet<Identifier>();
public bool HasTag(Identifier tag) => tags.Contains(tag);
[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]
public Identifier SpeciesTranslationOverride { get; private set; }
@@ -37,9 +47,21 @@ namespace Barotrauma
[Serialize(false, IsPropertySaveable.Yes, description: "Can the creature interact with items?"), Editable]
public bool CanInteract { get; private set; }
[Serialize(true, IsPropertySaveable.Yes, description: "Can the creature use ladders? Doesn't have an effect, if CanInteract is false."), Editable]
public bool CanClimb { get; private set; }
[Serialize(false, IsPropertySaveable.Yes, description: "If set true, this character only uses the climbing parameters defined in the walk parameters (not run)."), Editable]
public bool ForceSlowClimbing { get; private set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Should this character be treated as a husk?"), Editable]
public bool Husk { get; private set; }
[Serialize("", IsPropertySaveable.Yes, description: "If this character can turn into a husk, which character it turns to? If not defined, uses the default pattern (e.g. Crawler -> Crawlerhusk, Human -> Humanhusk)."), Editable]
public Identifier HuskedSpecies { get; private set; }
[Serialize("", IsPropertySaveable.Yes, description: "If this character is a husk, from what species it can be turned into? If not defined, uses the default pattern (e.g. Crawlerhusk -> Crawler, Humanhusk -> Human)."), Editable]
public Identifier NonHuskedSpecies { get; private set; }
[Serialize(false, IsPropertySaveable.Yes, description:"Should this character use a special husk appendage, attached to the ragdoll, when it turns into a husk?"), Editable]
public bool UseHuskAppendage { get; private set; }
@@ -161,7 +183,7 @@ namespace Barotrauma
}
}
public static XElement CreateVariantXml(XElement variantXML, XElement baseXML)
public static XElement CreateVariantXml(ContentXElement variantXML, ContentXElement baseXML)
{
XElement newXml = variantXML.CreateVariantXML(baseXML);
XElement variantAi = variantXML.GetChildElement("ai");
@@ -433,17 +455,11 @@ namespace Barotrauma
[Serialize("", IsPropertySaveable.Yes, description: "Which tags are required for this sound to play?"), Editable()]
public string Tags
{
get { return string.Join(',', TagSet); }
private set
{
TagSet = value.Split(',')
.ToIdentifiers()
.Where(id => !id.IsEmpty)
.ToImmutableHashSet();
}
get => TagSet.ConvertToString();
private set => TagSet = value.ToIdentifiers().ToImmutableHashSet();
}
public ImmutableHashSet<Identifier> TagSet { get; private set; }
public ImmutableHashSet<Identifier> TagSet { get; private set; } = ImmutableHashSet<Identifier>.Empty;
public SoundParams(ContentXElement element, CharacterParams character) : base(element, character)
{
@@ -549,6 +565,15 @@ namespace Barotrauma
[Serialize(0f, IsPropertySaveable.Yes), Editable]
public float EmpVulnerability { get; set; }
[Serialize(true, IsPropertySaveable.Yes, description: "Apply movement penalties when legs or tail limbs get damaged. Enabled by default."), Editable]
public bool ApplyMovementPenalties { get; set; }
[Serialize(true, IsPropertySaveable.Yes, description: "Normally characters die when they don't have a head. But maybe not all of them?"), Editable]
public bool DieFromBeheading { get; set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Severing legs doesn't work with most characters, because we'd need to take that into account with the walking animations and the standing position of the main collider etc. But there might be cases where you'll want to override this default."), Editable]
public bool AllowSeveringLegs { get; set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Can afflictions affect the face/body tint of the character."), Editable]
public bool ApplyAfflictionColors { get; private set; }
@@ -719,34 +744,47 @@ namespace Barotrauma
[Serialize(WallTargetingMethod.Target, IsPropertySaveable.Yes, description: "Defines the method of checking whether there's a blocking (submarine) wall."), Editable]
public WallTargetingMethod WallTargetingMethod { get; private set; }
[Serialize(0f, IsPropertySaveable.Yes, "How likely it is that the creature plays dead (= ragdolls) while idling? Only allowed inside a sub (not in the open waters). Evaluated once, when the creature spawns."), Editable]
public float PlayDeadProbability { get; set; }
public IEnumerable<TargetParams> Targets => targets;
protected readonly List<TargetParams> targets = new List<TargetParams>();
private readonly List<TargetParams> targets = new List<TargetParams>();
public AIParams(ContentXElement element, CharacterParams character) : base(element, character)
{
if (element == null) { return; }
element.GetChildElements("target").ForEach(t => TryAddTarget(t, out _));
element.GetChildElements("targetpriority").ForEach(t => TryAddTarget(t, out _));
element.GetChildElements("target").ForEach(t => AddTarget(t));
element.GetChildElements("targetpriority").ForEach(t => AddTarget(t));
}
/// <summary>
/// Adds a target but checks for duplicates first. Doesn't allow adding multiple targets with the same tag (see <see cref="AddTarget"/>).
/// </summary>
private bool TryAddTarget(ContentXElement targetElement, out TargetParams target)
{
string tag = targetElement.GetAttributeString("tag", null);
if (HasTag(tag))
{
target = null;
DebugConsole.AddWarning($"Trying to add multiple targets with the same tag ('{tag}') defined! Only the first will be used!",
targetElement.ContentPackage);
return false;
DebugConsole.AddWarning($"Trying to add multiple targets with the same tag ('{tag}') defined! Only the first will be used!", targetElement.ContentPackage);
}
else
{
target = new TargetParams(targetElement, Character);
targets.Add(target);
SubParams.Add(target);
return true;
target = AddTarget(targetElement);
}
return target != null;
}
/// <summary>
/// This method allows adding multiple targets with the same tag.
/// </summary>
private TargetParams AddTarget(ContentXElement targetElement)
{
var target = new TargetParams(targetElement, Character);
targets.Add(target);
SubParams.Add(target);
return target;
}
public bool TryAddEmptyTarget(out TargetParams targetParams) => TryAddNewTarget("newtarget" + targets.Count, AIState.Attack, 0f, out targetParams);
@@ -782,26 +820,40 @@ namespace Barotrauma
}
public bool RemoveTarget(TargetParams target) => RemoveSubParam(target, targets);
public bool TryGetTarget(string targetTag, out TargetParams target)
=> TryGetTarget(targetTag.ToIdentifier(), out target);
public bool TryGetTarget(Identifier targetTag, out TargetParams target)
public IEnumerable<TargetParams> GetMatchingTargets(Func<TargetParams, bool> predicate) => targets.Where(predicate);
public IEnumerable<TargetParams> GetTargets(Identifier target) => GetMatchingTargets(t => t.Tag == target);
public IEnumerable<TargetParams> GetTargets(Character target) => GetMatchingTargets(t => t.Tag == target.SpeciesName || t.Tag == target.Params.Group || target.Params.HasTag(t.Tag));
public TargetParams GetHighestPriorityTarget(Identifier target) => GetHighestPriorityTarget(GetTargets(target));
public TargetParams GetHighestPriorityTarget(Character target) => GetHighestPriorityTarget(GetTargets(target));
private static TargetParams GetHighestPriorityTarget(IEnumerable<TargetParams> targetParams) => targetParams.MaxBy(static t => t.Priority);
public bool TryGetTargets(Identifier target, out IEnumerable<TargetParams> targetParams)
{
target = targets.FirstOrDefault(t => t.Tag == targetTag);
return target != null;
targetParams = GetTargets(target);
return targetParams.Any();
}
public bool TryGetTargets(Character target, out IEnumerable<TargetParams> targetParams)
{
targetParams = GetTargets(target);
return targetParams.Any();
}
public bool TryGetHighestPriorityTarget(Identifier target, out TargetParams targetParams)
{
targetParams = GetHighestPriorityTarget(target);
return targetParams != null;
}
public bool TryGetHighestPriorityTarget(Character target, out TargetParams targetParams)
{
targetParams = GetHighestPriorityTarget(target);
return targetParams != null;
}
public bool TryGetTarget(Character targetCharacter, out TargetParams target)
{
if (!TryGetTarget(targetCharacter.SpeciesName, out target))
{
target = targets.FirstOrDefault(t => t.Tag == targetCharacter.Params.Group);
}
return target != null;
}
public bool TryGetTarget(IEnumerable<Identifier> tags, out TargetParams target)
public bool TryGetHighestPriorityTarget(IEnumerable<Identifier> tags, out TargetParams target)
{
target = null;
if (tags == null || tags.None()) { return false; }
@@ -819,22 +871,6 @@ namespace Barotrauma
}
return target != null;
}
public TargetParams GetTarget(string targetTag, bool throwError = true)
=> GetTarget(targetTag.ToIdentifier(), throwError);
public TargetParams GetTarget(Identifier targetTag, bool throwError = true)
{
if (targetTag.IsEmpty) { return null; }
if (!TryGetTarget(targetTag, out TargetParams target))
{
if (throwError)
{
DebugConsole.ThrowError($"Cannot find a target with the tag {targetTag}!");
}
}
return target;
}
}
public class TargetParams : SubParam
@@ -889,7 +925,7 @@ namespace Barotrauma
[Serialize(-1f, IsPropertySaveable.Yes, description: "A generic max threshold. Not used if set to negative."), Editable]
public float ThresholdMax { get; private set; }
[Serialize(1.0f, IsPropertySaveable.Yes, description: "Can be used to make the monster perceive the target further than it normally can."), Editable]
[Serialize(1.0f, IsPropertySaveable.Yes, description: "Can be used to make the monster perceive the target further or closer than it normally can."), Editable]
public float PerceptionDistanceMultiplier { get; private set; }
[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]
@@ -113,7 +113,7 @@ namespace Barotrauma
[Serialize(true, IsPropertySaveable.Yes), Editable]
public bool CanWalk { get; set; }
[Serialize(true, IsPropertySaveable.Yes, description: "Can the character be dragged around by other creatures?"), Editable()]
public bool Draggable { get; set; }
@@ -654,7 +654,7 @@ namespace Barotrauma
[Serialize(0.25f, IsPropertySaveable.Yes), Editable]
public float Stiffness { get; set; }
[Serialize(1f, IsPropertySaveable.Yes, description: "CAUTION: Not fully implemented. Only use for limb joints that connect non-animated limbs!"), Editable]
[Serialize(1f, IsPropertySaveable.Yes, description: "CAUTION: Not fully implemented. Only use for limb joints that connect non-animated limbs!"), Editable(DecimalCount = 2)]
public float Scale { get; set; }
[Serialize(false, IsPropertySaveable.No), Editable(ReadOnly = true)]
@@ -705,6 +705,9 @@ namespace Barotrauma
[Serialize(LimbType.None, IsPropertySaveable.Yes, description: "The limb type affects many things, like the animations. Torso or Head are considered as the main limbs. Every character should have at least one Torso or Head."), Editable()]
public LimbType Type { get; set; }
[Serialize(LimbType.None, IsPropertySaveable.Yes, description: "Secondary limb type to be used for generic purposes. Currently only used in climbing animations."), Editable()]
public LimbType SecondaryType { get; set; }
/// <summary>
/// The orientation of the sprite as drawn on the sprite sheet (in radians).
@@ -775,6 +778,12 @@ namespace Barotrauma
[Serialize("0, 0", IsPropertySaveable.Yes, description: "Relative offset for the mouth position (starting from the center). Only applicable for LimbType.Head. Used for eating."), Editable(DecimalCount = 2, MinValueFloat = -10f, MaxValueFloat = 10f)]
public Vector2 MouthPos { get; set; }
[Serialize(50f, IsPropertySaveable.Yes, description: "How much torque is applied on the head while updating the eating animations?"), Editable]
public float EatTorque { get; set; }
[Serialize(2f, IsPropertySaveable.Yes, description: "How strong a linear impulse is applied on the head while updating the eating animations?"), Editable]
public float EatImpulse { get; set; }
[Serialize(0f, IsPropertySaveable.Yes), Editable]
public float ConstantTorque { get; set; }
@@ -795,8 +804,11 @@ namespace Barotrauma
[Serialize(10f, IsPropertySaveable.Yes, "How long it takes for the severed limb to fade out"), Editable(MinValueFloat = 0, MaxValueFloat = 100, ValueStep = 1)]
public float SeveredFadeOutTime { get; set; } = 10.0f;
[Serialize(false, IsPropertySaveable.Yes, description: "Only applied when the limb is of type Tail. If none of the tails have been defined to use the angle and an angle is defined in the animation parameters, the first tail limb is used."), Editable]
[Serialize(false, IsPropertySaveable.Yes, description: "Should the tail angle be applied on this limb? If none of the limbs have been defined to use the angle and an angle is defined in the animation parameters, the first tail limb is used."), Editable]
public bool ApplyTailAngle { get; set; }
[Serialize(false, IsPropertySaveable.Yes, description: "Should this limb be moved like a tail when swimming? Always true for tail limbs. On tails, disable by setting SineFrequencyMultiplier to 0."), Editable]
public bool ApplySineMovement { get; set; }
[Serialize(1f, IsPropertySaveable.Yes), Editable(ValueStep = 0.1f, DecimalCount = 2)]
public float SineFrequencyMultiplier { get; set; }