Skip to content

Commit

Permalink
Merge pull request #47 from Talberon/SOL-47_netplay_updates_quality_o…
Browse files Browse the repository at this point in the history
…f_life

Sol 47 netplay updates quality of life
  • Loading branch information
Talberon committed Nov 3, 2019
2 parents e5645b9 + 7295227 commit fb7824f
Show file tree
Hide file tree
Showing 119 changed files with 2,674 additions and 1,560 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ packages/
.idea/
TestResults/
sol-standard-web/
RELEASE/
RELEASE/
.DS_Store
8 changes: 1 addition & 7 deletions SolStandard.sln
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,6 @@ Global
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Debug|Any CPU.ActiveCfg = Debug|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Debug|x86.ActiveCfg = Debug|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Debug|x86.Build.0 = Debug|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Release|Any CPU.ActiveCfg = Release|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Release|x86.ActiveCfg = Release|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Release|x86.Build.0 = Release|x86
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Debug|Any CPU.Build.0 = Debug|x86
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Debug|Any CPU.Build.0 = Debug|Any CPU
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Debug|x86.ActiveCfg = Debug|Any CPU
Expand All @@ -30,6 +23,7 @@ Global
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Release|Any CPU.Build.0 = Release|Any CPU
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Release|x86.ActiveCfg = Release|Any CPU
{12F9D5D4-AF29-4720-AB1A-064A5106C732}.Release|x86.Build.0 = Release|Any CPU
{5401DE7F-824B-45F5-9EEF-2CAAA608908D}.Release|Any CPU.ActiveCfg = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
3 changes: 2 additions & 1 deletion SolStandard.sln.DotSettings
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:String x:Key="/Default/Environment/Hierarchy/RiderUnitTestMsTestOptions/VisualStudioRootFolder/@EntryValue">C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE</s:String></wpf:ResourceDictionary>
<s:String x:Key="/Default/Environment/Hierarchy/RiderUnitTestMsTestOptions/VisualStudioRootFolder/@EntryValue">C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE</s:String>
<s:Boolean x:Key="/Default/UserDictionary/Words/=Borderless/@EntryIndexedValue">True</s:Boolean></wpf:ResourceDictionary>
4 changes: 2 additions & 2 deletions SolStandard/Containers/Contexts/BattleContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,9 @@
using SolStandard.Map.Elements.Cursor;
using SolStandard.Utility;
using SolStandard.Utility.Assets;
using SolStandard.Utility.Buttons;
using SolStandard.Utility.Events;
using SolStandard.Utility.Events.Network;
using SolStandard.Utility.Inputs;

namespace SolStandard.Containers.Contexts
{
Expand Down Expand Up @@ -269,7 +269,7 @@ private void SetPromptWindowText(string promptText)
new RenderText(AssetManager.PromptFont, "["),
new RenderText(AssetManager.PromptFont, "Press "),
InputIconProvider.GetInputIcon(Input.Confirm,
new Vector2(AssetManager.PromptFont.MeasureString("A").Y)),
Convert.ToInt32(AssetManager.PromptFont.MeasureString("A").Y)),
new RenderText(AssetManager.PromptFont, "]")
}
};
Expand Down
288 changes: 288 additions & 0 deletions SolStandard/Containers/Contexts/ControlConfigContext.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,288 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using SolStandard.Containers.View;
using SolStandard.HUD.Menu;
using SolStandard.Utility.Assets;
using SolStandard.Utility.Inputs;
using SolStandard.Utility.Inputs.Gamepad;
using SolStandard.Utility.Inputs.KeyboardInput;

