Revert "OBT1.1.0 Merge branch 'dev_pte' into dev"

This reverts commit 177cf89756, reversing
changes made to 42ba733cd4.
This commit is contained in:
Eero
2025-12-29 11:18:11 +08:00
parent 177cf89756
commit 046483b9da
86 changed files with 800 additions and 2496 deletions
@@ -3,13 +3,15 @@ using Barotrauma.Extensions;
using Barotrauma.Networking;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
using Barotrauma.Networking;
using Barotrauma.Extensions;
using System.Globalization;
using MoonSharp.Interpreter;
using Barotrauma.Abilities;
namespace Barotrauma
{
@@ -130,9 +132,8 @@ namespace Barotrauma
private readonly List<LimbHealth> limbHealths = new List<LimbHealth>();
// Thread-safe afflictions dictionary for concurrent access
private readonly ConcurrentDictionary<Affliction, LimbHealth> afflictions = new ConcurrentDictionary<Affliction, LimbHealth>();
private readonly ConcurrentDictionary<Affliction, byte> irremovableAfflictions = new ConcurrentDictionary<Affliction, byte>();
private readonly Dictionary<Affliction, LimbHealth> afflictions = new Dictionary<Affliction, LimbHealth>();
private readonly HashSet<Affliction> irremovableAfflictions = new HashSet<Affliction>();
private Affliction bloodlossAffliction;
private Affliction oxygenLowAffliction;
private Affliction pressureAffliction;
@@ -323,13 +324,13 @@ namespace Barotrauma
private void InitIrremovableAfflictions()
{
irremovableAfflictions.TryAdd(bloodlossAffliction = new Affliction(AfflictionPrefab.Bloodloss, 0.0f), 0);
irremovableAfflictions.TryAdd(stunAffliction = new Affliction(AfflictionPrefab.Stun, 0.0f), 0);
irremovableAfflictions.TryAdd(pressureAffliction = new Affliction(AfflictionPrefab.Pressure, 0.0f), 0);
irremovableAfflictions.TryAdd(oxygenLowAffliction = new Affliction(AfflictionPrefab.OxygenLow, 0.0f), 0);
foreach (Affliction affliction in irremovableAfflictions.Keys)
irremovableAfflictions.Add(bloodlossAffliction = new Affliction(AfflictionPrefab.Bloodloss, 0.0f));
irremovableAfflictions.Add(stunAffliction = new Affliction(AfflictionPrefab.Stun, 0.0f));
irremovableAfflictions.Add(pressureAffliction = new Affliction(AfflictionPrefab.Pressure, 0.0f));
irremovableAfflictions.Add(oxygenLowAffliction = new Affliction(AfflictionPrefab.OxygenLow, 0.0f));
foreach (Affliction affliction in irremovableAfflictions)
{
afflictions.TryAdd(affliction, null);
afflictions.Add(affliction, null);
}
}
@@ -337,7 +338,7 @@ namespace Barotrauma
public IReadOnlyCollection<Affliction> GetAllAfflictions()
{
return afflictions.Keys.ToList();
return afflictions.Keys;
}
public IEnumerable<Affliction> GetAllAfflictions(Func<Affliction, bool> limbHealthFilter)
@@ -502,18 +503,19 @@ namespace Barotrauma
/// </summary>
public float GetResistance(AfflictionPrefab afflictionPrefab, LimbType limbType)
{
// ConcurrentDictionary is thread-safe, no lock needed
// 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, limbType);
lock (afflictions) {
// 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, limbType);
}
// This is a multiplier, ie. 0.0 = 100% resistance and 1.0 = 0% resistance
float abilityResistanceMultiplier = Character.GetAbilityResistance(afflictionPrefab);
// The returned value is calculated to be a % resistance again
return 1 - ((1 - resistance) * abilityResistanceMultiplier);
}
// This is a multiplier, ie. 0.0 = 100% resistance and 1.0 = 0% resistance
float abilityResistanceMultiplier = Character.GetAbilityResistance(afflictionPrefab);
// The returned value is calculated to be a % resistance again
return 1 - ((1 - resistance) * abilityResistanceMultiplier);
}
public float GetStatValue(StatTypes statType)
@@ -537,25 +539,20 @@ namespace Barotrauma
return false;
}
// Thread-static to avoid concurrent modification in parallel item updates
[ThreadStatic]
private static List<Affliction> t_matchingAfflictions;
private static List<Affliction> MatchingAfflictions => t_matchingAfflictions ??= new List<Affliction>();
private readonly List<Affliction> matchingAfflictions = new List<Affliction>();
public void ReduceAllAfflictionsOnAllLimbs(float amount, ActionType? treatmentAction = null)
{
var matchingAfflictions = MatchingAfflictions;
matchingAfflictions.Clear();
matchingAfflictions.AddRange(afflictions.Keys);
ReduceMatchingAfflictions(matchingAfflictions, amount, treatmentAction);
ReduceMatchingAfflictions(amount, treatmentAction);
}
public void ReduceAfflictionOnAllLimbs(Identifier afflictionIdOrType, float amount, ActionType? treatmentAction = null, Character attacker = null)
{
if (afflictionIdOrType.IsEmpty) { throw new ArgumentException($"{nameof(afflictionIdOrType)} is empty"); }
var matchingAfflictions = MatchingAfflictions;
matchingAfflictions.Clear();
foreach (var affliction in afflictions)
{
@@ -565,7 +562,7 @@ namespace Barotrauma
}
}
ReduceMatchingAfflictions(matchingAfflictions, amount, treatmentAction, attacker);
ReduceMatchingAfflictions(amount, treatmentAction, attacker);
}
private IEnumerable<Affliction> GetAfflictionsForLimb(Limb targetLimb)
@@ -575,11 +572,10 @@ namespace Barotrauma
{
if (targetLimb is null) { throw new ArgumentNullException(nameof(targetLimb)); }
var matchingAfflictions = MatchingAfflictions;
matchingAfflictions.Clear();
matchingAfflictions.AddRange(GetAfflictionsForLimb(targetLimb));
ReduceMatchingAfflictions(matchingAfflictions, amount, treatmentAction);
ReduceMatchingAfflictions(amount, treatmentAction);
}
public void ReduceAfflictionOnLimb(Limb targetLimb, Identifier afflictionIdOrType, float amount, ActionType? treatmentAction = null, Character attacker = null)
@@ -587,7 +583,6 @@ namespace Barotrauma
if (afflictionIdOrType.IsEmpty) { throw new ArgumentException($"{nameof(afflictionIdOrType)} is empty"); }
if (targetLimb is null) { throw new ArgumentNullException(nameof(targetLimb)); }
var matchingAfflictions = MatchingAfflictions;
matchingAfflictions.Clear();
var targetLimbHealth = limbHealths[targetLimb.HealthIndex];
foreach (var affliction in afflictions)
@@ -598,10 +593,10 @@ namespace Barotrauma
matchingAfflictions.Add(affliction.Key);
}
}
ReduceMatchingAfflictions(matchingAfflictions, amount, treatmentAction, attacker);
ReduceMatchingAfflictions(amount, treatmentAction, attacker);
}
private void ReduceMatchingAfflictions(List<Affliction> matchingAfflictions, float amount, ActionType? treatmentAction, Character attacker = null)
private void ReduceMatchingAfflictions(float amount, ActionType? treatmentAction, Character attacker = null)
{
if (matchingAfflictions.Count == 0) { return; }
@@ -688,19 +683,12 @@ namespace Barotrauma
}
}
// Thread-static to avoid concurrent modification when multiple characters are updated in parallel
[ThreadStatic]
private static List<Affliction> t_afflictionsToRemove;
[ThreadStatic]
private static List<KeyValuePair<Affliction, LimbHealth>> t_afflictionsToUpdate;
private static List<Affliction> AfflictionsToRemove => t_afflictionsToRemove ??= new List<Affliction>();
private static List<KeyValuePair<Affliction, LimbHealth>> AfflictionsToUpdate => t_afflictionsToUpdate ??= new List<KeyValuePair<Affliction, LimbHealth>>();
private readonly static List<Affliction> afflictionsToRemove = new List<Affliction>();
private readonly static List<KeyValuePair<Affliction, LimbHealth>> afflictionsToUpdate = new List<KeyValuePair<Affliction, LimbHealth>>();
public void SetAllDamage(float damageAmount, float bleedingDamageAmount, float burnDamageAmount)
{
if (Unkillable || Character.GodMode) { return; }
var afflictionsToRemove = AfflictionsToRemove;
afflictionsToRemove.Clear();
afflictionsToRemove.AddRange(afflictions.Keys.Where(a =>
a.Prefab.AfflictionType == AfflictionPrefab.InternalDamage.AfflictionType ||
@@ -708,14 +696,14 @@ namespace Barotrauma
a.Prefab.AfflictionType == AfflictionPrefab.Bleeding.AfflictionType));
foreach (var affliction in afflictionsToRemove)
{
afflictions.TryRemove(affliction, out _);
afflictions.Remove(affliction);
}
foreach (LimbHealth limbHealth in limbHealths)
{
if (damageAmount > 0.0f) { afflictions.TryAdd(AfflictionPrefab.InternalDamage.Instantiate(damageAmount), limbHealth); }
if (bleedingDamageAmount > 0.0f && DoesBleed) { afflictions.TryAdd(AfflictionPrefab.Bleeding.Instantiate(bleedingDamageAmount), limbHealth); }
if (burnDamageAmount > 0.0f) { afflictions.TryAdd(AfflictionPrefab.Burn.Instantiate(burnDamageAmount), limbHealth); }
if (damageAmount > 0.0f) { afflictions.Add(AfflictionPrefab.InternalDamage.Instantiate(damageAmount), limbHealth); }
if (bleedingDamageAmount > 0.0f && DoesBleed) { afflictions.Add(AfflictionPrefab.Bleeding.Instantiate(bleedingDamageAmount), limbHealth); }
if (burnDamageAmount > 0.0f) { afflictions.Add(AfflictionPrefab.Burn.Instantiate(burnDamageAmount), limbHealth); }
}
RecalculateVitality();
@@ -751,28 +739,26 @@ namespace Barotrauma
public void RemoveAfflictions(Func<Affliction, bool> predicate)
{
var afflictionsToRemove = AfflictionsToRemove;
afflictionsToRemove.Clear();
afflictionsToRemove.AddRange(afflictions.Keys.Where(affliction => predicate(affliction)));
foreach (var affliction in afflictionsToRemove)
{
afflictions.TryRemove(affliction, out _);
afflictions.Remove(affliction);
}
CalculateVitality();
}
public void RemoveAllAfflictions()
{
var afflictionsToRemove = AfflictionsToRemove;
afflictionsToRemove.Clear();
afflictionsToRemove.AddRange(afflictions.Keys.Where(a => !irremovableAfflictions.ContainsKey(a)));
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.TryRemove(affliction, out _);
afflictions.Remove(affliction);
}
foreach (Affliction affliction in irremovableAfflictions.Keys)
foreach (Affliction affliction in irremovableAfflictions)
{
affliction.Strength = 0.0f;
}
@@ -781,18 +767,17 @@ namespace Barotrauma
public void RemoveNegativeAfflictions()
{
var afflictionsToRemove = AfflictionsToRemove;
afflictionsToRemove.Clear();
afflictionsToRemove.AddRange(afflictions.Keys.Where(a =>
!irremovableAfflictions.ContainsKey(a) &&
!irremovableAfflictions.Contains(a) &&
!a.Prefab.IsBuff &&
a.Prefab.AfflictionType != "geneticmaterialbuff" &&
a.Prefab.AfflictionType != "geneticmaterialdebuff"));
foreach (var affliction in afflictionsToRemove)
{
afflictions.TryRemove(affliction, out _);
afflictions.Remove(affliction);
}
foreach (Affliction affliction in irremovableAfflictions.Keys)
foreach (Affliction affliction in irremovableAfflictions)
{
affliction.Strength = 0.0f;
}
@@ -884,7 +869,7 @@ namespace Barotrauma
var copyAffliction = newAffliction.Prefab.Instantiate(
Math.Min(newAffliction.Prefab.MaxStrength, newAffliction.Strength * (100.0f / MaxVitality) * (1f - GetResistance(newAffliction.Prefab, limbType))),
newAffliction.Source);
afflictions.TryAdd(copyAffliction, limbHealth);
afflictions.Add(copyAffliction, limbHealth);
AchievementManager.OnAfflictionReceived(copyAffliction, Character);
MedicalClinic.OnAfflictionCountChanged(Character);
@@ -921,8 +906,6 @@ namespace Barotrauma
if (!Character.GodMode)
{
var afflictionsToRemove = AfflictionsToRemove;
var afflictionsToUpdate = AfflictionsToUpdate;
afflictionsToRemove.Clear();
afflictionsToUpdate.Clear();
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
@@ -931,7 +914,7 @@ namespace Barotrauma
if (affliction.Strength <= 0.0f)
{
AchievementManager.OnAfflictionRemoved(affliction, Character);
if (!irremovableAfflictions.ContainsKey(affliction)) { afflictionsToRemove.Add(affliction); }
if (!irremovableAfflictions.Contains(affliction)) { afflictionsToRemove.Add(affliction); }
continue;
}
if (affliction.Prefab.Duration > 0.0f)
@@ -969,7 +952,7 @@ namespace Barotrauma
foreach (var affliction in afflictionsToRemove)
{
afflictions.TryRemove(affliction, out _);
afflictions.Remove(affliction);
}
if (afflictionsToRemove.Count is not 0)
@@ -1217,14 +1200,9 @@ namespace Barotrauma
return (causeOfDeath, strongestAffliction);
}
// Thread-static to avoid concurrent modification in parallel item updates
[ThreadStatic]
private static List<Affliction> t_allAfflictions;
private static List<Affliction> AllAfflictionsList => t_allAfflictions ??= new List<Affliction>();
private readonly List<Affliction> allAfflictions = new List<Affliction>();
private IEnumerable<Affliction> GetAllAfflictions(bool mergeSameAfflictions, Func<Affliction, bool> predicate = null)
{
var allAfflictions = AllAfflictionsList;
allAfflictions.Clear();
if (!mergeSameAfflictions)
{
@@ -1407,17 +1385,10 @@ namespace Barotrauma
return MathHelper.Clamp(strength, 0.0f, affliction.Prefab.MaxStrength);
}
// Thread-static to avoid concurrent modification in parallel updates
[ThreadStatic]
private static List<Affliction> t_activeAfflictions;
[ThreadStatic]
private static List<(LimbHealth limbHealth, Affliction affliction)> t_limbAfflictions;
private static List<Affliction> ActiveAfflictionsList => t_activeAfflictions ??= new List<Affliction>();
private static List<(LimbHealth limbHealth, Affliction affliction)> LimbAfflictionsList => t_limbAfflictions ??= new List<(LimbHealth limbHealth, Affliction affliction)>();
private readonly List<Affliction> activeAfflictions = new List<Affliction>();
private readonly List<(LimbHealth limbHealth, Affliction affliction)> limbAfflictions = new List<(LimbHealth limbHealth, Affliction affliction)>();
public void ServerWrite(IWriteMessage msg)
{
var activeAfflictions = ActiveAfflictionsList;
activeAfflictions.Clear();
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
{
@@ -1443,7 +1414,6 @@ namespace Barotrauma
}
}
var limbAfflictions = LimbAfflictionsList;
limbAfflictions.Clear();
foreach (KeyValuePair<Affliction, LimbHealth> kvp in afflictions)
{
@@ -1473,9 +1443,8 @@ namespace Barotrauma
public void Remove()
{
RemoveProjSpecific();
// Clear thread-static lists to help with garbage collection
AfflictionsToRemove.Clear();
AfflictionsToUpdate.Clear();
afflictionsToRemove.Clear();
afflictionsToUpdate.Clear();
}
partial void RemoveProjSpecific();
@@ -1550,14 +1519,14 @@ namespace Barotrauma
}
if (afflictionPredicate != null && !afflictionPredicate.Invoke(afflictionPrefab)) { return; }
float strength = afflictionElement.GetAttributeFloat("strength", 0.0f);
var irremovableAffliction = irremovableAfflictions.Keys.FirstOrDefault(a => a.Prefab == afflictionPrefab);
var irremovableAffliction = irremovableAfflictions.FirstOrDefault(a => a.Prefab == afflictionPrefab);
if (irremovableAffliction != null)
{
irremovableAffliction.Strength = strength;
}
else
{
afflictions.TryAdd(afflictionPrefab.Instantiate(strength), limbHealth);
afflictions.Add(afflictionPrefab.Instantiate(strength), limbHealth);
}
}
}