From fac0c850a52525f13efa8077adf3d7eec6957deb Mon Sep 17 00:00:00 2001 From: juanjp600 Date: Wed, 16 Nov 2016 21:30:49 -0300 Subject: [PATCH] Changes to collider behavior The collider now levitates above the ground, which makes small obstacles a non-issue. The raytest also helps the collider stick to staircases, so players don't jump off anymore. Crouching now changes the collider to a smaller version, so now there is actual functionality to crouching. I also removed the anchor from corpses of network players. I'm not entirely sure why this was done, but removing it doesn't seem to break anything. --- Subsurface/Content/Characters/Human/human.xml | 3 +- .../Content/Characters/Human/humanhusk.xml | 3 +- Subsurface/Content/Characters/Husk/husk.xml | 3 +- .../Animation/FishAnimController.cs | 40 +-- .../Animation/HumanoidAnimController.cs | 115 ++++---- .../Source/Characters/Animation/Ragdoll.cs | 249 +++++++++++++----- Subsurface/Source/GUI/GUI.cs | 2 + .../GameSession/GameModes/SinglePlayerMode.cs | 13 +- Subsurface/Source/GameSession/GameSession.cs | 4 +- Subsurface/Source/Networking/GameServer.cs | 2 +- 10 files changed, 287 insertions(+), 147 deletions(-) diff --git a/Subsurface/Content/Characters/Human/human.xml b/Subsurface/Content/Characters/Human/human.xml index 6b70f9857..b190c755c 100644 --- a/Subsurface/Content/Characters/Human/human.xml +++ b/Subsurface/Content/Characters/Human/human.xml @@ -13,7 +13,8 @@ swimspeed="2.0" impacttolerance="7.5"> - + + diff --git a/Subsurface/Content/Characters/Human/humanhusk.xml b/Subsurface/Content/Characters/Human/humanhusk.xml index 73b9e9e13..52f0e389e 100644 --- a/Subsurface/Content/Characters/Human/humanhusk.xml +++ b/Subsurface/Content/Characters/Human/humanhusk.xml @@ -13,7 +13,8 @@ swimspeed="2.5" impacttolerance="7.5"> - + + diff --git a/Subsurface/Content/Characters/Husk/husk.xml b/Subsurface/Content/Characters/Husk/husk.xml index 177bd1407..0376a0262 100644 --- a/Subsurface/Content/Characters/Husk/husk.xml +++ b/Subsurface/Content/Characters/Husk/husk.xml @@ -14,7 +14,8 @@ walkspeed="1.2" swimspeed="2.5"> - + + diff --git a/Subsurface/Source/Characters/Animation/FishAnimController.cs b/Subsurface/Source/Characters/Animation/FishAnimController.cs index cb6a1c7ed..5547e9a70 100644 --- a/Subsurface/Source/Characters/Animation/FishAnimController.cs +++ b/Subsurface/Source/Characters/Animation/FishAnimController.cs @@ -51,17 +51,17 @@ namespace Barotrauma if (character.IsDead || character.IsUnconscious || stunTimer > 0.0f) { - collider.FarseerBody.FixedRotation = false; + Collider.FarseerBody.FixedRotation = false; if (character.IsRemotePlayer) { - MainLimb.pullJoint.WorldAnchorB = collider.SimPosition; + MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition; MainLimb.pullJoint.Enabled = true; } else { - collider.LinearVelocity = (MainLimb.SimPosition - collider.SimPosition) * 60.0f; - collider.SmoothRotate(MainLimb.Rotation); + Collider.LinearVelocity = (MainLimb.SimPosition - Collider.SimPosition) * 60.0f; + Collider.SmoothRotate(MainLimb.Rotation); } if (stunTimer > 0) @@ -73,16 +73,16 @@ namespace Barotrauma } //re-enable collider - if (!collider.FarseerBody.Enabled) + if (!Collider.FarseerBody.Enabled) { var lowestLimb = FindLowestLimb(); - collider.SetTransform(new Vector2( - collider.SimPosition.X, - Math.Max(lowestLimb.SimPosition.Y + (collider.radius + collider.height / 2), collider.SimPosition.Y)), + Collider.SetTransform(new Vector2( + Collider.SimPosition.X, + Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), 0.0f); - collider.FarseerBody.Enabled = true; + Collider.FarseerBody.Enabled = true; } ResetPullJoints(); @@ -96,20 +96,20 @@ namespace Barotrauma if (inWater) { - collider.FarseerBody.FixedRotation = false; + Collider.FarseerBody.FixedRotation = false; UpdateSineAnim(deltaTime); } else if (currentHull != null && CanEnterSubmarine) { - if (Math.Abs(MathUtils.GetShortestAngle(collider.Rotation, 0.0f)) > 0.001f) + if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, 0.0f)) > 0.001f) { //rotate collider back upright - collider.AngularVelocity = MathUtils.GetShortestAngle(collider.Rotation, 0.0f) * 60.0f; - collider.FarseerBody.FixedRotation = false; + Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, 0.0f) * 60.0f; + Collider.FarseerBody.FixedRotation = false; } else { - collider.FarseerBody.FixedRotation = true; + Collider.FarseerBody.FixedRotation = true; } UpdateWalkAnim(deltaTime); @@ -172,7 +172,7 @@ namespace Barotrauma movement = TargetMovement*swimSpeed; MainLimb.pullJoint.Enabled = true; - MainLimb.pullJoint.WorldAnchorB = collider.SimPosition; + MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition; if (movement.LengthSquared() < 0.00001f) return; @@ -180,12 +180,12 @@ namespace Barotrauma if (rotateTowardsMovement) { - collider.SmoothRotate(movementAngle, 25.0f); + Collider.SmoothRotate(movementAngle, 25.0f); MainLimb.body.SmoothRotate(movementAngle, 25.0f); } else { - collider.SmoothRotate(HeadAngle * Dir, 25.0f); + Collider.SmoothRotate(HeadAngle * Dir, 25.0f); MainLimb.body.SmoothRotate(HeadAngle * Dir, 25.0f); } @@ -216,7 +216,7 @@ namespace Barotrauma Limbs[i].body.ApplyForce(((limbPos - Limbs[i].SimPosition) * 3.0f - Limbs[i].LinearVelocity * 3.0f) * Limbs[i].Mass); } - collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement, 0.5f); + Collider.LinearVelocity = Vector2.Lerp(Collider.LinearVelocity, movement, 0.5f); floorY = Limbs[0].SimPosition.Y; } @@ -242,9 +242,9 @@ namespace Barotrauma MainLimb.body.SmoothRotate(mainLimbAngle * Dir, 50.0f); - collider.LinearVelocity = new Vector2( + Collider.LinearVelocity = new Vector2( movement.X, - collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y); + Collider.LinearVelocity.Y > 0.0f ? Collider.LinearVelocity.Y * 0.5f : Collider.LinearVelocity.Y); MainLimb.MoveToPos(GetColliderBottom() + Vector2.UnitY * mainLimbHeight, 10.0f); diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index 838c86aec..e50fa3094 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -54,21 +54,25 @@ namespace Barotrauma public override void UpdateAnim(float deltaTime) { if (Frozen) return; - + + levitatingCollider = true; + ColliderIndex = Crouching ? 1 : 0; + if (!Crouching && ColliderIndex == 1) Crouching = true; + if (character.IsDead || character.IsUnconscious || stunTimer > 0.0f) { - collider.FarseerBody.FixedRotation = false; + Collider.FarseerBody.FixedRotation = false; - if (character.IsRemotePlayer) + /*if (character.IsRemotePlayer) { - MainLimb.pullJoint.WorldAnchorB = collider.SimPosition; + MainLimb.pullJoint.WorldAnchorB = Collider.SimPosition; MainLimb.pullJoint.Enabled = true; } else - { - collider.LinearVelocity = (GetLimb(LimbType.Waist).SimPosition - collider.SimPosition) * 20.0f; - collider.SmoothRotate(GetLimb(LimbType.Torso).Rotation); - } + {*/ + Collider.LinearVelocity = (GetLimb(LimbType.Waist).SimPosition - Collider.SimPosition) * 20.0f; + Collider.SmoothRotate(GetLimb(LimbType.Torso).Rotation); + //} if (stunTimer > 0) { @@ -90,39 +94,39 @@ namespace Barotrauma if (!character.IsRemotePlayer || true) { //re-enable collider - if (!collider.FarseerBody.Enabled) + if (!Collider.FarseerBody.Enabled) { var lowestLimb = FindLowestLimb(); - collider.SetTransform(new Vector2( - collider.SimPosition.X, - Math.Max(lowestLimb.SimPosition.Y + (collider.radius + collider.height / 2), collider.SimPosition.Y)), - collider.Rotation); + Collider.SetTransform(new Vector2( + Collider.SimPosition.X, + Math.Max(lowestLimb.SimPosition.Y + (Collider.radius + Collider.height / 2), Collider.SimPosition.Y)), + Collider.Rotation); - collider.FarseerBody.Enabled = true; + Collider.FarseerBody.Enabled = true; } if (swimming) { - collider.FarseerBody.FixedRotation = false; + Collider.FarseerBody.FixedRotation = false; } - else if (!collider.FarseerBody.FixedRotation) + else if (!Collider.FarseerBody.FixedRotation) { - if (Math.Abs(MathUtils.GetShortestAngle(collider.Rotation, 0.0f)) > 0.001f) + if (Math.Abs(MathUtils.GetShortestAngle(Collider.Rotation, 0.0f)) > 0.001f) { //rotate collider back upright - collider.AngularVelocity = MathUtils.GetShortestAngle(collider.Rotation, 0.0f) * 10.0f; - collider.FarseerBody.FixedRotation = false; + Collider.AngularVelocity = MathUtils.GetShortestAngle(Collider.Rotation, 0.0f) * 10.0f; + Collider.FarseerBody.FixedRotation = false; } else { - collider.FarseerBody.FixedRotation = true; + Collider.FarseerBody.FixedRotation = true; } } } else { - collider.FarseerBody.Enabled = false; + Collider.FarseerBody.Enabled = false; } if (character.LockHands) @@ -165,6 +169,7 @@ namespace Barotrauma switch (Anim) { case Animation.Climbing: + levitatingCollider = false; UpdateClimbing(); break; case Animation.UsingConstruction: @@ -210,7 +215,7 @@ namespace Barotrauma } aiming = false; - if (character.IsRemotePlayer && GameMain.Server == null) collider.LinearVelocity = Vector2.Zero; + if (character.IsRemotePlayer && GameMain.Server == null) Collider.LinearVelocity = Vector2.Zero; } @@ -240,12 +245,12 @@ namespace Barotrauma { TargetMovement = new Vector2(MathHelper.Clamp(TargetMovement.X, -1.5f, 1.5f), TargetMovement.Y); - if ((TargetMovement.X > 0.0f && stairs.StairDirection == Direction.Right) || + /*if ((TargetMovement.X > 0.0f && stairs.StairDirection == Direction.Right) || TargetMovement.X < 0.0f && stairs.StairDirection == Direction.Left) { TargetMovement *= 1.7f; //walkCycleSpeed *= 1.0f; - } + }*/ } Vector2 colliderPos = GetColliderBottom(); @@ -308,14 +313,14 @@ namespace Barotrauma if (onGround && (!character.IsRemotePlayer || GameMain.Server != null)) { //move slower if collider isn't upright - float rotationFactor = (float)Math.Abs(Math.Cos(collider.Rotation)); + float rotationFactor = (float)Math.Abs(Math.Cos(Collider.Rotation)); - collider.LinearVelocity = new Vector2( + Collider.LinearVelocity = new Vector2( movement.X * rotationFactor, - collider.LinearVelocity.Y > 0.0f ? collider.LinearVelocity.Y * 0.5f : collider.LinearVelocity.Y); + Collider.LinearVelocity.Y > 0.0f ? Collider.LinearVelocity.Y * 0.5f : Collider.LinearVelocity.Y); } - ClimbOverObstacles(); + //ClimbOverObstacles(); getUpSpeed = getUpSpeed * Math.Max(head.SimPosition.Y - colliderPos.Y, 0.5f); @@ -323,8 +328,8 @@ namespace Barotrauma head.pullJoint.Enabled = true; waist.pullJoint.Enabled = true; - collider.FarseerBody.Friction = 0.05f; - collider.FarseerBody.Restitution = 0.05f; + Collider.FarseerBody.Friction = 0.05f; + Collider.FarseerBody.Restitution = 0.05f; if (stairs != null) { @@ -486,11 +491,11 @@ namespace Barotrauma private void ClimbOverObstacles() { - if (collider.FarseerBody.ContactList == null || Math.Abs(movement.X) < 0.01f) return; + if (Collider.FarseerBody.ContactList == null || Math.Abs(movement.X) < 0.01f) return; //check if the collider is touching a suitable obstacle to climb over Vector2? handle = null; - FarseerPhysics.Dynamics.Contacts.ContactEdge ce = collider.FarseerBody.ContactList; + FarseerPhysics.Dynamics.Contacts.ContactEdge ce = Collider.FarseerBody.ContactList; while (ce != null && ce.Contact != null) { if (ce.Contact.Enabled && ce.Contact.IsTouching && ce.Contact.FixtureA.CollisionCategories.HasFlag(Physics.CollisionWall)) @@ -500,7 +505,7 @@ namespace Barotrauma ce.Contact.GetWorldManifold(out contactNormal, out contactPos); //only climb if moving towards the obstacle - if (Math.Sign(contactPos[0].X - collider.SimPosition.X) == Math.Sign(movement.X) && + if (Math.Sign(contactPos[0].X - Collider.SimPosition.X) == Math.Sign(movement.X) && (handle == null || contactPos[0].Y > ((Vector2)handle).Y)) { handle = contactPos[0]; @@ -516,7 +521,7 @@ namespace Barotrauma //the contact point should be higher than the bottom of the collider if (((Vector2)handle).Y < colliderBottomY + 0.01f || - ((Vector2)handle).Y > collider.SimPosition.Y) return; + ((Vector2)handle).Y > Collider.SimPosition.Y) return; //find the height of the floor below the torso //(if moving towards towards an obstacle that's low enough to climb over, the torso should be above it) @@ -525,7 +530,7 @@ namespace Barotrauma if (obstacleY > colliderBottomY) { //higher vertical velocity for taller obstacles - collider.LinearVelocity += Vector2.UnitY * (((Vector2)handle).Y - colliderBottomY + 0.01f) * 50; + Collider.LinearVelocity += Vector2.UnitY * (((Vector2)handle).Y - colliderBottomY + 0.01f) * 50; onGround = true; } } @@ -543,7 +548,7 @@ namespace Barotrauma if (currentHull != null && (currentHull.Rect.Y - currentHull.Surface > 50.0f)) { - surfaceLimiter = (ConvertUnits.ToDisplayUnits(collider.SimPosition.Y + 0.4f) - surfaceY); + surfaceLimiter = (ConvertUnits.ToDisplayUnits(Collider.SimPosition.Y + 0.4f) - surfaceY); surfaceLimiter = Math.Max(1.0f, surfaceLimiter); if (surfaceLimiter > 50.0f) return; } @@ -554,7 +559,7 @@ namespace Barotrauma Limb leftFoot = GetLimb(LimbType.LeftFoot); Limb rightFoot = GetLimb(LimbType.RightFoot); - float rotation = MathHelper.WrapAngle(collider.Rotation); + float rotation = MathHelper.WrapAngle(Collider.Rotation); rotation = MathHelper.ToDegrees(rotation); if (rotation < 0.0f) rotation += 360; @@ -574,7 +579,7 @@ namespace Barotrauma if (!aiming) { float newRotation = MathUtils.VectorToAngle(TargetMovement) - MathHelper.PiOver2; - collider.SmoothRotate(newRotation, 5.0f); + Collider.SmoothRotate(newRotation, 5.0f); //torso.body.SmoothRotate(newRotation); } @@ -589,12 +594,12 @@ namespace Barotrauma TargetMovement = new Vector2(0.0f, -0.1f); float newRotation = MathUtils.VectorToAngle(diff); - collider.SmoothRotate(newRotation, 5.0f); + Collider.SmoothRotate(newRotation, 5.0f); } } - torso.body.SmoothRotate(collider.Rotation); - torso.body.MoveToPos(collider.SimPosition + new Vector2((float)Math.Sin(-collider.Rotation), (float)Math.Cos(-collider.Rotation))*0.4f, 5.0f); + torso.body.SmoothRotate(Collider.Rotation); + torso.body.MoveToPos(Collider.SimPosition + new Vector2((float)Math.Sin(-Collider.Rotation), (float)Math.Cos(-Collider.Rotation))*0.4f, 5.0f); if (TargetMovement == Vector2.Zero) return; @@ -626,11 +631,11 @@ namespace Barotrauma if (!character.IsRemotePlayer || GameMain.Server != null) { - collider.LinearVelocity = Vector2.Lerp(collider.LinearVelocity, movement * swimSpeed, movementLerp); + Collider.LinearVelocity = Vector2.Lerp(Collider.LinearVelocity, movement * swimSpeed, movementLerp); } walkPos += movement.Length() * 0.15f; - footPos = collider.SimPosition - new Vector2((float)Math.Sin(-collider.Rotation), (float)Math.Cos(-collider.Rotation)) * 0.4f; + footPos = Collider.SimPosition - new Vector2((float)Math.Sin(-Collider.Rotation), (float)Math.Cos(-Collider.Rotation)) * 0.4f; var rightThigh = GetLimb(LimbType.RightThigh); var leftThigh = GetLimb(LimbType.LeftThigh); @@ -641,7 +646,7 @@ namespace Barotrauma Vector2 transformedFootPos = new Vector2((float)Math.Sin(walkPos) * 0.5f, 0.0f); transformedFootPos = Vector2.Transform( transformedFootPos, - Matrix.CreateRotationZ(collider.Rotation)); + Matrix.CreateRotationZ(Collider.Rotation)); MoveLimb(rightFoot, footPos - transformedFootPos, 1.0f); MoveLimb(leftFoot, footPos + transformedFootPos, 1.0f); @@ -742,20 +747,20 @@ namespace Barotrauma ladderSimPos += character.SelectedConstruction.Submarine.SimPosition - currentHull.Submarine.SimPosition; } - MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, collider.SimPosition.Y + 0.7f), 10.5f); - MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, collider.SimPosition.Y+0.5f), 10.5f); - MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, collider.SimPosition.Y+0.4f), 10.5f); + MoveLimb(head, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y + 0.7f), 10.5f); + MoveLimb(torso, new Vector2(ladderSimPos.X - 0.27f * Dir, Collider.SimPosition.Y+0.5f), 10.5f); + MoveLimb(waist, new Vector2(ladderSimPos.X - 0.35f * Dir, Collider.SimPosition.Y+0.4f), 10.5f); if (!character.IsRemotePlayer) { - collider.MoveToPos(new Vector2(ladderSimPos.X - 0.2f * Dir, collider.SimPosition.Y), 10.5f); + Collider.MoveToPos(new Vector2(ladderSimPos.X - 0.2f * Dir, Collider.SimPosition.Y), 10.5f); } bool slide = targetMovement.Y < -1.1f; Vector2 handPos = new Vector2( ladderSimPos.X, - collider.SimPosition.Y + 0.6f + movement.Y * 0.1f - ladderSimPos.Y); + Collider.SimPosition.Y + 0.6f + movement.Y * 0.1f - ladderSimPos.Y); handPos.Y = Math.Min(-0.5f, handPos.Y); @@ -774,7 +779,7 @@ namespace Barotrauma Vector2 footPos = new Vector2( handPos.X - Dir * 0.05f, - collider.SimPosition.Y + 0.7f - stepHeight * 2.7f - ladderSimPos.Y - 0.7f); + Collider.SimPosition.Y + 0.7f - stepHeight * 2.7f - ladderSimPos.Y - 0.7f); //if (movement.Y < 0) footPos.Y += 0.05f; @@ -805,7 +810,7 @@ namespace Barotrauma //if (climbForce.Y > 0.5f) climbForce.Y = Math.Max(climbForce.Y, 1.3f); //apply forces to the collider to move the Character up/down - collider.ApplyForce((climbForce * 20.0f + subSpeed * 50.0f) * collider.Mass); + Collider.ApplyForce((climbForce * 20.0f + subSpeed * 50.0f) * Collider.Mass); head.body.SmoothRotate(0.0f); if (!character.SelectedConstruction.Prefab.Triggers.Any()) @@ -907,10 +912,10 @@ namespace Barotrauma } } - float dist = Vector2.Distance(target.SimPosition, collider.SimPosition); + float dist = Vector2.Distance(target.SimPosition, Collider.SimPosition); //limit movement if moving away from the target - if (Vector2.Dot(target.SimPosition - collider.SimPosition, targetMovement)<0) + if (Vector2.Dot(target.SimPosition - Collider.SimPosition, targetMovement)<0) { targetMovement *= MathHelper.Clamp(2.0f - dist, 0.0f, 1.0f); } @@ -1148,8 +1153,8 @@ namespace Barotrauma float angle = flipAngle ? -limb.body.Rotation : limb.body.Rotation; if (wrapAngle) angle = MathUtils.WrapAnglePi(angle); - - TrySetLimbPosition(limb, collider.SimPosition, position); + + TrySetLimbPosition(limb, Collider.SimPosition, position); limb.body.SetTransform(limb.body.SimPosition, angle); } diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index aee5ff37d..429d39be9 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -35,7 +35,7 @@ namespace Barotrauma { l.body.PhysEnabled = !frozen; } - collider.PhysEnabled = !frozen; + Collider.PhysEnabled = !frozen; } } @@ -77,13 +77,45 @@ namespace Barotrauma public Direction TargetDir; - protected PhysicsBody collider; - + protected List collider; + protected int colliderIndex = 0; + public PhysicsBody Collider { get { - return collider; + return collider[colliderIndex]; + } + } + + public int ColliderIndex + { + get + { + return colliderIndex; + } + set + { + if (value == colliderIndex) return; + if (value >= collider.Count) return; + if (collider[colliderIndex].height f.CollisionCategories.HasFlag(Physics.CollisionWall))) return; + } + collider[value].LinearVelocity = collider[colliderIndex].LinearVelocity; + collider[value].AngularVelocity = collider[colliderIndex].AngularVelocity; + Vector2 pos = collider[colliderIndex].SimPosition; + pos.Y -= collider[colliderIndex].height * 0.5f; + pos.Y += collider[value].height * 0.5f; + collider[value].SetTransform(pos, collider[colliderIndex].Rotation); + collider[value].PhysEnabled = !frozen; + collider[value].Enabled = !simplePhysicsEnabled; + collider[colliderIndex].PhysEnabled = false; + colliderIndex = value; } } @@ -109,8 +141,8 @@ namespace Barotrauma get { return character.Submarine == null ? - ConvertUnits.ToDisplayUnits(collider.SimPosition) : - ConvertUnits.ToDisplayUnits(collider.SimPosition) + character.Submarine.Position; + ConvertUnits.ToDisplayUnits(Collider.SimPosition) : + ConvertUnits.ToDisplayUnits(Collider.SimPosition) + character.Submarine.Position; } } @@ -137,7 +169,7 @@ namespace Barotrauma { foreach (Limb limb in Limbs) { - limb.body.SetTransform(collider.SimPosition, collider.Rotation); + limb.body.SetTransform(Collider.SimPosition, Collider.Rotation); } } } @@ -207,7 +239,7 @@ namespace Barotrauma { limb.body.Submarine = currSubmarine; } - collider.Submarine = currSubmarine; + Collider.Submarine = currSubmarine; } } @@ -266,7 +298,9 @@ namespace Barotrauma ImpactTolerance = ToolBox.GetAttributeFloat(element, "impacttolerance", 50.0f); CanEnterSubmarine = ToolBox.GetAttributeBool(element, "canentersubmarine", true); - + + collider = new List(); + foreach (XElement subElement in element.Elements()) { switch (subElement.Name.ToString()) @@ -287,24 +321,28 @@ namespace Barotrauma break; case "collider": - collider = new PhysicsBody(subElement, scale); - collider.FarseerBody.FixedRotation = true; + collider.Add(new PhysicsBody(subElement, scale)); + collider[collider.Count - 1].FarseerBody.FixedRotation = true; + collider[collider.Count - 1].CollisionCategories = Physics.CollisionCharacter; + collider[collider.Count - 1].FarseerBody.AngularDamping = 5.0f; + collider[collider.Count - 1].FarseerBody.FixedRotation = true; + collider[collider.Count - 1].FarseerBody.OnCollision += OnLimbCollision; + if (collider.Count > 1) collider[collider.Count - 1].PhysEnabled = false; break; } } - if (collider == null) + if (collider[0] == null) { DebugConsole.ThrowError("No collider configured for ''"+character.Name+"''!"); - collider = new PhysicsBody(0.0f, 0.0f, 0.5f, 5.0f); - collider.BodyType = BodyType.Dynamic; + collider[0] = new PhysicsBody(0.0f, 0.0f, 0.5f, 5.0f); + collider[0].BodyType = BodyType.Dynamic; + collider[0].CollisionCategories = Physics.CollisionCharacter; + collider[0].FarseerBody.AngularDamping = 5.0f; + collider[0].FarseerBody.FixedRotation = true; + collider[0].FarseerBody.OnCollision += OnLimbCollision; } - collider.CollisionCategories = Physics.CollisionCharacter; - collider.FarseerBody.AngularDamping = 5.0f; - collider.FarseerBody.FixedRotation = true; - collider.FarseerBody.OnCollision += OnLimbCollision; - UpdateCollisionCategories(); foreach (var joint in limbJoints) @@ -431,7 +469,7 @@ namespace Barotrauma //4. contact points is above the bottom half of the collider Vector2 normal; FarseerPhysics.Common.FixedArray2 points; contact.GetWorldManifold(out normal, out points); - if (points[0].Y > collider.SimPosition.Y) return false; + if (points[0].Y > Collider.SimPosition.Y) return false; //5. in water if (inWater && targetMovement.Y < 0.5f) return false; @@ -475,14 +513,14 @@ namespace Barotrauma limb.HitSound.Play(volume, impact * 100.0f, limb.WorldPosition); } } - else if (f1.Body == collider.FarseerBody) + else if (f1.Body == Collider.FarseerBody) { if (!character.IsRemotePlayer || GameMain.Server != null) { if (impact > ImpactTolerance) { character.AddDamage(CauseOfDeath.Damage, impact - ImpactTolerance, null); - SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, collider); + SoundPlayer.PlayDamageSound(DamageSoundType.LimbBlunt, strongestImpact, Collider); strongestImpact = Math.Max(strongestImpact, impact - ImpactTolerance); } } @@ -495,7 +533,7 @@ namespace Barotrauma { if (simplePhysicsEnabled) return; - collider.UpdateDrawPosition(); + Collider.UpdateDrawPosition(); foreach (Limb limb in Limbs) { @@ -522,7 +560,7 @@ namespace Barotrauma limb.body.DebugDraw(spriteBatch, inWater ? Color.Cyan : Color.White); } - collider.DebugDraw(spriteBatch, inWater ? Color.SkyBlue : Color.Gray); + Collider.DebugDraw(spriteBatch, inWater ? Color.SkyBlue : Color.Gray); foreach (RevoluteJoint joint in limbJoints) { @@ -568,8 +606,8 @@ namespace Barotrauma if (ignorePlatforms) { GUI.DrawLine(spriteBatch, - new Vector2(collider.DrawPosition.X, -collider.DrawPosition.Y), - new Vector2(collider.DrawPosition.X, -collider.DrawPosition.Y + 50), + new Vector2(Collider.DrawPosition.X, -Collider.DrawPosition.Y), + new Vector2(Collider.DrawPosition.X, -Collider.DrawPosition.Y + 50), Color.Orange, 0, 5); } } @@ -718,7 +756,7 @@ namespace Barotrauma //character.Stun = 0.1f; character.DisableImpactDamageTimer = 0.25f; - SetPosition(collider.SimPosition + moveAmount); + SetPosition(Collider.SimPosition + moveAmount); character.CursorPosition += moveAmount; } @@ -732,7 +770,7 @@ namespace Barotrauma wall | Physics.CollisionProjectile | Physics.CollisionStairs : wall | Physics.CollisionProjectile | Physics.CollisionPlatform | Physics.CollisionStairs; - collider.CollidesWith = collisionCategory; + Collider.CollidesWith = collisionCategory; foreach (Limb limb in Limbs) { @@ -749,19 +787,21 @@ namespace Barotrauma } } + protected bool levitatingCollider = true; + public void Update(Camera cam, float deltaTime) { if (!character.Enabled || Frozen) return; UpdateNetPlayerPosition(deltaTime); CheckDistFromCollider(); - + Vector2 flowForce = Vector2.Zero; FindHull(); splashSoundTimer -= deltaTime; - + //ragdoll isn't in any room -> it's in the water if (currentHull == null) { @@ -779,41 +819,41 @@ namespace Barotrauma float floorY = GetFloorY(); - if (currentHull.Volume > currentHull.FullVolume * 0.95f || - (waterSurface - floorY > HeadPosition * 0.95f && collider.SimPosition.Y < waterSurface)) - inWater = true; + if (currentHull.Volume > currentHull.FullVolume * 0.95f || + (waterSurface - floorY > HeadPosition * 0.95f && Collider.SimPosition.Y < waterSurface)) + inWater = true; } if (flowForce.LengthSquared() > 0.001f) { - collider.ApplyForce(flowForce); + Collider.ApplyForce(flowForce); } - if (currentHull==null || - currentHull.Volume > currentHull.FullVolume * 0.95f || - ConvertUnits.ToSimUnits(currentHull.Surface) > collider.SimPosition.Y) + if (currentHull == null || + currentHull.Volume > currentHull.FullVolume * 0.95f || + ConvertUnits.ToSimUnits(currentHull.Surface) > Collider.SimPosition.Y) { - collider.ApplyWaterForces(); + Collider.ApplyWaterForces(); } - - + + foreach (Limb limb in Limbs) { //find the room which the limb is in //the room where the ragdoll is in is used as the "guess", meaning that it's checked first Hull limbHull = currentHull == null ? null : Hull.FindHull(limb.WorldPosition, currentHull); - + bool prevInWater = limb.inWater; limb.inWater = false; if (limbHull == null) - { + { //limb isn't in any room -> it's in the water limb.inWater = true; } else if (limbHull.Volume > 0.0f && Submarine.RectContains(limbHull.Rect, limb.Position)) { - if (limb.Position.Y < limbHull.Surface) + if (limb.Position.Y < limbHull.Surface) { limb.inWater = true; @@ -829,7 +869,7 @@ namespace Barotrauma headInWater = true; } } - //the limb has gone through the surface of the water + //the limb has gone through the surface of the water if (Math.Abs(limb.LinearVelocity.Y) > 5.0f && limb.inWater != prevInWater) { @@ -838,14 +878,14 @@ namespace Barotrauma new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, new Vector2(0.0f, Math.Abs(-limb.LinearVelocity.Y * 20.0f)), 0.0f, limbHull); - + GameMain.ParticleManager.CreateParticle("bubbles", - new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, - limb.LinearVelocity*0.001f, + new Vector2(limb.Position.X, limbHull.Surface) + limbHull.Submarine.Position, + limb.LinearVelocity * 0.001f, 0.0f, limbHull); //if the Character dropped into water, create a wave - if (limb.LinearVelocity.Y<0.0f) + if (limb.LinearVelocity.Y < 0.0f) { if (splashSoundTimer <= 0.0f) { @@ -866,13 +906,12 @@ namespace Barotrauma limb.Update(deltaTime); } - - + bool onStairs = stairs != null; stairs = null; - var contacts = collider.FarseerBody.ContactList; - while (collider.FarseerBody.Enabled && contacts != null && contacts.Contact != null) + var contacts = Collider.FarseerBody.ContactList; + while (Collider.FarseerBody.Enabled && contacts != null && contacts.Contact != null) { if (contacts.Contact.Enabled && contacts.Contact.IsTouching) { @@ -907,7 +946,7 @@ namespace Barotrauma //} - if (points[0].Y < collider.SimPosition.Y) + if (points[0].Y < Collider.SimPosition.Y) { floorY = Math.Max(floorY, points[0].Y); @@ -931,12 +970,86 @@ namespace Barotrauma onFloorTimer -= deltaTime; } + Vector2 rayStart = Collider.SimPosition; + Vector2 rayEnd = rayStart; + rayEnd.Y -= Collider.height * 0.5f + Collider.radius + ConvertUnits.ToSimUnits(55.0f); + var lowestLimb = FindLowestLimb(); + + //TODO: use something like this instead of lowest limb, whenever we get to that + //float footY = Collider.SimPosition.Y + Collider.height * 0.5f + Collider.radius + ConvertUnits.ToSimUnits(45.0f); + + if (!inWater && levitatingCollider) + { + float closestFraction = 1.0f; + Fixture closestFixture = null; + GameMain.World.RayCast((fixture, point, normal, fraction) => + { + switch (fixture.CollisionCategories) + { + case Physics.CollisionStairs: + Structure structure = fixture.Body.UserData as Structure; + if (lowestLimb.Position.Y 0.01f && Collider.SimPosition.Y allowedDist*allowedDist) + if (Vector2.DistanceSquared(Collider.SimPosition, MainLimb.SimPosition) > allowedDist*allowedDist) { if (!collisionsDisabled) { @@ -1057,7 +1170,7 @@ namespace Barotrauma else if (collisionsDisabled) { //set the position of the ragdoll to make sure limbs don't get stuck inside walls when re-enabling collisions - SetPosition(collider.SimPosition, true); + SetPosition(Collider.SimPosition, true); UpdateCollisionCategories(); collisionsDisabled = false; @@ -1096,8 +1209,8 @@ namespace Barotrauma { if (character.MemPos.Count > 0) { - collider.LinearVelocity = Vector2.Zero; - collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement); + Collider.LinearVelocity = Vector2.Zero; + Collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement); } } } @@ -1133,10 +1246,12 @@ namespace Barotrauma public Vector2 GetColliderBottom() { - float halfHeight = collider.height / 2 + collider.radius; + float halfHeight = Collider.height * 0.5f + Collider.radius; - return collider.SimPosition + - new Vector2((float)Math.Sin(collider.Rotation), -(float)Math.Cos(collider.Rotation)) * halfHeight; + Vector2 offset = Vector2.Zero; + offset.Y = ConvertUnits.ToSimUnits(-45.0f); + return Collider.SimPosition + offset + + new Vector2((float)Math.Sin(Collider.Rotation), -(float)Math.Cos(Collider.Rotation)) * halfHeight; } public Limb FindLowestLimb() @@ -1161,8 +1276,10 @@ namespace Barotrauma } Limbs = null; - collider.Remove(); - collider = null; + foreach (PhysicsBody b in collider) + { + b.Remove(); + } foreach (RevoluteJoint joint in limbJoints) { diff --git a/Subsurface/Source/GUI/GUI.cs b/Subsurface/Source/GUI/GUI.cs index 18b8f3c59..99040670c 100644 --- a/Subsurface/Source/GUI/GUI.cs +++ b/Subsurface/Source/GUI/GUI.cs @@ -200,6 +200,8 @@ namespace Barotrauma GameMain.NetworkMember = null; } + CoroutineManager.StopCoroutines("EndCinematic"); + GameMain.GameSession = null; GameMain.MainMenuScreen.Select(); diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index a176b3ac3..5d26ecd4f 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -215,6 +215,17 @@ namespace Barotrauma endShiftButton.Draw(spriteBatch); } + public override void AddToGUIUpdateList() + { + if (!isRunning) return; + + base.AddToGUIUpdateList(); + + CrewManager.AddToGUIUpdateList(); + + endShiftButton.AddToGUIUpdateList(); + } + public override void Update(float deltaTime) { if (!isRunning) return; @@ -357,7 +368,7 @@ namespace Barotrauma SoundPlayer.OverrideMusicType = CrewManager.characters.Any(c => !c.IsDead) ? "endshift" : "crewdead"; - CoroutineManager.StartCoroutine(EndCinematic(cinematic)); + CoroutineManager.StartCoroutine(EndCinematic(cinematic),"EndCinematic"); return true; } diff --git a/Subsurface/Source/GameSession/GameSession.cs b/Subsurface/Source/GameSession/GameSession.cs index 681b47fd5..57703053f 100644 --- a/Subsurface/Source/GameSession/GameSession.cs +++ b/Subsurface/Source/GameSession/GameSession.cs @@ -364,7 +364,9 @@ namespace Barotrauma { if (gameMode != null) gameMode.AddToGUIUpdateList(); - if (infoFrame != null) infoButton.AddToGUIUpdateList(); + infoButton.AddToGUIUpdateList(); + + if (infoFrame != null) infoFrame.AddToGUIUpdateList(); } public void Update(float deltaTime) diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 98fc5b4b4..3fd4f9ba7 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -1165,7 +1165,7 @@ namespace Barotrauma.Networking } } - CoroutineManager.StartCoroutine(EndCinematic()); + CoroutineManager.StartCoroutine(EndCinematic(),"EndCinematic"); } public IEnumerable EndCinematic()