From 3a30e2049df587b77c84201a2c4f44762c9897e8 Mon Sep 17 00:00:00 2001 From: Regalis11 Date: Sun, 23 Aug 2015 18:48:03 +0300 Subject: [PATCH] Sending keypresses instead of targetmovement --- Subsurface/Source/Characters/Character.cs | 68 ++++++++++++++++------ Subsurface/Source/GameSettings.cs | 3 +- Subsurface/Source/PlayerInput.cs | 9 ++- Subsurface_Solution.v12.suo | Bin 598016 -> 598016 bytes 4 files changed, 59 insertions(+), 21 deletions(-) diff --git a/Subsurface/Source/Characters/Character.cs b/Subsurface/Source/Characters/Character.cs index f4de16796..08a9028a5 100644 --- a/Subsurface/Source/Characters/Character.cs +++ b/Subsurface/Source/Characters/Character.cs @@ -460,6 +460,23 @@ namespace Subsurface { if (isDead) return; + Vector2 targetMovement = Vector2.Zero; + if (GetInputState(InputType.Left)) targetMovement.X -= 1.0f; + if (GetInputState(InputType.Right)) targetMovement.X += 1.0f; + if (GetInputState(InputType.Up)) targetMovement.Y += 1.0f; + if (GetInputState(InputType.Down)) targetMovement.Y -= 1.0f; + + //the vertical component is only used for falling through platforms and climbing ladders when not in water, + //so the movement can't be normalized or the character would walk slower when pressing down/up + if (AnimController.InWater) + { + float length = targetMovement.Length(); + if (length > 0.0f) targetMovement = targetMovement / length; + } + + if (Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir) && GetInputState(InputType.Run)) + targetMovement *= 3.0f; + //find the closest item if selectkey has been hit, or if the character is being //controlled by the player (in order to highlight it) if (controlled == this) @@ -560,22 +577,15 @@ namespace Subsurface if (!DisableControls) { - if (PlayerInput.KeyDown(Keys.W)) targetMovement.Y += 1.0f; - if (PlayerInput.KeyDown(Keys.S)) targetMovement.Y -= 1.0f; - if (PlayerInput.KeyDown(Keys.A)) targetMovement.X -= 1.0f; - if (PlayerInput.KeyDown(Keys.D)) targetMovement.X += 1.0f; - - //the vertical component is only used for falling through platforms and climbing ladders when not in water, - //so the movement can't be normalized or the character would walk slower when pressing down/up - if (AnimController.InWater) - { - float length = targetMovement.Length(); - if (length > 0.0f) targetMovement = targetMovement / length; - } - - if (Keyboard.GetState().IsKeyDown(Keys.LeftShift) && Math.Sign(targetMovement.X) == Math.Sign(AnimController.Dir)) - targetMovement *= 3.0f; + keys[(int)InputType.Left].SetState(PlayerInput.KeyDown(Keys.A)); + keys[(int)InputType.Right].SetState(PlayerInput.KeyDown(Keys.D)); + keys[(int)InputType.Up].SetState(PlayerInput.KeyDown(Keys.W)); + keys[(int)InputType.Down].SetState(PlayerInput.KeyDown(Keys.S)); + //if (PlayerInput.KeyDown(Keys.W)) targetMovement.Y += 1.0f; + //if (PlayerInput.KeyDown(Keys.S)) targetMovement.Y -= 1.0f; + //if () targetMovement.X -= 1.0f; + //if (PlayerInput.KeyDown(Keys.D)) targetMovement.X += 1.0f; keys[(int)InputType.Select].SetState(PlayerInput.KeyHit(Keys.E)); keys[(int)InputType.ActionHit].SetState(PlayerInput.LeftButtonClicked()); @@ -1013,9 +1023,15 @@ namespace Subsurface message.Write(keys[(int)InputType.ActionHeld].Dequeue); message.Write(keys[(int)InputType.SecondaryHeld].Dequeue); - + message.Write((float)NetTime.Now); + message.Write(keys[(int)InputType.Left].Dequeue); + message.Write(keys[(int)InputType.Right].Dequeue); + + message.Write(keys[(int)InputType.Up].Dequeue); + message.Write(keys[(int)InputType.Down].Dequeue); + // Write byte = move direction message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.X, -10.0f, 10.0f), -10.0f, 10.0f, 8); message.WriteRangedSingle(MathHelper.Clamp(AnimController.TargetMovement.Y, -10.0f, 10.0f), -10.0f, 10.0f, 8); @@ -1114,6 +1130,9 @@ namespace Subsurface bool targetDir = false; Vector2 cursorPos = Vector2.Zero; + bool leftKeyState = false, rightKeyState = false; + bool upKeyState = false, downKeyState = false; + try { actionKeyState = message.ReadBoolean(); @@ -1121,9 +1140,14 @@ namespace Subsurface sendingTime = message.ReadFloat(); - targetMovement = new Vector2(message.ReadRangedSingle(-10.0f, 10.0f, 8), message.ReadRangedSingle(-10.0f, 10.0f, 8)); - targetMovement.X = MathUtils.Round(targetMovement.X, 0.1f); - targetMovement.Y = MathUtils.Round(targetMovement.Y, 0.1f); + leftKeyState = message.ReadBoolean(); + rightKeyState = message.ReadBoolean(); + upKeyState = message.ReadBoolean(); + downKeyState = message.ReadBoolean(); + + //targetMovement = new Vector2(message.ReadRangedSingle(-10.0f, 10.0f, 8), message.ReadRangedSingle(-10.0f, 10.0f, 8)); + //targetMovement.X = MathUtils.Round(targetMovement.X, 0.1f); + //targetMovement.Y = MathUtils.Round(targetMovement.Y, 0.1f); targetDir = message.ReadBoolean(); @@ -1145,6 +1169,12 @@ namespace Subsurface keys[(int)InputType.ActionHeld].State = actionKeyState; keys[(int)InputType.SecondaryHeld].State = secondaryKeyState; + keys[(int)InputType.Left].State = leftKeyState; + keys[(int)InputType.Right].State = rightKeyState; + + keys[(int)InputType.Up].State = upKeyState; + keys[(int)InputType.Down].State = downKeyState; + if (sendingTime <= LastNetworkUpdate) return; cursorPosition = cursorPos; diff --git a/Subsurface/Source/GameSettings.cs b/Subsurface/Source/GameSettings.cs index c9d28a2b6..bfe7f1ee4 100644 --- a/Subsurface/Source/GameSettings.cs +++ b/Subsurface/Source/GameSettings.cs @@ -68,7 +68,6 @@ namespace Subsurface MasterServerUrl = ToolBox.GetAttributeString(doc.Root, "masterserverurl", ""); - foreach (XElement subElement in doc.Root.Elements()) { switch (subElement.Name.ToString().ToLower()) @@ -92,6 +91,8 @@ namespace Subsurface doc.Add(new XElement("config")); } + doc.Root.Add(new XAttribute("masterserverurl", MasterServerUrl)); + XElement gMode = doc.Root.Element("graphicsmode"); if (gMode == null) { diff --git a/Subsurface/Source/PlayerInput.cs b/Subsurface/Source/PlayerInput.cs index bb7a3e10a..a6427ac94 100644 --- a/Subsurface/Source/PlayerInput.cs +++ b/Subsurface/Source/PlayerInput.cs @@ -4,7 +4,14 @@ using Microsoft.Xna.Framework.Input; namespace Subsurface { - public enum InputType { Select, ActionHit, ActionHeld, SecondaryHit, SecondaryHeld } + public enum InputType + { + Select, + ActionHit, ActionHeld, + SecondaryHit, SecondaryHeld, + Left, Right, Up, Down, + Run + } class Key { diff --git a/Subsurface_Solution.v12.suo b/Subsurface_Solution.v12.suo index f9c6f6d568727781c9a1250e6db3e79fd2aa5394..06ba39842def984d78cccdc6d1fa425687b8edb4 100644 GIT binary patch delta 9909 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 E7e-BQK>z>%