diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index b5d55eaa2..9a18e3aaf 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -706,17 +706,36 @@ namespace Barotrauma public void FindHull(Vector2? worldPosition = null, bool setSubmarine = true) { - if (!CanEnterSubmarine) - { - return; - } - Vector2 findPos = worldPosition==null ? this.WorldPosition : (Vector2)worldPosition; Hull newHull = Hull.FindHull(findPos, currentHull); if (newHull == currentHull) return; + if (!CanEnterSubmarine) + { + //character is inside the sub even though it shouldn't be able to enter -> teleport it out + + //far from an ideal solution, but monsters getting lodged inside the sub seems to be + //pretty rare during normal gameplay (requires abnormally high velocities), so I think + //this is preferable to the cost of using continuous collision detection for the character collider + if (newHull != null) + { + //find a position 32 units away from the hull + Vector2? intersection = MathUtils.GetLineRectangleIntersection( + newHull.WorldPosition, + newHull.WorldPosition + Vector2.Normalize(WorldPosition - newHull.WorldPosition) * Math.Max(newHull.Rect.Width, newHull.Rect.Height), + new Rectangle(newHull.WorldRect.X - 32, newHull.WorldRect.Y + 32, newHull.WorldRect.Width + 64, newHull.Rect.Height + 64)); + + if (intersection != null) + { + Collider.SetTransform(ConvertUnits.ToSimUnits((Vector2)intersection), Collider.Rotation); + } + } + + return; + } + if (setSubmarine) { //in -> out