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
@@ -685,7 +685,7 @@ namespace Barotrauma
{
movement = MathUtils.SmoothStep(movement, TargetMovement, 0.2f);
if (Collider.BodyType == BodyType.Dynamic)
if (Collider.BodyType == BodyType.Dynamic && onGround)
{
Collider.LinearVelocity = new Vector2(
movement.X,
@@ -1,5 +1,6 @@
using Barotrauma.Extensions;
using Barotrauma.Items.Components;
using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using FarseerPhysics;
using Microsoft.Xna.Framework;
@@ -1305,11 +1306,11 @@ namespace Barotrauma
//increase oxygen and clamp it above zero
// -> the character should be revived if there are no major afflictions in addition to lack of oxygen
target.Oxygen = Math.Max(target.Oxygen + 10.0f, 10.0f);
GameMain.LuaCs.Hook.Call("human.CPRSuccess", this);
LuaCsSetup.Instance.EventService.PublishEvent<IEventHumanCPRSuccess>(x => x.OnCharacterCPRSuccess(this));
}
else
{
GameMain.LuaCs.Hook.Call("human.CPRFailed", this);
LuaCsSetup.Instance.EventService.PublishEvent<IEventHumanCPRFailed>(x => x.OnCharacterCPRFailed(this));
}
}
}
@@ -1,17 +1,18 @@
using Barotrauma.Networking;
using Barotrauma.Extensions;
using Barotrauma.LuaCs.Events;
using Barotrauma.Networking;
using FarseerPhysics;
using FarseerPhysics.Dynamics;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;
using MoonSharp.Interpreter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq;
using Barotrauma.Extensions;
using LimbParams = Barotrauma.RagdollParams.LimbParams;
using JointParams = Barotrauma.RagdollParams.JointParams;
using MoonSharp.Interpreter;
using LimbParams = Barotrauma.RagdollParams.LimbParams;
namespace Barotrauma
{
@@ -31,6 +32,7 @@ namespace Barotrauma
{
public Fixture F1, F2;
public Vector2 LocalNormal;
public Vector2 WorldNormal;
public Vector2 Velocity;
public Vector2 ImpactPos;
@@ -40,7 +42,7 @@ namespace Barotrauma
F2 = f2;
Velocity = velocity;
LocalNormal = contact.Manifold.LocalNormal;
contact.GetWorldManifold(out _, out FarseerPhysics.Common.FixedArray2<Vector2> points);
contact.GetWorldManifold(out WorldNormal, out FarseerPhysics.Common.FixedArray2<Vector2> points);
ImpactPos = points[0];
}
}
@@ -827,7 +829,7 @@ namespace Barotrauma
return true;
}
private void ApplyImpact(Fixture f1, Fixture f2, Vector2 localNormal, Vector2 impactPos, Vector2 velocity)
private void ApplyImpact(Fixture f1, Fixture f2, Vector2 worldNormal, Vector2 impactPos, Vector2 velocity)
{
if (character.DisableImpactDamageTimer > 0.0f) { return; }
@@ -839,7 +841,7 @@ namespace Barotrauma
return;
}
Vector2 normal = localNormal;
Vector2 normal = worldNormal;
float impact = Vector2.Dot(velocity, -normal);
if (f1.Body == Collider.FarseerBody || !Collider.Enabled)
{
@@ -857,7 +859,8 @@ namespace Barotrauma
float impactDamage = GetImpactDamage(impact, impactTolerance);
var should = GameMain.LuaCs.Hook.Call<float?>("changeFallDamage", impactDamage, character, impactPos, velocity);
float? should = null;
LuaCsSetup.Instance.EventService.PublishEvent<IEventChangeFallDamage>(x => should = x.OnChangeFallDamage(impactDamage, character, impactPos, velocity) ?? should);
if (should != null)
{
@@ -1077,9 +1080,12 @@ namespace Barotrauma
}
Hull newHull = Hull.FindHull(findPos, currentHull);
if (setInWater && newHull == null)
if (setInWater)
{
inWater = true;
if (newHull == null || findPos.Y < newHull.WorldSurface)
{
inWater = true;
}
}
if (newHull == currentHull) { return; }
@@ -1122,7 +1128,10 @@ namespace Barotrauma
{
//don't teleport out yet if the character is going through a gap
if (Gap.FindAdjacent(Gap.GapList.Where(g => g.Submarine == currentHull.Submarine), findPos, 150.0f, allowRoomToRoom: true) != null) { return; }
if (Limbs.Any(l => Gap.FindAdjacent(currentHull.ConnectedGaps, l.WorldPosition, ConvertUnits.ToDisplayUnits(l.body.GetSize().Combine()), allowRoomToRoom: true) != null)) { return; }
if (Limbs.Any(l => !l.IsSevered && Gap.FindAdjacent(currentHull.ConnectedGaps, l.WorldPosition, ConvertUnits.ToDisplayUnits(l.body.GetSize().Combine()), allowRoomToRoom: true) != null))
{
return;
}
character.MemLocalState?.Clear();
Teleport(ConvertUnits.ToSimUnits(currentHull.Submarine.Position), currentHull.Submarine.Velocity);
}
@@ -1259,6 +1268,9 @@ namespace Barotrauma
private float BodyInRestDelay = 1.0f;
/// <summary>
/// Controls the sleeping state of this character
/// </summary>
public bool BodyInRest
{
get { return bodyInRestTimer > BodyInRestDelay; }
@@ -1282,7 +1294,7 @@ namespace Barotrauma
while (impactQueue.Count > 0)
{
var impact = impactQueue.Dequeue();
ApplyImpact(impact.F1, impact.F2, impact.LocalNormal, impact.ImpactPos, impact.Velocity);
ApplyImpact(impact.F1, impact.F2, impact.WorldNormal, impact.ImpactPos, impact.Velocity);
}
CheckValidity();
@@ -1325,9 +1337,18 @@ namespace Barotrauma
}
float MaxVel = NetConfig.MaxPhysicsBodyVelocity;
Collider.LinearVelocity = new Vector2(
NetConfig.Quantize(Collider.LinearVelocity.X, -MaxVel, MaxVel, 12),
NetConfig.Quantize(Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12));
if (GameMain.NetworkMember != null)
{
Collider.LinearVelocity = new Vector2(
NetConfig.Quantize(Collider.LinearVelocity.X, -MaxVel, MaxVel, 12),
NetConfig.Quantize(Collider.LinearVelocity.Y, -MaxVel, MaxVel, 12));
}
else
{
Collider.LinearVelocity = new Vector2(
MathHelper.Clamp(Collider.LinearVelocity.X, -MaxVel, MaxVel),
MathHelper.Clamp(Collider.LinearVelocity.Y, -MaxVel, MaxVel));
}
if (forceStanding)
{
@@ -1381,9 +1402,19 @@ namespace Barotrauma
UpdateHullFlowForces(deltaTime);
if (currentHull == null ||
bool applyWaterForces =
currentHull == null ||
currentHull.WaterVolume > currentHull.Volume * 0.95f ||
ConvertUnits.ToSimUnits(currentHull.Surface) > Collider.SimPosition.Y)
ConvertUnits.ToSimUnits(currentHull.Surface) > Collider.SimPosition.Y;
#if CLIENT
if (Screen.Selected is CharacterEditor.CharacterEditorScreen &&
this is AnimController animController)
{
applyWaterForces = animController.CurrentAnimationParams is SwimParams;
}
#endif
if (applyWaterForces)
{
Collider.ApplyWaterForces();
}
@@ -1473,10 +1504,10 @@ namespace Barotrauma
else
{
// Falling -> ragdoll briefly if we are not moving at all, because we are probably stuck.
if (Collider.LinearVelocity == Vector2.Zero && !character.IsRemotePlayer)
if (Collider.LinearVelocity == Vector2.Zero && GameMain.NetworkMember is not { IsClient: true })
{
character.IsRagdolled = true;
if (character.IsBot)
if (!character.IsPlayer)
{
// Seems to work without this on player controlled characters -> not sure if we should call it always or just for the bots.
character.SetInput(InputType.Ragdoll, hit: false, held: true);
@@ -1836,7 +1867,13 @@ namespace Barotrauma
{
floorFixture = standOnFloorFixture;
standOnFloorY = rayStart.Y + (rayEnd.Y - rayStart.Y) * standOnFloorFraction;
if (rayStart.Y - standOnFloorY < Collider.Height * 0.5f + Collider.Radius + ColliderHeightFromFloor * 1.2f)
//allow the floor to be just a bit below the bottom of the collider for the character to be "on ground"
//there is some inaccuracy in the physics simulation (and floats), the collider isn't usually precisely ColliderHeightFromFloor above the floor
const float Tolerance = 0.1f;
float standHeight = Collider.Height * 0.5f + Collider.Radius + ColliderHeightFromFloor;
if (rayStart.Y - standOnFloorY <= standHeight + Tolerance)
{
onGround = true;
if (standOnFloorFixture.CollisionCategories == Physics.CollisionStairs)