From 99cf438ed7c159ba1c62a6ec53deb585c3de15c9 Mon Sep 17 00:00:00 2001 From: Regalis Date: Fri, 17 Feb 2017 19:27:54 +0200 Subject: [PATCH 1/2] The lowest point of a character collider is calculated from its AABB (works correctly now even if the collider is rotated, allowing prone characters to be dragged through stairs), dragged characters collide with stairs when climbing up, the AI of unconscious or stunned characters isn't updated --- Subsurface/Source/Characters/AICharacter.cs | 2 +- .../Animation/HumanoidAnimController.cs | 3 +++ .../Source/Characters/Animation/Ragdoll.cs | 24 +++++++++++++++---- 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index 43affafbc..904789a7b 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -47,7 +47,7 @@ namespace Barotrauma AnimController.SimplePhysicsEnabled = false; } - if (isDead || health <= 0.0f) return; + if (IsDead || Health <= 0.0f || IsUnconscious || Stun > 0.0f) return; if (Controlled == this || !aiController.Enabled) return; diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index 0a413ba52..b131e258d 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -932,6 +932,9 @@ namespace Barotrauma { target.AnimController.TargetMovement = Vector2.Lerp(target.AnimController.TargetMovement, (character.SimPosition + Vector2.UnitX * Dir) - target.SimPosition, 0.5f); } + + //if on stairs, make the dragged character "climb up" (= collide with stairs) + if (stairs != null) target.AnimController.TargetMovement = new Vector2 (target.AnimController.TargetMovement.X, 1.0f); } public void Grab(Vector2 rightHandPos, Vector2 leftHandPos) diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index ce775b1e3..b5d55eaa2 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -1268,10 +1268,26 @@ namespace Barotrauma { float halfHeight = Collider.height * 0.5f + Collider.radius; - Vector2 offset = Vector2.Zero; - offset.Y = -colliderHeightFromFloor; - return Collider.SimPosition + offset + - new Vector2((float)Math.Sin(Collider.Rotation), -(float)Math.Cos(Collider.Rotation)) * halfHeight; + float offset = 0.0f; + + if (!character.IsUnconscious && !character.IsDead && character.Stun <= 0.0f) + { + offset = -colliderHeightFromFloor; + } + + float lowestBound = Collider.SimPosition.Y; + for (int i = 0; i < Collider.FarseerBody.FixtureList.Count; i++) + { + FarseerPhysics.Collision.AABB aabb; + FarseerPhysics.Common.Transform transform; + + Collider.FarseerBody.GetTransform(out transform); + Collider.FarseerBody.FixtureList[i].Shape.ComputeAABB(out aabb, ref transform, i); + + lowestBound = Math.Min(aabb.LowerBound.Y, lowestBound); + } + + return new Vector2(Collider.SimPosition.X, lowestBound + offset); } public Limb FindLowestLimb() From a5e56f7d4d73a3cc7c42b7c9a72af0047505c176 Mon Sep 17 00:00:00 2001 From: Regalis Date: Fri, 17 Feb 2017 19:28:16 +0200 Subject: [PATCH 2/2] Hacky fix for monsters getting lodged inside the sub due to tunneling --- .../Source/Characters/Animation/Ragdoll.cs | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) 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