diff --git a/osu.Game/Modes/Mod.cs b/osu.Game/Modes/Mod.cs index d51de7ece1..66593483fc 100644 --- a/osu.Game/Modes/Mod.cs +++ b/osu.Game/Modes/Mod.cs @@ -14,6 +14,7 @@ namespace osu.Game.Modes public virtual string Description(PlayMode mode) => @""; public abstract double ScoreMultiplier(PlayMode mode); public abstract bool Ranked(PlayMode mode); + public abstract Mods[] DisablesMods(PlayMode mode); } public abstract class KeyMod : Mod @@ -23,6 +24,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @""; public override double ScoreMultiplier(PlayMode mode) => 1; // TODO: Implement the mania key mod score multiplier public override bool Ranked(PlayMode mode) => mode == PlayMode.Mania; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] {}; } public class ModNoFail : Mod @@ -32,6 +34,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"You can't fail, no matter what."; public override double ScoreMultiplier(PlayMode mode) => 0.5; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Relax, Mods.Autopilot, Mods.SuddenDeath, Mods.Perfect }; } public class ModEasy : Mod @@ -41,6 +44,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Reduces overall difficulty - larger circles, more forgiving HP drain, less accuracy required."; public override double ScoreMultiplier(PlayMode mode) => 0.5; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.HardRock }; } public class ModHidden : Mod @@ -65,6 +69,7 @@ namespace osu.Game.Modes } public override double ScoreMultiplier(PlayMode mode) => mode == PlayMode.Mania ? 1.0 : 1.06; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => (mode == PlayMode.Mania) ? new Mods[] { Mods.Flashlight } : new Mods[] { }; } public class ModHardRock : Mod @@ -91,6 +96,7 @@ namespace osu.Game.Modes } } public override bool Ranked(PlayMode mode) => mode != PlayMode.Mania; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Easy }; } public class ModSuddenDeath : Mod @@ -100,6 +106,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Miss a note and fail."; public override double ScoreMultiplier(PlayMode mode) => 1; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.NoFail, Mods.Relax, Mods.Autopilot, Mods.Autoplay, Mods.Cinema }; } public class ModDoubleTime : Mod @@ -126,6 +133,7 @@ namespace osu.Game.Modes } } public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.HalfTime }; } public class ModRelax : Mod @@ -154,6 +162,7 @@ namespace osu.Game.Modes } public override double ScoreMultiplier(PlayMode mode) => 0; public override bool Ranked(PlayMode mode) => false; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Autopilot, Mods.Autoplay, Mods.Cinema, Mods.NoFail, Mods.SuddenDeath, Mods.Perfect }; } public class ModHalfTime : Mod @@ -163,6 +172,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Less zoom"; public override double ScoreMultiplier(PlayMode mode) => mode == PlayMode.Mania ? 0.5 : 0.3; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.DoubleTime, Mods.Nightcore }; } public class ModNightcore : ModDoubleTime @@ -179,6 +189,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Restricted view area."; public override double ScoreMultiplier(PlayMode mode) => mode == PlayMode.Mania ? 1.0 : 1.12; public override bool Ranked(PlayMode mode) => true; + public override Mods[] DisablesMods(PlayMode mode) => (mode == PlayMode.Mania) ? new Mods[] { Mods.Hidden } : new Mods[] {}; } public class ModAutoplay : Mod @@ -188,6 +199,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Watch a perfect automated play through the song"; public override double ScoreMultiplier(PlayMode mode) => 0; public override bool Ranked(PlayMode mode) => false; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Relax, Mods.Autopilot, Mods.SpunOut, Mods.SuddenDeath, Mods.Perfect }; } public class ModSpunOut : Mod @@ -197,6 +209,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Spinners will be automatically completed"; public override double ScoreMultiplier(PlayMode mode) => 0.9; public override bool Ranked(PlayMode mode) => mode == PlayMode.Osu; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Autoplay, Mods.Cinema, Mods.Autopilot }; } public class ModAutopilot : Mod @@ -206,6 +219,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Automatic cursor movement - just follow the rhythm."; public override double ScoreMultiplier(PlayMode mode) => 0; public override bool Ranked(PlayMode mode) => false; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.SpunOut, Mods.Relax, Mods.SuddenDeath, Mods.Perfect, Mods.NoFail, Mods.Autoplay, Mods.Cinema }; } public class ModPerfect : ModSuddenDeath @@ -251,6 +265,7 @@ namespace osu.Game.Modes public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override double ScoreMultiplier(PlayMode mode) => 1; public override bool Ranked(PlayMode mode) => mode == PlayMode.Mania; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] { Mods.Flashlight }; } public class ModRandom : Mod @@ -260,14 +275,13 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Shuffle around the notes!"; public override double ScoreMultiplier(PlayMode mode) => 1; public override bool Ranked(PlayMode mode) => false; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] {}; } - public class ModCinema : Mod + public class ModCinema : ModAutoplay { public override Mods Name => Mods.Cinema; public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema; - public override double ScoreMultiplier(PlayMode mode) => 0; - public override bool Ranked(PlayMode mode) => false; } public class ModTarget : Mod @@ -276,6 +290,7 @@ namespace osu.Game.Modes public override FontAwesome Icon => FontAwesome.fa_osu_mod_target; public override double ScoreMultiplier(PlayMode mode) => 1; public override bool Ranked(PlayMode mode) => mode == PlayMode.Osu; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] {}; // TODO: Find out what mods target practice disables as it's not in the stable client } public class ModKey9 : KeyMod @@ -291,6 +306,7 @@ namespace osu.Game.Modes public override string Description(PlayMode mode) => @"Double the key amount, double the fun!"; public override double ScoreMultiplier(PlayMode mode) => 1; public override bool Ranked(PlayMode mode) => mode == PlayMode.Mania; + public override Mods[] DisablesMods(PlayMode mode) => new Mods[] {}; } public class ModKey1 : KeyMod diff --git a/osu.Game/Overlays/Mods/ModSection.cs b/osu.Game/Overlays/Mods/ModSection.cs index 8f829c998b..747ecaacb7 100644 --- a/osu.Game/Overlays/Mods/ModSection.cs +++ b/osu.Game/Overlays/Mods/ModSection.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Mods } } - public Action Action; + public Action Action; public Mod[] SelectedMods { @@ -131,7 +131,7 @@ namespace osu.Game.Overlays.Mods private void buttonPressed(Mod mod) { - Action?.Invoke(SelectedMods); + Action?.Invoke(mod); } public ModSection() @@ -144,7 +144,7 @@ namespace osu.Game.Overlays.Mods { Origin = Anchor.TopLeft, Anchor = Anchor.TopLeft, - Position = new Vector2(0f, 10f), + Position = new Vector2(0f, 0f), Font = @"Exo2.0-Bold", Text = Header, }, @@ -153,11 +153,10 @@ namespace osu.Game.Overlays.Mods AutoSizeAxes = Axes.Both, Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, - //Direction = FlowDirections.Horizontal, Spacing = new Vector2(50f, 0f), Margin = new MarginPadding { - Top = 16, + Top = 6, }, }, }; diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs index 52d76f0941..5cf054c187 100644 --- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs +++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs @@ -138,7 +138,7 @@ namespace osu.Game.Overlays.Mods { section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), content_exit_duration, EasingTypes.InSine); section.ButtonsContainer.MoveToX(100f, content_exit_duration, EasingTypes.InSine); - section.ButtonsContainer.FadeTo(0.01f, content_exit_duration, EasingTypes.InSine); // TODO: Fix this so 0.01 opacity isn't used + section.ButtonsContainer.FadeTo(0f, content_exit_duration, EasingTypes.InSine); // TODO: Maybe fix this as when items are fully transparent the mod section resizes to 0 height } } @@ -153,53 +153,18 @@ namespace osu.Game.Overlays.Mods } } - private void modButtonPressed(Mod[] sectionSelectedMods) + private void modButtonPressed(Mod selectedMod) { - // - // Inverse mod deselection - // - // Hard Rock is the inverse of Easy - // Sudden Death / Perfect is the inverse of No Fail, Relax, AutoPilot, and Auto - // Double Time is the inverse of Half Time - // - // TODO: Probably make a better way for inverse mod handling - // - - foreach (Mod sectionMod in sectionSelectedMods) - { - if (sectionMod.Name == Modes.Mods.HardRock) + // TODO: Find out why selectedMod is occasionally null when spamming mod buttons + if (selectedMod != null) + { + foreach (Modes.Mods disableMod in selectedMod.DisablesMods(ModMode)) { - difficultyReductionSection.EasyButton?.Deselect(); + DeselectMod(disableMod); } - else if (sectionMod.Name == Modes.Mods.Easy) - { - difficultyIncreaseSection.HardRockButton?.Deselect(); - } - - if (sectionMod.Name == Modes.Mods.SuddenDeath || sectionMod.Name == Modes.Mods.Perfect) - { - difficultyReductionSection.NoFailButton?.Deselect(); - assistedSection.RelaxButton?.Deselect(); - assistedSection.AutopilotButton?.Deselect(); - assistedSection.AutoplayCinemaButton?.Deselect(); - } - else if (sectionMod.Name == Modes.Mods.NoFail || sectionMod.Name == Modes.Mods.Relax || sectionMod.Name == Modes.Mods.Autopilot || sectionMod.Name == Modes.Mods.Autoplay || sectionMod.Name == Modes.Mods.Cinema) - { - difficultyIncreaseSection.SuddenDeathButton?.Deselect(); - } - - if (sectionMod.Name == Modes.Mods.DoubleTime || sectionMod.Name == Modes.Mods.Nightcore) - { - difficultyReductionSection.HalfTimeButton?.Deselect(); - } - else if (sectionMod.Name == Modes.Mods.HalfTime) - { - difficultyIncreaseSection.DoubleTimeNightcoreButton?.Deselect(); - } + refreshSelectedMods(); } - refreshSelectedMods(); - double multiplier = 1; bool ranked = true; @@ -233,6 +198,24 @@ namespace osu.Game.Overlays.Mods } } + public void DeselectMod(Modes.Mods modName) + { + foreach (ModSection section in sections) + { + foreach (ModButton button in section.Buttons) + { + foreach (Mod mod in button.Mods) + { + if (mod.Name == modName) + { + button.Deselect(); + return; + } + } + } + } + } + private void refreshSelectedMods() { List selectedMods = new List(); @@ -262,7 +245,7 @@ namespace osu.Game.Overlays.Mods ThirdWaveColour = OsuColour.FromHex(@"005774"); FourthWaveColour = OsuColour.FromHex(@"003a4e"); - Height = 548; // TODO: Remove when autosize works + Height = 510; // TODO: Remove when autosize works //AutoSizeAxes = Axes.Y; Content.RelativeSizeAxes = Axes.X; Content.AutoSizeAxes = Axes.Y; @@ -302,7 +285,7 @@ namespace osu.Game.Overlays.Mods new Container { RelativeSizeAxes = Axes.X, - Height = 90, + Height = 82, Origin = Anchor.TopCentre, Anchor = Anchor.TopCentre, Children = new Drawable[]