namespace SolStandard.Containers.Contexts
{
public class ControlConfigContext
{
public enum ControlMenuState
{
DeviceSelect,
InputRemapSelect,
ListeningForInput
}

public enum Device
{
Keyboard,
P1Gamepad,
P2Gamepad
}

public const string KeyboardConfigFileName = "KeyboardConfig";
public const string P1GamepadConfigFileName = "P1GamepadConfig";
public const string P2GamepadConfigFileName = "P2GamepadConfig";

private readonly ControlConfigView view;
private IController metakeyboard;
private IController metaP1Gamepad;
private IController metaP2Gamepad;
private GameContext.GameState previousGameState;

private Device currentListeningDevice;
private Input currentListeningInput;

public IUserInterface View => view;
public ControlMenuState CurrentState => view.CurrentState;

private const int CooldownInterval = 15;
private int frameCooldown;

public ControlConfigContext(ControlConfigView configView)
{
view = configView;
InitializeMetaControls();
view.CurrentState = ControlMenuState.DeviceSelect;
currentListeningDevice = Device.Keyboard;
currentListeningInput = Input.None;
frameCooldown = 0;
}

#region MenuControls

public void OpenRemapMenu(Device device)
{
IController controller;

switch (device)
{
case Device.Keyboard:
controller = metakeyboard;
break;
case Device.P1Gamepad:
controller = metaP1Gamepad;
break;
case Device.P2Gamepad:
controller = metaP2Gamepad;
break;
default:
throw new ArgumentOutOfRangeException(nameof(device), device, null);
}

currentListeningDevice = device;
view.OpenInputRemapMenu(device, controller);
}

public void SelectCurrentOption()
{
view.SelectCurrentOption();
}

public void Cancel()
{
if (frameCooldown > 0) return;

AssetManager.MapUnitCancelSFX.Play();

if (view.CurrentState == ControlMenuState.DeviceSelect)
{
CloseMenu();
}
else
{
view.GoToPreviousMenu();
}
}

public void OpenMenu()
{
if (GameContext.CurrentGameState == GameContext.GameState.ControlConfig) return;

previousGameState = GameContext.CurrentGameState;
GameContext.CurrentGameState = GameContext.GameState.ControlConfig;
view.CurrentState = ControlMenuState.DeviceSelect;
}

private void CloseMenu()
{
AssetManager.MapUnitCancelSFX.Play();
GameContext.CurrentGameState = previousGameState;
}

public void MoveMenuCursor(MenuCursorDirection direction)
{
view.CurrentMenu.MoveMenuCursor(direction);
}

#endregion

public void ResetMetaController(Device deviceType)
{
switch (deviceType)
{
case Device.Keyboard:
metakeyboard = new KeyboardController();
break;
case Device.P1Gamepad:
metaP1Gamepad = new GamepadController(PlayerIndex.One);
break;
case Device.P2Gamepad:
metaP2Gamepad = new GamepadController(PlayerIndex.Two);
break;
default:
throw new ArgumentOutOfRangeException();
}

OpenRemapMenu(currentListeningDevice);
}

public void StartListeningForInput(Device device, Input input)
{
currentListeningDevice = device;
currentListeningInput = input;
view.CurrentState = ControlMenuState.ListeningForInput;
frameCooldown = CooldownInterval;
}

public void Update()
{
frameCooldown--;

if (view.CurrentState != ControlMenuState.ListeningForInput || currentListeningInput == Input.None ||
frameCooldown > 0) return;

if (frameCooldown == -CooldownInterval * 10)
{
Cancel();
return;
}

switch (currentListeningDevice)
{
case Device.Keyboard:
ListenForKeyboardInput(currentListeningInput);
break;
case Device.P1Gamepad:
ListenForGamepadInputFromPlayer(PlayerIndex.One, currentListeningInput);
break;
case Device.P2Gamepad:
ListenForGamepadInputFromPlayer(PlayerIndex.Two, currentListeningInput);
break;
default:
throw new ArgumentOutOfRangeException();
}
}


private void ListenForKeyboardInput(Input inputToMap)
{
foreach (Keys key in Keyboard.GetState().GetPressedKeys())
{
if (!InputKey.KeyIcons.ContainsKey(key)) continue;

UpdateKeyboardControls(inputToMap, key);
OpenRemapMenu(currentListeningDevice);
AssetManager.CoinSFX.Play();
frameCooldown = CooldownInterval;
break;
}
}

private void ListenForGamepadInputFromPlayer(PlayerIndex playerIndex, Input inputToMap)
{
foreach (Buttons pressedButton in GetPressedButtons(GamePad.GetState(playerIndex)))
{
if (!InputButton.ButtonIcons.ContainsKey(pressedButton)) continue;

UpdateGamepadControls(playerIndex, inputToMap, pressedButton);
OpenRemapMenu(currentListeningDevice);
AssetManager.CoinSFX.Play();
frameCooldown = CooldownInterval;
break;
}
}

private static IEnumerable<Buttons> GetPressedButtons(GamePadState gamePadState)
{
return Enum.GetValues(typeof(Buttons))
.Cast<Buttons>()
.Where(gamePadState.IsButtonDown)
.ToList();
}

public void SaveControlMappings()
{
if (InputsAreValid())
{
GameDriver.KeyboardParser = new GameControlParser(metakeyboard);
GameDriver.P1GamepadParser = new GameControlParser(metaP1Gamepad);
GameDriver.P2GamepadParser = new GameControlParser(metaP2Gamepad);
GameDriver.InitializeControlMappers(GameContext.P1Team);
InitializeMetaControls();
GlobalHudView.AddNotification("Saved control inputs.");
frameCooldown = CooldownInterval;
view.CurrentState = ControlMenuState.DeviceSelect;

GameDriver.SystemFileIO.Save(KeyboardConfigFileName, GameDriver.KeyboardParser.Controller);
GameDriver.SystemFileIO.Save(P1GamepadConfigFileName, GameDriver.P1GamepadParser.Controller);
GameDriver.SystemFileIO.Save(P2GamepadConfigFileName, GameDriver.P2GamepadParser.Controller);
}
else
{
AssetManager.WarningSFX.Play();
GlobalHudView.AddNotification("All controls must be unique!");
}
}

private bool InputsAreValid()
{
return AllInputsAreUnique(metakeyboard.Inputs.Values) &&
AllInputsAreUnique(metaP1Gamepad.Inputs.Values) &&
AllInputsAreUnique(metaP2Gamepad.Inputs.Values);
}

private static bool AllInputsAreUnique(IReadOnlyCollection<GameControl> enumerable)
{
return enumerable.Distinct().Count() == enumerable.Count;
}

private void UpdateKeyboardControls(Input controlType, Keys keyToMap)
{
GameControl keyControl = new InputKey(keyToMap);
metakeyboard.RemapControl(controlType, keyControl);
}

private void UpdateGamepadControls(PlayerIndex playerIndex, Input controlType, Buttons buttonToMap)
{
GameControl gamepadControl = new InputButton(playerIndex, buttonToMap);

switch (playerIndex)
{
case PlayerIndex.One:
metaP1Gamepad.RemapControl(controlType, gamepadControl);
break;
case PlayerIndex.Two:
metaP2Gamepad.RemapControl(controlType, gamepadControl);
break;
default:
throw new ArgumentOutOfRangeException(nameof(playerIndex), playerIndex, null);
}
}

private void InitializeMetaControls()
{
metakeyboard = KeyboardController.From((KeyboardController) GameDriver.KeyboardParser.Controller);
metaP1Gamepad = GamepadController.From((GamepadController) GameDriver.P1GamepadParser.Controller);
metaP2Gamepad = GamepadController.From((GamepadController) GameDriver.P2GamepadParser.Controller);
}
}
}
Loading

0 comments on commit fb7824f

Please sign in to comment.