From f4a9458d66a213ac0101c8884a6860c2cda8c078 Mon Sep 17 00:00:00 2001 From: Joonas Rikkonen Date: Thu, 22 Nov 2018 18:47:57 +0200 Subject: [PATCH] Attempt to fix "invalid force to a physics body" errors. Haven't been able to consistently reproduce the errors, but I'm pretty sure it was caused by GetCenterOfMass returning invalid values when all character's limbs are disabled (may happen for example when a character that's far away from the client's character dies). --- .../Animation/FishAnimController.cs | 22 +++++++++++++++++-- .../Source/Characters/Animation/Ragdoll.cs | 16 +++++++++++++- 2 files changed, 35 insertions(+), 3 deletions(-) diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs index 5ffc3bd6f..0f7210c2a 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/FishAnimController.cs @@ -400,9 +400,27 @@ namespace Barotrauma foreach (Limb limb in Limbs) { - if (limb.type == LimbType.Head || limb.type == LimbType.Tail || limb.IsSevered) continue; + if (limb.type == LimbType.Head || limb.type == LimbType.Tail || limb.IsSevered || !limb.body.Enabled) continue; + if (limb.Mass <= 0.0f) + { + string errorMsg = "Creature death animation error: invalid limb mass on character \"" + character.SpeciesName + "\" (type: " + limb.type + ", mass: " + limb.Mass + ")"; + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("FishAnimController.UpdateDying:InvalidMass" + character.ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + deathAnimTimer = deathAnimDuration; + return; + } - limb.body.ApplyForce((centerOfMass - limb.SimPosition) * (float)(Math.Sin(walkPos) * Math.Sqrt(limb.Mass)) * 10.0f); + Vector2 diff = (centerOfMass - limb.SimPosition); + if (!MathUtils.IsValid(diff)) + { + string errorMsg = "Creature death animation error: invalid diff (center of mass: " + centerOfMass + ", limb position: " + limb.SimPosition + ")"; + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("FishAnimController.UpdateDying:InvalidDiff" + character.ID, GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + deathAnimTimer = deathAnimDuration; + return; + } + + limb.body.ApplyForce(diff * (float)(Math.Sin(walkPos) * Math.Sqrt(limb.Mass)) * 10.0f); } } diff --git a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs index 4e3a743ec..7bbc8f4c0 100644 --- a/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs +++ b/Barotrauma/BarotraumaShared/Source/Characters/Animation/Ragdoll.cs @@ -711,6 +711,12 @@ namespace Barotrauma public Vector2 GetCenterOfMass() { + //all limbs disabled -> use the position of the collider + if (!Limbs.Any(l => !l.IsSevered && l.body.Enabled)) + { + return Collider.SimPosition; + } + Vector2 centerOfMass = Vector2.Zero; float totalMass = 0.0f; foreach (Limb limb in Limbs) @@ -719,9 +725,17 @@ namespace Barotrauma centerOfMass += limb.Mass * limb.SimPosition; totalMass += limb.Mass; } - centerOfMass /= totalMass; + if (!MathUtils.IsValid(centerOfMass)) + { + string errorMsg = "Ragdoll.GetCenterOfMass returned an invalid value (" + centerOfMass + "). Limb positions: {" + + string.Join(", ", limbs.Select(l => l.SimPosition)) + "}, total mass: " + totalMass + "."; + DebugConsole.ThrowError(errorMsg); + GameAnalyticsManager.AddErrorEventOnce("Ragdoll.GetCenterOfMass", GameAnalyticsSDK.Net.EGAErrorSeverity.Error, errorMsg); + return Collider.SimPosition; + } + return centerOfMass; }