From 1b59d1bc215d282fae149099f650ac5f8493ce88 Mon Sep 17 00:00:00 2001 From: Regalis Date: Fri, 14 Oct 2016 16:08:55 +0300 Subject: [PATCH] - disabling the collider and placing it on the torso when swimming, stunned or dead (todo: attempt to get swimming working with the collider controlling movement) - only the collider can receive impact damage - shorter collider to allow crouching in tight spaces - AI characters are considered close enough to a waypoint if their collider overlaps with it (instead of a distance check) --- Subsurface/Content/Characters/Human/human.xml | 2 +- .../Source/Characters/AI/HumanAIController.cs | 22 +++--- .../Characters/AI/IndoorsSteeringManager.cs | 13 +++- .../AI/Objectives/AIObjectiveCombat.cs | 11 +-- .../Animation/HumanoidAnimController.cs | 47 ++++++++---- .../Source/Characters/Animation/Ragdoll.cs | 73 ++++++++++--------- Subsurface/Source/Characters/Character.cs | 2 +- Subsurface/Source/Characters/Limb.cs | 2 +- 8 files changed, 102 insertions(+), 70 deletions(-) diff --git a/Subsurface/Content/Characters/Human/human.xml b/Subsurface/Content/Characters/Human/human.xml index eef8ab7b9..bf5391794 100644 --- a/Subsurface/Content/Characters/Human/human.xml +++ b/Subsurface/Content/Characters/Human/human.xml @@ -76,7 +76,7 @@ - + diff --git a/Subsurface/Source/Characters/AI/HumanAIController.cs b/Subsurface/Source/Characters/AI/HumanAIController.cs index 300ceb8ef..9ab385454 100644 --- a/Subsurface/Source/Characters/AI/HumanAIController.cs +++ b/Subsurface/Source/Characters/AI/HumanAIController.cs @@ -82,20 +82,20 @@ namespace Barotrauma Character.AnimController.IgnorePlatforms = true; } - if (Character.AnimController.Stairs != null) - { - float yDiff = currPath.CurrentNode.WorldPosition.Y - Character.WorldPosition.Y; + //if (Character.AnimController.Stairs != null) + //{ + // float yDiff = currPath.CurrentNode.WorldPosition.Y - Character.WorldPosition.Y; - if (Math.Abs(yDiff)>10.0f) - { - int dir = Math.Sign(yDiff); + // if (Math.Abs(yDiff) > 20.0f) + // { + // int dir = Math.Sign(yDiff); - float movement = Character.AnimController.Stairs.StairDirection == Direction.Right ? - dir * Character.AnimController.TargetMovement.Length() : -dir * Character.AnimController.TargetMovement.Length(); + // float movement = Character.AnimController.Stairs.StairDirection == Direction.Right ? + // dir * Character.AnimController.TargetMovement.Length() : -dir * Character.AnimController.TargetMovement.Length(); - Character.AnimController.TargetMovement = new Vector2(movement, 0.0f); - } - } + // steeringManager.SteeringManual(deltaTime, new Vector2(movement*2, 0.0f)); + // } + //} } (Character.AnimController as HumanoidAnimController).Crouching = false; diff --git a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs index 1d68fbc30..368bbaf53 100644 --- a/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs +++ b/Subsurface/Source/Characters/AI/IndoorsSteeringManager.cs @@ -111,7 +111,7 @@ namespace Barotrauma if (canOpenDoors && !character.LockHands) CheckDoorsInPath(); float allowedDistance = character.AnimController.InWater ? 1.0f : 0.6f; - if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f; + //if (currentPath.CurrentNode!=null && currentPath.CurrentNode.SimPosition.Y > character.SimPosition.Y+1.0f) allowedDistance*=0.5f; Vector2 pos = host.SimPosition; @@ -139,7 +139,16 @@ namespace Barotrauma } } - currentPath.CheckProgress(pos, allowedDistance); + //currentPath.CheckProgress(pos, allowedDistance); + var collider = character.AnimController.GetLimb(LimbType.Collider); + Vector2 colliderBottom = character.AnimController.GetColliderBottom(); + + if (Math.Abs(collider.SimPosition.X - currentPath.CurrentNode.SimPosition.X) < collider.body.radius*2 && + currentPath.CurrentNode.SimPosition.Y > colliderBottom.Y && + currentPath.CurrentNode.SimPosition.Y < colliderBottom.Y + collider.body.height + collider.body.radius*2) + { + currentPath.SkipToNextNode(); + } if (currentPath.CurrentNode == null) return Vector2.Zero; diff --git a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs index 17e7cc1f6..a64df2069 100644 --- a/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs +++ b/Subsurface/Source/Characters/AI/Objectives/AIObjectiveCombat.cs @@ -90,11 +90,12 @@ namespace Barotrauma escapeObjective.TryComplete(deltaTime); - if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f) - { - character.AIController.SteeringManager.SteeringManual(deltaTime, (character.SimPosition - enemy.SimPosition)*0.1f); - coolDownTimer = CoolDown; - } + //if (Vector2.Distance(character.SimPosition, enemy.SimPosition) < 3.0f) + //{ + // character.AIController.SteeringManager.SteeringManual(deltaTime, + // new Vector2(Math.Sign(character.SimPosition.X - enemy.SimPosition.X), 0.0f)); + // coolDownTimer = CoolDown; + //} } public override bool IsCompleted() diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index a2cac7cfd..ee0e30f7b 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -61,13 +61,24 @@ namespace Barotrauma public override void UpdateAnim(float deltaTime) { - if (character.IsDead) return; - if (Frozen) return; + if (character.IsDead || Frozen || character.IsUnconscious || stunTimer > 0.0f) + { + collider.Disabled = true; + collider.body.PhysEnabled = false; + + var lowestLimb = FindLowestLimb(true); + collider.body.SetTransform(GetLimb(LimbType.Torso).SimPosition, 0.0f); + + if (stunTimer > 0) + { + stunTimer -= deltaTime; + } + + return; + } if (collider == null) return; - - Vector2 colliderPos = GetColliderBottom(); - + //if (inWater) stairs = null; //if (onFloorTimer <= 0.0f && !SimplePhysicsEnabled) @@ -143,7 +154,7 @@ namespace Barotrauma stairs = null; var contacts = collider.body.FarseerBody.ContactList; - while (contacts != null && contacts.Contact != null) + while (collider.body.PhysEnabled && contacts != null && contacts.Contact != null) { if (contacts.Contact.Enabled && contacts.Contact.IsTouching) { @@ -215,12 +226,11 @@ namespace Barotrauma } strongestImpact = 0.0f; - - if (stunTimer > 0) + if (collider.Disabled && !swimming) { - collider.Disabled = true; - stunTimer -= deltaTime; - return; + var lowestLimb = FindLowestLimb(true); + collider.body.SetTransform(lowestLimb.SimPosition + Vector2.UnitY * (collider.body.radius + collider.body.height / 2), 0.0f); + collider.Disabled = false; } if (character.LockHands) @@ -265,8 +275,11 @@ namespace Barotrauma return; } - inWater = false; + collider.body.PhysEnabled = true; + collider.body.Enabled = true; + + switch (Anim) { case Animation.Climbing: @@ -311,6 +324,7 @@ namespace Barotrauma foreach (Limb limb in Limbs) { + if (limb == collider) continue; limb.Disabled = false; } @@ -339,7 +353,7 @@ namespace Barotrauma Limb rightLeg = GetLimb(LimbType.RightLeg); float getUpSpeed = 0.3f; - float walkCycleSpeed = head.LinearVelocity.X * walkAnimSpeed; + float walkCycleSpeed = collider.LinearVelocity.X * walkAnimSpeed; if (stairs != null) { TargetMovement = new Vector2(MathHelper.Clamp(TargetMovement.X, -1.5f, 1.5f), TargetMovement.Y); @@ -619,6 +633,11 @@ namespace Barotrauma float surfaceLimiter = 1.0f; Limb head = GetLimb(LimbType.Head); + Limb torso = GetLimb(LimbType.Torso); + + collider.body.PhysEnabled = false; + collider.Disabled = true; + collider.body.SetTransform(torso.SimPosition, 0.0f); if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f) && !head.inWater) { @@ -627,13 +646,13 @@ namespace Barotrauma if (surfaceLimiter > 20.0f) return; } - Limb torso = GetLimb(LimbType.Torso); Limb leftHand = GetLimb(LimbType.LeftHand); Limb rightHand = GetLimb(LimbType.RightHand); Limb leftFoot = GetLimb(LimbType.LeftFoot); Limb rightFoot = GetLimb(LimbType.RightFoot); + float rotation = MathHelper.WrapAngle(torso.Rotation); rotation = MathHelper.ToDegrees(rotation); if (rotation < 0.0f) rotation += 360; diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index 4f96dc97f..3042705e5 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -30,8 +30,6 @@ namespace Barotrauma private Character character; - private Limb lowestLimb; - protected float strongestImpact; public float headPosition, headAngle; @@ -275,8 +273,7 @@ namespace Barotrauma limb.sprite.Depth = startDepth + limb.sprite.Depth * 0.0001f; } - - collider = GetLimb(LimbType.Controller); + collider = GetLimb(LimbType.Collider); if (collider == null) return; collider.body.FarseerBody.FixedRotation = true; @@ -383,6 +380,10 @@ namespace Barotrauma contact.GetWorldManifold(out normal, out points); if (points[0].Y > collider.SimPosition.Y) return false; + //--------------- + + if (inWater && targetMovement.Y < 0.5f) return false; + //--------------- stairs = structure; @@ -406,7 +407,6 @@ namespace Barotrauma - //Limb limb = f1.Body.UserData as Limb; //if (limb != null)// && (limb.type == LimbType.LeftFoot || limb.type == LimbType.RightFoot)) //{ // if (contact.Manifold.LocalNormal.Y >= 0.0f) @@ -425,9 +425,9 @@ namespace Barotrauma // } //} } - CalculateImpact(f1, f2, contact); + return true; } @@ -437,39 +437,39 @@ namespace Barotrauma Vector2 normal = contact.Manifold.LocalNormal; - Vector2 avgVelocity = Vector2.Zero; - foreach (Limb limb in Limbs) - { - avgVelocity += limb.LinearVelocity; - } + //Vector2 avgVelocity = Vector2.Zero; + //foreach (Limb limb in Limbs) + //{ + // avgVelocity += limb.LinearVelocity; + //} - avgVelocity = avgVelocity / Limbs.Count(); + Limb limb = (Limb)f1.Body.UserData; + Vector2 velocity = limb.LinearVelocity; - if (character.Submarine == null && f2.Body.UserData is Submarine) avgVelocity -= ((Submarine)f2.Body.UserData).Velocity; + if (character.Submarine == null && f2.Body.UserData is Submarine) velocity -= ((Submarine)f2.Body.UserData).Velocity; - float impact = Vector2.Dot(avgVelocity, -normal); + float impact = Vector2.Dot(velocity, -normal); - Limb l = (Limb)f1.Body.UserData; float volume = stairs == null ? impact / 5.0f : impact; volume = Math.Min(impact, 1.0f); - if (impact > 0.5f && l.HitSound != null && l.soundTimer <= 0.0f) + if (impact > 0.5f && limb.HitSound != null && limb.soundTimer <= 0.0f) { - l.soundTimer = Limb.SoundInterval; - l.HitSound.Play(volume, impact * 250.0f, l.WorldPosition); + limb.soundTimer = Limb.SoundInterval; + limb.HitSound.Play(volume, impact * 250.0f, limb.WorldPosition); } - if (impact > l.impactTolerance) + if (impact > limb.impactTolerance && limb == collider) { if (!character.IsNetworkPlayer || GameMain.Server != null) { - character.AddDamage(CauseOfDeath.Damage, impact - l.impactTolerance * 0.1f, null); + character.AddDamage(CauseOfDeath.Damage, impact - limb.impactTolerance * 0.1f, null); - strongestImpact = Math.Max(strongestImpact, impact - l.impactTolerance); + strongestImpact = Math.Max(strongestImpact, impact - limb.impactTolerance); } - SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, l.body); + SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, limb.body); if (Character.Controlled == character) GameMain.GameScreen.Cam.Shake = strongestImpact; } @@ -765,7 +765,7 @@ namespace Barotrauma headInWater = false; if (currentHull.Volume > currentHull.FullVolume * 0.95f || - ConvertUnits.ToSimUnits(currentHull.Surface) - floorY > HeadPosition * 0.95f) + ConvertUnits.ToSimUnits(currentHull.Surface) - GetColliderBottom().Y > HeadPosition * 0.95f) inWater = true; } @@ -1044,18 +1044,21 @@ namespace Barotrauma { return collider == null ? Vector2.Zero : collider.SimPosition - Vector2.UnitY * (collider.body.height / 2 + collider.body.radius); } - - //public void FindLowestLimb() - //{ //find the lowest limb - // lowestLimb = null; - // foreach (Limb limb in Limbs) - // { - // if (lowestLimb == null) - // lowestLimb = limb; - // else if (limb.SimPosition.Y < lowestLimb.SimPosition.Y) - // lowestLimb = limb; - // } - //} + + public Limb FindLowestLimb(bool ignoreCollider) + { + Limb lowestLimb = null; + foreach (Limb limb in Limbs) + { + if (ignoreCollider && limb == collider) continue; + if (lowestLimb == null) + lowestLimb = limb; + else if (limb.SimPosition.Y < lowestLimb.SimPosition.Y) + lowestLimb = limb; + } + + return lowestLimb; + } public void Remove() { diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 1f227c50e..267c3c822 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1196,7 +1196,7 @@ namespace Barotrauma { foreach (Character c in CharacterList) { - if (c.isDead || c.health <= 0.0f || !c.Enabled) continue; + if (!c.Enabled) continue; c.AnimController.UpdateAnim(deltaTime); } } diff --git a/Subsurface/Source/Characters/Limb.cs b/Subsurface/Source/Characters/Limb.cs index 39cf82e8a..0f93fbd96 100644 --- a/Subsurface/Source/Characters/Limb.cs +++ b/Subsurface/Source/Characters/Limb.cs @@ -17,7 +17,7 @@ namespace Barotrauma { None, LeftHand, RightHand, LeftArm, RightArm, LeftLeg, RightLeg, LeftFoot, RightFoot, Head, Torso, Tail, Legs, RightThigh, LeftThigh, Waist, - Controller + Collider }; class Limb