From beac45458e1486a5dcf5e9dd78ca56da94c9d835 Mon Sep 17 00:00:00 2001 From: Regalis Date: Thu, 5 Jan 2017 19:07:18 +0200 Subject: [PATCH] Transforming received in-sub mouse coordinates to outside coordinates if the character is outside and vice versa, HiddenSubPosition fix (can't use Level.Loaded to find the top of the level because the level isn't loaded yet) --- Subsurface/Source/Camera.cs | 2 +- Subsurface/Source/Characters/Character.cs | 82 +++++++++++++------ .../GameSession/GameModes/SinglePlayerMode.cs | 2 +- Subsurface/Source/Map/Submarine.cs | 25 +++++- Subsurface/Source/Map/SubmarineBody.cs | 2 +- Subsurface/Source/Physics/PhysicsBody.cs | 20 +---- Subsurface/Source/Screens/GameScreen.cs | 2 +- 7 files changed, 86 insertions(+), 49 deletions(-) diff --git a/Subsurface/Source/Camera.cs b/Subsurface/Source/Camera.cs index 6f6c7aa6d..dc04f3e7f 100644 --- a/Subsurface/Source/Camera.cs +++ b/Subsurface/Source/Camera.cs @@ -188,7 +188,7 @@ namespace Barotrauma if (Screen.Selected == GameMain.GameScreen) { - var closestSub = Submarine.GetClosest(WorldViewCenter); + var closestSub = Submarine.FindClosest(WorldViewCenter); if (closestSub != null) { moveCam += FarseerPhysics.ConvertUnits.ToDisplayUnits(closestSub.Velocity * deltaTime); diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index 171691ede..13798aaa1 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -1101,6 +1101,27 @@ namespace Barotrauma return closestCharacter; } + private void TransformCursorPos() + { + if (Submarine == null) + { + //character is outside but cursor position inside + if (cursorPosition.Y > Level.Loaded.Size.Y) + { + var sub = Submarine.FindContaining(cursorPosition); + if (sub != null) cursorPosition += sub.Position; + } + } + else + { + //character is inside but cursor position is outside + if (cursorPosition.Y < Level.Loaded.Size.Y) + { + cursorPosition -= Submarine.Position; + } + } + } + private void SelectCharacter(Character character) { if (character == null) return; @@ -1315,41 +1336,46 @@ namespace Barotrauma { if (GameMain.Server != null && !(this is AICharacter) && AllowMovement) { - if (memInput.Count > 0) + if (memInput.Count == 0) { - AnimController.Frozen = false; - prevDequeuedInput = dequeuedInput; - dequeuedInput = memInput[memInput.Count - 1]; - cursorPosition = memMousePos[memMousePos.Count - 1]; - memInput.RemoveAt(memInput.Count - 1); - memMousePos.RemoveAt(memMousePos.Count - 1); - if (dequeuedInput == InputNetFlags.None) + + if (AllowMovement) AnimController.Frozen = true; + return; + } + + AnimController.Frozen = false; + prevDequeuedInput = dequeuedInput; + + dequeuedInput = memInput[memInput.Count - 1]; + memInput.RemoveAt(memInput.Count - 1); + + cursorPosition = memMousePos[memMousePos.Count - 1]; + memMousePos.RemoveAt(memMousePos.Count - 1); + + TransformCursorPos(); + + if (dequeuedInput == InputNetFlags.None) + { + if (isStillCountdown <= 0) { - if (isStillCountdown<=0) + while (memInput.Count > 5 && memInput[memInput.Count - 1] == 0) { - while (memInput.Count>5 && memInput[memInput.Count-1]==0) - { - //remove inputs where the player is not moving at all - //helps the server catch up, shouldn't affect final position - memInput.RemoveAt(memInput.Count - 1); - memMousePos.RemoveAt(memMousePos.Count - 1); - } - isStillCountdown = 15; + //remove inputs where the player is not moving at all + //helps the server catch up, shouldn't affect final position + memInput.RemoveAt(memInput.Count - 1); + memMousePos.RemoveAt(memMousePos.Count - 1); } - else - { - isStillCountdown--; - } - } else - { isStillCountdown = 15; } + else + { + isStillCountdown--; + } } else { - if (AllowMovement) AnimController.Frozen = true; - return; - } + isStillCountdown = 15; + } } } else if (GameMain.Client != null) @@ -2077,6 +2103,8 @@ namespace Barotrauma if (aiming) { //TODO: write this with less accuracy? + + msg.Write(cursorPosition.X); msg.Write(cursorPosition.Y); } @@ -2141,6 +2169,8 @@ namespace Barotrauma cursorPosition = new Vector2( msg.ReadFloat(), msg.ReadFloat()); + + TransformCursorPos(); } facingRight = msg.ReadBoolean(); } diff --git a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs index 5d26ecd4f..685d2ffde 100644 --- a/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs +++ b/Subsurface/Source/GameSession/GameModes/SinglePlayerMode.cs @@ -163,7 +163,7 @@ namespace Barotrauma return null; } - Submarine closestSub = Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter); + Submarine closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter); if (closestSub != null && (closestSub.AtEndPosition || closestSub.AtStartPosition)) { return closestSub.DockedTo.Contains(Submarine.MainSub) ? Submarine.MainSub : closestSub; diff --git a/Subsurface/Source/Map/Submarine.cs b/Subsurface/Source/Map/Submarine.cs index 4b39d0af5..24f3a1398 100644 --- a/Subsurface/Source/Map/Submarine.cs +++ b/Subsurface/Source/Map/Submarine.cs @@ -811,7 +811,7 @@ namespace Barotrauma //Level.Loaded.Move(-amount); } - public static Submarine GetClosest(Vector2 worldPosition) + public static Submarine FindClosest(Vector2 worldPosition) { Submarine closest = null; float closestDist = 0.0f; @@ -828,6 +828,24 @@ namespace Barotrauma return closest; } + /// + /// Finds the sub whose borders contain the position + /// + public static Submarine FindContaining(Vector2 position) + { + foreach (Submarine sub in Submarine.Loaded) + { + Rectangle subBorders = sub.Borders; + subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Microsoft.Xna.Framework.Point(0, sub.Borders.Height); + + subBorders.Inflate(500.0f, 500.0f); + + if (subBorders.Contains(position)) return sub; + } + + return null; + } + //saving/loading ---------------------------------------------------- public bool Save() @@ -1056,7 +1074,10 @@ namespace Barotrauma //place the sub above the top of the level HiddenSubPosition = HiddenSubStartPosition; - if (Level.Loaded != null) HiddenSubPosition += Vector2.UnitY * Level.Loaded.Size.Y; + if (GameMain.GameSession != null && GameMain.GameSession.Level != null) + { + HiddenSubPosition += Vector2.UnitY * GameMain.GameSession.Level.Size.Y; + } foreach (Submarine sub in Submarine.loaded) { diff --git a/Subsurface/Source/Map/SubmarineBody.cs b/Subsurface/Source/Map/SubmarineBody.cs index b882e5865..f540eadec 100644 --- a/Subsurface/Source/Map/SubmarineBody.cs +++ b/Subsurface/Source/Map/SubmarineBody.cs @@ -207,7 +207,7 @@ namespace Barotrauma Submarine closestSub = null; if (Character.Controlled == null) { - closestSub = Submarine.GetClosest(GameMain.GameScreen.Cam.WorldViewCenter); + closestSub = Submarine.FindClosest(GameMain.GameScreen.Cam.WorldViewCenter); } else { diff --git a/Subsurface/Source/Physics/PhysicsBody.cs b/Subsurface/Source/Physics/PhysicsBody.cs index d3a27c786..fc8b7f981 100644 --- a/Subsurface/Source/Physics/PhysicsBody.cs +++ b/Subsurface/Source/Physics/PhysicsBody.cs @@ -50,25 +50,11 @@ namespace Barotrauma public static PosInfo TransformInToOutside(PosInfo posInfo) { - Submarine closestSub = null; - foreach (Submarine sub in Submarine.Loaded) - { - Rectangle subBorders = sub.Borders; - subBorders.Location += sub.HiddenSubPosition.ToPoint() - new Point(0, sub.Borders.Height); - - subBorders.Inflate(500.0f, 500.0f); - - if (subBorders.Contains(ConvertUnits.ToDisplayUnits(posInfo.Position))) - { - closestSub = sub; - break; - } - } - - if (closestSub == null) return posInfo; + var sub = Submarine.FindContaining(ConvertUnits.ToDisplayUnits(posInfo.Position)); + if (sub == null) return posInfo; return new PosInfo( - posInfo.Position + ConvertUnits.ToSimUnits(closestSub.Position), + posInfo.Position + ConvertUnits.ToSimUnits(sub.Position), posInfo.Direction, posInfo.ID, posInfo.Timestamp); diff --git a/Subsurface/Source/Screens/GameScreen.cs b/Subsurface/Source/Screens/GameScreen.cs index 9a4f81cdb..b4269a619 100644 --- a/Subsurface/Source/Screens/GameScreen.cs +++ b/Subsurface/Source/Screens/GameScreen.cs @@ -118,7 +118,7 @@ namespace Barotrauma if (GameMain.GameSession != null && GameMain.GameSession.Level != null && GameMain.GameSession.Submarine != null && !DebugConsole.IsOpen) { - var closestSub = Submarine.GetClosest(cam.WorldViewCenter); + var closestSub = Submarine.FindClosest(cam.WorldViewCenter); if (closestSub == null) closestSub = GameMain.GameSession.Submarine; Vector2 targetMovement = Vector2.Zero;