From 07f8c966ab639a6930411322daea4582209b9e9a Mon Sep 17 00:00:00 2001 From: Regalis Date: Tue, 25 Oct 2016 19:01:19 +0300 Subject: [PATCH] Submarine position is synced using the same logic as the characters, AICharacter position syncing --- .../Content/Characters/Crawler/crawler.xml | 2 +- .../Content/Characters/Endworm/endworm.xml | 2 +- .../Content/Characters/Moloch/moloch.xml | 2 +- Subsurface/Source/Characters/AICharacter.cs | 15 +- .../Animation/FishAnimController.cs | 2 + Subsurface/Source/Characters/Character.cs | 42 +-- .../Source/Items/Components/DockingPort.cs | 4 +- Subsurface/Source/Map/Submarine.cs | 77 ++++-- Subsurface/Source/Map/SubmarineBody.cs | 245 +++++++----------- Subsurface/Source/Networking/GameClient.cs | 1 + .../Source/Networking/RespawnManager.cs | 10 +- Subsurface/Source/Physics/PhysicsBody.cs | 88 ++++--- 12 files changed, 234 insertions(+), 256 deletions(-) diff --git a/Subsurface/Content/Characters/Crawler/crawler.xml b/Subsurface/Content/Characters/Crawler/crawler.xml index 313a7867d..d2a2dbab5 100644 --- a/Subsurface/Content/Characters/Crawler/crawler.xml +++ b/Subsurface/Content/Characters/Crawler/crawler.xml @@ -8,7 +8,7 @@ diff --git a/Subsurface/Content/Characters/Endworm/endworm.xml b/Subsurface/Content/Characters/Endworm/endworm.xml index 157c81d7a..8090dd20d 100644 --- a/Subsurface/Content/Characters/Endworm/endworm.xml +++ b/Subsurface/Content/Characters/Endworm/endworm.xml @@ -5,7 +5,7 @@ - + diff --git a/Subsurface/Content/Characters/Moloch/moloch.xml b/Subsurface/Content/Characters/Moloch/moloch.xml index aba30598b..9a9b66030 100644 --- a/Subsurface/Content/Characters/Moloch/moloch.xml +++ b/Subsurface/Content/Characters/Moloch/moloch.xml @@ -6,7 +6,7 @@ - + diff --git a/Subsurface/Source/Characters/AICharacter.cs b/Subsurface/Source/Characters/AICharacter.cs index cf48cf5a9..3fe736a58 100644 --- a/Subsurface/Source/Characters/AICharacter.cs +++ b/Subsurface/Source/Characters/AICharacter.cs @@ -254,10 +254,7 @@ namespace Barotrauma AnimController.TargetDir = (targetDir) ? Direction.Right : Direction.Left; AnimController.TargetMovement = targetMovement; - - AnimController.MainLimb.body.TargetPosition = pos; - //AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime); - + if (inSub) { Hull newHull = Hull.FindHull(ConvertUnits.ToDisplayUnits(pos), AnimController.CurrentHull, false); @@ -267,7 +264,15 @@ namespace Barotrauma Submarine = newHull.Submarine; } } - + + int index = 0; + while (index < memPos.Count && sendingTime > memPos[index].Timestamp) + { + index++; + } + + memPos.Insert(index, new PosInfo(pos, (targetDir) ? Direction.Right : Direction.Left, sendingTime)); + LastNetworkUpdate = sendingTime; break; } diff --git a/Subsurface/Source/Characters/Animation/FishAnimController.cs b/Subsurface/Source/Characters/Animation/FishAnimController.cs index 9afc2afb2..b28c589bf 100644 --- a/Subsurface/Source/Characters/Animation/FishAnimController.cs +++ b/Subsurface/Source/Characters/Animation/FishAnimController.cs @@ -195,6 +195,8 @@ namespace Barotrauma for (int i = 0; i < Limbs.Count(); i++) { + if (Limbs[i].SteerForce <= 0.0f) continue; + Vector2 pullPos = Limbs[i].pullJoint == null ? Limbs[i].SimPosition : Limbs[i].pullJoint.WorldAnchorA; Limbs[i].body.ApplyForce(movement * Limbs[i].SteerForce * Limbs[i].Mass, pullPos); diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 1e6543c59..88124bb67 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -14,33 +14,6 @@ using System.Xml.Linq; namespace Barotrauma { - struct PosInfo - { - public readonly Vector2 Position; - public readonly Direction Direction; - - public readonly float Timestamp; - public readonly UInt32 ID; - - public PosInfo(Vector2 pos, Direction dir, float time) - { - Position = pos; - Direction = dir; - Timestamp = time; - - ID = 0; - } - - public PosInfo(Vector2 pos, Direction dir, UInt32 ID) - { - Position = pos; - Direction = dir; - this.ID = ID; - - Timestamp = 0.0f; - } - } - class Character : Entity, IDamageable, IPropertyObject { public static List CharacterList = new List(); @@ -53,7 +26,7 @@ namespace Barotrauma get { return netStateID; } } - List memPos = new List(); + protected List memPos = new List(); private bool networkUpdateSent; List memLocalPos = new List(); @@ -2148,14 +2121,15 @@ namespace Barotrauma else { cursorPosition = Position + new Vector2(1000.0f, 0.0f) * dir; - - //AnimController.TargetDir = dir < 0 ? Direction.Left : Direction.Right; + } + + int index = 0; + while (index < memPos.Count && sendingTime > memPos[index].Timestamp) + { + index++; } - //AnimController.RefLimb.body.TargetPosition = - // AnimController.EstimateCurrPosition(pos, (float)(NetTime.Now) - sendingTime); - - memPos.Add(new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime)); + memPos.Insert(index, new PosInfo(pos, dir < 0 ? Direction.Left : Direction.Right, sendingTime)); LastNetworkUpdate = sendingTime; diff --git a/Subsurface/Source/Items/Components/DockingPort.cs b/Subsurface/Source/Items/Components/DockingPort.cs index f89987ced..57757c14f 100644 --- a/Subsurface/Source/Items/Components/DockingPort.cs +++ b/Subsurface/Source/Items/Components/DockingPort.cs @@ -214,7 +214,7 @@ namespace Barotrauma.Items.Components if (useWeldJoint) { joint = JointFactory.CreateWeldJoint(GameMain.World, - item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body, + item.Submarine.PhysicsBody.FarseerBody, dockingTarget.item.Submarine.PhysicsBody.FarseerBody, ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true); ((WeldJoint)joint).FrequencyHz = 1.0f; @@ -222,7 +222,7 @@ namespace Barotrauma.Items.Components else { var distanceJoint = JointFactory.CreateDistanceJoint(GameMain.World, - item.Submarine.SubBody.Body, dockingTarget.item.Submarine.SubBody.Body, + item.Submarine.PhysicsBody.FarseerBody, dockingTarget.item.Submarine.PhysicsBody.FarseerBody, ConvertUnits.ToSimUnits(pos1), FarseerPhysics.ConvertUnits.ToSimUnits(pos2), true); distanceJoint.Length = 0.01f; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index d6bda4e63..2eb0cd2c4 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -75,7 +75,7 @@ namespace Barotrauma private Vector2 prevPosition; - private float lastNetworkUpdate, networkUpdateTimer; + private float networkUpdateTimer; private EntityGrid entityGrid = null; @@ -140,6 +140,11 @@ namespace Barotrauma get { return subBody; } } + public PhysicsBody PhysicsBody + { + get { return subBody.Body; } + } + public Rectangle Borders { get @@ -289,6 +294,7 @@ namespace Barotrauma { MapEntity.mapEntityList[i].Draw(spriteBatch, editing); } + } public static void DrawFront(SpriteBatch spriteBatch, bool editing = false) @@ -298,6 +304,32 @@ namespace Barotrauma if (MapEntity.mapEntityList[i].DrawOverWater) MapEntity.mapEntityList[i].Draw(spriteBatch, editing, false); } + + + if (GameMain.DebugDraw) + { + foreach (Submarine sub in Submarine.Loaded) + { + if (sub.subBody.MemPos.Count < 2) continue; + + Vector2 prevPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[0].Position); + prevPos.Y = -prevPos.Y; + + for (int i = 1; i < sub.subBody.MemPos.Count; i++) + { + Vector2 currPos = ConvertUnits.ToDisplayUnits(sub.subBody.MemPos[i].Position); + currPos.Y = -currPos.Y; + + GUI.DrawRectangle(spriteBatch, new Rectangle((int)currPos.X - 10, (int)currPos.Y - 10, 20, 20), Color.Blue * 0.6f, true, 0.01f); + GUI.DrawLine(spriteBatch, prevPos, currPos, Color.Cyan * 0.5f, 0, 5); + + prevPos = currPos; + } + + } + + + } } public static void DrawDamageable(SpriteBatch spriteBatch, Effect damageEffect, bool editing = false) @@ -530,9 +562,8 @@ namespace Barotrauma } Vector2 pos = new Vector2(subBody.Position.X, subBody.Position.Y); - SubmarineBody newSubBody = new SubmarineBody(this); - GameMain.World.RemoveBody(subBody.Body); - subBody = newSubBody; + subBody.Body.Remove(); + subBody = new SubmarineBody(this); SetPosition(pos); if (entityGrid != null) @@ -580,7 +611,7 @@ namespace Barotrauma if (this != MainSub && MainSub.DockedTo.Contains(this)) return; //send updates more frequently if moving fast - networkUpdateTimer -= MathHelper.Clamp(Velocity.Length(), 0.1f, 5.0f) * deltaTime; + networkUpdateTimer -= MathHelper.Clamp(Velocity.Length()*10.0f, 0.1f, 5.0f) * deltaTime; if (networkUpdateTimer < 0.0f) { @@ -651,12 +682,9 @@ namespace Barotrauma { if (subBody == null) return false; - message.Write(subBody.Position.X); - message.Write(subBody.Position.Y); - - message.Write(Velocity.X); - message.Write(Velocity.Y); - + message.Write(PhysicsBody.SimPosition.X); + message.Write(PhysicsBody.SimPosition.Y); + return true; } @@ -666,13 +694,13 @@ namespace Barotrauma if (GameMain.Server != null) return false; - Vector2 newTargetPosition, newSpeed; + + Vector2 newTargetPosition; try { - if (sendingTime <= lastNetworkUpdate) return false; - - newTargetPosition = new Vector2(message.ReadFloat(), message.ReadFloat()); - newSpeed = new Vector2(message.ReadFloat(), message.ReadFloat()); + newTargetPosition = new Vector2( + message.ReadFloat(), + message.ReadFloat()); } catch (Exception e) @@ -683,14 +711,21 @@ namespace Barotrauma return false; } - if (!newSpeed.IsValid() || !newTargetPosition.IsValid()) return false; + if (!newTargetPosition.IsValid()) return false; - //newTargetPosition = newTargetPosition + newSpeed * (float)(NetTime.Now - sendingTime); + //already interpolating with more up-to-date data -> ignore + if (subBody.MemPos.Count > 1 && subBody.MemPos[0].Timestamp > sendingTime) + { + return true; + } - subBody.TargetPosition = newTargetPosition; - subBody.Velocity = newSpeed; + int index = 0; + while (index < subBody.MemPos.Count && sendingTime > subBody.MemPos[index].Timestamp) + { + index++; + } - lastNetworkUpdate = sendingTime; + subBody.MemPos.Insert(index, new PosInfo(newTargetPosition, Direction.Right, sendingTime)); return true; } diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index 1a0d1296a..61b531a1d 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -32,12 +32,10 @@ namespace Barotrauma private float depthDamageTimer; private readonly Submarine submarine; - - public readonly Body Body; - private Vector2? targetPosition; + public readonly PhysicsBody Body; - //private float mass = 10000.0f; + List memPos = new List(); public Rectangle Borders { @@ -55,19 +53,14 @@ namespace Barotrauma } } - public Vector2 TargetPosition - { - //get { return targetPosition.Value; } - set - { - if (!MathUtils.IsValid(value)) return; - targetPosition = value; - } - } - public Vector2 Position { - get { return ConvertUnits.ToDisplayUnits(Body.Position); } + get { return ConvertUnits.ToDisplayUnits(Body.SimPosition); } + } + + public List MemPos + { + get { return memPos; } } public bool AtDamageDepth @@ -79,10 +72,12 @@ namespace Barotrauma { this.submarine = sub; + Body farseerBody = null; + if (!Hull.hullList.Any()) { - - Body = BodyFactory.CreateRectangle(GameMain.World, 1.0f, 1.0f, 1.0f); + Body = new PhysicsBody(1,1,1,1); + farseerBody = Body.FarseerBody; DebugConsole.ThrowError("WARNING: no hulls found, generating a physics body for the submarine failed."); } else @@ -108,21 +103,20 @@ namespace Barotrauma (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.X * 2.0f), (int)ConvertUnits.ToDisplayUnits(hullAABB.Extents.Y * 2.0f)); - //var triangulatedVertices = Triangulate.ConvexPartition(shapevertices, TriangulationAlgorithm.Bayazit); - - Body = BodyFactory.CreateBody(GameMain.World, this); + farseerBody = BodyFactory.CreateBody(GameMain.World, this); foreach (Structure wall in Structure.WallList) { if (wall.Submarine != submarine) continue; Rectangle rect = wall.Rect; + FixtureFactory.AttachRectangle( ConvertUnits.ToSimUnits(rect.Width), ConvertUnits.ToSimUnits(rect.Height), 50.0f, ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), - Body, this); + farseerBody, this); } foreach (Hull hull in Hull.hullList) @@ -135,30 +129,32 @@ namespace Barotrauma ConvertUnits.ToSimUnits(rect.Height), 5.0f, ConvertUnits.ToSimUnits(new Vector2(rect.X + rect.Width / 2, rect.Y - rect.Height / 2)), - Body, this); + farseerBody, this); } } - Body.BodyType = BodyType.Dynamic; - Body.CollisionCategories = Physics.CollisionWall; - Body.CollidesWith = + farseerBody.BodyType = BodyType.Dynamic; + farseerBody.CollisionCategories = Physics.CollisionWall; + farseerBody.CollidesWith = Physics.CollisionItem | Physics.CollisionLevel | Physics.CollisionCharacter | Physics.CollisionProjectile | Physics.CollisionWall; - Body.Restitution = Restitution; - Body.Friction = Friction; - Body.FixedRotation = true; + farseerBody.Restitution = Restitution; + farseerBody.Friction = Friction; + farseerBody.FixedRotation = true; //mass = Body.Mass; - Body.Awake = true; - Body.SleepingAllowed = false; - Body.IgnoreGravity = true; - Body.OnCollision += OnCollision; - Body.UserData = submarine; + farseerBody.Awake = true; + farseerBody.SleepingAllowed = false; + farseerBody.IgnoreGravity = true; + farseerBody.OnCollision += OnCollision; + farseerBody.UserData = submarine; + + Body = new PhysicsBody(farseerBody); } @@ -187,59 +183,66 @@ namespace Barotrauma } public void Update(float deltaTime) - { - if (targetPosition != null && targetPosition != Position) + { + if (GameMain.Client != null) { - float dist = Vector2.Distance((Vector2)targetPosition, Position); + //if (memPos.Count > 1 && Vector2.Distance(memPos[1].Position, Body.SimPosition) > 5.0f) + //{ + // Vector2 moveAmount = ConvertUnits.ToDisplayUnits(memPos[1].Position - Body.SimPosition); + + // ForceTranslate(moveAmount); + // DisplaceCharacters(moveAmount); + + // foreach (Submarine sub in submarine.DockedTo) + // { + // sub.SubBody.ForceTranslate(moveAmount); + // sub.SubBody.DisplaceCharacters(moveAmount); + // } + + // memPos.RemoveRange(0, 2); + //} + //else - if (dist > 500.0f) //immediately snap the sub to the target position if more than 500.0f units away + Vector2 newVelocity = Body.LinearVelocity; + Vector2 newPosition = Body.SimPosition; + + Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition); + Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition); + + List subsToMove = new List() { this.submarine }; + subsToMove.AddRange(submarine.DockedTo); + + Submarine closestSub = null; + if (Character.Controlled == null) { - Vector2 moveAmount = (Vector2)targetPosition - ConvertUnits.ToDisplayUnits(Body.Position); - - List dockedBodies = new List() { this }; - submarine.DockedTo.ForEach(d => dockedBodies.Add(d.SubBody)); - - foreach (SubmarineBody dockedBody in dockedBodies) - { - dockedBody.ForceTranslate(moveAmount); - - if ((Character.Controlled != null && Character.Controlled.Submarine == dockedBody.submarine) || - (Character.Controlled == null && Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == dockedBody.submarine)) - { - GameMain.GameScreen.Cam.UpdateTransform(false); - } - - dockedBody.submarine.SetPrevTransform(dockedBody.submarine.Position); - dockedBody.submarine.UpdateTransform(); - targetPosition = null; - - dockedBody.DisplaceCharacters(moveAmount); - } - - - } - else if (dist > 50.0f) //lerp the position if (50 < dist < 500) - { - Vector2 moveAmount = Vector2.Normalize((Vector2)targetPosition - Position); - moveAmount *= Math.Min(dist, 100.0f); - - ForceTranslate(moveAmount * deltaTime); - - foreach (Submarine sub in submarine.DockedTo) - { - sub.SubBody.ForceTranslate(moveAmount * deltaTime); - } + closestSub= Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter); } else { - targetPosition = null; + closestSub = Character.Controlled.Submarine; } - } - else - { - targetPosition = null; - } + bool displace = moveAmount.Length() > 100.0f; + + foreach (Submarine sub in subsToMove) + { + sub.PhysicsBody.SetTransform(sub.PhysicsBody.SimPosition + ConvertUnits.ToSimUnits(moveAmount), 0.0f); + sub.PhysicsBody.LinearVelocity = newVelocity; + + if (displace) sub.SubBody.DisplaceCharacters(moveAmount); + } + + if (closestSub != null && subsToMove.Contains(closestSub)) + { + GameMain.GameScreen.Cam.Position += moveAmount; + if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += moveAmount; + + if (Character.Controlled!=null) Character.Controlled.CursorPosition += moveAmount; + } + + return; + } + //------------------------- Vector2 totalForce = CalculateBuoyancy(); @@ -258,51 +261,22 @@ namespace Barotrauma UpdateDepthDamage(deltaTime); } - - + /// - /// Immediately translates the position of the physics body, gamescreen camera and Character.Controlled.CursorPosition - /// - /// Amount to move in display units - private void ForceTranslate(Vector2 amount) - { - Body.SetTransform(Body.Position + ConvertUnits.ToSimUnits(amount), 0.0f); - - bool isClosestSub = false; - if (Character.Controlled == null) - { - isClosestSub = Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter) == submarine; - } - else - { - isClosestSub = Character.Controlled.Submarine == submarine; - - Character.Controlled.CursorPosition += amount; - } - - if (isClosestSub) - { - GameMain.GameScreen.Cam.Position += amount; - if (GameMain.GameScreen.Cam.TargetPos != Vector2.Zero) GameMain.GameScreen.Cam.TargetPos += amount; - } - } - - - /// - /// Moves away any character that is inside the bounding box of the sub (but not inside it) + /// Moves away any character that is inside the bounding box of the sub (but not inside the sub) /// /// The translation that was applied to the sub before doing the displacement /// (used for determining where to push the characters) private void DisplaceCharacters(Vector2 subTranslation) { Rectangle worldBorders = Borders; - worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.Position).ToPoint(); + worldBorders.Location += ConvertUnits.ToDisplayUnits(Body.SimPosition).ToPoint(); Vector2 translateDir = Vector2.Normalize(subTranslation); foreach (Character c in Character.CharacterList) { - if (c.AnimController.CurrentHull != null) continue; + if (c.AnimController.CurrentHull != null && c.AnimController.CanEnterSubmarine) continue; foreach (Limb limb in c.AnimController.Limbs) { @@ -317,7 +291,7 @@ namespace Barotrauma //should never be null when casting a line out from inside the bounding box Debug.Assert(intersection != null); - //\"+ translatedir\" in order to move the character slightly away from the wall + //"+ translatedir" in order to move the character slightly away from the wall c.AnimController.SetPosition(ConvertUnits.ToSimUnits(c.WorldPosition + ((Vector2)intersection - limb.WorldPosition)) + translateDir); return; @@ -342,8 +316,6 @@ namespace Barotrauma float neutralPercentage = 0.07f; - Body.IgnoreGravity = true; - float buoyancy = neutralPercentage - waterPercentage; if (buoyancy > 0.0f) buoyancy *= 2.0f; @@ -367,58 +339,25 @@ namespace Barotrauma float depth = DamageDepth - Position.Y; - // float prevTimer = depthDamageTimer; - depthDamageTimer -= deltaTime; - //if (prevTimer>5.0f && depthDamageTimer<=5.0f) - //{ - // SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f,); - //} - if (depthDamageTimer > 0.0f) return; foreach (Structure wall in Structure.WallList) { if (wall.Submarine != submarine) continue; - //if (Rand.Int(5) < 4) continue; - if (wall.Health < depth*0.01f) + if (wall.Health < depth * 0.01f) { - Explosion.RangedStructureDamage(wall.WorldPosition, 100.0f, depth*0.01f); + Explosion.RangedStructureDamage(wall.WorldPosition, 100.0f, depth * 0.01f); if (Character.Controlled != null && Character.Controlled.Submarine == submarine) { - GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(depth *0.001f, 50.0f)); + GameMain.GameScreen.Cam.Shake = Math.Max(GameMain.GameScreen.Cam.Shake, Math.Min(depth * 0.001f, 50.0f)); } } } - //Vector2 damagePos = Vector2.Zero; - //if (Rand.Int(2)==0) - //{ - // damagePos = new Vector2( - // (Rand.Int(2) == 0) ? Borders.X : Borders.X+Borders.Width, - // Rand.Range(Borders.Y - Borders.Height, Borders.Y)); - //} - //else - //{ - // damagePos = new Vector2( - // Rand.Range(Borders.X, Borders.X + Borders.Width), - // (Rand.Int(2) == 0) ? Borders.Y : Borders.Y - Borders.Height); - //} - - //damagePos += submarine.Position + submarine.HiddenSubPosition; - //SoundPlayer.PlayDamageSound(DamageSoundType.Pressure, 50.0f, damagePos, 10000.0f); - - //if (Character.Controlled != null && Character.Controlled.Submarine == submarine) - //{ - // GameMain.GameScreen.Cam.Shake = depth * PressureDamageMultiplier * 0.1f; - //} - - //Explosion.RangedStructureDamage(damagePos, depth * PressureDamageMultiplier * 50.0f, depth * PressureDamageMultiplier); - //SoundPlayer.PlayDamageSound(DamageSoundType.StructureBlunt, Rand.Range(0.0f, 100.0f), damagePos, 5000.0f); - depthDamageTimer = 10.0f; } @@ -432,7 +371,7 @@ namespace Barotrauma if (collision && limb.Mass > 100.0f) { - Vector2 normal = Vector2.Normalize(Body.Position - limb.SimPosition); + Vector2 normal = Vector2.Normalize(Body.SimPosition - limb.SimPosition); float impact = Math.Min(Vector2.Dot(Velocity - limb.LinearVelocity, -normal), 50.0f) / 5.0f; @@ -445,7 +384,7 @@ namespace Barotrauma VoronoiCell cell = f2.Body.UserData as VoronoiCell; if (cell != null) { - var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.Position) - cell.Center); + var collisionNormal = Vector2.Normalize(ConvertUnits.ToDisplayUnits(Body.SimPosition) - cell.Center); float wallImpact = Vector2.Dot(Velocity, -collisionNormal); @@ -474,7 +413,7 @@ namespace Barotrauma Vector2 normal; FixedArray2 points; contact.GetWorldManifold(out normal, out points); - if (contact.FixtureA.Body == sub.SubBody.Body) + if (contact.FixtureA.Body == sub.SubBody.Body.FarseerBody) { normal = -normal; } diff --git a/Subsurface/Source/Networking/GameClient.cs b/Subsurface/Source/Networking/GameClient.cs index 00d5ba276..e4e0b2b0f 100644 --- a/Subsurface/Source/Networking/GameClient.cs +++ b/Subsurface/Source/Networking/GameClient.cs @@ -271,6 +271,7 @@ namespace Barotrauma.Networking GameMain.NetLobbyScreen.Select(); new GUIMessageBox("Connection timed out", "You were disconnected for too long and your character was deleted. Please wait for another round to start."); + myCharacter = null; } GameMain.NetLobbyScreen.ClearPlayers(); diff --git a/Subsurface/Source/Networking/RespawnManager.cs b/Subsurface/Source/Networking/RespawnManager.cs index 0a1be059b..987cd1068 100644 --- a/Subsurface/Source/Networking/RespawnManager.cs +++ b/Subsurface/Source/Networking/RespawnManager.cs @@ -231,8 +231,8 @@ namespace Barotrauma.Networking if (updateReturnTimer > 10.0f) { updateReturnTimer = 0.0f; - - respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBody); + + respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.ShaftBody); shuttleSteering.AutoPilot = true; shuttleSteering.MaintainPos = false; @@ -302,7 +302,7 @@ namespace Barotrauma.Networking private IEnumerable ForceShuttleToPos(Vector2 position, float speed) { - respawnShuttle.SubBody.Body.IgnoreCollisionWith(Level.Loaded.ShaftBody); + respawnShuttle.PhysicsBody.FarseerBody.IgnoreCollisionWith(Level.Loaded.ShaftBody); while (Math.Abs(position.Y - respawnShuttle.WorldPosition.Y) > 100.0f) { @@ -313,7 +313,7 @@ namespace Barotrauma.Networking if (respawnShuttle.SubBody == null) yield return CoroutineStatus.Success; } - respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBody); + respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.ShaftBody); yield return CoroutineStatus.Success; } @@ -378,7 +378,7 @@ namespace Barotrauma.Networking respawnShuttle.Velocity = Vector2.Zero; - respawnShuttle.SubBody.Body.RestoreCollisionWith(Level.Loaded.ShaftBody); + respawnShuttle.PhysicsBody.FarseerBody.RestoreCollisionWith(Level.Loaded.ShaftBody); } diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index 50b217a3c..e3e4b2e25 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -11,9 +11,35 @@ using System; namespace Barotrauma { + struct PosInfo + { + public readonly Vector2 Position; + public readonly Direction Direction; + + public readonly float Timestamp; + public readonly UInt32 ID; + + public PosInfo(Vector2 pos, Direction dir, float time) + { + Position = pos; + Direction = dir; + Timestamp = time; + + ID = 0; + } + + public PosInfo(Vector2 pos, Direction dir, UInt32 ID) + { + Position = pos; + Direction = dir; + this.ID = ID; + + Timestamp = 0.0f; + } + } + class PhysicsBody { - public enum Shape { Circle, Rectangle, Capsule @@ -70,18 +96,7 @@ namespace Barotrauma targetPosition.Y = MathHelper.Clamp(value.Y, -10000.0f, 10000.0f); } } - - //public Vector2 TargetVelocity - //{ - // get { return targetVelocity; } - // set - // { - // if (!MathUtils.IsValid(value)) return; - // targetVelocity.X = MathHelper.Clamp(value.X, -100.0f, 100.0f); - // targetVelocity.Y = MathHelper.Clamp(value.Y, -100.0f, 100.0f); - // } - //} - + public float TargetRotation { get { return targetRotation; } @@ -92,16 +107,6 @@ namespace Barotrauma } } - //public float TargetAngularVelocity - //{ - // get { return targetAngularVelocity; } - // set - // { - // if (!MathUtils.IsValid(value)) return; - // targetAngularVelocity = value; - // } - //} - public Vector2 DrawPosition { get { return Submarine == null ? drawPosition : drawPosition + Submarine.DrawPosition; } @@ -223,6 +228,16 @@ namespace Barotrauma list.Add(this); } + public PhysicsBody(Body farseerBody) + { + body = farseerBody; + body.UserData = this; + + LastSentPosition = body.Position; + + list.Add(this); + } + public PhysicsBody(XElement element, Vector2 position, float scale=1.0f) { float radius = ConvertUnits.ToSimUnits(ToolBox.GetAttributeFloat(element, "radius", 0.0f)) * scale; @@ -464,35 +479,42 @@ namespace Barotrauma public void CorrectPosition(List positionBuffer, float deltaTime, out Vector2 newVelocity) { - newVelocity = Vector2.Zero; - if (positionBuffer.Count < 2) return; + Vector2 newPosition = SimPosition; + CorrectPosition(positionBuffer, deltaTime, out newVelocity, out newPosition); + + SetTransform(newPosition, Rotation); + } + + public void CorrectPosition(List positionBuffer, float deltaTime, out Vector2 newVelocity, out Vector2 newPosition) + { + newVelocity = Vector2.Zero; + newPosition = SimPosition; + + 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); + float speedMultiplier = 0.9f + (float)Math.Pow((positionBuffer.Count - 2) / 5.0f, 2.0f); netInterpolationState += (deltaTime * speedMultiplier) / (next.Timestamp - prev.Timestamp); - currPos = Vector2.Lerp(prev.Position, next.Position, netInterpolationState); + newPosition = 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; + newPosition = next.Position; netInterpolationState = 1.0f; } - SetTransform(currPos, Rotation); - if (netInterpolationState >= 1.0f) { netInterpolationState = 0.0f;