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
@@ -9,7 +9,6 @@ using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Threading;
using System.Xml.Linq;
namespace Barotrauma.Items.Components
@@ -486,10 +485,7 @@ namespace Barotrauma.Items.Components
}
else
{
// Calculate target position
Vector2 targetPos;
Submarine forceSubmarine = picker.Submarine;
item.body.ResetDynamics();
Limb heldHand, arm;
if (picker.Inventory.IsInLimbSlot(item, InvSlotType.LeftHand))
{
@@ -507,42 +503,17 @@ namespace Barotrauma.Items.Components
Vector2 diff = new Vector2(
(heldHand.SimPosition.X - arm.SimPosition.X) / 2f,
(heldHand.SimPosition.Y - arm.SimPosition.Y) / 2.5f);
targetPos = heldHand.SimPosition + diff;
}
else
{
targetPos = picker.SimPosition;
}
// Defer physics operations if in parallel context
if (PhysicsBodyQueue.IsInParallelContext)
{
var capturedBody = item.body;
var capturedItem = item;
var capturedTargetPos = targetPos;
var capturedForceSubmarine = forceSubmarine;
PhysicsBodyQueue.Enqueue(() =>
{
if (capturedBody.Removed || capturedItem.Removed) { return; }
capturedBody.ResetDynamics();
//we have forced the item to be in the same sub as the dropper above,
//and are placing it to the position of the hands in "local" coordinates
//which may be outside the sub if the character is e.g. standing half-way through the airlock
// -> let's use the forceSubmarine argument ensure the item is still considered to be in the sub's coordinate space,
// or it will end up in a weird state and seemingly disappear
capturedItem.SetTransform(capturedTargetPos, 0.0f, forceSubmarine: capturedForceSubmarine);
});
}
else
{
item.body.ResetDynamics();
//we have forced the item to be in the same sub as the dropper above,
//and are placing it to the position of the hands in "local" coordinates
//which may be outside the sub if the character is e.g. standing half-way through the airlock
// -> let's use the forceSubmarine argument ensure the item is still considered to be in the sub's coordinate space,
// or it will end up in a weird state and seemingly disappear
item.SetTransform(targetPos, 0.0f, forceSubmarine: forceSubmarine);
item.SetTransform(heldHand.SimPosition + diff, 0.0f, forceSubmarine: picker.Submarine);
}
else
{
item.SetTransform(picker.SimPosition, 0.0f, forceSubmarine: picker.Submarine);
}
}
}
@@ -645,13 +616,12 @@ namespace Barotrauma.Items.Components
return CanBeAttached(user, out _);
}
private static readonly ThreadLocal<List<Item>> tempOverlappingItems = new ThreadLocal<List<Item>>(() => new List<Item>());
private static List<Item> tempOverlappingItems = new List<Item>();
private bool CanBeAttached(Character user, out IEnumerable<Item> overlappingItems)
{
var overlapping = tempOverlappingItems.Value;
overlapping.Clear();
overlappingItems = overlapping;
tempOverlappingItems.Clear();
overlappingItems = tempOverlappingItems;
if (!attachable || !Reattachable) { return false; }
//can be attached anywhere in sub editor
@@ -694,9 +664,9 @@ namespace Barotrauma.Items.Components
}
if (attachPos.X + size.X < worldRect.X || attachPos.X - size.X > worldRect.Right) { continue; }
if (attachPos.Y - size.Y > worldRect.Y || attachPos.Y + size.Y < worldRect.Y - worldRect.Height) { continue; }
overlapping.Add(otherItem);
tempOverlappingItems.Add(otherItem);
}
if (overlapping.Any()) { return false; }
if (tempOverlappingItems.Any()) { return false; }
}
//can be attached anywhere inside hulls
@@ -13,12 +13,6 @@ namespace Barotrauma.Items.Components
private Holdable holdable;
private float deattachTimer;
/// <summary>
/// Flag to prevent multiple queued creation requests.
/// Uses volatile to ensure visibility across threads.
/// </summary>
private volatile bool triggerBodyCreationQueued;
[Serialize(1.0f, IsPropertySaveable.No, description: "How long it takes to deattach the item from the level walls (in seconds).")]
public float DeattachDuration
@@ -92,16 +86,13 @@ namespace Barotrauma.Items.Components
{
if (trigger != null && amount.LengthSquared() > 0.00001f)
{
// Defer physics operation if in parallel context (Farseer is not thread-safe)
var capturedTrigger = trigger;
var capturedPos = item.SimPosition;
if (ignoreContacts)
{
PhysicsBodyQueue.ExecuteOrDefer(() => capturedTrigger.SetTransformIgnoreContacts(capturedPos, 0.0f));
trigger.SetTransformIgnoreContacts(item.SimPosition, 0.0f);
}
else
{
PhysicsBodyQueue.ExecuteOrDefer(() => capturedTrigger.SetTransform(capturedPos, 0.0f));
trigger.SetTransform(item.SimPosition, 0.0f);
}
}
}
@@ -118,29 +109,13 @@ namespace Barotrauma.Items.Components
}
else
{
if (trigger == null && !triggerBodyCreationQueued)
if (trigger == null)
{
// Queue the physics body creation to be processed on the main thread.
// This is necessary because physics body creation is not thread-safe
// and Update() may be called from a parallel loop.
triggerBodyCreationQueued = true;
PhysicsBodyQueue.EnqueueCreation(() =>
{
// Double-check that trigger hasn't been created yet
// (in case this was called multiple times before queue processing)
if (trigger == null && !item.Removed)
{
CreateTriggerBody();
}
triggerBodyCreationQueued = false;
});
CreateTriggerBody();
}
if (trigger != null && Vector2.DistanceSquared(item.SimPosition, trigger.SimPosition) > 0.01f)
{
// Defer physics operation if in parallel context (Farseer is not thread-safe)
var capturedTrigger = trigger;
var capturedPos = item.SimPosition;
PhysicsBodyQueue.ExecuteOrDefer(() => capturedTrigger.SetTransform(capturedPos, 0.0f));
trigger.SetTransform(item.SimPosition, 0.0f);
}
IsActive = false;
}
@@ -3,7 +3,6 @@ using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
@@ -25,7 +24,7 @@ namespace Barotrauma.Items.Components
private readonly HashSet<Entity> hitTargets = new HashSet<Entity>();
private readonly ConcurrentQueue<Fixture> impactQueue = new ConcurrentQueue<Fixture>();
private readonly Queue<Fixture> impactQueue = new Queue<Fixture>();
public Character User { get; private set; }
@@ -191,16 +190,17 @@ namespace Barotrauma.Items.Components
{
if (!item.body.Enabled)
{
while (impactQueue.TryDequeue(out _)) { } // Clear queue
impactQueue.Clear();
return;
}
if (picker == null || !picker.HeldItems.Contains(item))
{
while (impactQueue.TryDequeue(out _)) { } // Clear queue
impactQueue.Clear();
IsActive = false;
}
while (impactQueue.TryDequeue(out var impact))
while (impactQueue.Count > 0)
{
var impact = impactQueue.Dequeue();
HandleImpact(impact);
}
//in case handling the impact does something to the picker
@@ -300,7 +300,7 @@ namespace Barotrauma.Items.Components
private void RestoreCollision()
{
while (impactQueue.TryDequeue(out _)) { } // Clear queue
impactQueue.Clear();
item.body.FarseerBody.OnCollision -= OnCollision;
item.body.CollisionCategories = Physics.CollisionItem;
item.body.CollidesWith = Physics.DefaultItemCollidesWith;
@@ -4,7 +4,6 @@ using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Barotrauma.Extensions;
using Barotrauma.MapCreatures.Behavior;
@@ -316,7 +315,7 @@ namespace Barotrauma.Items.Components
partial void UseProjSpecific(float deltaTime, Vector2 raystart);
private static readonly ThreadLocal<List<Body>> hitBodies = new ThreadLocal<List<Body>>(() => new List<Body>());
private static readonly List<Body> hitBodies = new List<Body>();
private readonly HashSet<Character> hitCharacters = new HashSet<Character>();
private readonly List<FireSource> fireSourcesInRange = new List<FireSource>();
private void Repair(Vector2 rayStart, Vector2 rayEnd, float deltaTime, Character user, float degreeOfSuccess, List<Body> ignoredBodies)
@@ -374,13 +373,13 @@ namespace Barotrauma.Items.Components
},
allowInsideFixture: true);
hitBodies.Value.Clear();
hitBodies.Value.AddRange(bodies.Distinct());
hitBodies.Clear();
hitBodies.AddRange(bodies.Distinct());
lastPickedFraction = Submarine.LastPickedFraction;
Type lastHitType = null;
hitCharacters.Clear();
foreach (Body body in hitBodies.Value)
foreach (Body body in hitBodies)
{
Type bodyType = body.UserData?.GetType();
if (!RepairThroughWalls && bodyType != null && bodyType != lastHitType)
@@ -898,49 +897,48 @@ namespace Barotrauma.Items.Components
}
}
private static readonly ThreadLocal<List<ISerializableEntity>> currentTargets = new ThreadLocal<List<ISerializableEntity>>(() => new List<ISerializableEntity>());
private static List<ISerializableEntity> currentTargets = new List<ISerializableEntity>();
private void ApplyStatusEffectsOnTarget(Character user, float deltaTime, ActionType actionType, Item targetItem = null, Character character = null, Limb limb = null, Structure structure = null)
{
if (statusEffectLists == null) { return; }
if (!statusEffectLists.TryGetValue(actionType, out List<StatusEffect> statusEffects)) { return; }
var targets = currentTargets.Value;
foreach (StatusEffect effect in statusEffects)
{
targets.Clear();
currentTargets.Clear();
effect.SetUser(user);
if (effect.HasTargetType(StatusEffect.TargetType.UseTarget))
{
if (targetItem != null)
{
targets.AddRange(targetItem.AllPropertyObjects);
currentTargets.AddRange(targetItem.AllPropertyObjects);
}
if (structure != null)
{
targets.Add(structure);
currentTargets.Add(structure);
}
if (character != null)
{
targets.Add(character);
currentTargets.Add(character);
}
effect.Apply(actionType, deltaTime, item, targets);
effect.Apply(actionType, deltaTime, item, currentTargets);
}
else if (effect.HasTargetType(StatusEffect.TargetType.Character))
{
targets.Add(user);
effect.Apply(actionType, deltaTime, item, targets);
currentTargets.Add(user);
effect.Apply(actionType, deltaTime, item, currentTargets);
}
else if (effect.HasTargetType(StatusEffect.TargetType.Limb))
{
targets.Add(limb);
effect.Apply(actionType, deltaTime, item, targets);
currentTargets.Add(limb);
effect.Apply(actionType, deltaTime, item, currentTargets);
}
#if CLIENT
if (user == null) { return; }
// Hard-coded progress bars for welding doors stuck.
// A general purpose system could be better, but it would most likely require changes in the way we define the status effects in xml.
foreach (ISerializableEntity target in targets)
foreach (ISerializableEntity target in currentTargets)
{
if (target is not Door door) { continue; }
if (!door.CanBeWelded || !door.Item.IsInteractable(user)) { continue; }