v1.12.6.2 (Spring Update 2026)

This commit is contained in:
Regalis11
2026-04-09 15:10:07 +03:00
parent c8657caefa
commit a4607dffad
197 changed files with 5586 additions and 3461 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,
@@ -30,6 +30,7 @@ namespace Barotrauma
{
public Fixture F1, F2;
public Vector2 LocalNormal;
public Vector2 WorldNormal;
public Vector2 Velocity;
public Vector2 ImpactPos;
@@ -39,7 +40,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];
}
}
@@ -826,7 +827,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; }
@@ -838,7 +839,7 @@ namespace Barotrauma
return;
}
Vector2 normal = localNormal;
Vector2 normal = worldNormal;
float impact = Vector2.Dot(velocity, -normal);
if (f1.Body == Collider.FarseerBody || !Collider.Enabled)
{
@@ -1069,9 +1070,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; }
@@ -1114,7 +1118,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);
}
@@ -1246,6 +1253,9 @@ namespace Barotrauma
private float BodyInRestDelay = 1.0f;
/// <summary>
/// Controls the sleeping state of this character
/// </summary>
public bool BodyInRest
{
get { return bodyInRestTimer > BodyInRestDelay; }
@@ -1269,7 +1279,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();
@@ -1312,9 +1322,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)
{
@@ -1368,9 +1387,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();
}
@@ -1460,10 +1489,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);
@@ -1823,7 +1852,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)