diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index 3456f0ccf..7d55f8c61 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -368,8 +368,8 @@ namespace Barotrauma foreach (var joint in LimbJoints) { - joint.BodyB.SetTransform( - joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB)*0.1f, + joint.LimbB?.body?.SetTransform( + joint.BodyA.Position + (joint.LocalAnchorA - joint.LocalAnchorB) * 0.1f, (joint.LowerLimit + joint.UpperLimit) / 2.0f); } @@ -394,7 +394,7 @@ namespace Barotrauma Limb torso = GetLimb(LimbType.Torso); Limb head = GetLimb(LimbType.Head); - MainLimb = torso == null ? head : torso; + MainLimb = torso ?? head; } public void AddJoint(XElement subElement, float scale = 1.0f) diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs index 236a2c85d..63108d2ea 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/DockingPort.cs @@ -345,17 +345,31 @@ namespace Barotrauma.Items.Components private void CreateDoorBody() { + Vector2 position = ConvertUnits.ToSimUnits(item.Position + (dockingTarget.door.Item.WorldPosition - item.WorldPosition)); + if (!MathUtils.IsValid(position)) + { + string errorMsg = + "Attempted to create a door body at an invalid position (item pos: " + item.Position + + ", item world pos: " + item.WorldPosition + + ", docking target world pos: " + DockingTarget.door.Item.WorldPosition + ")\n" + Environment.StackTrace; + + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce( + "DockingPort.CreateDoorBody:InvalidPosition", + GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + errorMsg); + position = Vector2.Zero; + } + doorBody = BodyFactory.CreateRectangle(GameMain.World, dockingTarget.door.Body.width, dockingTarget.door.Body.height, 1.0f, + position, dockingTarget.door); doorBody.CollisionCategories = Physics.CollisionWall; doorBody.BodyType = BodyType.Static; - doorBody.SetTransform( - ConvertUnits.ToSimUnits(item.Position + (dockingTarget.door.Item.WorldPosition - item.WorldPosition)), - 0.0f); } private void CreateHull() diff --git a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs index b3c8a5b03..c86ce633a 100644 --- a/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs +++ b/Barotrauma/BarotraumaShared/Source/Items/Components/Door.cs @@ -386,6 +386,15 @@ namespace Barotrauma.Items.Components foreach (PhysicsBody body in bodies) { float diff = 0.0f; + if (!MathUtils.IsValid(body.SimPosition)) + { + DebugConsole.ThrowError("Failed to push a limb out of a doorway - position of the body (character \"" + c.Name + "\") is not valid (" + body.SimPosition + ")"); + GameAnalyticsManager.AddErrorEventOnce("PushCharactersAway:LimbPosInvalid", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + "Failed to push a character out of a doorway - position of the character \"" + c.Name + "\" is not valid (" + body.SimPosition + ")." + + " Removed: " + c.Removed + + " Remoteplayer: " + c.IsRemotePlayer); + continue; + } if (isHorizontal) { diff --git a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs index 7ce46113a..4972e4f70 100644 --- a/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs +++ b/Barotrauma/BarotraumaShared/Source/Physics/PhysicsBody.cs @@ -360,6 +360,44 @@ namespace Barotrauma this.radius = radius; } + private bool IsValidValue(float value, string valueName) + { + if (!MathUtils.IsValid(value)) + { + string errorMsg = + "Attempted to apply invalid " + valueName + + " to a physics body (userdata: " + UserData == null ? "null" : UserData.ToString() + + "), value: " + value + "\n" + Environment.StackTrace; + + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce( + "PhysicsBody.SetPosition:InvalidPosition", + GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + errorMsg); + return false; + } + return true; + } + + private bool IsValidValue(Vector2 value, string valueName) + { + if (!MathUtils.IsValid(value)) + { + string errorMsg = + "Attempted to apply invalid " + valueName + + " to a physics body (userdata: " + UserData == null ? "null" : UserData.ToString() + + "), value: " + value + "\n" + Environment.StackTrace; + + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce( + "PhysicsBody.SetPosition:InvalidPosition", + GameAnalyticsSDK.Net.EGAErrorSeverity.Error, + errorMsg); + return false; + } + return true; + } + public void ResetDynamics() { body.ResetDynamics(); @@ -367,6 +405,7 @@ namespace Barotrauma public void ApplyLinearImpulse(Vector2 impulse) { + if (!IsValidValue(impulse, "impulse")) return; body.ApplyLinearImpulse(impulse); } @@ -375,6 +414,9 @@ namespace Barotrauma /// public void ApplyLinearImpulse(Vector2 impulse, float maxVelocity) { + if (!IsValidValue(impulse, "impulse")) return; + if (!IsValidValue(maxVelocity, "max velocity")) return; + float currSpeed = body.LinearVelocity.Length(); Vector2 velocityAddition = impulse / Mass; Vector2 newVelocity = body.LinearVelocity + velocityAddition; @@ -385,21 +427,26 @@ namespace Barotrauma public void ApplyLinearImpulse(Vector2 impulse, Vector2 point) { + if (!IsValidValue(impulse, "impulse")) return; body.ApplyLinearImpulse(impulse, point); } public void ApplyForce(Vector2 force) { + if (!IsValidValue(force, "force")) return; body.ApplyForce(force); } public void ApplyForce(Vector2 force, Vector2 point) { + if (!IsValidValue(force, "force")) return; + if (!IsValidValue(point, "point")) return; body.ApplyForce(force, point); } public void ApplyTorque(float torque) { + if (!IsValidValue(torque, "torque")) return; body.ApplyTorque(torque); } @@ -408,7 +455,10 @@ namespace Barotrauma 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")) return; + if (!IsValidValue(rotation, "rotation")) return; + body.SetTransform(simPosition, rotation); SetPrevTransform(simPosition, rotation); } @@ -418,14 +468,20 @@ namespace Barotrauma 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")) return; + if (!IsValidValue(rotation, "rotation")) return; + body.SetTransformIgnoreContacts(ref simPosition, rotation); SetPrevTransform(simPosition, rotation); } - public void SetPrevTransform(Vector2 position, float rotation) + public void SetPrevTransform(Vector2 simPosition, float rotation) { - prevPosition = position; + if (!IsValidValue(simPosition, "position")) return; + if (!IsValidValue(rotation, "rotation")) return; + + prevPosition = simPosition; prevRotation = rotation; } @@ -440,16 +496,19 @@ namespace Barotrauma prevPosition = (Vector2)targetPosition; } - body.SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation); + SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation); targetPosition = null; } - public void MoveToPos(Vector2 pos, float force, Vector2? pullPos = null) + public void MoveToPos(Vector2 simPosition, float force, Vector2? pullPos = null) { if (pullPos == null) pullPos = body.Position; + if (!IsValidValue(simPosition, "position")) return; + if (!IsValidValue(force, "force")) return; + Vector2 vel = body.LinearVelocity; - Vector2 deltaPos = pos - (Vector2)pullPos; + Vector2 deltaPos = simPosition - (Vector2)pullPos; deltaPos *= force; body.ApplyLinearImpulse((deltaPos - vel * 0.5f) * body.Mass, (Vector2)pullPos); } @@ -474,8 +533,8 @@ namespace Barotrauma dragForce = Math.Min(drag, Mass * 500.0f) * -velDir; } - body.ApplyForce(dragForce + buoyancy); - body.ApplyTorque(body.AngularVelocity * body.Mass * -0.08f); + ApplyForce(dragForce + buoyancy); + ApplyTorque(body.AngularVelocity * body.Mass * -0.08f); } @@ -559,18 +618,17 @@ namespace Barotrauma public void SmoothRotate(float targetRotation, float force = 10.0f) { float nextAngle = body.Rotation + body.AngularVelocity * (float)Timing.Step; - float angle = MathUtils.GetShortestAngle(nextAngle, targetRotation); - - float torque = angle * 60.0f * (force/100.0f); + float torque = angle * 60.0f * (force / 100.0f); if (body.IsKinematic) { + if (!IsValidValue(torque, "torque")) return; body.AngularVelocity = torque; } else { - body.ApplyTorque(body.Mass * torque); + ApplyTorque(body.Mass * torque); } }