public void Update(float deltaTime) { if (GameMain.Client != null) { if (memPos.Count == 0) { return; } Vector2 newVelocity = Body.LinearVelocity; Vector2 newPosition = Body.SimPosition; Body.CorrectPosition(memPos, deltaTime, out newVelocity, out newPosition); Vector2 moveAmount = ConvertUnits.ToDisplayUnits(newPosition - Body.SimPosition); newVelocity = newVelocity.ClampLength(100.0f); if (!MathUtils.IsValid(newVelocity)) { return; } List <Submarine> subsToMove = submarine.GetConnectedSubs(); foreach (Submarine dockedSub in subsToMove) { if (dockedSub == submarine) { continue; } //clear the position buffer of the docked subs to prevent unnecessary position corrections dockedSub.SubBody.memPos.Clear(); } Submarine closestSub = null; if (Character.Controlled == null) { closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter); } else { closestSub = Character.Controlled.Submarine; } 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; } //if outside left or right edge of the level if (Position.X < 0 || Position.X > Level.Loaded.Size.X) { Rectangle worldBorders = Borders; worldBorders.Location += MathUtils.ToPoint(Position); //push the sub back below the upper "barrier" of the level if (worldBorders.Y > Level.Loaded.Size.Y) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Min(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.Size.Y - worldBorders.Y))); } else if (worldBorders.Y - worldBorders.Height < Level.Loaded.BottomPos) { Body.LinearVelocity = new Vector2( Body.LinearVelocity.X, Math.Max(Body.LinearVelocity.Y, ConvertUnits.ToSimUnits(Level.Loaded.BottomPos - (worldBorders.Y - worldBorders.Height)))); } } //------------------------- Vector2 totalForce = CalculateBuoyancy(); if (Body.LinearVelocity.LengthSquared() > 0.000001f) { float dragCoefficient = 0.01f; float speedLength = (Body.LinearVelocity == Vector2.Zero) ? 0.0f : Body.LinearVelocity.Length(); float drag = speedLength * speedLength * dragCoefficient * Body.Mass; totalForce += -Vector2.Normalize(Body.LinearVelocity) * drag; } ApplyForce(totalForce); UpdateDepthDamage(deltaTime); }