Build 1.1.4.0

This commit is contained in:
Markus Isberg
2023-03-31 18:40:44 +03:00
parent efba17e0ff
commit 9470edead3
483 changed files with 17487 additions and 8548 deletions
@@ -173,18 +173,18 @@ namespace Barotrauma
if (value == colliderIndex || collider == null) { return; }
if (value >= collider.Count || value < 0) { return; }
if (collider[colliderIndex].height < collider[value].height)
if (collider[colliderIndex].Height < collider[value].Height)
{
Vector2 pos1 = collider[colliderIndex].SimPosition;
pos1.Y -= collider[colliderIndex].height * ColliderHeightFromFloor;
pos1.Y -= collider[colliderIndex].Height * ColliderHeightFromFloor;
Vector2 pos2 = pos1;
pos2.Y += collider[value].height * 1.1f;
pos2.Y += collider[value].Height * 1.1f;
if (GameMain.World.RayCast(pos1, pos2).Any(f => f.CollisionCategories.HasFlag(Physics.CollisionWall) && !(f.Body.UserData is Submarine))) { return; }
}
Vector2 pos = collider[colliderIndex].SimPosition;
pos.Y -= collider[colliderIndex].height * 0.5f;
pos.Y += collider[value].height * 0.5f;
pos.Y -= collider[colliderIndex].Height * 0.5f;
pos.Y += collider[value].Height * 0.5f;
collider[value].SetTransform(pos, collider[colliderIndex].Rotation);
collider[value].LinearVelocity = collider[colliderIndex].LinearVelocity;
@@ -575,6 +575,10 @@ namespace Barotrauma
protected void AddLimb(LimbParams limbParams)
{
if (limbParams.ID < 0 || limbParams.ID > 255)
{
throw new Exception($"Invalid limb params in limb \"{limbParams.Type}\". \"{limbParams.ID}\" is not a valid limb ID.");
}
byte ID = Convert.ToByte(limbParams.ID);
Limb limb = new Limb(this, character, limbParams);
limb.body.FarseerBody.OnCollision += OnLimbCollision;
@@ -680,6 +684,10 @@ namespace Barotrauma
}
return true;
}
else if (character.Submarine != null && structure.Submarine != null && character.Submarine != structure.Submarine)
{
return false;
}
Vector2 colliderBottom = GetColliderBottom();
if (structure.IsPlatform)
@@ -1189,7 +1197,7 @@ namespace Barotrauma
{
inWater = false;
headInWater = false;
RefreshFloorY(ignoreStairs: Stairs == null);
RefreshFloorY(deltaTime, ignoreStairs: Stairs == null);
}
//ragdoll isn't in any room -> it's in the water
else if (currentHull == null)
@@ -1201,10 +1209,12 @@ namespace Barotrauma
{
headInWater = false;
inWater = false;
RefreshFloorY(ignoreStairs: Stairs == null);
RefreshFloorY(deltaTime, ignoreStairs: Stairs == null);
if (currentHull.WaterPercentage > 0.001f)
{
float waterSurface = ConvertUnits.ToSimUnits(GetSurfaceY());
(float waterSurfaceDisplayUnits, float ceilingDisplayUnits) = GetWaterSurfaceAndCeilingY();
float waterSurfaceY = ConvertUnits.ToSimUnits(waterSurfaceDisplayUnits);
float ceilingY = ConvertUnits.ToSimUnits(ceilingDisplayUnits);
if (targetMovement.Y < 0.0f)
{
Vector2 colliderBottom = GetColliderBottom();
@@ -1214,13 +1224,21 @@ namespace Barotrauma
{
//set floorY to the position of the floor in the hull below the character
var lowerHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(colliderBottom), useWorldCoordinates: false);
if (lowerHull != null) floorY = ConvertUnits.ToSimUnits(lowerHull.Rect.Y - lowerHull.Rect.Height);
if (lowerHull != null)
{
floorY = ConvertUnits.ToSimUnits(lowerHull.Rect.Y - lowerHull.Rect.Height);
}
}
}
float standHeight = HeadPosition ?? TorsoPosition ?? Collider.GetMaxExtent() * 0.5f;
if (Collider.SimPosition.Y < waterSurface && waterSurface - floorY > standHeight * 0.8f)
if (Collider.SimPosition.Y < waterSurfaceY)
{
inWater = true;
//too deep to stand up, or not enough room to stand up
if (waterSurfaceY - floorY > standHeight * 0.8f ||
ceilingY - floorY < standHeight * 0.8f)
{
inWater = true;
}
}
}
}
@@ -1281,21 +1299,32 @@ namespace Barotrauma
limb.Update(deltaTime);
}
if (!inWater && character.AllowInput && levitatingCollider && Collider.LinearVelocity.Y > -ImpactTolerance && onGround)
if (!inWater && character.AllowInput && levitatingCollider)
{
float targetY = standOnFloorY + ((float)Math.Abs(Math.Cos(Collider.Rotation)) * Collider.height * 0.5f) + Collider.radius + ColliderHeightFromFloor;
if (Math.Abs(Collider.SimPosition.Y - targetY) > 0.01f && onGround)
if (onGround && Collider.LinearVelocity.Y > -ImpactTolerance)
{
if (Stairs != null)
float targetY = standOnFloorY + ((float)Math.Abs(Math.Cos(Collider.Rotation)) * Collider.Height * 0.5f) + Collider.Radius + ColliderHeightFromFloor;
if (Math.Abs(Collider.SimPosition.Y - targetY) > 0.01f)
{
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X,
(targetY < Collider.SimPosition.Y ? Math.Sign(targetY - Collider.SimPosition.Y) : (targetY - Collider.SimPosition.Y)) * 5.0f);
if (Stairs != null)
{
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X,
(targetY < Collider.SimPosition.Y ? Math.Sign(targetY - Collider.SimPosition.Y) : (targetY - Collider.SimPosition.Y)) * 5.0f);
}
else
{
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X, (targetY - Collider.SimPosition.Y) * 5.0f);
}
}
else
}
else
{
// Falling -> ragdoll briefly if we are not moving at all, because we are probably stuck.
if (Collider.LinearVelocity == Vector2.Zero)
{
Collider.LinearVelocity = new Vector2(Collider.LinearVelocity.X, (targetY - Collider.SimPosition.Y) * 5.0f);
character.IsRagdolled = true;
}
}
}
}
UpdateProjSpecific(deltaTime, cam);
forceNotStanding = false;
@@ -1525,15 +1554,24 @@ namespace Barotrauma
lastFloorCheckPos = Vector2.Zero;
}
private void RefreshFloorY(Limb refLimb = null, bool ignoreStairs = false)
// Force check floor y at least once a second so that we'll drop through gaps that we are standing upon.
private const float FloorYStaleTime = 1;
private float floorYCheckTimer;
private void RefreshFloorY(float deltaTime, Limb refLimb = null, bool ignoreStairs = false)
{
floorYCheckTimer -= deltaTime;
PhysicsBody refBody = refLimb == null ? Collider : refLimb.body;
if (Vector2.DistanceSquared(lastFloorCheckPos, refBody.SimPosition) > 0.1f * 0.1f || lastFloorCheckIgnoreStairs != ignoreStairs || lastFloorCheckIgnorePlatforms != IgnorePlatforms)
if (floorYCheckTimer < 0 ||
lastFloorCheckIgnoreStairs != ignoreStairs ||
lastFloorCheckIgnorePlatforms != IgnorePlatforms ||
Vector2.DistanceSquared(lastFloorCheckPos, refBody.SimPosition) > 0.1f * 0.1f)
{
floorY = GetFloorY(refBody.SimPosition, ignoreStairs);
lastFloorCheckPos = refBody.SimPosition;
lastFloorCheckIgnoreStairs = ignoreStairs;
lastFloorCheckIgnorePlatforms = IgnorePlatforms;
// Add some randomness to prevent all stationary characters doing the checks at the same frame.
floorYCheckTimer = FloorYStaleTime * Rand.Range(0.9f, 1.1f);
}
}
@@ -1616,7 +1654,7 @@ 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)
if (rayStart.Y - standOnFloorY < Collider.Height * 0.5f + Collider.Radius + ColliderHeightFromFloor * 1.2f)
{
onGround = true;
if (standOnFloorFixture.CollisionCategories == Physics.CollisionStairs)
@@ -1655,22 +1693,34 @@ namespace Barotrauma
}
}
/// <summary>
/// Get the position of the surface of water at the position of the character, in display units (taking into account connected hulls above the hull the character is in)
/// </summary>
public float GetSurfaceY()
{
return GetWaterSurfaceAndCeilingY().WaterSurfaceY;
}
/// <summary>
/// Get the position of the surface of water and the ceiling (= upper edge of the hull) at the position of the character, in display units (taking into account connected hulls above the hull the character is in).
/// </summary>
private (float WaterSurfaceY, float CeilingY) GetWaterSurfaceAndCeilingY()
{
//check both hulls: the hull whose coordinate space the ragdoll is in, and the hull whose bounds the character's origin actually is inside
if (currentHull == null || character.CurrentHull == null)
{
return float.PositiveInfinity;
return (float.PositiveInfinity, float.PositiveInfinity);
}
float surfacePos = currentHull.Surface;
float surfaceY = currentHull.Surface;
float ceilingY = currentHull.Rect.Y;
float surfaceThreshold = ConvertUnits.ToDisplayUnits(Collider.SimPosition.Y + 1.0f);
//if the hull is almost full of water, check if there's a water-filled hull above it
//and use its water surface instead of the current hull's
if (currentHull.Rect.Y - currentHull.Surface < 5.0f)
{
GetSurfacePos(currentHull, ref surfacePos);
void GetSurfacePos(Hull hull, ref float prevSurfacePos)
{
GetSurfacePos(currentHull, ref surfaceY, ref ceilingY);
void GetSurfacePos(Hull hull, ref float prevSurfacePos, ref float ceilingPos)
{
if (prevSurfacePos > surfaceThreshold) { return; }
foreach (Gap gap in hull.ConnectedGaps)
@@ -1681,6 +1731,7 @@ namespace Barotrauma
//if the gap is above us and leads outside, there's no surface to limit the movement
if (!gap.IsRoomToRoom && gap.Position.Y > hull.Position.Y)
{
ceilingPos += 100000.0f;
prevSurfacePos += 100000.0f;
return;
}
@@ -1689,15 +1740,16 @@ namespace Barotrauma
{
if (linkedTo is Hull otherHull && otherHull != hull && otherHull != currentHull)
{
prevSurfacePos = Math.Max(surfacePos, otherHull.Surface);
GetSurfacePos(otherHull, ref prevSurfacePos);
prevSurfacePos = Math.Max(surfaceY, otherHull.Surface);
ceilingPos = Math.Max(ceilingPos, otherHull.Rect.Y);
GetSurfacePos(otherHull, ref prevSurfacePos, ref ceilingPos);
break;
}
}
}
}
}
return surfacePos;
return (surfaceY, ceilingY);
}
public void SetPosition(Vector2 simPosition, bool lerp = false, bool ignorePlatforms = true, bool forceMainLimbToCollider = false, bool detachProjectiles = true)
@@ -1803,22 +1855,36 @@ namespace Barotrauma
private bool collisionsDisabled;
private double lastObstacleRayCastTime;
protected void CheckDistFromCollider()
{
float allowedDist = Math.Max(Math.Max(Collider.radius, Collider.width), Collider.height) * 2.0f;
float allowedDist = Math.Max(Math.Max(Collider.Radius, Collider.Width), Collider.Height) * 2.0f;
allowedDist = Math.Max(allowedDist, 1.0f);
float resetDist = allowedDist * 5.0f;
float obstacleCheckDist = 0.3f;
Vector2 diff = Collider.SimPosition - MainLimb.SimPosition;
float distSqrd = diff.LengthSquared();
if (distSqrd > resetDist * resetDist)
bool shouldReset = distSqrd > resetDist * resetDist;
if (!shouldReset && distSqrd > obstacleCheckDist * obstacleCheckDist)
{
if (Timing.TotalTime > lastObstacleRayCastTime + 1 &&
Submarine.PickBody(Collider.SimPosition, MainLimb.SimPosition, collisionCategory: Physics.CollisionWall) != null)
{
shouldReset = true;
lastObstacleRayCastTime = Timing.TotalTime;
}
}
if (shouldReset)
{
//ragdoll way too far, reset position
SetPosition(Collider.SimPosition, lerp: true, forceMainLimbToCollider: true);
}
if (distSqrd > allowedDist * allowedDist)
else if (distSqrd > allowedDist * allowedDist)
{
//ragdoll too far from the collider, disable collisions until it's close enough
//(in case the ragdoll has gotten stuck somewhere)
@@ -1840,7 +1906,7 @@ namespace Barotrauma
collisionsDisabled = false;
//force collision categories to be updated
prevCollisionCategory = Category.None;
}
}
}
partial void UpdateNetPlayerPositionProjSpecific(float deltaTime, float lowestSubPos);