Build 1.1.4.0
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user