diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index d80ce16dc..2f5f017c1 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -1255,6 +1255,24 @@ namespace Barotrauma //use simple interpolation for other players' characters and characters that can't move if (character.MemPos.Count > 0) { + if (character.MemPos[0].Interact == null) + { + character.DeselectCharacter(); + character.SelectedConstruction = null; + } + else if (character.MemPos[0].Interact is Character) + { + character.SelectCharacter((Character)character.MemPos[0].Interact); + } + else if (character.MemPos[0].Interact is Item) + { + var newSelectedConstruction = (Item)character.MemPos[0].Interact; + if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction) + { + newSelectedConstruction.Pick(character, true, true); + } + } + Collider.LinearVelocity = Vector2.Zero; Collider.CorrectPosition(character.MemPos, deltaTime, out overrideTargetMovement); @@ -1307,36 +1325,42 @@ namespace Barotrauma if (localPosIndex > -1) { PosInfo localPos = character.MemLocalPos[localPosIndex]; - - Vector2 positionError = serverPos.Position - localPos.Position; - - float errorMagnitude = positionError.Length(); - - /*if (errorMagnitude > 8.0f) + + //the entity we're interacting with doesn't match the server's + if (localPos.Interact != serverPos.Interact) { - //predicted position was way off, reset completely - SetPosition(serverPos.Position, false); - //local positions are incorrect now -> just clear the list - character.MemLocalPos.Clear(); + if (serverPos.Interact == null) + { + character.DeselectCharacter(); + character.SelectedConstruction = null; + } + else if (serverPos.Interact is Character) + { + character.SelectCharacter((Character)serverPos.Interact); + } + else if (serverPos.Interact is Item) + { + var newSelectedConstruction = (Item)serverPos.Interact; + if (newSelectedConstruction != null && character.SelectedConstruction != newSelectedConstruction) + { + newSelectedConstruction.Pick(character, true, true); + } + } } - else if (errorMagnitude > Collider.LinearVelocity.Length() / 10.0f + 0.02f && false) - {*/ - //our prediction differs from the server position - //-> we need to move the saved local position and all the positions saved after it - //(a better way to do this would be to move the character back to - //serverPos and "replay" inputs to see where the character should be now) + Vector2 positionError = serverPos.Position - localPos.Position; for (int i = localPosIndex; i < character.MemLocalPos.Count; i++) { character.MemLocalPos[i] = new PosInfo( character.MemLocalPos[i].Position + positionError, character.MemLocalPos[i].Direction, - character.MemLocalPos[i].ID); + character.MemLocalPos[i].ID, + 0.0f, + character.MemLocalPos[i].Interact); } - //Collider.SetTransform(character.MemLocalPos.Last().Position, Collider.Rotation); + Collider.SetTransform(Collider.SimPosition + positionError, Collider.Rotation); - //} } if (character.MemLocalPos.Count > 120) character.MemLocalPos.RemoveRange(0, character.MemLocalPos.Count - 120); diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 2bb2d0302..fbc7ffd40 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1,8 +1,6 @@ - -using FarseerPhysics; +using FarseerPhysics; using FarseerPhysics.Dynamics; using FarseerPhysics.Dynamics.Joints; -using Lidgren.Network; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using Barotrauma.Networking; @@ -1113,14 +1111,14 @@ namespace Barotrauma } } - private void SelectCharacter(Character character) + public void SelectCharacter(Character character) { if (character == null) return; selectedCharacter = character; } - private void DeselectCharacter() + public void DeselectCharacter() { if (selectedCharacter == null) return; diff --git a/Subsurface/Source/Characters/CharacterNetworking.cs b/Subsurface/Source/Characters/CharacterNetworking.cs index ba6d6dd14..598fbd71b 100644 --- a/Subsurface/Source/Characters/CharacterNetworking.cs +++ b/Subsurface/Source/Characters/CharacterNetworking.cs @@ -43,7 +43,7 @@ namespace Barotrauma { public InputNetFlags states; //keys pressed/other boolean states at this step public UInt16 intAim; //aim angle, represented as an unsigned short where 0=0º, 65535=just a bit under 360º - public UInt16 interact; //id of the item being interacted with + public UInt16 interact; //id of the entity being interacted with public UInt16 networkUpdateID; } @@ -127,7 +127,13 @@ namespace Barotrauma } else if (GameMain.Client != null) { - memLocalPos.Add(new PosInfo(SimPosition, AnimController.TargetDir, LastNetworkUpdateID)); + var posInfo = new PosInfo( + SimPosition, + AnimController.TargetDir, + LastNetworkUpdateID, 0.0f, + selectedCharacter == null ? (Entity)selectedConstruction : (Entity)selectedCharacter); + + memLocalPos.Add(posInfo); InputNetFlags newInput = InputNetFlags.None; if (IsKeyDown(InputType.Left)) newInput |= InputNetFlags.Left; @@ -255,14 +261,6 @@ namespace Barotrauma if (AllowInput) { - /*if (newInput.HasFlag(InputNetFlags.Select) || newInput.HasFlag(InputNetFlags.Aim)) - { - newMousePos.X = msg.ReadSingle(); - newMousePos.Y = msg.ReadSingle(); - }*/ - - - if (NetIdUtils.IdMoreRecent((ushort)(networkUpdateID - i), LastNetworkUpdateID) && (i < 60)) { NetInputMem newMem = new NetInputMem(); @@ -364,15 +362,6 @@ namespace Barotrauma tempBuffer.Write(attack); } - if (selectedCharacter != null || selectedConstruction != null) - { - tempBuffer.Write(true); - tempBuffer.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID); - } - else - { - tempBuffer.Write(false); - } if (aiming) { @@ -383,6 +372,16 @@ namespace Barotrauma tempBuffer.Write(AnimController.TargetDir == Direction.Right); } + if (selectedCharacter != null || selectedConstruction != null) + { + tempBuffer.Write(true); + tempBuffer.Write(selectedCharacter != null ? selectedCharacter.ID : selectedConstruction.ID); + } + else + { + tempBuffer.Write(false); + } + tempBuffer.Write(SimPosition.X); tempBuffer.Write(SimPosition.Y); @@ -426,31 +425,7 @@ namespace Barotrauma keys[(int)InputType.Attack].Held = attackInput; keys[(int)InputType.Attack].SetState(false, attackInput); } - - bool entitySelected = msg.ReadBoolean(); - if (entitySelected) - { - ushort entityID = msg.ReadUInt16(); - Entity selectedEntity = Entity.FindEntityByID(entityID); - if (selectedEntity is Character) - { - SelectCharacter((Character)selectedEntity); - } - else if (selectedEntity is Item) - { - var newSelectedConstruction = (Item)selectedEntity; - if (newSelectedConstruction != null && selectedConstruction != newSelectedConstruction) - { - newSelectedConstruction.Pick(this, true, true); - } - } - } - else - { - if (selectedCharacter != null) DeselectCharacter(); - selectedConstruction = null; - } - + if (aimInput) { double aimAngle = ((double)msg.ReadUInt16() / 65535.0) * 2.0 * Math.PI; @@ -462,11 +437,19 @@ namespace Barotrauma facingRight = msg.ReadBoolean(); } + bool entitySelected = msg.ReadBoolean(); + Entity selectedEntity = null; + if (entitySelected) + { + ushort entityID = msg.ReadUInt16(); + selectedEntity = FindEntityByID(entityID); + } + Vector2 pos = new Vector2( msg.ReadFloat(), msg.ReadFloat()); - var posInfo = new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID, sendingTime); + var posInfo = new PosInfo(pos, facingRight ? Direction.Right : Direction.Left, networkUpdateID, sendingTime, selectedEntity); int index = 0; if (GameMain.NetworkMember.Character == this && AllowInput) diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index fd9e826b6..4b464afce 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -19,6 +19,8 @@ namespace Barotrauma public readonly float Timestamp; public readonly UInt16 ID; + public readonly Entity Interact; //the entity being interacted with + public PosInfo(Vector2 pos, Direction dir, float time) : this(pos, dir, 0, time) { @@ -30,11 +32,18 @@ namespace Barotrauma } public PosInfo(Vector2 pos, Direction dir, UInt16 ID, float time) + : this(pos, dir, ID, time, null) + { + } + + public PosInfo(Vector2 pos, Direction dir, UInt16 ID, float time, Entity interact) { Position = pos; Direction = dir; this.ID = ID; + Interact = interact; + Timestamp = time; }