Unstable 1.8.4.0
This commit is contained in:
@@ -248,6 +248,12 @@ namespace Barotrauma
|
||||
/// Was the character in full health at the beginning of the frame?
|
||||
/// </summary>
|
||||
public bool WasInFullHealth { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Show the blood overlay screen space effect when the character takes damage.
|
||||
/// Enabled normally, but can be disabled for some special cases.
|
||||
/// </summary>
|
||||
public bool ShowDamageOverlay = true;
|
||||
|
||||
public Affliction PressureAffliction
|
||||
{
|
||||
@@ -442,7 +448,7 @@ namespace Barotrauma
|
||||
return strength;
|
||||
}
|
||||
|
||||
public void ApplyAffliction(Limb targetLimb, Affliction affliction, bool allowStacking = true, bool ignoreUnkillability = false)
|
||||
public void ApplyAffliction(Limb targetLimb, Affliction affliction, bool allowStacking = true, bool ignoreUnkillability = false, bool recalculateVitality = true)
|
||||
{
|
||||
if (Character.GodMode) { return; }
|
||||
if (!ignoreUnkillability)
|
||||
@@ -456,12 +462,12 @@ namespace Barotrauma
|
||||
//if a limb-specific affliction is applied to no specific limb, apply to all limbs
|
||||
foreach (LimbHealth limbHealth in limbHealths)
|
||||
{
|
||||
AddLimbAffliction(limbHealth, affliction, allowStacking: allowStacking);
|
||||
AddLimbAffliction(limbHealth, limb: null, affliction, allowStacking: allowStacking, recalculateVitality: recalculateVitality);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
AddLimbAffliction(targetLimb, affliction, allowStacking: allowStacking);
|
||||
AddLimbAffliction(targetLimb, affliction, allowStacking: allowStacking, recalculateVitality: recalculateVitality);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -470,14 +476,17 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public float GetResistance(AfflictionPrefab afflictionPrefab)
|
||||
/// <summary>
|
||||
/// How much resistance all the afflictions the character has give to the specified affliction?
|
||||
/// </summary>
|
||||
public float GetResistance(AfflictionPrefab afflictionPrefab, LimbType limbType)
|
||||
{
|
||||
// This is a % resistance (0 to 1.0)
|
||||
float resistance = 0.0f;
|
||||
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
|
||||
{
|
||||
var affliction = kvp.Key;
|
||||
resistance += affliction.GetResistance(afflictionPrefab.Identifier);
|
||||
resistance += affliction.GetResistance(afflictionPrefab.Identifier, limbType);
|
||||
}
|
||||
// This is a multiplier, ie. 0.0 = 100% resistance and 1.0 = 0% resistance
|
||||
float abilityResistanceMultiplier = Character.GetAbilityResistance(afflictionPrefab);
|
||||
@@ -610,7 +619,11 @@ namespace Barotrauma
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
public void ApplyDamage(Limb hitLimb, AttackResult attackResult, bool allowStacking = true)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="recalculateVitality">Set false only as an optimization when you manually call <see cref="RecalculateVitality"/>. Only applies to limb specific afflictions.</param>
|
||||
public void ApplyDamage(Limb hitLimb, AttackResult attackResult, bool allowStacking = true, bool recalculateVitality = true)
|
||||
{
|
||||
if (Unkillable || Character.GodMode) { return; }
|
||||
if (hitLimb.HealthIndex < 0 || hitLimb.HealthIndex >= limbHealths.Count)
|
||||
@@ -619,18 +632,19 @@ namespace Barotrauma
|
||||
"\" only has health configured for" + limbHealths.Count + " limbs but the limb " + hitLimb.type + " is targeting index " + hitLimb.HealthIndex);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
foreach (Affliction newAffliction in attackResult.Afflictions)
|
||||
{
|
||||
if (newAffliction.Prefab.LimbSpecific)
|
||||
{
|
||||
AddLimbAffliction(hitLimb, newAffliction, allowStacking);
|
||||
AddLimbAffliction(hitLimb, newAffliction, allowStacking, recalculateVitality: recalculateVitality);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Always recalculate vitality for non-limb specific afflictions.
|
||||
AddAffliction(newAffliction, allowStacking);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void KillIfOutOfVitality()
|
||||
@@ -664,9 +678,8 @@ namespace Barotrauma
|
||||
if (bleedingDamageAmount > 0.0f && DoesBleed) { afflictions.Add(AfflictionPrefab.Bleeding.Instantiate(bleedingDamageAmount), limbHealth); }
|
||||
if (burnDamageAmount > 0.0f) { afflictions.Add(AfflictionPrefab.Burn.Instantiate(burnDamageAmount), limbHealth); }
|
||||
}
|
||||
|
||||
CalculateVitality();
|
||||
KillIfOutOfVitality();
|
||||
|
||||
RecalculateVitality();
|
||||
}
|
||||
|
||||
public float GetLimbDamage(Limb limb, Identifier afflictionType)
|
||||
@@ -697,12 +710,25 @@ namespace Barotrauma
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveAfflictions(Func<Affliction, bool> predicate)
|
||||
{
|
||||
afflictionsToRemove.Clear();
|
||||
afflictionsToRemove.AddRange(afflictions.Keys.Where(affliction => predicate(affliction)));
|
||||
foreach (var affliction in afflictionsToRemove)
|
||||
{
|
||||
afflictions.Remove(affliction);
|
||||
}
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
public void RemoveAllAfflictions()
|
||||
{
|
||||
afflictionsToRemove.Clear();
|
||||
afflictionsToRemove.AddRange(afflictions.Keys.Where(a => !irremovableAfflictions.Contains(a)));
|
||||
foreach (var affliction in afflictionsToRemove)
|
||||
{
|
||||
//set strength to 0 in case the affliction needs to react to becoming inactive
|
||||
affliction.Strength = 0.0f;
|
||||
afflictions.Remove(affliction);
|
||||
}
|
||||
foreach (Affliction affliction in irremovableAfflictions)
|
||||
@@ -731,7 +757,11 @@ namespace Barotrauma
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction, bool allowStacking = true)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="recalculateVitality">Set false only as an optimization when you manually call <see cref="RecalculateVitality"/></param>
|
||||
private void AddLimbAffliction(Limb limb, Affliction newAffliction, bool allowStacking = true, bool recalculateVitality = true)
|
||||
{
|
||||
if (!newAffliction.Prefab.LimbSpecific || limb == null) { return; }
|
||||
if (limb.HealthIndex < 0 || limb.HealthIndex >= limbHealths.Count)
|
||||
@@ -740,11 +770,16 @@ namespace Barotrauma
|
||||
"\" only has health configured for" + limbHealths.Count + " limbs but the limb " + limb.type + " is targeting index " + limb.HealthIndex);
|
||||
return;
|
||||
}
|
||||
AddLimbAffliction(limbHealths[limb.HealthIndex], newAffliction, allowStacking);
|
||||
AddLimbAffliction(limbHealths[limb.HealthIndex], limb, newAffliction, allowStacking, recalculateVitality);
|
||||
}
|
||||
|
||||
private void AddLimbAffliction(LimbHealth limbHealth, Affliction newAffliction, bool allowStacking = true)
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="recalculateVitality">Set false only as an optimization when you manually call <see cref="RecalculateVitality"/></param>
|
||||
private void AddLimbAffliction(LimbHealth limbHealth, Limb limb, Affliction newAffliction, bool allowStacking = true, bool recalculateVitality = true)
|
||||
{
|
||||
LimbType limbType = limb?.type ?? LimbType.None;
|
||||
if (Character.Params.IsMachine && !newAffliction.Prefab.AffectMachines) { return; }
|
||||
if (!DoesBleed && newAffliction is AfflictionBleeding) { return; }
|
||||
if (!Character.NeedsOxygen && newAffliction.Prefab == AfflictionPrefab.OxygenLow) { return; }
|
||||
@@ -778,26 +813,29 @@ namespace Barotrauma
|
||||
|
||||
if (existingAffliction != null)
|
||||
{
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(existingAffliction.Prefab));
|
||||
float newStrength = newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(existingAffliction.Prefab, limbType));
|
||||
if (allowStacking)
|
||||
{
|
||||
// Add the existing strength
|
||||
newStrength += existingAffliction.Strength;
|
||||
}
|
||||
newStrength = Math.Min(existingAffliction.Prefab.MaxStrength, newStrength);
|
||||
if (existingAffliction == stunAffliction) { Character.SetStun(newStrength, true, true); }
|
||||
existingAffliction.Strength = newStrength;
|
||||
//set stun after setting the strength, because stun multipliers might want to set the strength to something else
|
||||
if (existingAffliction == stunAffliction) { Character.SetStun(newStrength, allowStunDecrease: true, isNetworkMessage: true); }
|
||||
existingAffliction.Duration = existingAffliction.Prefab.Duration;
|
||||
if (newAffliction.Source != null) { existingAffliction.Source = newAffliction.Source; }
|
||||
CalculateVitality();
|
||||
KillIfOutOfVitality();
|
||||
if (recalculateVitality)
|
||||
{
|
||||
RecalculateVitality();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
//create a new instance of the affliction to make sure we don't use the same instance for multiple characters
|
||||
//or modify the affliction instance of an Attack or a StatusEffect
|
||||
var copyAffliction = newAffliction.Prefab.Instantiate(
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab))),
|
||||
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab, limbType))),
|
||||
newAffliction.Source);
|
||||
afflictions.Add(copyAffliction, limbHealth);
|
||||
AchievementManager.OnAfflictionReceived(copyAffliction, Character);
|
||||
@@ -805,8 +843,10 @@ namespace Barotrauma
|
||||
|
||||
Character.HealthUpdateInterval = 0.0f;
|
||||
|
||||
CalculateVitality();
|
||||
KillIfOutOfVitality();
|
||||
if (recalculateVitality)
|
||||
{
|
||||
RecalculateVitality();
|
||||
}
|
||||
#if CLIENT
|
||||
if (OpenHealthWindow != this && limbHealth != null)
|
||||
{
|
||||
@@ -817,7 +857,7 @@ namespace Barotrauma
|
||||
|
||||
private void AddAffliction(Affliction newAffliction, bool allowStacking = true)
|
||||
{
|
||||
AddLimbAffliction(limbHealth: null, newAffliction, allowStacking);
|
||||
AddLimbAffliction(limbHealth: null, limb: null, newAffliction, allowStacking);
|
||||
}
|
||||
|
||||
partial void UpdateSkinTint();
|
||||
@@ -850,6 +890,8 @@ namespace Barotrauma
|
||||
affliction.Duration -= deltaTime;
|
||||
if (affliction.Duration <= 0.0f)
|
||||
{
|
||||
//set strength to 0 in case the affliction needs to react to becoming inactive
|
||||
affliction.Strength = 0.0f;
|
||||
afflictionsToRemove.Add(affliction);
|
||||
continue;
|
||||
}
|
||||
@@ -902,14 +944,15 @@ namespace Barotrauma
|
||||
if (!Character.GodMode)
|
||||
{
|
||||
#if CLIENT
|
||||
if (Character.IsVisible)
|
||||
updateVisualsTimer -= deltaTime;
|
||||
if (Character.IsVisible && updateVisualsTimer <= 0.0f)
|
||||
{
|
||||
UpdateLimbAfflictionOverlays();
|
||||
UpdateSkinTint();
|
||||
updateVisualsTimer = UpdateVisualsInterval;
|
||||
}
|
||||
#endif
|
||||
CalculateVitality();
|
||||
KillIfOutOfVitality();
|
||||
RecalculateVitality();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -941,7 +984,7 @@ namespace Barotrauma
|
||||
/// <summary>
|
||||
/// 0-1.
|
||||
/// </summary>
|
||||
public float OxygenLowResistance => !Character.NeedsOxygen ? 1 : GetResistance(oxygenLowAffliction.Prefab);
|
||||
public float OxygenLowResistance => !Character.NeedsOxygen ? 1 : GetResistance(oxygenLowAffliction.Prefab, LimbType.None);
|
||||
|
||||
private void UpdateOxygen(float deltaTime)
|
||||
{
|
||||
@@ -951,7 +994,7 @@ namespace Barotrauma
|
||||
return;
|
||||
}
|
||||
|
||||
float oxygenlowResistance = GetResistance(oxygenLowAffliction.Prefab);
|
||||
float oxygenlowResistance = GetResistance(oxygenLowAffliction.Prefab, LimbType.None);
|
||||
float prevOxygen = OxygenAmount;
|
||||
if (IsUnconscious)
|
||||
{
|
||||
@@ -991,13 +1034,13 @@ namespace Barotrauma
|
||||
CalculateVitality();
|
||||
}
|
||||
|
||||
public void CalculateVitality()
|
||||
private void CalculateVitality()
|
||||
{
|
||||
vitality = MaxVitality;
|
||||
IsParalyzed = false;
|
||||
if (Unkillable || Character.GodMode) { return; }
|
||||
|
||||
foreach (var (affliction, limbHealth) in afflictions)
|
||||
foreach ((Affliction affliction, LimbHealth limbHealth) in afflictions)
|
||||
{
|
||||
float vitalityDecrease = affliction.GetVitalityDecrease(this);
|
||||
if (limbHealth != null)
|
||||
@@ -1020,6 +1063,12 @@ namespace Barotrauma
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
public void RecalculateVitality()
|
||||
{
|
||||
CalculateVitality();
|
||||
KillIfOutOfVitality();
|
||||
}
|
||||
|
||||
private static float GetVitalityMultiplier(Affliction affliction, LimbHealth limbHealth)
|
||||
{
|
||||
@@ -1139,7 +1188,11 @@ namespace Barotrauma
|
||||
/// </summary>
|
||||
/// <param name="treatmentSuitability">A dictionary where the key is the identifier of the item and the value the suitability</param>
|
||||
/// <param name="predictFutureDuration">If above 0, the method will take into account how much currently active status effects while affect the afflictions in the next x seconds.</param>
|
||||
public void GetSuitableTreatments(Dictionary<Identifier, float> treatmentSuitability, Character user, Limb limb = null, bool ignoreHiddenAfflictions = false, float predictFutureDuration = 0.0f)
|
||||
/// <param name="checkTreatmentThreshold">Should the method check whether the afflictions are above <see cref="AfflictionPrefab.TreatmentThreshold"/> (whether they're severe enough for AI to treat)?</param>
|
||||
/// <param name="checkTreatmentSuggestionThreshold">Should the method check whether the afflictions are above <see cref="AfflictionPrefab.TreatmentSuggestionThreshold"/> (whether treatment suggestions are shown in the health interface)?</param>
|
||||
public void GetSuitableTreatments(Dictionary<Identifier, float> treatmentSuitability, Character user, Limb limb = null, bool ignoreHiddenAfflictions = false,
|
||||
bool checkTreatmentThreshold = true, bool checkTreatmentSuggestionThreshold = true,
|
||||
float predictFutureDuration = 0.0f)
|
||||
{
|
||||
//key = item identifier
|
||||
//float = suitability
|
||||
@@ -1190,7 +1243,14 @@ namespace Barotrauma
|
||||
//if this a suitable treatment, ignore it if the affliction isn't severe enough to treat
|
||||
//if the suitability is negative though, we need to take it into account!
|
||||
//otherwise we may end up e.g. giving too much opiates to someone already close to overdosing
|
||||
if (totalAfflictionStrength < affliction.Prefab.TreatmentThreshold) { continue; }
|
||||
if (checkTreatmentThreshold)
|
||||
{
|
||||
if (totalAfflictionStrength < affliction.Prefab.TreatmentThreshold) { continue; }
|
||||
}
|
||||
if (checkTreatmentSuggestionThreshold)
|
||||
{
|
||||
if (totalAfflictionStrength < affliction.Prefab.TreatmentSuggestionThreshold) { continue; }
|
||||
}
|
||||
}
|
||||
if (treatment.Value > strength)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user