diff --git a/Subsurface/Source/Characters/Animation/FishAnimController.cs b/Subsurface/Source/Characters/Animation/FishAnimController.cs index 242493576..9afc2afb2 100644 --- a/Subsurface/Source/Characters/Animation/FishAnimController.cs +++ b/Subsurface/Source/Characters/Animation/FishAnimController.cs @@ -321,16 +321,6 @@ namespace Barotrauma l.body.SetTransform(l.SimPosition, -l.body.Rotation); } - - } - - public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed) - { - timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f); - - Vector2 currPosition = prevPosition + targetMovement * timePassed; - - return currPosition; } private void Mirror() diff --git a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs index e970efebf..8a99f86f9 100644 --- a/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs +++ b/Subsurface/Source/Characters/Animation/HumanoidAnimController.cs @@ -1083,17 +1083,6 @@ namespace Barotrauma hand.body.SmoothRotate((ang2 + handAngle * Dir), 100.0f * force); } - public override Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed) - { - timePassed = MathHelper.Clamp(timePassed, 0.0f, 1.0f); - - Vector2 targetMovement = character.GetTargetMovement(); - - Vector2 currPosition = prevPosition + targetMovement * timePassed / 500.0f; - - return currPosition; - } - public override void Flip() { base.Flip(); diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index f1f6b04bb..4aed729b1 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -941,18 +941,6 @@ namespace Barotrauma { case Physics.CollisionStairs: if (inWater && TargetMovement.Y < 0.5f) return -1; - //Structure structure = fixture.Body.UserData as Structure; - //if (stairs == null && structure != null) - //{ - // if (LowestLimb.SimPosition.Y < structure.SimPosition.Y) - // { - // return -1; - // } - // else - // { - // stairs = structure; - // } - //} break; case Physics.CollisionPlatform: Structure platform = fixture.Body.UserData as Structure; @@ -1040,7 +1028,7 @@ namespace Barotrauma protected void CheckDistFromCollider() { - float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height); + float allowedDist = Math.Max(Math.Max(collider.radius, collider.width), collider.height) * 2.0f; //if the ragdoll is too far from the collider, disable collisions until it's close enough //(in case the ragdoll has gotten stuck somewhere) @@ -1055,19 +1043,20 @@ 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(MainLimb.SimPosition, true); + UpdateCollisionCategories(); collisionsDisabled = false; } } - - float t = 0.0f; - + private void UpdateNetPlayerPosition(float deltaTime) { - if (character.MemPos.Count < 2) return; - if (character == GameMain.NetworkMember.Character) { + if (character.MemPos.Count < 2) return; + PosInfo serverPos = character.MemPos.Last(); int localPosIndex = character.MemLocalPos.FindIndex(m => m.ID == serverPos.ID); @@ -1086,46 +1075,10 @@ namespace Barotrauma } else { - PosInfo prev = character.MemPos[0]; - PosInfo next = character.MemPos[1]; - - Vector2 currPos = collider.SimPosition; - - //interpolate the position of the collider from the first position in the buffer towards the second - if (prev.Timestamp < next.Timestamp) - { - //if there are more than 2 positions in the buffer, - //increase the interpolation speed to catch up with the server - float speedMultiplier = 1.0f + (float)Math.Pow((character.MemPos.Count - 2) / 2.0f, 2.0f); - - t += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp); - currPos = Vector2.Lerp(prev.Position, next.Position, t); - - //override the targetMovement to make the character play the walking/running animation - overrideTargetMovement = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp); - } - else - { - currPos = next.Position; - t = 1.0f; - } - - collider.SetTransform(currPos, collider.Rotation); - - if (t >= 1.0f) - { - t = 0.0f; - character.MemPos.RemoveAt(0); - } + collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement); } } - - public virtual Vector2 EstimateCurrPosition(Vector2 prevPosition, float timePassed) - { - return prevPosition; - } - - + private Vector2 GetFlowForce() { Vector2 limbPos = ConvertUnits.ToDisplayUnits(Limbs[0].SimPosition); diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 89356a0dc..8842488ff 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -798,14 +798,23 @@ namespace Barotrauma if (length > 0.0f) targetMovement = targetMovement / length; } - if (AnimController is HumanoidAnimController && - !((HumanoidAnimController)AnimController).Crouching && - Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir) && - IsKeyDown(InputType.Run)) + if (IsKeyDown(InputType.Run)) { - targetMovement *= 3.0f; + //can't run if + // - not a humanoid + // - dragging someone + // - crouching + // - moving backwards + if (AnimController is HumanoidAnimController && + selectedCharacter == null && + !((HumanoidAnimController)AnimController).Crouching && + Math.Sign(targetMovement.X) != -Math.Sign(AnimController.Dir)) + { + targetMovement *= 3.0f; + } } + targetMovement *= SpeedMultiplier; SpeedMultiplier = 1.0f; @@ -1845,41 +1854,39 @@ namespace Barotrauma { msg.Write(ID); - //todo: only write this if sending for the client who's controlling the character? - msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count)); + if (this == c.Character) + { + //length of the message + msg.Write((byte)(4+4+4+4)); + msg.Write(true); + msg.Write((UInt32)(LastNetworkUpdateID - memInput.Count)); + } + else + { + //length of the message + msg.Write((byte)(4+4+4)); + msg.Write(false); + } msg.Write(AnimController.Dir > 0.0f); msg.Write(SimPosition.X); msg.Write(SimPosition.Y); - } - public static void ClientReadStatic(NetIncomingMessage msg, float sendingTime) - { - UInt16 id = msg.ReadUInt16(); - var character = Entity.FindEntityByID(id) as Character; - - if (character == null) - { - //skip through the rest of the message - //todo: a better way to skip through the message? - msg.Position += 32 + 1 + 32 + 32; - } - else - { - character.ClientRead(msg, sendingTime); - } + msg.WritePadBits(); } public virtual void ClientRead(NetIncomingMessage msg, float sendingTime) { - UInt32 networkUpdateID = msg.ReadUInt32(); + UInt32 networkUpdateID = 0; + if (msg.ReadBoolean()) + { + networkUpdateID = msg.ReadUInt32(); + } - //float sendingTime = msg.ReadSingle(); bool facingRight = msg.ReadBoolean(); Vector2 pos = new Vector2(msg.ReadFloat(), msg.ReadFloat()); - - + var posInfo = GameMain.NetworkMember.Character == this ? new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID) : diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index ab90810fa..211b5d86e 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -707,7 +707,20 @@ namespace Barotrauma.Networking lastSentChatMsgID = inc.ReadUInt32(); break; case ServerNetObject.CHARACTER_POSITION: - Character.ClientReadStatic(inc, sendingTime); + UInt16 id = inc.ReadUInt16(); + byte msgLength = inc.ReadByte(); + + var character = Entity.FindEntityByID(id) as Character; + if (character == null) + { + //skip through the rest of the message + inc.Position += msgLength * 8; + } + else + { + character.ClientRead(inc, sendingTime); + } + inc.ReadPadBits(); break; case ServerNetObject.CHAT_MESSAGE: diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index 3d63aa225..d975a67b3 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -53,6 +53,8 @@ namespace Barotrauma Vector2 offsetFromTargetPos; + private float netInterpolationState; + public Shape BodyShape { get { return bodyShape; } @@ -461,6 +463,45 @@ namespace Barotrauma new Vector2(bodyShapeTexture.Width / 2, bodyShapeTexture.Height / 2), 1.0f, SpriteEffects.None, 0.0f); } + + public void CorrectPosition(List positionBuffer, float deltaTime, out Vector2 newVelocity) + { + newVelocity = Vector2.Zero; + if (positionBuffer.Count < 2) return; + + PosInfo prev = positionBuffer[0]; + PosInfo next = positionBuffer[1]; + + Vector2 currPos = SimPosition; + + //interpolate the position of the collider from the first position in the buffer towards the second + if (prev.Timestamp < next.Timestamp) + { + //if there are more than 2 positions in the buffer, + //increase the interpolation speed to catch up with the server + float speedMultiplier = 1.0f + (float)Math.Pow((positionBuffer.Count - 2) / 2.0f, 2.0f); + + netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp); + currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState); + + //override the targetMovement to make the character play the walking/running animation + newVelocity = (next.Position - prev.Position) / (next.Timestamp - prev.Timestamp); + } + else + { + currPos = next.Position; + netInterpolationState = 1.0f; + } + + SetTransform(currPos, Rotation); + + if (netInterpolationState >= 1.0f) + { + netInterpolationState = 0.0f; + positionBuffer.RemoveAt(0); + } + } + ///