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; }