Merge branch 'master' of https://github.com/Regalis11/Barotrauma into develop
This commit is contained in:
+24
-5
@@ -19,6 +19,10 @@ namespace Barotrauma
|
||||
|
||||
private float fluctuationTimer;
|
||||
|
||||
private AfflictionPrefab.Effect activeEffect;
|
||||
private float prevActiveEffectStrength;
|
||||
protected bool activeEffectDirty = true;
|
||||
|
||||
protected float _strength;
|
||||
|
||||
[Serialize(0f, IsPropertySaveable.Yes), Editable]
|
||||
@@ -46,6 +50,7 @@ namespace Barotrauma
|
||||
Duration = Prefab.Duration;
|
||||
}
|
||||
_strength = newValue;
|
||||
activeEffectDirty = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,7 +152,16 @@ namespace Barotrauma
|
||||
MathHelper.Clamp((int)Math.Floor(strength / maxStrength * strengthTexts.Length), 0, strengthTexts.Length - 1)];
|
||||
}
|
||||
|
||||
public AfflictionPrefab.Effect GetActiveEffect() => Prefab.GetActiveEffect(Strength);
|
||||
public AfflictionPrefab.Effect GetActiveEffect()
|
||||
{
|
||||
if (activeEffectDirty)
|
||||
{
|
||||
activeEffect = Prefab.GetActiveEffect(_strength);
|
||||
prevActiveEffectStrength = _strength;
|
||||
activeEffectDirty = false;
|
||||
}
|
||||
return activeEffect;
|
||||
}
|
||||
|
||||
public float GetVitalityDecrease(CharacterHealth characterHealth)
|
||||
{
|
||||
@@ -158,7 +172,7 @@ namespace Barotrauma
|
||||
{
|
||||
if (strength < Prefab.ActivationThreshold) { return 0.0f; }
|
||||
strength = MathHelper.Clamp(strength, 0.0f, Prefab.MaxStrength);
|
||||
AfflictionPrefab.Effect currentEffect = Prefab.GetActiveEffect(strength);
|
||||
AfflictionPrefab.Effect currentEffect = GetActiveEffect();
|
||||
if (currentEffect == null) { return 0.0f; }
|
||||
if (currentEffect.MaxStrength - currentEffect.MinStrength <= 0.0f) { return 0.0f; }
|
||||
|
||||
@@ -349,7 +363,7 @@ namespace Barotrauma
|
||||
|
||||
public float GetStatValue(StatTypes statType)
|
||||
{
|
||||
if (!(GetViableEffect() is AfflictionPrefab.Effect currentEffect)) { return 0.0f; }
|
||||
if (GetViableEffect() is not AfflictionPrefab.Effect currentEffect) { return 0.0f; }
|
||||
|
||||
if (currentEffect.AfflictionStatValues.TryGetValue(statType, out var value))
|
||||
{
|
||||
@@ -363,7 +377,7 @@ namespace Barotrauma
|
||||
|
||||
public bool HasFlag(AbilityFlags flagType)
|
||||
{
|
||||
if (!(GetViableEffect() is AfflictionPrefab.Effect currentEffect)) { return false; }
|
||||
if (GetViableEffect() is not AfflictionPrefab.Effect currentEffect) { return false; }
|
||||
return currentEffect.AfflictionAbilityFlags.HasFlag(flagType);
|
||||
}
|
||||
|
||||
@@ -415,6 +429,7 @@ namespace Barotrauma
|
||||
}
|
||||
// Don't use the property, because it's virtual and some afflictions like husk overload it for external use.
|
||||
_strength = MathHelper.Clamp(_strength, 0.0f, Prefab.MaxStrength);
|
||||
activeEffectDirty |= !MathUtils.NearlyEqual(prevActiveEffectStrength, _strength);
|
||||
|
||||
foreach (StatusEffect statusEffect in currentEffect.StatusEffects)
|
||||
{
|
||||
@@ -445,7 +460,10 @@ namespace Barotrauma
|
||||
var currentEffect = GetActiveEffect();
|
||||
if (currentEffect != null)
|
||||
{
|
||||
currentEffect.StatusEffects.ForEach(se => ApplyStatusEffect(type, se, deltaTime, characterHealth, targetLimb));
|
||||
foreach (var statusEffect in currentEffect.StatusEffects)
|
||||
{
|
||||
ApplyStatusEffect(type, statusEffect, deltaTime, characterHealth, targetLimb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -484,6 +502,7 @@ namespace Barotrauma
|
||||
{
|
||||
_nonClampedStrength = strength;
|
||||
_strength = _nonClampedStrength;
|
||||
activeEffectDirty |= !MathUtils.NearlyEqual(_strength, prevActiveEffectStrength);
|
||||
}
|
||||
|
||||
public bool ShouldShowIcon(Character afflictedCharacter)
|
||||
|
||||
+4
-2
@@ -22,7 +22,7 @@ namespace Barotrauma
|
||||
|
||||
private Character character;
|
||||
|
||||
private bool stun = true;
|
||||
private bool stun = false;
|
||||
|
||||
private readonly List<Affliction> huskInfection = new List<Affliction>();
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Barotrauma
|
||||
DeactivateHusk();
|
||||
highestStrength = 0;
|
||||
}
|
||||
activeEffectDirty = true;
|
||||
}
|
||||
}
|
||||
private float highestStrength;
|
||||
@@ -216,7 +217,8 @@ namespace Barotrauma
|
||||
private void DeactivateHusk()
|
||||
{
|
||||
if (character?.AnimController == null || character.Removed) { return; }
|
||||
if (Prefab is AfflictionPrefabHusk { NeedsAir: false })
|
||||
if (Prefab is AfflictionPrefabHusk { NeedsAir: false } &&
|
||||
!character.CharacterHealth.GetAllAfflictions().Any(a => a != this && a.Prefab is AfflictionPrefabHusk { NeedsAir: false }))
|
||||
{
|
||||
character.NeedsAir = character.Params.MainElement.GetAttributeBool("needsair", false);
|
||||
}
|
||||
|
||||
+32
-7
@@ -68,7 +68,6 @@ namespace Barotrauma
|
||||
}
|
||||
// Remove "[speciesname]" for backward support (we don't use it anymore)
|
||||
HuskedSpeciesName = HuskedSpeciesName.Remove("[speciesname]").ToIdentifier();
|
||||
TargetSpecies = element.GetAttributeIdentifierArray("targets", Array.Empty<Identifier>(), trim: true);
|
||||
if (TargetSpecies.Length == 0)
|
||||
{
|
||||
DebugConsole.NewMessage($"No 'targets' defined for the husk affliction ({Identifier}) in {element}", Color.Orange);
|
||||
@@ -110,7 +109,6 @@ namespace Barotrauma
|
||||
public float TransformThresholdOnDeath;
|
||||
|
||||
public readonly Identifier HuskedSpeciesName;
|
||||
public readonly Identifier[] TargetSpecies;
|
||||
|
||||
public readonly bool TransferBuffs;
|
||||
public readonly bool SendMessages;
|
||||
@@ -344,17 +342,30 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public static readonly Identifier DamageType = "damage".ToIdentifier();
|
||||
public static readonly Identifier BurnType = "burn".ToIdentifier();
|
||||
public static readonly Identifier BleedingType = "bleeding".ToIdentifier();
|
||||
public static readonly Identifier ParalysisType = "paralysis".ToIdentifier();
|
||||
public static readonly Identifier PoisonType = "poison".ToIdentifier();
|
||||
public static readonly Identifier StunType = "stun".ToIdentifier();
|
||||
public static readonly Identifier EMPType = "emp".ToIdentifier();
|
||||
public static readonly Identifier SpaceHerpesType = "spaceherpes".ToIdentifier();
|
||||
public static readonly Identifier AlienInfectedType = "alieninfected".ToIdentifier();
|
||||
public static readonly Identifier InvertControlsType = "invertcontrols".ToIdentifier();
|
||||
public static readonly Identifier HuskInfectionType = "huskinfection".ToIdentifier();
|
||||
|
||||
public static AfflictionPrefab InternalDamage => Prefabs["internaldamage"];
|
||||
public static AfflictionPrefab BiteWounds => Prefabs["bitewounds"];
|
||||
public static AfflictionPrefab ImpactDamage => Prefabs["blunttrauma"];
|
||||
public static AfflictionPrefab Bleeding => Prefabs["bleeding"];
|
||||
public static AfflictionPrefab Burn => Prefabs["burn"];
|
||||
public static AfflictionPrefab Bleeding => Prefabs[BleedingType];
|
||||
public static AfflictionPrefab Burn => Prefabs[BurnType];
|
||||
public static AfflictionPrefab OxygenLow => Prefabs["oxygenlow"];
|
||||
public static AfflictionPrefab Bloodloss => Prefabs["bloodloss"];
|
||||
public static AfflictionPrefab Pressure => Prefabs["pressure"];
|
||||
public static AfflictionPrefab Stun => Prefabs["stun"];
|
||||
public static AfflictionPrefab Stun => Prefabs[StunType];
|
||||
public static AfflictionPrefab RadiationSickness => Prefabs["radiationsickness"];
|
||||
|
||||
|
||||
public static readonly PrefabCollection<AfflictionPrefab> Prefabs = new PrefabCollection<AfflictionPrefab>();
|
||||
|
||||
public override void Dispose() { }
|
||||
@@ -421,6 +432,9 @@ namespace Barotrauma
|
||||
public readonly float BurnOverlayAlpha;
|
||||
public readonly float DamageOverlayAlpha;
|
||||
|
||||
//steam achievement given when the controlled character receives the affliction
|
||||
public readonly Identifier AchievementOnReceived;
|
||||
|
||||
//steam achievement given when the affliction is removed from the controlled character
|
||||
public readonly Identifier AchievementOnRemoved;
|
||||
|
||||
@@ -453,6 +467,8 @@ namespace Barotrauma
|
||||
|
||||
private readonly ConstructorInfo constructor;
|
||||
|
||||
public Identifier[] TargetSpecies { get; protected set; }
|
||||
|
||||
public readonly bool ResetBetweenRounds;
|
||||
|
||||
public IEnumerable<KeyValuePair<Identifier, float>> TreatmentSuitability
|
||||
@@ -536,13 +552,22 @@ namespace Barotrauma
|
||||
|
||||
KarmaChangeOnApplied = element.GetAttributeFloat(nameof(KarmaChangeOnApplied), 0.0f);
|
||||
|
||||
CauseOfDeathDescription = TextManager.Get($"AfflictionCauseOfDeath.{TranslationIdentifier}").Fallback(element.GetAttributeString("causeofdeathdescription", ""));
|
||||
SelfCauseOfDeathDescription = TextManager.Get($"AfflictionCauseOfDeathSelf.{TranslationIdentifier}").Fallback(element.GetAttributeString("selfcauseofdeathdescription", ""));
|
||||
CauseOfDeathDescription =
|
||||
TextManager.Get($"AfflictionCauseOfDeath.{TranslationIdentifier}")
|
||||
.Fallback(TextManager.Get(element.GetAttributeString("causeofdeathdescription", "")))
|
||||
.Fallback(element.GetAttributeString("causeofdeathdescription", ""));
|
||||
SelfCauseOfDeathDescription =
|
||||
TextManager.Get($"AfflictionCauseOfDeathSelf.{TranslationIdentifier}")
|
||||
.Fallback(TextManager.Get(element.GetAttributeString("selfcauseofdeathdescription", "")))
|
||||
.Fallback(element.GetAttributeString("selfcauseofdeathdescription", ""));
|
||||
|
||||
IconColors = element.GetAttributeColorArray(nameof(IconColors), null);
|
||||
AfflictionOverlayAlphaIsLinear = element.GetAttributeBool(nameof(AfflictionOverlayAlphaIsLinear), false);
|
||||
AchievementOnReceived = element.GetAttributeIdentifier(nameof(AchievementOnReceived), "");
|
||||
AchievementOnRemoved = element.GetAttributeIdentifier(nameof(AchievementOnRemoved), "");
|
||||
|
||||
TargetSpecies = element.GetAttributeIdentifierArray("targets", Array.Empty<Identifier>(), trim: true);
|
||||
|
||||
ResetBetweenRounds = element.GetAttributeBool("resetbetweenrounds", false);
|
||||
|
||||
DamageParticles = element.GetAttributeBool(nameof(DamageParticles), true);
|
||||
|
||||
@@ -344,12 +344,12 @@ namespace Barotrauma
|
||||
return null;
|
||||
}
|
||||
|
||||
public T GetAffliction<T>(string identifier, bool allowLimbAfflictions = true) where T : Affliction
|
||||
public T GetAffliction<T>(Identifier identifier, bool allowLimbAfflictions = true) where T : Affliction
|
||||
{
|
||||
return GetAffliction(identifier, allowLimbAfflictions) as T;
|
||||
}
|
||||
|
||||
public Affliction GetAffliction(string identifier, Limb limb)
|
||||
public Affliction GetAffliction(Identifier identifier, Limb limb)
|
||||
{
|
||||
if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count)
|
||||
{
|
||||
@@ -385,7 +385,7 @@ namespace Barotrauma
|
||||
/// <param name="limb">The limb the affliction is attached to</param>
|
||||
/// <param name="requireLimbSpecific">Does the affliction have to be attached to only the specific limb.
|
||||
/// Most monsters for example don't have separate healths for different limbs, essentially meaning that every affliction is applied to every limb.</param>
|
||||
public float GetAfflictionStrength(string afflictionType, Limb limb, bool requireLimbSpecific)
|
||||
public float GetAfflictionStrength(Identifier afflictionType, Limb limb, bool requireLimbSpecific)
|
||||
{
|
||||
if (requireLimbSpecific && limbHealths.Count == 1) { return 0.0f; }
|
||||
|
||||
@@ -406,7 +406,7 @@ namespace Barotrauma
|
||||
return strength;
|
||||
}
|
||||
|
||||
public float GetAfflictionStrength(string afflictionType, bool allowLimbAfflictions = true)
|
||||
public float GetAfflictionStrength(Identifier afflictionType, bool allowLimbAfflictions = true)
|
||||
{
|
||||
float strength = 0.0f;
|
||||
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
|
||||
@@ -489,16 +489,19 @@ namespace Barotrauma
|
||||
ReduceMatchingAfflictions(amount, treatmentAction);
|
||||
}
|
||||
|
||||
public void ReduceAfflictionOnAllLimbs(Identifier affliction, float amount, ActionType? treatmentAction = null)
|
||||
public void ReduceAfflictionOnAllLimbs(Identifier afflictionIdOrType, float amount, ActionType? treatmentAction = null)
|
||||
{
|
||||
if (affliction.IsEmpty) { throw new ArgumentException($"{nameof(affliction)} is empty"); }
|
||||
|
||||
if (afflictionIdOrType.IsEmpty) { throw new ArgumentException($"{nameof(afflictionIdOrType)} is empty"); }
|
||||
|
||||
matchingAfflictions.Clear();
|
||||
matchingAfflictions.AddRange(afflictions.Keys);
|
||||
matchingAfflictions.RemoveAll(a =>
|
||||
a.Prefab.Identifier != affliction &&
|
||||
a.Prefab.AfflictionType != affliction);
|
||||
|
||||
foreach (var affliction in afflictions)
|
||||
{
|
||||
if (affliction.Key.Prefab.Identifier == afflictionIdOrType || affliction.Key.Prefab.AfflictionType == afflictionIdOrType)
|
||||
{
|
||||
matchingAfflictions.Add(affliction.Key);
|
||||
}
|
||||
}
|
||||
|
||||
ReduceMatchingAfflictions(amount, treatmentAction);
|
||||
}
|
||||
|
||||
@@ -515,18 +518,21 @@ namespace Barotrauma
|
||||
ReduceMatchingAfflictions(amount, treatmentAction);
|
||||
}
|
||||
|
||||
public void ReduceAfflictionOnLimb(Limb targetLimb, Identifier affliction, float amount, ActionType? treatmentAction = null)
|
||||
public void ReduceAfflictionOnLimb(Limb targetLimb, Identifier afflictionIdOrType, float amount, ActionType? treatmentAction = null)
|
||||
{
|
||||
if (affliction.IsEmpty) { throw new ArgumentException($"{nameof(affliction)} is empty"); }
|
||||
if (afflictionIdOrType.IsEmpty) { throw new ArgumentException($"{nameof(afflictionIdOrType)} is empty"); }
|
||||
if (targetLimb is null) { throw new ArgumentNullException(nameof(targetLimb)); }
|
||||
|
||||
|
||||
matchingAfflictions.Clear();
|
||||
matchingAfflictions.AddRange(GetAfflictionsForLimb(targetLimb));
|
||||
|
||||
matchingAfflictions.RemoveAll(a =>
|
||||
a.Prefab.Identifier != affliction &&
|
||||
a.Prefab.AfflictionType != affliction);
|
||||
|
||||
var targetLimbHealth = limbHealths[targetLimb.HealthIndex];
|
||||
foreach (var affliction in afflictions)
|
||||
{
|
||||
if ((affliction.Key.Prefab.Identifier == afflictionIdOrType || affliction.Key.Prefab.AfflictionType == afflictionIdOrType) &&
|
||||
affliction.Value == targetLimbHealth)
|
||||
{
|
||||
matchingAfflictions.Add(affliction.Key);
|
||||
}
|
||||
}
|
||||
ReduceMatchingAfflictions(amount, treatmentAction);
|
||||
}
|
||||
|
||||
@@ -633,7 +639,7 @@ namespace Barotrauma
|
||||
KillIfOutOfVitality();
|
||||
}
|
||||
|
||||
public float GetLimbDamage(Limb limb, string afflictionType = null)
|
||||
public float GetLimbDamage(Limb limb, Identifier afflictionType)
|
||||
{
|
||||
float damageStrength;
|
||||
if (limb.IsSevered)
|
||||
@@ -646,16 +652,16 @@ namespace Barotrauma
|
||||
// Therefore with e.g. 80 health, the max damage per limb would be 40.
|
||||
// Having at least 40 damage on both legs would cause maximum limping.
|
||||
float max = MaxVitality / 2;
|
||||
if (string.IsNullOrEmpty(afflictionType))
|
||||
if (afflictionType.IsEmpty)
|
||||
{
|
||||
float damage = GetAfflictionStrength("damage", limb, true);
|
||||
float bleeding = GetAfflictionStrength("bleeding", limb, true);
|
||||
float burn = GetAfflictionStrength("burn", limb, true);
|
||||
float damage = GetAfflictionStrength(AfflictionPrefab.DamageType, limb, true);
|
||||
float bleeding = GetAfflictionStrength(AfflictionPrefab.BleedingType, limb, true);
|
||||
float burn = GetAfflictionStrength(AfflictionPrefab.BurnType, limb, true);
|
||||
damageStrength = Math.Min(damage + bleeding + burn, max);
|
||||
}
|
||||
else
|
||||
{
|
||||
damageStrength = Math.Min(GetAfflictionStrength("damage", limb, true), max);
|
||||
damageStrength = Math.Min(GetAfflictionStrength(afflictionType, limb, true), max);
|
||||
}
|
||||
return damageStrength / max;
|
||||
}
|
||||
@@ -712,22 +718,17 @@ namespace Barotrauma
|
||||
if (Character.Params.IsMachine && !newAffliction.Prefab.AffectMachines) { return; }
|
||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||
if (Character.Params.Health.StunImmunity && newAffliction.Prefab.AfflictionType == "stun")
|
||||
if (Character.Params.Health.StunImmunity && newAffliction.Prefab.AfflictionType == AfflictionPrefab.StunType)
|
||||
{
|
||||
if (Character.EmpVulnerability <= 0 || GetAfflictionStrength("emp", allowLimbAfflictions: false) <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Character.Params.Health.PoisonImmunity && (newAffliction.Prefab.AfflictionType == "poison" || newAffliction.Prefab.AfflictionType == "paralysis")) { return; }
|
||||
if (Character.EmpVulnerability <= 0 && newAffliction.Prefab.AfflictionType == "emp") { return; }
|
||||
if (newAffliction.Prefab is AfflictionPrefabHusk huskPrefab)
|
||||
{
|
||||
if (huskPrefab.TargetSpecies.None(s => s == Character.SpeciesName))
|
||||
if (Character.EmpVulnerability <= 0 || GetAfflictionStrength(AfflictionPrefab.EMPType, allowLimbAfflictions: false) <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (Character.Params.Health.PoisonImmunity &&
|
||||
(newAffliction.Prefab.AfflictionType == AfflictionPrefab.PoisonType || newAffliction.Prefab.AfflictionType == AfflictionPrefab.ParalysisType)) { return; }
|
||||
if (Character.EmpVulnerability <= 0 && newAffliction.Prefab.AfflictionType == AfflictionPrefab.EMPType) { return; }
|
||||
if (newAffliction.Prefab.TargetSpecies.Any() && newAffliction.Prefab.TargetSpecies.None(s => s == Character.SpeciesName)) { return; }
|
||||
|
||||
var should = GameMain.LuaCs.Hook.Call<bool?>("character.applyAffliction", this, limbHealth, newAffliction, allowStacking);
|
||||
|
||||
@@ -769,7 +770,9 @@ namespace Barotrauma
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||
newAffliction.Source);
|
||||
afflictions.Add(copyAffliction, limbHealth);
|
||||
|
||||
SteamAchievementManager.OnAfflictionReceived(copyAffliction, Character);
|
||||
MedicalClinic.OnAfflictionCountChanged(Character);
|
||||
|
||||
Character.HealthUpdateInterval = 0.0f;
|
||||
|
||||
CalculateVitality();
|
||||
@@ -842,10 +845,16 @@ namespace Barotrauma
|
||||
}
|
||||
Character.StackSpeedMultiplier(affliction.GetSpeedMultiplier());
|
||||
}
|
||||
|
||||
foreach (var affliction in afflictionsToRemove)
|
||||
{
|
||||
afflictions.Remove(affliction);
|
||||
}
|
||||
}
|
||||
|
||||
if (afflictionsToRemove.Count is not 0)
|
||||
{
|
||||
MedicalClinic.OnAfflictionCountChanged(Character);
|
||||
}
|
||||
}
|
||||
|
||||
Character.StackSpeedMultiplier(1f + Character.GetStatValue(StatTypes.MovementSpeed));
|
||||
@@ -899,6 +908,11 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 0-1.
|
||||
/// </summary>
|
||||
public float OxygenLowResistance => !Character.NeedsOxygen ? 1 : GetResistance(oxygenLowAffliction.Prefab);
|
||||
|
||||
private void UpdateOxygen(float deltaTime)
|
||||
{
|
||||
if (!Character.NeedsOxygen)
|
||||
|
||||
Reference in New Issue
Block a user