diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs index 23bb70eb46..6586935c02 100644 --- a/osu.Game.Rulesets.Mania/ManiaInputManager.cs +++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs @@ -17,8 +17,10 @@ public ManiaInputManager(RulesetInfo ruleset, int variant) public enum ManiaAction { - [Description("Special")] + [Description("Special 1")] Special = 1, + [Description("Special 2")] + Special2 = 2, [Description("Key 1")] Key1 = 1000, @@ -37,6 +39,24 @@ public enum ManiaAction [Description("Key 8")] Key8, [Description("Key 9")] - Key9 + Key9, + [Description("Key 10")] + Key10, + [Description("Key 11")] + Key11, + [Description("Key 12")] + Key12, + [Description("Key 13")] + Key13, + [Description("Key 14")] + Key14, + [Description("Key 15")] + Key15, + [Description("Key 16")] + Key16, + [Description("Key 17")] + Key17, + [Description("Key 18")] + Key18, } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index e05b320b95..14251359d6 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -1,12 +1,14 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; using System.Collections.Generic; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Graphics; @@ -117,42 +119,220 @@ public ManiaRuleset(RulesetInfo rulesetInfo = null) { } - public override IEnumerable AvailableVariants => new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; + public override IEnumerable AvailableVariants + { + get + { + for (int i = 1; i <= 9; i++) + yield return (int)ManiaVariantType.Solo + i; + for (int i = 2; i <= 18; i++) + yield return (int)ManiaVariantType.Coop + i; + // Todo: Versus mode + } + } public override IEnumerable GetDefaultKeyBindings(int variant = 0) { - var leftKeys = new[] + switch (getVariantType(variant)) { - InputKey.A, - InputKey.S, - InputKey.D, - InputKey.F - }; + case ManiaVariantType.Solo: + return new VariantMappingGenerator + { + LeftKeys = new[] + { + InputKey.A, + InputKey.S, + InputKey.D, + InputKey.F + }, + RightKeys = new[] + { + InputKey.J, + InputKey.K, + InputKey.L, + InputKey.Semicolon + }, + SpecialKey = InputKey.Space, + SpecialAction = ManiaAction.Special, + NormalActionStart = ManiaAction.Key1, + }.GenerateKeyBindingsFor(variant); + case ManiaVariantType.Coop: + case ManiaVariantType.Versus: + getMultiVariantKeyCounts(variant, out int p1K, out int p2K); - var rightKeys = new[] + var player1Bindings = new VariantMappingGenerator + { + LeftKeys = new[] + { + InputKey.Number1, + InputKey.Number2, + InputKey.Number3, + InputKey.Number4, + }, + RightKeys = new[] + { + InputKey.Z, + InputKey.X, + InputKey.C, + InputKey.V + }, + SpecialKey = InputKey.Tilde, + SpecialAction = ManiaAction.Special, + NormalActionStart = ManiaAction.Key1 + }.GenerateKeyBindingsFor(p1K); + + var player2Bindings = new VariantMappingGenerator + { + LeftKeys = new[] + { + InputKey.Number7, + InputKey.Number8, + InputKey.Number9, + InputKey.Number0 + }, + RightKeys = new[] + { + InputKey.O, + InputKey.P, + InputKey.BracketLeft, + InputKey.BracketRight + }, + SpecialKey = InputKey.BackSlash, + SpecialAction = ManiaAction.Special2, + NormalActionStart = ManiaAction.Key10 + }.GenerateKeyBindingsFor(p2K); + + return player1Bindings.Concat(player2Bindings); + } + + return new KeyBinding[0]; + } + + public override string GetVariantName(int variant) + { + switch (getVariantType(variant)) { - InputKey.J, - InputKey.K, - InputKey.L, - InputKey.Semicolon - }; + default: + case ManiaVariantType.Solo: + return $"{variant}K"; + case ManiaVariantType.Coop: + { + getMultiVariantKeyCounts(variant, out int p1K, out int p2K); + return $"{p1K}K + {p2K}K"; + } + case ManiaVariantType.Versus: + { + getMultiVariantKeyCounts(variant, out int p1K, out int p2K); + return $"{p1K}K Vs. {p2K}K"; + } + } + } - ManiaAction currentKey = ManiaAction.Key1; + /// + /// Finds the number of keys for each player in or . + /// + /// The variant. + /// The number of keys for player 1. + /// The number of keys for player 2. + private void getMultiVariantKeyCounts(int variant, out int player1Keys, out int player2Keys) + { + player1Keys = 0; + player2Keys = 0; + + switch (getVariantType(variant)) + { + case ManiaVariantType.Coop: + { + int totalKeys = variant - (int)ManiaVariantType.Coop; + player1Keys = (int)Math.Ceiling(totalKeys / 2f); + player2Keys = (int)Math.Floor(totalKeys / 2f); + break; + } + case ManiaVariantType.Versus: + { + int totalKeys = variant - (int)ManiaVariantType.Versus; + player1Keys = totalKeys; + player2Keys = totalKeys; + break; + } + } + } + + /// + /// Finds the that corresponds to a variant value. + /// + /// The variant value. + /// The that corresponds to . + private ManiaVariantType getVariantType(int variant) + { + return (ManiaVariantType)Enum.GetValues(typeof(ManiaVariantType)).Cast().OrderByDescending(i => i).First(v => variant > v); + } + } + + public class VariantMappingGenerator + { + /// + /// All the s available to the left hand. + /// + public InputKey[] LeftKeys; + + /// + /// All the s available to the right hand. + /// + public InputKey[] RightKeys; + + /// + /// The for the special key. + /// + public InputKey SpecialKey; + + /// + /// The at which the normal columns should begin. + /// + public ManiaAction NormalActionStart; + + /// + /// The for the special column. + /// + public ManiaAction SpecialAction; + + /// + /// Generates a list of s for a specific number of columns. + /// + /// The number of columns that need to be bound. + /// The keybindings. + public IEnumerable GenerateKeyBindingsFor(int columns) + { + ManiaAction currentNormalAction = NormalActionStart; var bindings = new List(); - for (int i = leftKeys.Length - variant / 2; i < leftKeys.Length; i++) - bindings.Add(new KeyBinding(leftKeys[i], currentKey++)); + for (int i = LeftKeys.Length - columns / 2; i < LeftKeys.Length; i++) + bindings.Add(new KeyBinding(LeftKeys[i], currentNormalAction++)); - for (int i = 0; i < variant / 2; i++) - bindings.Add(new KeyBinding(rightKeys[i], currentKey++)); + for (int i = 0; i < columns / 2; i++) + bindings.Add(new KeyBinding(RightKeys[i], currentNormalAction++)); - if (variant % 2 == 1) - bindings.Insert(variant / 2, new KeyBinding(InputKey.Space, ManiaAction.Special)); + if (columns % 2 == 1) + bindings.Add(new KeyBinding(SpecialKey, SpecialAction)); return bindings; } + } - public override string GetVariantName(int variant) => $"{variant}K"; + public enum ManiaVariantType + { + /// + /// Solo play keybinding variant (single stage). + /// + Solo = 0, + /// + /// Co-op play keybinding variant (multiple stages). + /// + Coop = 1000, + /// + /// Versus play keybinding variant (multiple stages). + /// + Versus = 10000 } }