v1.0.13.1 (first post-1.0 patch)
This commit is contained in:
+36
-38
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using Barotrauma.Extensions;
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -14,8 +15,8 @@ namespace Barotrauma
|
||||
|
||||
public Dictionary<Identifier, SerializableProperty> SerializableProperties { get; set; }
|
||||
|
||||
public float PendingAdditionStrength { get; set; }
|
||||
public float AdditionStrength { get; set; }
|
||||
public float PendingGrainEffectStrength { get; set; }
|
||||
public float GrainEffectStrength { get; set; }
|
||||
|
||||
private float fluctuationTimer;
|
||||
|
||||
@@ -46,7 +47,7 @@ namespace Barotrauma
|
||||
float newValue = MathHelper.Clamp(value, 0.0f, Prefab.MaxStrength);
|
||||
if (newValue > _strength)
|
||||
{
|
||||
PendingAdditionStrength = Prefab.GrainBurst;
|
||||
PendingGrainEffectStrength = Prefab.GrainBurst;
|
||||
Duration = Prefab.Duration;
|
||||
}
|
||||
_strength = newValue;
|
||||
@@ -73,8 +74,7 @@ namespace Barotrauma
|
||||
public float DamagePerSecondTimer;
|
||||
public float PreviousVitalityDecrease;
|
||||
|
||||
public float StrengthDiminishMultiplier = 1.0f;
|
||||
public Affliction MultiplierSource;
|
||||
public (float Value, Affliction Source) StrengthDiminishMultiplier = (1.0f, null);
|
||||
|
||||
public readonly Dictionary<AfflictionPrefab.PeriodicEffect, float> PeriodicEffectTimers = new Dictionary<AfflictionPrefab.PeriodicEffect, float>();
|
||||
|
||||
@@ -100,7 +100,7 @@ namespace Barotrauma
|
||||
prefab?.ReloadSoundsIfNeeded();
|
||||
#endif
|
||||
Prefab = prefab;
|
||||
PendingAdditionStrength = Prefab.GrainBurst;
|
||||
PendingGrainEffectStrength = Prefab.GrainBurst;
|
||||
_strength = strength;
|
||||
Identifier = prefab.Identifier;
|
||||
|
||||
@@ -179,7 +179,7 @@ namespace Barotrauma
|
||||
float currVitalityDecrease = MathHelper.Lerp(
|
||||
currentEffect.MinVitalityDecrease,
|
||||
currentEffect.MaxVitalityDecrease,
|
||||
(strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(strength));
|
||||
|
||||
if (currentEffect.MultiplyByMaxVitality)
|
||||
{
|
||||
@@ -200,11 +200,11 @@ namespace Barotrauma
|
||||
float amount = MathHelper.Lerp(
|
||||
currentEffect.MinGrainStrength,
|
||||
currentEffect.MaxGrainStrength,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||
currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
|
||||
|
||||
if (Prefab.GrainBurst > 0 && AdditionStrength > amount)
|
||||
if (Prefab.GrainBurst > 0 && GrainEffectStrength > amount)
|
||||
{
|
||||
return Math.Min(AdditionStrength, 1.0f);
|
||||
return Math.Min(GrainEffectStrength, 1.0f);
|
||||
}
|
||||
|
||||
return amount;
|
||||
@@ -220,7 +220,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinScreenDistort,
|
||||
currentEffect.MaxScreenDistort,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||
currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
|
||||
}
|
||||
|
||||
public float GetRadialDistortStrength()
|
||||
@@ -233,7 +233,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinRadialDistort,
|
||||
currentEffect.MaxRadialDistort,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||
currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
|
||||
}
|
||||
|
||||
public float GetChromaticAberrationStrength()
|
||||
@@ -246,7 +246,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinChromaticAberration,
|
||||
currentEffect.MaxChromaticAberration,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||
currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
|
||||
}
|
||||
|
||||
public float GetAfflictionOverlayMultiplier()
|
||||
@@ -261,7 +261,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinAfflictionOverlayAlphaMultiplier,
|
||||
currentEffect.MaxAfflictionOverlayAlphaMultiplier,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public Color GetFaceTint()
|
||||
@@ -273,7 +273,7 @@ namespace Barotrauma
|
||||
return Color.Lerp(
|
||||
currentEffect.MinFaceTint,
|
||||
currentEffect.MaxFaceTint,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public Color GetBodyTint()
|
||||
@@ -285,7 +285,7 @@ namespace Barotrauma
|
||||
return Color.Lerp(
|
||||
currentEffect.MinBodyTint,
|
||||
currentEffect.MaxBodyTint,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public float GetScreenBlurStrength()
|
||||
@@ -298,7 +298,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinScreenBlur,
|
||||
currentEffect.MaxScreenBlur,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength)) * GetScreenEffectFluctuation(currentEffect);
|
||||
currentEffect.GetStrengthFactor(this)) * GetScreenEffectFluctuation(currentEffect);
|
||||
}
|
||||
|
||||
private float GetScreenEffectFluctuation(AfflictionPrefab.Effect currentEffect)
|
||||
@@ -316,7 +316,7 @@ namespace Barotrauma
|
||||
float amount = MathHelper.Lerp(
|
||||
currentEffect.MinSkillMultiplier,
|
||||
currentEffect.MaxSkillMultiplier,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
|
||||
return amount;
|
||||
}
|
||||
@@ -347,7 +347,7 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinResistance,
|
||||
currentEffect.MaxResistance,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public float GetSpeedMultiplier()
|
||||
@@ -358,21 +358,16 @@ namespace Barotrauma
|
||||
return MathHelper.Lerp(
|
||||
currentEffect.MinSpeedMultiplier,
|
||||
currentEffect.MaxSpeedMultiplier,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public float GetStatValue(StatTypes statType)
|
||||
{
|
||||
if (GetViableEffect() is not AfflictionPrefab.Effect currentEffect) { return 0.0f; }
|
||||
|
||||
if (currentEffect.AfflictionStatValues.TryGetValue(statType, out var value))
|
||||
{
|
||||
return MathHelper.Lerp(
|
||||
value.minValue,
|
||||
value.maxValue,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
}
|
||||
return 0.0f;
|
||||
if (!currentEffect.AfflictionStatValues.TryGetValue(statType, out var appliedStat)) { return 0.0f; }
|
||||
|
||||
return MathHelper.Lerp(appliedStat.MinValue, appliedStat.MaxValue, currentEffect.GetStrengthFactor(this));
|
||||
}
|
||||
|
||||
public bool HasFlag(AbilityFlags flagType)
|
||||
@@ -415,13 +410,16 @@ namespace Barotrauma
|
||||
fluctuationTimer += deltaTime * currentEffect.ScreenEffectFluctuationFrequency;
|
||||
fluctuationTimer %= 1.0f;
|
||||
|
||||
if (currentEffect.StrengthChange < 0) // Reduce diminishing of buffs if boosted
|
||||
if (currentEffect.StrengthChange < 0) // Only apply StrengthDiminish.Multiplier if affliction is being weakened
|
||||
{
|
||||
float durationMultiplier = 1 / (1 + (Prefab.IsBuff ? characterHealth.Character.GetStatValue(StatTypes.BuffDurationMultiplier)
|
||||
: characterHealth.Character.GetStatValue(StatTypes.DebuffDurationMultiplier)));
|
||||
float stat = characterHealth.Character.GetStatValue(
|
||||
Prefab.IsBuff
|
||||
? StatTypes.BuffDurationMultiplier
|
||||
: StatTypes.DebuffDurationMultiplier);
|
||||
|
||||
_strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier * durationMultiplier;
|
||||
float durationMultiplier = 1f / (1f + stat);
|
||||
|
||||
_strength += currentEffect.StrengthChange * deltaTime * StrengthDiminishMultiplier.Value * durationMultiplier;
|
||||
}
|
||||
else if (currentEffect.StrengthChange > 0) // Reduce strengthening of afflictions if resistant
|
||||
{
|
||||
@@ -441,14 +439,14 @@ namespace Barotrauma
|
||||
{
|
||||
amount /= Prefab.GrainBurst;
|
||||
}
|
||||
if (PendingAdditionStrength >= 0)
|
||||
if (PendingGrainEffectStrength >= 0)
|
||||
{
|
||||
AdditionStrength += amount;
|
||||
PendingAdditionStrength -= deltaTime;
|
||||
GrainEffectStrength += amount;
|
||||
PendingGrainEffectStrength -= deltaTime;
|
||||
}
|
||||
else if (AdditionStrength > 0)
|
||||
else if (GrainEffectStrength > 0)
|
||||
{
|
||||
AdditionStrength -= amount;
|
||||
GrainEffectStrength -= amount;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+3
@@ -1,5 +1,8 @@
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A special affliction type that increases the character's Bloodloss affliction with a rate relative to the strength of the bleeding.
|
||||
/// </summary>
|
||||
class AfflictionBleeding : Affliction
|
||||
{
|
||||
public AfflictionBleeding(AfflictionPrefab prefab, float strength) :
|
||||
|
||||
+5
@@ -7,6 +7,10 @@ using Microsoft.Xna.Framework;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A special affliction type that gradually makes the character turn into another type of character.
|
||||
/// See <see cref="AfflictionPrefabHusk"/> for more details.
|
||||
/// </summary>
|
||||
partial class AfflictionHusk : Affliction
|
||||
{
|
||||
public enum InfectionState
|
||||
@@ -63,6 +67,7 @@ namespace Barotrauma
|
||||
private float DormantThreshold => HuskPrefab.DormantThreshold;
|
||||
private float ActiveThreshold => HuskPrefab.ActiveThreshold;
|
||||
private float TransitionThreshold => HuskPrefab.TransitionThreshold;
|
||||
|
||||
private float TransformThresholdOnDeath => HuskPrefab.TransformThresholdOnDeath;
|
||||
|
||||
public AfflictionHusk(AfflictionPrefab prefab, float strength) : base(prefab, strength)
|
||||
|
||||
+481
-111
@@ -6,6 +6,7 @@ using System.Reflection;
|
||||
using System.Xml.Linq;
|
||||
using Barotrauma.Extensions;
|
||||
using System.Collections.Immutable;
|
||||
using Barotrauma.Items.Components;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
@@ -56,8 +57,77 @@ namespace Barotrauma
|
||||
public override void Dispose() { }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AfflictionPrefabHusk is a special type of affliction that has added functionality for husk infection.
|
||||
/// </summary>
|
||||
class AfflictionPrefabHusk : AfflictionPrefab
|
||||
{
|
||||
// Use any of these to define which limb the appendage is attached to.
|
||||
// If multiple are defined, the order of preference is: id, name, type.
|
||||
public readonly int AttachLimbId;
|
||||
public readonly string AttachLimbName;
|
||||
public readonly LimbType AttachLimbType;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum strength at which husk infection will be in the dormant stage.
|
||||
/// It must be less than or equal to ActiveThreshold.
|
||||
/// </summary>
|
||||
public readonly float DormantThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum strength at which husk infection will be in the active stage.
|
||||
/// It must be greater than or equal to DormantThreshold and less than or equal to TransitionThreshold.
|
||||
/// </summary>
|
||||
public readonly float ActiveThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum strength at which husk infection will be in its final stage.
|
||||
/// It must be greater than or equal to ActiveThreshold.
|
||||
/// </summary>
|
||||
public readonly float TransitionThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum strength the affliction must have for the affected character
|
||||
/// to transform into a husk upon death.
|
||||
/// </summary>
|
||||
public readonly float TransformThresholdOnDeath;
|
||||
|
||||
/// <summary>
|
||||
/// The species of husk to convert the affected character to
|
||||
/// once husk infection reaches its final stage.
|
||||
/// </summary>
|
||||
public readonly Identifier HuskedSpeciesName;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, all buffs are transferred to the converted
|
||||
/// character after husk transformation is complete.
|
||||
/// </summary>
|
||||
public readonly bool TransferBuffs;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the affected player will see on-screen messages describing husk infection symptoms
|
||||
/// and affected bots will speak about their current husk infection stage.
|
||||
/// </summary>
|
||||
public readonly bool SendMessages;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, affected characters will have their speech impeded once the affliction
|
||||
/// reaches the dormant stage.
|
||||
/// </summary>
|
||||
public readonly bool CauseSpeechImpediment;
|
||||
|
||||
/// <summary>
|
||||
/// If set to false, affected characters will no longer require air
|
||||
/// once the affliction reaches the active stage.
|
||||
/// </summary>
|
||||
public readonly bool NeedsAir;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, affected players will retain control of their character
|
||||
/// after transforming into a husk.
|
||||
/// </summary>
|
||||
public readonly bool ControlHusk;
|
||||
|
||||
public AfflictionPrefabHusk(ContentXElement element, AfflictionsFile file, Type type = null) : base(element, file, type)
|
||||
{
|
||||
HuskedSpeciesName = element.GetAttributeIdentifier("huskedspeciesname", Identifier.Empty);
|
||||
@@ -78,7 +148,7 @@ namespace Barotrauma
|
||||
{
|
||||
AttachLimbId = attachElement.GetAttributeInt("id", -1);
|
||||
AttachLimbName = attachElement.GetAttributeString("name", null);
|
||||
AttachLimbType = Enum.TryParse(attachElement.GetAttributeString("type", "none"), true, out LimbType limbType) ? limbType : LimbType.None;
|
||||
AttachLimbType = attachElement.GetAttributeEnum("type", LimbType.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -96,174 +166,282 @@ namespace Barotrauma
|
||||
DormantThreshold = element.GetAttributeFloat("dormantthreshold", MaxStrength * 0.5f);
|
||||
ActiveThreshold = element.GetAttributeFloat("activethreshold", MaxStrength * 0.75f);
|
||||
TransitionThreshold = element.GetAttributeFloat("transitionthreshold", MaxStrength);
|
||||
|
||||
if (DormantThreshold > ActiveThreshold)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in \"{Identifier}\": {nameof(DormantThreshold)} is greater than {nameof(ActiveThreshold)} ({DormantThreshold} > {ActiveThreshold})");
|
||||
}
|
||||
if (ActiveThreshold > TransitionThreshold)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in \"{Identifier}\": {nameof(ActiveThreshold)} is greater than {nameof(TransitionThreshold)} ({ActiveThreshold} > {TransitionThreshold})");
|
||||
}
|
||||
|
||||
TransformThresholdOnDeath = element.GetAttributeFloat("transformthresholdondeath", ActiveThreshold);
|
||||
}
|
||||
|
||||
// Use any of these to define which limb the appendage is attached to.
|
||||
// If multiple are defined, the order of preference is: id, name, type.
|
||||
public readonly int AttachLimbId;
|
||||
public readonly string AttachLimbName;
|
||||
public readonly LimbType AttachLimbType;
|
||||
|
||||
public float ActiveThreshold, DormantThreshold, TransitionThreshold;
|
||||
public float TransformThresholdOnDeath;
|
||||
|
||||
public readonly Identifier HuskedSpeciesName;
|
||||
|
||||
public readonly bool TransferBuffs;
|
||||
public readonly bool SendMessages;
|
||||
public readonly bool CauseSpeechImpediment;
|
||||
public readonly bool NeedsAir;
|
||||
public readonly bool ControlHusk;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AfflictionPrefab is a prefab that defines a type of affliction that can be applied to a character.
|
||||
/// There are multiple sub-types of afflictions such as AfflictionPrefabHusk, AfflictionPsychosis and AfflictionBleeding that can be used for additional functionality.
|
||||
///
|
||||
/// When defining a new affliction, the type will be determined by the element name.
|
||||
/// </summary>
|
||||
/// <example>
|
||||
/// <code language="xml">
|
||||
/// <Afflictions>
|
||||
/// <!-- Defines a regular affliction. -->
|
||||
/// <Affliction identifier="mycoolaffliction1" />
|
||||
///
|
||||
/// <!-- Defines an AfflictionPrefabHusk affliction. -->
|
||||
/// <AfflictionPrefabHusk identifier="mycoolaffliction2"/>
|
||||
///
|
||||
/// <!-- Defines an AfflictionBleeding affliction. -->
|
||||
/// <AfflictionBleeding identifier="mycoolaffliction3"/>
|
||||
/// </Afflictions>
|
||||
/// </code>
|
||||
/// </example>
|
||||
class AfflictionPrefab : PrefabWithUintIdentifier
|
||||
{
|
||||
public class Effect
|
||||
/// <summary>
|
||||
/// Effects are the primary way to add functionality to afflictions.
|
||||
/// </summary>
|
||||
/// <doc>
|
||||
/// <Ignore type="SubElement" identifier="AbilityFlag" />
|
||||
/// <SubElement identifier="abilityflag" type="AppliedAbilityFlag">
|
||||
/// Enables the specified flag on the character as long as the effect is active.
|
||||
/// </SubElement>
|
||||
/// <Type identifier="AppliedAbilityFlag">
|
||||
/// <Summary>
|
||||
/// Flag that will be enabled for the character as long as the effect is active.
|
||||
/// <example>
|
||||
/// <code language="xml">
|
||||
/// <Effect minstrength="0" maxstrength="100">
|
||||
/// <!-- Grants pressure immunity to the character while the effect is active. -->
|
||||
/// <AbilityFlag flagtype="ImmuneToPressure" />
|
||||
/// </Effect>
|
||||
/// </code>
|
||||
/// </example>
|
||||
/// </Summary>
|
||||
/// <Field identifier="FlagType" type="AbilityFlags" defaultValue="None">
|
||||
/// Which ability flag to enable.
|
||||
/// </Field>
|
||||
/// </Type>
|
||||
/// </doc>
|
||||
public sealed class Effect
|
||||
{
|
||||
//this effect is applied when the strength is within this range
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Minimum affliction strength required for this effect to be active.")]
|
||||
public float MinStrength { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Maximum affliction strength for which this effect will be active.")]
|
||||
public float MaxStrength { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "The amount of vitality that is lost at this effect's lowest strength.")]
|
||||
public float MinVitalityDecrease { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "The amount of vitality that is lost at this effect's highest strength.")]
|
||||
public float MaxVitalityDecrease { get; private set; }
|
||||
|
||||
//how much the strength of the affliction changes per second
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "How much the affliction's strength changes every second while this effect is active.")]
|
||||
public float StrengthChange { get; private set; }
|
||||
|
||||
[Serialize(false, IsPropertySaveable.No)]
|
||||
[Serialize(false, IsPropertySaveable.No, description:
|
||||
"If set to true, MinVitalityDecrease and MaxVitalityDecrease represent a fraction of the affected character's maximum " +
|
||||
"vitality, with 1 meaning 100%, instead of the same amount for all species.")]
|
||||
public bool MultiplyByMaxVitality { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Blur effect strength at this effect's lowest strength.")]
|
||||
public float MinScreenBlur { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Blur effect strength at this effect's highest strength.")]
|
||||
public float MaxScreenBlur { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Generic distortion effect strength at this effect's lowest strength.")]
|
||||
public float MinScreenDistort { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Generic distortion effect strength at this effect's highest strength.")]
|
||||
public float MaxScreenDistort { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Radial distortion effect strength at this effect's lowest strength.")]
|
||||
public float MinRadialDistort { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Radial distortion effect strength at this effect's highest strength.")]
|
||||
public float MaxRadialDistort { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Chromatic aberration effect strength at this effect's lowest strength.")]
|
||||
public float MinChromaticAberration { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Chromatic aberration effect strength at this effect's highest strength.")]
|
||||
public float MaxChromaticAberration { get; private set; }
|
||||
|
||||
[Serialize("255,255,255,255", IsPropertySaveable.No)]
|
||||
[Serialize("255,255,255,255", IsPropertySaveable.No, description: "Radiation grain effect color.")]
|
||||
public Color GrainColor { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Radiation grain effect strength at this effect's lowest strength.")]
|
||||
public float MinGrainStrength { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description: "Radiation grain effect strength at this effect's highest strength.")]
|
||||
public float MaxGrainStrength { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No, description:
|
||||
"The maximum rate of fluctuation to apply to visual effects caused by this affliction effect. " +
|
||||
"Effective fluctuation is proportional to the affliction's current strength.")]
|
||||
public float ScreenEffectFluctuationFrequency { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description:
|
||||
"Multiplier for the affliction overlay's opacity at this effect's lowest strength. " +
|
||||
"See the list of elements for more details.")]
|
||||
public float MinAfflictionOverlayAlphaMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description:
|
||||
"Multiplier for the affliction overlay's opacity at this effect's highest strength. " +
|
||||
"See the list of elements for more details.")]
|
||||
public float MaxAfflictionOverlayAlphaMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description:
|
||||
"Multiplier for every buff's decay rate at this effect's lowest strength. " +
|
||||
"Only applies to afflictions of class BuffDurationIncrease.")]
|
||||
public float MinBuffMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description:
|
||||
"Multiplier for every buff's decay rate at this effect's highest strength. " +
|
||||
"Only applies to afflictions of class BuffDurationIncrease.")]
|
||||
public float MaxBuffMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Multiplier to apply to the affected character's speed at this effect's lowest strength.")]
|
||||
public float MinSpeedMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Multiplier to apply to the affected character's speed at this effect's highest strength.")]
|
||||
public float MaxSpeedMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Multiplier to apply to all of the affected character's skill levels at this effect's lowest strength.")]
|
||||
public float MinSkillMultiplier { get; private set; }
|
||||
|
||||
[Serialize(1.0f, IsPropertySaveable.No)]
|
||||
[Serialize(1.0f, IsPropertySaveable.No, description: "Multiplier to apply to all of the affected character's skill levels at this effect's highest strength.")]
|
||||
public float MaxSkillMultiplier { get; private set; }
|
||||
|
||||
private readonly Identifier[] resistanceFor;
|
||||
public IReadOnlyList<Identifier> ResistanceFor => resistanceFor;
|
||||
/// <summary>
|
||||
/// A list of identifiers of afflictions that the affected character will be
|
||||
/// resistant to when this effect is active.
|
||||
/// </summary>
|
||||
public readonly ImmutableArray<Identifier> ResistanceFor;
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No,
|
||||
description: "The amount of resistance to the afflictions specified by ResistanceFor to apply at this effect's lowest strength.")]
|
||||
public float MinResistance { get; private set; }
|
||||
|
||||
[Serialize(0.0f, IsPropertySaveable.No)]
|
||||
[Serialize(0.0f, IsPropertySaveable.No,
|
||||
description: "The amount of resistance to the afflictions specified by ResistanceFor to apply at this effect's highest strength.")]
|
||||
public float MaxResistance { get; private set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.No)]
|
||||
[Serialize("", IsPropertySaveable.No, description: "Identifier used by AI to determine conversation lines to say when this effect is active.")]
|
||||
public Identifier DialogFlag { get; private set; }
|
||||
|
||||
[Serialize("", IsPropertySaveable.No)]
|
||||
[Serialize("", IsPropertySaveable.No, description: "Tag that enemy AI may use to target the affected character when this effect is active.")]
|
||||
public Identifier Tag { get; private set; }
|
||||
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No)]
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No,
|
||||
description: "Color to tint the affected character's face with at this effect's lowest strength. The alpha channel is used to determine how much to tint the character's face.")]
|
||||
public Color MinFaceTint { get; private set; }
|
||||
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No)]
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No,
|
||||
description: "Color to tint the affected character's face with at this effect's highest strength. The alpha channel is used to determine how much to tint the character's face.")]
|
||||
public Color MaxFaceTint { get; private set; }
|
||||
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No)]
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No,
|
||||
description: "Color to tint the affected character's entire body with at this effect's lowest strength. The alpha channel is used to determine how much to tint the character.")]
|
||||
public Color MinBodyTint { get; private set; }
|
||||
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No)]
|
||||
[Serialize("0,0,0,0", IsPropertySaveable.No,
|
||||
description: "Color to tint the affected character's entire body with at this effect's highest strength. The alpha channel is used to determine how much to tint the character.")]
|
||||
public Color MaxBodyTint { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Prevents AfflictionHusks with the specified identifier(s) from transforming the character into an AI-controlled character
|
||||
/// StatType that will be applied to the affected character when the effect is active that is proportional to the effect's strength.
|
||||
/// </summary>
|
||||
public Identifier[] BlockTransformation { get; private set; }
|
||||
/// <example>
|
||||
/// <code language="xml">
|
||||
/// <Effect minstrength="0" maxstrength="100">
|
||||
/// <!-- Walking speed will be increased by 10% at strength 0, 20% at 50 and 30% at 100 -->
|
||||
/// <StatValue stattype="WalkingSpeed" minvalue="0.1" maxvalue="0.3" />
|
||||
/// <!-- Maximum health will be increased by 20% regardless of the effect strength -->
|
||||
/// <StatValue stattype="MaximumHealthMultiplier" value="0.2" />
|
||||
/// </Effect>
|
||||
/// </code>
|
||||
/// </example>
|
||||
public readonly struct AppliedStatValue
|
||||
{
|
||||
/// <summary>
|
||||
/// Which StatType to apply
|
||||
/// </summary>
|
||||
public readonly StatTypes StatType;
|
||||
|
||||
public readonly Dictionary<StatTypes, (float minValue, float maxValue)> AfflictionStatValues = new Dictionary<StatTypes, (float minValue, float maxValue)>();
|
||||
public AbilityFlags AfflictionAbilityFlags;
|
||||
/// <summary>
|
||||
/// Minimum value to apply
|
||||
/// </summary>
|
||||
public readonly float MinValue;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum value to apply
|
||||
/// </summary>
|
||||
public readonly float MaxValue;
|
||||
|
||||
/// <summary>
|
||||
/// Constant value to apply, will be ignored if MinValue or MaxValue are set
|
||||
/// </summary>
|
||||
private readonly float Value;
|
||||
|
||||
public AppliedStatValue(ContentXElement element)
|
||||
{
|
||||
Value = element.GetAttributeFloat("value", 0.0f);
|
||||
StatType = element.GetAttributeEnum("stattype", StatTypes.None);
|
||||
MinValue = element.GetAttributeFloat("minvalue", Value);
|
||||
MaxValue = element.GetAttributeFloat("maxvalue", Value);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Prevents AfflictionHusks with the specified identifier(s) from transforming the character into an AI-controlled character.
|
||||
/// </summary>
|
||||
public readonly ImmutableArray<Identifier> BlockTransformation;
|
||||
|
||||
/// <summary>
|
||||
/// StatType that will be applied to the affected character when the effect is active that is proportional to the effect's strength.
|
||||
/// </summary>
|
||||
public readonly ImmutableDictionary<StatTypes, AppliedStatValue> AfflictionStatValues;
|
||||
|
||||
public readonly AbilityFlags AfflictionAbilityFlags;
|
||||
|
||||
//statuseffects applied on the character when the affliction is active
|
||||
public readonly List<StatusEffect> StatusEffects = new List<StatusEffect>();
|
||||
public readonly ImmutableArray<StatusEffect> StatusEffects;
|
||||
|
||||
public Effect(ContentXElement element, string parentDebugName)
|
||||
{
|
||||
SerializableProperty.DeserializeProperties(this, element);
|
||||
|
||||
resistanceFor = element.GetAttributeIdentifierArray("resistancefor", Array.Empty<Identifier>());
|
||||
BlockTransformation = element.GetAttributeIdentifierArray("blocktransformation", Array.Empty<Identifier>());
|
||||
ResistanceFor = element.GetAttributeIdentifierArray("resistancefor", Array.Empty<Identifier>())!.ToImmutableArray();
|
||||
BlockTransformation = element.GetAttributeIdentifierArray("blocktransformation", Array.Empty<Identifier>())!.ToImmutableArray();
|
||||
|
||||
var afflictionStatValues = new Dictionary<StatTypes, AppliedStatValue>();
|
||||
var statusEffects = new List<StatusEffect>();
|
||||
foreach (var subElement in element.Elements())
|
||||
{
|
||||
switch (subElement.Name.ToString().ToLowerInvariant())
|
||||
{
|
||||
case "statuseffect":
|
||||
StatusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
|
||||
statusEffects.Add(StatusEffect.Load(subElement, parentDebugName));
|
||||
break;
|
||||
case "statvalue":
|
||||
var statType = CharacterAbilityGroup.ParseStatType(subElement.GetAttributeString("stattype", ""), parentDebugName);
|
||||
|
||||
float defaultValue = subElement.GetAttributeFloat("value", 0f);
|
||||
float minValue = subElement.GetAttributeFloat("minvalue", defaultValue);
|
||||
float maxValue = subElement.GetAttributeFloat("maxvalue", defaultValue);
|
||||
|
||||
AfflictionStatValues.TryAdd(statType, (minValue, maxValue));
|
||||
var newStatValue = new AppliedStatValue(subElement);
|
||||
afflictionStatValues.Add(newStatValue.StatType, newStatValue);
|
||||
break;
|
||||
case "abilityflag":
|
||||
var flagType = CharacterAbilityGroup.ParseFlagType(subElement.GetAttributeString("flagtype", ""), parentDebugName);
|
||||
AbilityFlags flagType = subElement.GetAttributeEnum("flagtype", AbilityFlags.None);
|
||||
if (flagType is AbilityFlags.None)
|
||||
{
|
||||
DebugConsole.ThrowError($"Error in affliction \"{parentDebugName}\" - invalid ability flag type \"{subElement.GetAttributeString("flagtype", "")}\".");
|
||||
continue;
|
||||
}
|
||||
AfflictionAbilityFlags |= flagType;
|
||||
break;
|
||||
case "affliction":
|
||||
@@ -271,21 +449,77 @@ namespace Barotrauma
|
||||
break;
|
||||
}
|
||||
}
|
||||
AfflictionStatValues = afflictionStatValues.ToImmutableDictionary();
|
||||
StatusEffects = statusEffects.ToImmutableArray();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns 0 if affliction.Strength is MinStrength,
|
||||
/// 1 if affliction.Strength is MaxStrength
|
||||
/// </summary>
|
||||
public float GetStrengthFactor(Affliction affliction) => GetStrengthFactor(affliction.Strength);
|
||||
|
||||
/// <summary>
|
||||
/// Returns 0 if affliction.Strength is MinStrength,
|
||||
/// 1 if affliction.Strength is MaxStrength
|
||||
/// </summary>
|
||||
public float GetStrengthFactor(float strength)
|
||||
=> MathUtils.InverseLerp(
|
||||
MinStrength,
|
||||
MaxStrength,
|
||||
strength);
|
||||
}
|
||||
|
||||
public class Description
|
||||
/// <summary>
|
||||
/// The description element can be used to define descriptions for the affliction which are shown under specific conditions;
|
||||
/// for example a description that only shows to other players or only at certain strength levels.
|
||||
/// </summary>
|
||||
/// <doc>
|
||||
/// <Field identifier="Text" type="string" defaultValue="""">
|
||||
/// Raw text for the description.
|
||||
/// </Field>
|
||||
/// </doc>
|
||||
public sealed class Description
|
||||
{
|
||||
public enum TargetType
|
||||
{
|
||||
/// <summary>
|
||||
/// Everyone can see the description.
|
||||
/// </summary>
|
||||
Any,
|
||||
/// <summary>
|
||||
/// Only the affected character can see the description.
|
||||
/// </summary>
|
||||
Self,
|
||||
/// <summary>
|
||||
/// The affected character cannot see the description but others can.
|
||||
/// </summary>
|
||||
OtherCharacter
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Raw text for the description.
|
||||
/// </summary>
|
||||
public readonly LocalizedString Text;
|
||||
|
||||
/// <summary>
|
||||
/// Text tag used to set the text from the localization files.
|
||||
/// </summary>
|
||||
public readonly Identifier TextTag;
|
||||
public readonly float MinStrength, MaxStrength;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum strength required for the description to be shown.
|
||||
/// </summary>
|
||||
public readonly float MinStrength;
|
||||
|
||||
/// <summary>
|
||||
/// Maximum strength required for the description to be shown.
|
||||
/// </summary>
|
||||
public readonly float MaxStrength;
|
||||
|
||||
/// <summary>
|
||||
/// Who can see the description.
|
||||
/// </summary>
|
||||
public readonly TargetType Target;
|
||||
|
||||
public Description(ContentXElement element, AfflictionPrefab affliction)
|
||||
@@ -315,7 +549,23 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public class PeriodicEffect
|
||||
/// <summary>
|
||||
/// PeriodicEffect applies StatusEffects to the character periodically.
|
||||
/// </summary>
|
||||
/// <doc>
|
||||
/// <SubElement identifier="StatusEffect" type="StatusEffect" />
|
||||
/// <Field identifier="Interval" type="float" defaultValue="1.0">
|
||||
/// How often the status effect is applied in seconds.
|
||||
/// Setting this attribute will set both the min and max interval to the specified value.
|
||||
/// </Field>
|
||||
/// <Field identifier="MinInterval" type="float" defaultValue="1.0">
|
||||
/// Minimum interval between applying the status effect in seconds.
|
||||
/// </Field>
|
||||
/// <Field identifier="MaxInterval" type="float" defaultValue="1.0">
|
||||
/// Maximum interval between applying the status effect in seconds.
|
||||
/// </Field>
|
||||
/// </doc>
|
||||
public sealed class PeriodicEffect
|
||||
{
|
||||
public readonly List<StatusEffect> StatusEffects = new List<StatusEffect>();
|
||||
public readonly float MinInterval, MaxInterval;
|
||||
@@ -368,52 +618,124 @@ namespace Barotrauma
|
||||
|
||||
public static readonly PrefabCollection<AfflictionPrefab> Prefabs = new PrefabCollection<AfflictionPrefab>();
|
||||
|
||||
public override void Dispose() { }
|
||||
|
||||
public static IEnumerable<AfflictionPrefab> List => Prefabs;
|
||||
|
||||
// Arbitrary string that is used to identify the type of the affliction.
|
||||
public readonly Identifier AfflictionType;
|
||||
public override void Dispose() { }
|
||||
|
||||
private readonly ContentXElement configElement;
|
||||
|
||||
//Does the affliction affect a specific limb or the whole character
|
||||
public readonly bool LimbSpecific;
|
||||
|
||||
//If not a limb-specific affliction, which limb is the indicator shown on in the health menu
|
||||
//(e.g. mental health problems on head, lack of oxygen on torso...)
|
||||
public readonly LimbType IndicatorLimb;
|
||||
|
||||
public readonly LocalizedString Name;
|
||||
public readonly Identifier TranslationIdentifier;
|
||||
public readonly bool IsBuff;
|
||||
public readonly bool AffectMachines;
|
||||
public readonly bool HealableInMedicalClinic;
|
||||
public readonly float HealCostMultiplier;
|
||||
public readonly int BaseHealCost;
|
||||
public readonly bool ShowBarInHealthMenu;
|
||||
|
||||
|
||||
public readonly LocalizedString CauseOfDeathDescription, SelfCauseOfDeathDescription;
|
||||
|
||||
private readonly LocalizedString defaultDescription;
|
||||
public readonly ImmutableList<Description> Descriptions;
|
||||
|
||||
/// <summary>
|
||||
/// Arbitrary string that is used to identify the type of the affliction.
|
||||
/// </summary>
|
||||
public readonly Identifier AfflictionType;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the affliction affects individual limbs. Otherwise, it affects the whole character.
|
||||
/// </summary>
|
||||
public readonly bool LimbSpecific;
|
||||
|
||||
/// <summary>
|
||||
/// If the affliction doesn't affect individual limbs, this attribute determines
|
||||
/// where the game will render the affliction's indicator when viewed in the
|
||||
/// in-game health UI.
|
||||
///
|
||||
/// For example, the psychosis indicator is rendered on the head, and low oxygen
|
||||
/// is rendered on the torso.
|
||||
/// </summary>
|
||||
public readonly LimbType IndicatorLimb;
|
||||
|
||||
/// <summary>
|
||||
/// Can be set to the identifier of another affliction to make this affliction
|
||||
/// reuse the same name and description.
|
||||
/// </summary>
|
||||
public readonly Identifier TranslationIdentifier;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, the game will recognize this affliction as a buff.
|
||||
/// This means, among other things, that bots won't attempt to treat it,
|
||||
/// and the health UI will render the affected limb in green rather than red.
|
||||
/// </summary>
|
||||
public readonly bool IsBuff;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, this affliction can affect characters that are marked as
|
||||
/// machines, such as the Fractal Guardian.
|
||||
/// </summary>
|
||||
public readonly bool AffectMachines;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, this affliction can be healed at the medical clinic.
|
||||
/// </summary>
|
||||
/// <doc>
|
||||
/// <override type="DefaultValue">
|
||||
/// false if the affliction is a buff or has the type "geneticmaterialbuff" or "geneticmaterialdebuff", true otherwise.
|
||||
/// </override>
|
||||
/// </doc>
|
||||
public readonly bool HealableInMedicalClinic;
|
||||
|
||||
/// <summary>
|
||||
/// How much each unit of this affliction's strength will add
|
||||
/// to the cost of healing at the medical clinic.
|
||||
/// </summary>
|
||||
public readonly float HealCostMultiplier;
|
||||
|
||||
/// <summary>
|
||||
/// The minimum cost of healing this affliction at the medical clinic.
|
||||
/// </summary>
|
||||
public readonly int BaseHealCost;
|
||||
|
||||
/// <summary>
|
||||
/// If set to false, the health UI will not show the strength of the affliction
|
||||
/// as a bar under its indicator.
|
||||
/// </summary>
|
||||
public readonly bool ShowBarInHealthMenu;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, this affliction's icon will be hidden from the HUD after 5 seconds.
|
||||
/// </summary>
|
||||
public readonly bool HideIconAfterDelay;
|
||||
|
||||
//how high the strength has to be for the affliction to take affect
|
||||
/// <summary>
|
||||
/// How high the strength has to be for the affliction to take effect
|
||||
/// </summary>
|
||||
public readonly float ActivationThreshold = 0.0f;
|
||||
//how high the strength has to be for the affliction icon to be shown in the UI
|
||||
|
||||
/// <summary>
|
||||
/// How high the strength has to be for the affliction icon to be shown in the UI
|
||||
/// </summary>
|
||||
public readonly float ShowIconThreshold = 0.05f;
|
||||
//how high the strength has to be for the affliction icon to be shown to others with a health scanner or via the health interface
|
||||
|
||||
/// <summary>
|
||||
/// How high the strength has to be for the affliction icon to be shown to others with a health scanner or via the health interface
|
||||
/// </summary>
|
||||
public readonly float ShowIconToOthersThreshold = 0.05f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum strength this affliction can have.
|
||||
/// </summary>
|
||||
public readonly float MaxStrength = 100.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The strength of the radiation grain effect to apply when the strength of this affliction increases.
|
||||
/// </summary>
|
||||
public readonly float GrainBurst;
|
||||
|
||||
//how high the strength has to be for the affliction icon to be shown with a health scanner
|
||||
/// <summary>
|
||||
/// How high the strength has to be for the affliction icon to be shown with a health scanner
|
||||
/// </summary>
|
||||
public readonly float ShowInHealthScannerThreshold = 0.05f;
|
||||
|
||||
//how strong the affliction needs to be before bots attempt to treat it
|
||||
/// <summary>
|
||||
/// How strong the affliction needs to be before bots attempt to treat it.
|
||||
/// Also effects when the affliction is shown in the suitable treatments list.
|
||||
/// </summary>
|
||||
public readonly float TreatmentThreshold = 5.0f;
|
||||
|
||||
/// <summary>
|
||||
@@ -422,43 +744,84 @@ namespace Barotrauma
|
||||
public ImmutableHashSet<Identifier> IgnoreTreatmentIfAfflictedBy;
|
||||
|
||||
/// <summary>
|
||||
/// The affliction is automatically removed after this time. 0 = unlimited
|
||||
/// The duration of the affliction, in seconds. If set to 0, the affliction does not expire.
|
||||
/// </summary>
|
||||
public readonly float Duration;
|
||||
|
||||
//how much karma changes when a player applies this affliction to someone (per strength of the affliction)
|
||||
/// <summary>
|
||||
/// How much karma changes when a player applies this affliction to someone (per strength of the affliction)
|
||||
/// </summary>
|
||||
public float KarmaChangeOnApplied;
|
||||
|
||||
/// <summary>
|
||||
/// Opacity of the burn effect (darker tint) on limbs affected by this affliction. 1 = full strength.
|
||||
/// </summary>
|
||||
public readonly float BurnOverlayAlpha;
|
||||
|
||||
/// <summary>
|
||||
/// Opacity of the bloody damage overlay on limbs affected by this affliction. 1 = full strength.
|
||||
/// </summary>
|
||||
public readonly float DamageOverlayAlpha;
|
||||
|
||||
//steam achievement given when the controlled character receives the affliction
|
||||
/// Steam achievement given when the controlled character receives the affliction.
|
||||
/// </summary>
|
||||
public readonly Identifier AchievementOnReceived;
|
||||
|
||||
//steam achievement given when the affliction is removed from the controlled character
|
||||
/// <summary>
|
||||
/// Steam achievement given when the affliction is removed from the controlled character.
|
||||
/// </summary>
|
||||
public readonly Identifier AchievementOnRemoved;
|
||||
|
||||
public readonly Sprite Icon;
|
||||
/// <summary>
|
||||
/// A gradient that defines which color to render this affliction's icon
|
||||
/// with, based on the affliction's current strength.
|
||||
/// </summary>
|
||||
public readonly Color[] IconColors;
|
||||
|
||||
public readonly Sprite AfflictionOverlay;
|
||||
/// <summary>
|
||||
/// If set to true and the affliction has an AfflictionOverlay element, the overlay's opacity will be strictly proportional to its strength.
|
||||
/// Otherwise, the overlay's opacity will be determined based on its activation threshold and effects.
|
||||
/// </summary>
|
||||
public readonly bool AfflictionOverlayAlphaIsLinear;
|
||||
|
||||
/// <summary>
|
||||
/// If set to true, this affliction will not persist between rounds.
|
||||
/// </summary>
|
||||
public readonly bool ResetBetweenRounds;
|
||||
|
||||
/// <summary>
|
||||
/// Should damage particles be emitted when a character receives this affliction?
|
||||
/// Only relevant if the affliction is of the type "bleeding" or "damage".
|
||||
/// </summary>
|
||||
public readonly bool DamageParticles;
|
||||
|
||||
/// <summary>
|
||||
/// An arbitrary modifier that affects how much medical skill is increased when you apply the affliction on a target.
|
||||
/// If the affliction causes damage or is of type poison or paralysis, the skill is increased only when the target is hostile.
|
||||
/// If the affliction is of type buff, the skill is increased only when the target is friendly.
|
||||
/// If the affliction causes damage or is of the 'poison' or 'paralysis' type, the skill is increased only when the target is hostile.
|
||||
/// If the affliction is of the 'buff' type, the skill is increased only when the target is friendly.
|
||||
/// </summary>
|
||||
public readonly float MedicalSkillGain;
|
||||
|
||||
/// <summary>
|
||||
/// An arbitrary modifier that affects how much weapons skill is increased when you apply the affliction on a target.
|
||||
/// The skill is increased only when the target is hostile.
|
||||
/// </summary>
|
||||
public readonly float WeaponsSkillGain;
|
||||
|
||||
/// <summary>
|
||||
/// A list of species this affliction is allowed to affect.
|
||||
/// </summary>
|
||||
public Identifier[] TargetSpecies { get; protected set; }
|
||||
|
||||
/// <summary>
|
||||
/// Effects to apply at various strength levels.
|
||||
/// Only one effect can be applied at any given moment, so their ranges should be defined with no overlap.
|
||||
/// </summary>
|
||||
private readonly List<Effect> effects = new List<Effect>();
|
||||
|
||||
/// <summary>
|
||||
/// PeriodicEffect applies StatusEffects to the character periodically.
|
||||
/// </summary>
|
||||
private readonly List<PeriodicEffect> periodicEffects = new List<PeriodicEffect>();
|
||||
|
||||
public IEnumerable<Effect> Effects => effects;
|
||||
@@ -467,9 +830,16 @@ namespace Barotrauma
|
||||
|
||||
private readonly ConstructorInfo constructor;
|
||||
|
||||
public Identifier[] TargetSpecies { get; protected set; }
|
||||
/// <summary>
|
||||
/// An icon that’s used in the UI to represent this affliction.
|
||||
/// </summary>
|
||||
public readonly Sprite Icon;
|
||||
|
||||
public readonly bool ResetBetweenRounds;
|
||||
/// <summary>
|
||||
/// A sprite that covers the affected player's entire screen when this affliction is active.
|
||||
/// Its opacity is controlled by the active effect's MinAfflictionOverlayAlphaMultiplier and MaxAfflictionOverlayAlphaMultiplier
|
||||
/// </summary>
|
||||
public readonly Sprite AfflictionOverlay;
|
||||
|
||||
public IEnumerable<KeyValuePair<Identifier, float>> TreatmentSuitability
|
||||
{
|
||||
@@ -497,7 +867,7 @@ namespace Barotrauma
|
||||
if (!string.IsNullOrEmpty(fallbackName))
|
||||
{
|
||||
Name = Name.Fallback(fallbackName);
|
||||
}
|
||||
}
|
||||
defaultDescription = TextManager.Get($"AfflictionDescription.{TranslationIdentifier}");
|
||||
string fallbackDescription = element.GetAttributeString("description", "");
|
||||
if (!string.IsNullOrEmpty(fallbackDescription))
|
||||
|
||||
+3
@@ -1,5 +1,8 @@
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A special affliction type that makes the character see and hear things that aren't there.
|
||||
/// </summary>
|
||||
partial class AfflictionPsychosis : Affliction
|
||||
{
|
||||
|
||||
|
||||
+4
-3
@@ -1,11 +1,12 @@
|
||||
using Microsoft.Xna.Framework;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A special affliction type that periodically inverts the character's controls and stuns the character.
|
||||
/// The frequency and duration of the effects increases the higher the strength of the affliction is.
|
||||
/// </summary>
|
||||
class AfflictionSpaceHerpes : Affliction
|
||||
{
|
||||
private float invertControlsCooldown = 60.0f;
|
||||
|
||||
+11
-7
@@ -3,6 +3,10 @@ using System;
|
||||
|
||||
namespace Barotrauma
|
||||
{
|
||||
/// <summary>
|
||||
/// A special affliction type that increases the duration of buffs (afflictions of the type "buff"). The increase is defined using the
|
||||
/// <see cref="AfflictionPrefab.Effect.MinBuffMultiplier"/> and <see cref="AfflictionPrefab.Effect.MaxBuffMultiplier"/> attributes of the affliction effect.
|
||||
/// </summary>
|
||||
class BuffDurationIncrease : Affliction
|
||||
{
|
||||
public BuffDurationIncrease(AfflictionPrefab prefab, float strength) : base(prefab, strength)
|
||||
@@ -20,9 +24,9 @@ namespace Barotrauma
|
||||
{
|
||||
foreach (Affliction affliction in afflictions)
|
||||
{
|
||||
if (!affliction.Prefab.IsBuff || affliction == this || affliction.MultiplierSource != this) { continue; }
|
||||
affliction.MultiplierSource = null;
|
||||
affliction.StrengthDiminishMultiplier = 1f;
|
||||
if (!affliction.Prefab.IsBuff || affliction == this || affliction.StrengthDiminishMultiplier.Source != this) { continue; }
|
||||
affliction.StrengthDiminishMultiplier.Source = null;
|
||||
affliction.StrengthDiminishMultiplier.Value = 1f;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -31,10 +35,10 @@ namespace Barotrauma
|
||||
{
|
||||
if (!affliction.Prefab.IsBuff || affliction == this) { continue; }
|
||||
float multiplier = GetDiminishMultiplier();
|
||||
if (affliction.StrengthDiminishMultiplier < multiplier && affliction.MultiplierSource != this) { continue; }
|
||||
if (affliction.StrengthDiminishMultiplier.Value < multiplier && affliction.StrengthDiminishMultiplier.Source != this) { continue; }
|
||||
|
||||
affliction.MultiplierSource = this;
|
||||
affliction.StrengthDiminishMultiplier = multiplier;
|
||||
affliction.StrengthDiminishMultiplier.Source = this;
|
||||
affliction.StrengthDiminishMultiplier.Value = multiplier;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -48,7 +52,7 @@ namespace Barotrauma
|
||||
float multiplier = MathHelper.Lerp(
|
||||
currentEffect.MinBuffMultiplier,
|
||||
currentEffect.MaxBuffMultiplier,
|
||||
(Strength - currentEffect.MinStrength) / (currentEffect.MaxStrength - currentEffect.MinStrength));
|
||||
currentEffect.GetStrengthFactor(this));
|
||||
return 1.0f / Math.Max(multiplier, 0.001f);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public Color DefaultFaceTint = Color.TransparentBlack;
|
||||
public static readonly Color DefaultFaceTint = Color.TransparentBlack;
|
||||
|
||||
public Color FaceTint
|
||||
{
|
||||
@@ -449,7 +449,11 @@ namespace Barotrauma
|
||||
var affliction = kvp.Key;
|
||||
resistance += affliction.GetResistance(afflictionPrefab.Identifier);
|
||||
}
|
||||
return 1 - ((1 - resistance) * Character.GetAbilityResistance(afflictionPrefab));
|
||||
|
||||
resistance = 1 - ((1 - resistance) * Character.GetAbilityResistance(afflictionPrefab));
|
||||
if (resistance > 1f) { resistance = 1f; }
|
||||
|
||||
return resistance;
|
||||
}
|
||||
|
||||
public float GetStatValue(StatTypes statType)
|
||||
@@ -1151,16 +1155,14 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerable<Identifier> GetActiveAfflictionTags() => GetActiveAfflictionTags(afflictions.Keys);
|
||||
|
||||
private readonly HashSet<Identifier> afflictionTags = new HashSet<Identifier>();
|
||||
public IEnumerable<Identifier> GetActiveAfflictionTags(IEnumerable<Affliction> afflictions)
|
||||
public IEnumerable<Identifier> GetActiveAfflictionTags()
|
||||
{
|
||||
afflictionTags.Clear();
|
||||
foreach (Affliction affliction in afflictions)
|
||||
foreach (Affliction affliction in afflictions.Keys)
|
||||
{
|
||||
var currentEffect = affliction.GetActiveEffect();
|
||||
if (currentEffect != null && !currentEffect.Tag.IsEmpty)
|
||||
if (currentEffect is { Tag.IsEmpty: false })
|
||||
{
|
||||
afflictionTags.Add(currentEffect.Tag);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user