diff --git a/Barotrauma/BarotraumaClient/Source/Items/Item.cs b/Barotrauma/BarotraumaClient/Source/Items/Item.cs index 978540201..5544e8c3a 100644 --- a/Barotrauma/BarotraumaClient/Source/Items/Item.cs +++ b/Barotrauma/BarotraumaClient/Source/Items/Item.cs @@ -453,7 +453,7 @@ namespace Barotrauma float newRotation = msg.ReadRangedSingle(0.0f, MathHelper.TwoPi, 7); bool awake = msg.ReadBoolean(); Vector2 newVelocity = Vector2.Zero; - + if (awake) { newVelocity = new Vector2( @@ -461,6 +461,19 @@ namespace Barotrauma msg.ReadRangedSingle(-MaxVel, MaxVel, 12)); } + if (!MathUtils.IsValid(newPosition) || !MathUtils.IsValid(newRotation) || !MathUtils.IsValid(newVelocity)) + { + string errorMsg = "Received invalid position data for the item \"" + Name + + "\" (position: " + newPosition + ", rotation: " + newRotation + ", velocity: " + newVelocity + ")"; +#if DEBUG + DebugConsole.ThrowError(errorMsg); +#endif + GameAnalyticsManager.AddErrorEventOnce("Item.ClientReadPosition:InvalidData" + ID, + GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + errorMsg); + return; + } + if (body == null) { DebugConsole.ThrowError("Received a position update for an item with no physics body (" + Name + ")"); @@ -470,7 +483,7 @@ namespace Barotrauma body.FarseerBody.Awake = awake; if (body.FarseerBody.Awake) { - if ((newVelocity - body.LinearVelocity).Length() > 8.0f) body.LinearVelocity = newVelocity; + if ((newVelocity - body.LinearVelocity).LengthSquared() > 8.0f * 8.0f) body.LinearVelocity = newVelocity; } else { @@ -490,11 +503,12 @@ namespace Barotrauma if ((newPosition - SimPosition).Length() > body.LinearVelocity.Length() * 2.0f) { - body.SetTransform(newPosition, newRotation); - - Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); - rect.X = (int)(displayPos.X - rect.Width / 2.0f); - rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); + if (body.SetTransform(newPosition, newRotation)) + { + Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); + rect.X = (int)(displayPos.X - rect.Width / 2.0f); + rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index e69c30f19..587edd342 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -1332,8 +1332,24 @@ namespace Barotrauma character.AnimController.Anim = AnimController.Animation.None; } - Collider.LinearVelocity = Vector2.Zero; - Collider.CorrectPosition(character.MemState, deltaTime, out overrideTargetMovement); + Vector2 newVelocity = overrideTargetMovement; + Vector2 newPosition = Collider.SimPosition; + Collider.CorrectPosition(character.MemState, deltaTime, out newVelocity, out newPosition); + + newVelocity = newVelocity.ClampLength(100.0f); + if (!MathUtils.IsValid(newVelocity)) newVelocity = Vector2.Zero; + + Collider.LinearVelocity = newVelocity; + float distSqrd = Vector2.DistanceSquared(newPosition, Collider.SimPosition); + if (distSqrd > 10.0f) + { + SetPosition(newPosition); + } + else if (distSqrd > 0.1f) + { + Collider.SetTransform(newPosition, Collider.Rotation); + overrideTargetMovement = newVelocity; + } //unconscious/dead characters can't correct their position using AnimController movement // -> we need to correct it manually @@ -1451,10 +1467,18 @@ namespace Barotrauma } } - Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation + rotationError); - foreach (Limb limb in Limbs) + float errorMagnitude = positionError.Length(); + if (errorMagnitude > 0.01f) { - limb.body.SetTransform(limb.body.SimPosition + positionError, limb.body.Rotation); + Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation + rotationError); + if (errorMagnitude > 0.5f) + { + character.MemLocalState.Clear(); + foreach (Limb limb in Limbs) + { + limb.body.SetTransform(limb.body.SimPosition + positionError, limb.body.Rotation); + } + } } } diff --git a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs index fd71f11a2..f6061e3b4 100644 --- a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs @@ -463,30 +463,32 @@ namespace Barotrauma body.ApplyTorque(torque); } - public void SetTransform(Vector2 simPosition, float rotation) + public bool SetTransform(Vector2 simPosition, float rotation) { System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition)); System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f); System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f); - if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return; - if (!IsValidValue(rotation, "rotation")) return; + if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false; + if (!IsValidValue(rotation, "rotation")) return false; body.SetTransform(simPosition, rotation); SetPrevTransform(simPosition, rotation); + return true; } - public void SetTransformIgnoreContacts(Vector2 simPosition, float rotation) + public bool SetTransformIgnoreContacts(Vector2 simPosition, float rotation) { System.Diagnostics.Debug.Assert(MathUtils.IsValid(simPosition)); System.Diagnostics.Debug.Assert(Math.Abs(simPosition.X) < 1000000.0f); System.Diagnostics.Debug.Assert(Math.Abs(simPosition.Y) < 1000000.0f); - if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return; - if (!IsValidValue(rotation, "rotation")) return; + if (!IsValidValue(simPosition, "position", -1e10f, 1e10f)) return false; + if (!IsValidValue(rotation, "rotation")) return false; body.SetTransformIgnoreContacts(ref simPosition, rotation); SetPrevTransform(simPosition, rotation); + return true; } public void SetPrevTransform(Vector2 simPosition, float rotation)