Merge branch 'heads/upstream' into OBT/1.2.0(SpringUpdate)

This commit is contained in:
NotAlwaysTrue
2026-04-25 13:08:16 +08:00
420 changed files with 24089 additions and 11191 deletions
@@ -1,5 +1,7 @@
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
@@ -888,8 +890,8 @@ namespace Barotrauma
if (Math.Max(hull1.WorldSurface + hull1.WaveY[hull1.WaveY.Length - 1], hull2.WorldSurface + hull2.WaveY[0]) > WorldRect.Y) { return; }
}
var should = GameMain.LuaCs.Hook.Call<bool?>("gapOxygenUpdate", this, hull1, hull2);
bool? should = null;
LuaCsSetup.Instance.EventService.PublishEvent<IEventGapOxygenUpdate>(x => should = x.OnGapOxygenUpdate(this, hull1, hull2) ?? should);
if (should != null && should.Value) return;
float totalOxygen = hull1.Oxygen + hull2.Oxygen;
@@ -123,6 +123,8 @@ namespace Barotrauma
public const float OxygenDeteriorationSpeed = 0.3f;
public const float OxygenConsumptionSpeed = 700.0f;
private const float DecalAlphaRemoveThreshold = 0.001f;
public const int WaveWidth = 32;
public static float WaveStiffness = 0.01f;
public static float WaveSpread = 0.02f;
@@ -913,7 +915,7 @@ namespace Barotrauma
for (int i = decals.Count - 1; i >= 0; i--)
{
var decal = decals[i];
if (decal.FadeTimer >= decal.LifeTime || decal.BaseAlpha <= 0.001f)
if (decal.FadeTimer >= decal.LifeTime || decal.BaseAlpha <= DecalAlphaRemoveThreshold)
{
decals.RemoveAt(i);
#if SERVER
@@ -1159,7 +1161,10 @@ namespace Barotrauma
Hull currentHull = current.hull;
Vector2 currentPos = current.pos;
if (currentDist > maxDistance) { return float.MaxValue; }
if (currentDist > maxDistance)
{
return float.MaxValue;
}
// If we've reached the target, add the final segment from hull to endPos
if (currentHull == targetHull)
@@ -1167,7 +1172,7 @@ namespace Barotrauma
return currentDist + Vector2.Distance(currentPos, endPos);
}
foreach (Gap g in ConnectedGaps)
foreach (Gap g in currentHull.ConnectedGaps)
{
float distanceMultiplier = 1;
if (g.ConnectedDoor != null && !g.ConnectedDoor.IsBroken)
@@ -1643,9 +1648,18 @@ namespace Barotrauma
bool decalsCleaned = false;
foreach (Decal decal in decals)
{
// Don't attempt to clean the decal if it's already below the remove threshold, since the server
// is already gonna remove the decal for us, sending another decal update event would result in
// us potentially modifying a different decal since the indices can briefly desync.
if (decal.BaseAlpha <= DecalAlphaRemoveThreshold)
{
continue;
}
if (decal.AffectsSection(section))
{
decal.Clean(cleanVal);
decalsCleaned = true;
#if SERVER
decalUpdatePending = true;
@@ -7,6 +7,7 @@ using FarseerPhysics.Dynamics;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Globalization;
using System.Linq;
@@ -327,6 +328,7 @@ namespace Barotrauma
public Submarine BeaconStation { get; private set; }
private Sonar beaconSonar;
private ImmutableArray<SonarTransducer> beaconTransducers = ImmutableArray<SonarTransducer>.Empty;
/// <summary>
/// Special wall chunks that aren't part of the normal level geometry: includes things like the ocean floor, floating ice chunks and ice spires.
@@ -4398,6 +4400,13 @@ namespace Barotrauma
attempts++;
}
}
foreach (var wreck in Wrecks)
{
wreck.SetCrushDepth(wreck.RealWorldDepth + 1000);
SetLinkedSubCrushDepth(wreck);
}
totalSW.Stop();
Debug.WriteLine($"{Wrecks.Count} wrecks created in { totalSW.ElapsedMilliseconds} (ms)");
}
@@ -4782,6 +4791,7 @@ namespace Barotrauma
return;
}
beaconSonar = sonarItem.GetComponent<Sonar>();
beaconTransducers = sonarItem.GetConnectedComponents<SonarTransducer>().ToImmutableArray();
}
public void PrepareBeaconStation()
@@ -4908,9 +4918,20 @@ namespace Barotrauma
public bool CheckBeaconActive()
{
if (beaconSonar == null) { return false; }
if (beaconSonar.UseTransducers)
{
var connectedTransducers = beaconSonar.Item.GetConnectedComponents<SonarTransducer>();
foreach (var beaconTransducer in beaconTransducers)
{
if (!beaconTransducer.HasPower || !connectedTransducers.Contains(beaconTransducer)) { return false; }
}
}
return beaconSonar.HasPower && beaconSonar.CurrentMode == Sonar.Mode.Active;
}
/// <summary>
/// Set the crush depths of the connected subs to match the crush depth of the parent sub.
/// </summary>
private void SetLinkedSubCrushDepth(Submarine parentSub)
{
foreach (var connectedSub in parentSub.GetConnectedSubs())
@@ -5149,6 +5170,7 @@ namespace Barotrauma
BeaconStation = null;
beaconSonar = null;
beaconTransducers = ImmutableArray<SonarTransducer>.Empty;
StartOutpost = null;
EndOutpost = null;
@@ -413,8 +413,7 @@ namespace Barotrauma
new XAttribute("difficulty", Difficulty.ToString("G", CultureInfo.InvariantCulture)),
new XAttribute("size", XMLExtensions.PointToString(Size)),
new XAttribute("generationparams", GenerationParams.Identifier),
new XAttribute("initialdepth", InitialDepth),
new XAttribute("exhaustedeventsets", allEventsExhausted));
new XAttribute("initialdepth", InitialDepth));
newElement.Add(
new XAttribute(nameof(exhaustedEventSets), string.Join(',', exhaustedEventSets.Select(e => e.Value))));
@@ -816,7 +816,7 @@ namespace Barotrauma
public static float GetDistanceFactor(PhysicsBody triggererBody, PhysicsBody triggerBody, float colliderRadius)
{
return 1.0f - ConvertUnits.ToDisplayUnits(Vector2.Distance(triggererBody.SimPosition, triggerBody.SimPosition)) / colliderRadius;
return 1.0f - ConvertUnits.ToDisplayUnits(Vector2.Distance(triggererBody.SimPosition, triggerBody.SimPosition) - triggererBody.GetMaxExtent() / 2) / colliderRadius;
}
public Vector2 GetWaterFlowVelocity(Vector2 viewPosition)
@@ -651,7 +651,7 @@ namespace Barotrauma
newBody.Friction = 0.8f;
newBody.UserData = this;
newBody.Position = ConvertUnits.ToSimUnits(stairPos) + BodyOffset * Scale;
newBody.Position = ConvertUnits.ToSimUnits(stairPos) + ConvertUnits.ToSimUnits(BodyOffset) * Scale;
bodyDimensions.Add(newBody, new Vector2(bodyWidth, bodyHeight));
@@ -583,7 +583,11 @@ namespace Barotrauma
{
for (int dir = -1; dir <= 1; dir += 2)
{
WayPoint closest = stairPoints[i].FindClosest(dir, horizontalSearch: true, new Vector2(minDist * 1.5f, minDist / 2));
//connect to the closest waypoint, preferring non-stair waypoyints
//(it's easier for characters to fully get off stairs before moving on to the next set of stairs, than to move directly from one set of stairs to another)
WayPoint closest =
stairPoints[i].FindClosest(dir, horizontalSearch: true, new Vector2(minDist * 1.5f, minDist / 2), filter: wp => wp.Stairs == null) ??
stairPoints[i].FindClosest(dir, horizontalSearch: true, new Vector2(minDist * 1.5f, minDist / 2));
if (closest == null) { continue; }
stairPoints[i].ConnectTo(closest);
}