From b5bac67c4ad446650dc7bf9c8920bd799e8d9a20 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 2 Feb 2017 20:40:58 +0200 Subject: [PATCH] WIP item position syncing --- .../Content/Items/Diving/divinggear.xml | 2 +- Subsurface/Content/Items/Jobgear/misc.xml | 4 +- .../Source/Characters/Animation/Ragdoll.cs | 4 +- Subsurface/Source/Characters/Character.cs | 2 +- .../Items/Components/Holdable/Pickable.cs | 5 +- Subsurface/Source/Items/Item.cs | 108 ++++++++++++++++-- Subsurface/Source/Networking/GameServer.cs | 19 ++- Subsurface/Source/Physics/PhysicsBody.cs | 89 ++++++++++----- 8 files changed, 185 insertions(+), 48 deletions(-) diff --git a/Subsurface/Content/Items/Diving/divinggear.xml b/Subsurface/Content/Items/Diving/divinggear.xml index cd1daebd3..875804ca1 100644 --- a/Subsurface/Content/Items/Diving/divinggear.xml +++ b/Subsurface/Content/Items/Diving/divinggear.xml @@ -36,7 +36,7 @@ - + diff --git a/Subsurface/Content/Items/Jobgear/misc.xml b/Subsurface/Content/Items/Jobgear/misc.xml index a1c01c197..d3ac00fb2 100644 --- a/Subsurface/Content/Items/Jobgear/misc.xml +++ b/Subsurface/Content/Items/Jobgear/misc.xml @@ -8,7 +8,7 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/Subsurface/Source/Characters/Animation/Ragdoll.cs b/Subsurface/Source/Characters/Animation/Ragdoll.cs index c26e4e7d1..390371687 100644 --- a/Subsurface/Source/Characters/Animation/Ragdoll.cs +++ b/Subsurface/Source/Characters/Animation/Ragdoll.cs @@ -584,9 +584,9 @@ namespace Barotrauma foreach (Limb limb in Limbs) { - if (limb.body.TargetPosition != Vector2.Zero) + if (limb.body.TargetPosition != null) { - Vector2 pos = ConvertUnits.ToDisplayUnits(limb.body.TargetPosition); + Vector2 pos = ConvertUnits.ToDisplayUnits((Vector2)limb.body.TargetPosition); if (currentHull != null) pos += currentHull.Submarine.DrawPosition; pos.Y = -pos.Y; diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 5a43f47b1..02d27b668 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1086,7 +1086,7 @@ namespace Barotrauma if (torso == null) return null; - Vector2 pos = (torso.body.TargetPosition != Vector2.Zero) ? torso.body.TargetPosition : torso.SimPosition; + Vector2 pos = (torso.body.TargetPosition != null) ? (Vector2)torso.body.TargetPosition : torso.SimPosition; Vector2 pickPos = mouseSimPos; if (Submarine != null) diff --git a/Subsurface/Source/Items/Components/Holdable/Pickable.cs b/Subsurface/Source/Items/Components/Holdable/Pickable.cs index bb6575bc2..176672899 100644 --- a/Subsurface/Source/Items/Components/Holdable/Pickable.cs +++ b/Subsurface/Source/Items/Components/Holdable/Pickable.cs @@ -195,10 +195,9 @@ namespace Barotrauma.Items.Components Limb rightHand = picker.AnimController.GetLimb(LimbType.RightHand); bodyDropPos = rightHand.SimPosition; - if (item.body!=null) + if (item.body != null) { - item.body.LinearVelocity = rightHand.body.LinearVelocity; - item.body.AngularVelocity = rightHand.body.AngularVelocity; + item.body.ResetDynamics(); } picker.Inventory.RemoveItem(item); diff --git a/Subsurface/Source/Items/Item.cs b/Subsurface/Source/Items/Item.cs index 09bf80dcb..ac5e5f740 100644 --- a/Subsurface/Source/Items/Item.cs +++ b/Subsurface/Source/Items/Item.cs @@ -46,8 +46,13 @@ namespace Barotrauma public List drawableComponents; public PhysicsBody body; + + private Vector2 lastSentPos; + private bool prevBodyAwake; + private bool needsPositionUpdate; private float lastSentCondition; + private float condition; private bool inWater; @@ -148,6 +153,18 @@ namespace Barotrauma return (body==null) ? base.SimPosition : body.SimPosition; } } + public bool NeedsPositionUpdate + { + get + { + if (body == null || !body.Enabled) return false; + return needsPositionUpdate; + } + set + { + needsPositionUpdate = value; + } + } protected Color spriteColor; [Editable, HasDefaultValue("1.0,1.0,1.0,1.0", true)] @@ -358,6 +375,8 @@ namespace Barotrauma { case "body": body = new PhysicsBody(subElement, ConvertUnits.ToSimUnits(Position)); + body.FarseerBody.AngularDamping = 0.2f; + body.FarseerBody.LinearDamping = 0.1f; break; case "trigger": case "sprite": @@ -790,18 +809,17 @@ namespace Barotrauma body.SetTransform(body.SimPosition - Submarine.SimPosition, body.Rotation); } - //Vector2 moveAmount = body.SimPosition - body.LastSentPosition; - //if (parentInventory == null && moveAmount != Vector2.Zero && moveAmount.Length() > NetConfig.ItemPosUpdateDistance) - //{ - // new NetworkEvent(NetworkEventType.PhysicsBodyPosition, ID, false); - //} - Vector2 displayPos = ConvertUnits.ToDisplayUnits(body.SimPosition); rect.X = (int)(displayPos.X - rect.Width / 2.0f); rect.Y = (int)(displayPos.Y + rect.Height / 2.0f); } - body.MoveToTargetPosition(); + UpdateNetPosition(deltaTime); + + if (GameMain.Client != null) + { + body.MoveToTargetPosition(); + } if (!inWater || Container != null || body == null) return; @@ -978,7 +996,7 @@ namespace Barotrauma (int)Math.Max((1.5f / GameScreen.Selected.Cam.Zoom), 1.0f)); } } - + if (!ShowLinks) return; foreach (MapEntity e in linkedTo) @@ -1540,6 +1558,8 @@ namespace Barotrauma parentInventory.RemoveItem(this); parentInventory = null; } + + lastSentPos = SimPosition; } public void Equip(Character character) @@ -1556,7 +1576,6 @@ namespace Barotrauma public List GetProperties() { - List editableProperties = ObjectProperty.GetProperties(this); foreach (ItemComponent ic in components) @@ -1713,6 +1732,12 @@ namespace Barotrauma public void ClientRead(ServerNetObject type, NetIncomingMessage msg, float sendingTime) { + if (type == ServerNetObject.ENTITY_POSITION) + { + ClientReadPosition(type, msg, sendingTime); + return; + } + NetEntityEvent.Type eventType = (NetEntityEvent.Type)msg.ReadByte(); switch (eventType) { @@ -2021,6 +2046,71 @@ namespace Barotrauma return item; } + private void UpdateNetPosition(float deltaTime) + { + if (GameMain.Server == null) return; + if (body == null || !body.Enabled || parentInventory != null) return; + + float minDistance = !body.FarseerBody.Awake && prevBodyAwake ? + 0.1f : NetConfig.ItemPosUpdateDistance; + + if (Vector2.Distance(lastSentPos, SimPosition) > minDistance) + { + needsPositionUpdate = true; + } + + prevBodyAwake = body.FarseerBody.Awake; + } + + public void ServerWritePosition(NetBuffer msg, Client c, object[] extraData = null) + { + msg.Write(ID); + //length in bytes + msg.Write((byte)(4 + 4 + 1)); + + msg.Write(SimPosition.X); + msg.Write(SimPosition.Y); + + msg.Write(MathUtils.AngleToByte(body.Rotation)); + + lastSentPos = SimPosition; + } + + public void ClientReadPosition(ServerNetObject type, NetIncomingMessage msg, float sendingTime) + { + + body.TargetPosition = new Vector2( + msg.ReadFloat(), + msg.ReadFloat()); + + body.FarseerBody.Rotation = MathUtils.ByteToAngle(msg.ReadByte()); + + DebugConsole.NewMessage("Received item pos, t: "+sendingTime+ " ("+Name+")", Color.LightGreen); + + + + /* //already interpolating with more up-to-date data -> ignore + if (MemPos.Count > 1 && MemPos[0].Timestamp > sendingTime) + { + return; + } + + int index = 0; + while (index < MemPos.Count && sendingTime > MemPos[index].Timestamp) + { + index++; + } + + //position with the same timestamp already in the buffer (duplicate packet?) + // -> no need to add again + if (index < MemPos.Count && sendingTime == MemPos[index].Timestamp) + { + return; + } + + MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.None, sendingTime));*/ + } + public static void Load(XElement element, Submarine submarine) { string rectString = ToolBox.GetAttributeString(element, "rect", "0,0,0,0"); diff --git a/Subsurface/Source/Networking/GameServer.cs b/Subsurface/Source/Networking/GameServer.cs index 8e573199b..965385ff2 100644 --- a/Subsurface/Source/Networking/GameServer.cs +++ b/Subsurface/Source/Networking/GameServer.cs @@ -77,7 +77,7 @@ namespace Barotrauma.Networking config.SimulatedDuplicatesChance = 0.05f; config.SimulatedMinimumLatency = 0.1f; - config.ConnectionTimeout = 5.0f; + config.ConnectionTimeout = 60.0f; #endif config.Port = port; Port = port; @@ -503,6 +503,11 @@ namespace Barotrauma.Networking ClientWriteLobby(c); } } + + foreach (Item item in Item.ItemList) + { + item.NeedsPositionUpdate = false; + } } updateTimer = DateTime.Now + updateInterval; @@ -688,6 +693,9 @@ namespace Barotrauma.Networking case ClientNetObject.ENTITY_STATE: entityEventManager.Read(inc, c); break; + case ClientNetObject.VOTE: + Voting.RegisterVote(inc, c); + break; default: return; } @@ -766,6 +774,15 @@ namespace Barotrauma.Networking outmsg.WritePadBits(); } + foreach (Item item in Item.ItemList) + { + if (!item.NeedsPositionUpdate) continue; + + outmsg.Write((byte)ServerNetObject.ENTITY_POSITION); + item.ServerWritePosition(outmsg, c); + outmsg.WritePadBits(); + } + entityEventManager.Write(c, outmsg); outmsg.Write((byte)ServerNetObject.END_OF_MESSAGE); diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index 15067520b..98730fe07 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -75,15 +75,12 @@ namespace Barotrauma protected Vector2 prevPosition; protected float prevRotation; - protected Vector2 targetPosition; - //protected Vector2 targetVelocity; - protected float targetRotation; - //protected float targetAngularVelocity; + protected Vector2? targetPosition; + protected float? targetRotation; private Vector2 drawPosition; private float drawRotation; - private float lastNetworkUpdateTime; public Vector2 LastSentPosition { @@ -109,24 +106,41 @@ namespace Barotrauma get { return bodyShape; } } - public Vector2 TargetPosition + public Vector2? TargetPosition { get { return targetPosition; } set { - if (!MathUtils.IsValid(value)) return; - targetPosition.X = MathHelper.Clamp(value.X, -10000.0f, 10000.0f); - targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f); + if (value == null) + { + targetPosition = null; + } + else + { + if (!MathUtils.IsValid((Vector2)value)) return; + + targetPosition = new Vector2( + MathHelper.Clamp(((Vector2)value).X, -10000.0f, 10000.0f), + MathHelper.Clamp(((Vector2)value).Y, -10000.0f, 10000.0f)); + } } } - public float TargetRotation + public float? TargetRotation { get { return targetRotation; } set { - if (!MathUtils.IsValid(value)) return; - targetRotation = value; + if (value == null) + { + targetRotation = null; + } + else + { + if (!MathUtils.IsValid((float)value)) return; + targetRotation = value; + } + } } @@ -378,25 +392,21 @@ namespace Barotrauma public void MoveToTargetPosition(bool lerp = true) { - if (targetPosition == Vector2.Zero) + if (targetPosition == null) return; + + if (lerp && Vector2.Distance((Vector2)targetPosition, body.Position) < 10.0f) { - offsetFromTargetPos = Vector2.Zero; - return; + offsetFromTargetPos = (Vector2)targetPosition - (body.Position - offsetFromTargetPos); + prevPosition = (Vector2)targetPosition; } - if (lerp && Vector2.Distance(targetPosition, body.Position)<10.0f) - { - offsetFromTargetPos = targetPosition - (body.Position - offsetFromTargetPos); - prevPosition = targetPosition; - } - - body.SetTransform(targetPosition, targetRotation == 0.0f ? body.Rotation : targetRotation); - targetPosition = Vector2.Zero; + body.SetTransform((Vector2)targetPosition, targetRotation == null ? body.Rotation : (float)targetRotation); + targetPosition = null; } - + public void MoveToPos(Vector2 pos, float force, Vector2? pullPos = null) { - if (pullPos==null) pullPos = body.Position; + if (pullPos == null) pullPos = body.Position; Vector2 vel = body.LinearVelocity; Vector2 deltaPos = pos - (Vector2)pullPos; @@ -445,7 +455,7 @@ namespace Barotrauma } else { - offsetFromTargetPos = Vector2.Lerp(offsetFromTargetPos, Vector2.Zero, 0.1f); + offsetFromTargetPos = Vector2.Lerp(offsetFromTargetPos, Vector2.Zero, 0.05f); } } @@ -459,12 +469,33 @@ namespace Barotrauma SpriteEffects spriteEffect = (dir == 1.0f) ? SpriteEffects.None : SpriteEffects.FlipHorizontally; - if (GameMain.DebugDraw && !body.Awake) + if (GameMain.DebugDraw) { - color = Color.Blue; + if (!body.Awake) color = Color.Blue; + + if (targetPosition != null) + { + Vector2 pos = ConvertUnits.ToDisplayUnits((Vector2)targetPosition); + if (Submarine != null) pos += Submarine.DrawPosition; + + GUI.DrawRectangle(spriteBatch, + new Vector2(pos.X - 5, -(pos.Y + 5)), + Vector2.One*10.0f, Color.Red, false, 0, 3); + } + + if (offsetFromTargetPos != Vector2.Zero) + { + Vector2 pos = ConvertUnits.ToDisplayUnits(body.Position); + if (Submarine != null) pos += Submarine.DrawPosition; + + GUI.DrawLine(spriteBatch, + new Vector2(pos.X, -pos.Y), + new Vector2(DrawPosition.X, -DrawPosition.Y), + Color.Cyan, 0, 5); + } } - sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, scale, spriteEffect, depth); + sprite.Draw(spriteBatch, new Vector2(DrawPosition.X, -DrawPosition.Y), color, -drawRotation, scale, spriteEffect, depth); } public void DebugDraw(SpriteBatch spriteBatch, Color color)