1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-12 00:27:25 +08:00
osu-lazer/osu.Game/Overlays/Mods/ModSelectOverlay.cs

405 lines
17 KiB
C#
Raw Normal View History

2018-01-05 19:21:19 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
2017-02-23 10:16:23 +08:00
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-02-17 04:05:03 +08:00
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Allocation;
2017-02-17 04:05:03 +08:00
using osu.Framework.Configuration;
using osu.Framework.Extensions.Color4Extensions;
2017-02-23 10:16:23 +08:00
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
2017-02-17 04:05:03 +08:00
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
2017-04-18 15:05:58 +08:00
using osu.Game.Rulesets.Mods;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Audio;
using osu.Framework.Audio.Sample;
using osu.Framework.Graphics.Shapes;
2017-07-26 12:22:46 +08:00
using osu.Game.Rulesets;
using osu.Game.Graphics.UserInterface;
2017-02-17 04:05:03 +08:00
2017-02-23 10:16:23 +08:00
namespace osu.Game.Overlays.Mods
{
public class ModSelectOverlay : WaveOverlayContainer
{
private const float content_width = 0.8f;
2018-03-25 07:00:18 +08:00
protected Color4 LowMultiplierColour, HighMultiplierColour, RankedColour;
2017-02-23 10:16:23 +08:00
protected readonly TriangleButton DeselectAllButton;
protected readonly OsuSpriteText MultiplierLabel;
2018-03-25 07:00:18 +08:00
protected readonly OsuSpriteText RankedLabel;
private readonly FillFlowContainer footerContainer;
2017-02-23 10:16:23 +08:00
protected override bool BlockPassThroughKeyboard => false;
protected readonly FillFlowContainer<ModSection> ModSectionsContainer;
2017-02-23 10:16:23 +08:00
public readonly Bindable<IEnumerable<Mod>> SelectedMods = new Bindable<IEnumerable<Mod>>();
2017-02-23 10:16:23 +08:00
2017-04-17 16:43:48 +08:00
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
2017-03-02 20:14:06 +08:00
2017-04-17 16:43:48 +08:00
private void rulesetChanged(RulesetInfo newRuleset)
2017-02-23 10:16:23 +08:00
{
2017-04-17 16:43:48 +08:00
var instance = newRuleset.CreateInstance();
foreach (ModSection section in ModSectionsContainer.Children)
section.Mods = instance.GetModsFor(section.ModType);
2017-03-07 00:58:32 +08:00
refreshSelectedMods();
2017-02-23 10:16:23 +08:00
}
2017-03-06 15:31:37 +08:00
[BackgroundDependencyLoader(permitNulls: true)]
private void load(OsuColour colours, OsuGame osu, RulesetStore rulesets, AudioManager audio)
2017-02-23 10:16:23 +08:00
{
SelectedMods.ValueChanged += selectedModsChanged;
2018-03-25 07:00:18 +08:00
LowMultiplierColour = colours.Yellow;
HighMultiplierColour = colours.Green;
2018-03-25 07:00:18 +08:00
RankedColour = colours.Red;
2017-03-02 20:14:06 +08:00
if (osu != null)
2017-04-15 04:22:41 +08:00
Ruleset.BindTo(osu.Ruleset);
2017-04-17 18:44:03 +08:00
else
2017-10-16 16:02:31 +08:00
Ruleset.Value = rulesets.AvailableRulesets.First();
2017-04-17 18:44:03 +08:00
2017-04-15 04:22:41 +08:00
Ruleset.ValueChanged += rulesetChanged;
Ruleset.TriggerChange();
sampleOn = audio.Sample.Get(@"UI/check-on");
sampleOff = audio.Sample.Get(@"UI/check-off");
2017-02-23 10:16:23 +08:00
}
protected override void Dispose(bool isDisposing)
{
base.Dispose(isDisposing);
Ruleset.UnbindAll();
SelectedMods.UnbindAll();
}
private void selectedModsChanged(IEnumerable<Mod> obj)
{
foreach (ModSection section in ModSectionsContainer.Children)
section.SelectTypes(obj.Select(m => m.GetType()).ToList());
updateMods();
}
private void updateMods()
{
double multiplier = 1.0;
bool ranked = true;
foreach (Mod mod in SelectedMods.Value)
{
multiplier *= mod.ScoreMultiplier;
ranked &= mod.Ranked;
}
MultiplierLabel.Text = $"{multiplier:N2}x";
if (multiplier > 1.0)
MultiplierLabel.FadeColour(HighMultiplierColour, 200);
else if (multiplier < 1.0)
MultiplierLabel.FadeColour(LowMultiplierColour, 200);
else
MultiplierLabel.FadeColour(Color4.White, 200);
2018-03-25 07:00:18 +08:00
RankedLabel.Text = null;
if (!ranked)
{
RankedLabel.Text += " (Unranked)";
RankedLabel.FadeColour(RankedColour, 200);
}
else
{
RankedLabel.Text = null;
RankedLabel.FadeColour(Color4.White, 200);
}
}
protected override void PopOut()
{
2017-02-23 10:16:23 +08:00
base.PopOut();
2017-02-23 11:42:31 +08:00
footerContainer.MoveToX(footerContainer.DrawSize.X, DISAPPEAR_DURATION, Easing.InSine);
footerContainer.FadeOut(DISAPPEAR_DURATION, Easing.InSine);
2017-02-23 11:42:31 +08:00
foreach (ModSection section in ModSectionsContainer.Children)
2017-02-23 11:42:31 +08:00
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.MoveToX(100f, DISAPPEAR_DURATION, Easing.InSine);
section.ButtonsContainer.FadeOut(DISAPPEAR_DURATION, Easing.InSine);
2017-02-23 11:42:31 +08:00
}
2017-02-23 10:16:23 +08:00
}
2017-02-23 11:42:31 +08:00
protected override void PopIn()
2017-02-23 10:16:23 +08:00
{
2017-02-23 11:42:31 +08:00
base.PopIn();
2017-02-23 19:36:31 +08:00
footerContainer.MoveToX(0, APPEAR_DURATION, Easing.OutQuint);
footerContainer.FadeIn(APPEAR_DURATION, Easing.OutQuint);
2017-02-23 10:16:23 +08:00
foreach (ModSection section in ModSectionsContainer.Children)
2017-02-23 10:16:23 +08:00
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.MoveToX(0, APPEAR_DURATION, Easing.OutQuint);
section.ButtonsContainer.FadeIn(APPEAR_DURATION, Easing.OutQuint);
2017-02-23 10:16:23 +08:00
}
}
public void DeselectAll()
{
foreach (ModSection section in ModSectionsContainer.Children)
section.DeselectAll();
refreshSelectedMods();
2017-02-23 10:16:23 +08:00
}
/// <summary>
/// Deselect one or more mods.
/// </summary>
/// <param name="modTypes">The types of <see cref="Mod"/>s which should be deselected.</param>
/// <param name="immediate">Set to true to bypass animations and update selections immediately.</param>
public void DeselectTypes(Type[] modTypes, bool immediate = false)
{
if (modTypes.Length == 0) return;
foreach (ModSection section in ModSectionsContainer.Children)
section.DeselectTypes(modTypes, immediate);
}
private SampleChannel sampleOn, sampleOff;
2017-02-23 10:16:23 +08:00
private void modButtonPressed(Mod selectedMod)
{
if (selectedMod != null)
{
if (State == Visibility.Visible) sampleOn?.Play();
DeselectTypes(selectedMod.IncompatibleMods, true);
}
else
{
if (State == Visibility.Visible) sampleOff?.Play();
}
refreshSelectedMods();
2017-03-07 00:58:32 +08:00
}
private void refreshSelectedMods() => SelectedMods.Value = ModSectionsContainer.Children.SelectMany(s => s.SelectedMods).ToArray();
2017-02-23 10:16:23 +08:00
public ModSelectOverlay()
{
FirstWaveColour = OsuColour.FromHex(@"19b0e2");
SecondWaveColour = OsuColour.FromHex(@"2280a2");
ThirdWaveColour = OsuColour.FromHex(@"005774");
FourthWaveColour = OsuColour.FromHex(@"003a4e");
Height = 510;
Content.RelativeSizeAxes = Axes.X;
Content.AutoSizeAxes = Axes.Y;
Children = new Drawable[]
{
new Container
{
RelativeSizeAxes = Axes.Both,
Masking = true,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = new Color4(36, 50, 68, 255)
},
new Triangles
{
TriangleScale = 5,
RelativeSizeAxes = Axes.X,
Height = Height, //set the height from the start to ensure correct triangle density.
2017-02-23 10:16:23 +08:00
ColourLight = new Color4(53, 66, 82, 255),
ColourDark = new Color4(41, 54, 70, 255),
},
},
},
new FillFlowContainer
2017-02-23 10:16:23 +08:00
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Anchor = Anchor.BottomCentre,
Origin = Anchor.BottomCentre,
2017-03-04 18:00:17 +08:00
Direction = FillDirection.Vertical,
2017-02-23 10:16:23 +08:00
Spacing = new Vector2(0f, 10f),
Children = new Drawable[]
{
// Header
new Container
{
RelativeSizeAxes = Axes.X,
Height = 82,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = OsuColour.Gray(10).Opacity(100),
},
new FillFlowContainer
2017-02-23 10:16:23 +08:00
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
2017-03-04 18:00:17 +08:00
Direction = FillDirection.Vertical,
2017-02-23 10:16:23 +08:00
Width = content_width,
Padding = new MarginPadding
{
Top = 10,
Bottom = 10,
},
Children = new Drawable[]
{
new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = @"Gameplay Mods",
TextSize = 22,
Shadow = true,
Margin = new MarginPadding
{
Bottom = 4,
},
},
new OsuSpriteText
{
Text = @"Mods provide different ways to enjoy gameplay. Some have an effect on the score you can achieve during ranked play.",
TextSize = 18,
Shadow = true,
},
new OsuSpriteText
{
Text = @"Others are just for fun.",
2017-02-23 10:16:23 +08:00
TextSize = 18,
Shadow = true,
},
},
},
},
},
// Body
ModSectionsContainer = new FillFlowContainer<ModSection>
2017-02-23 10:16:23 +08:00
{
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(0f, 10f),
Width = content_width,
2017-03-07 00:19:38 +08:00
Children = new ModSection[]
{
new DifficultyReductionSection
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
},
new DifficultyIncreaseSection
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
},
new SpecialSection
2017-03-07 00:19:38 +08:00
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
},
}
2017-02-23 10:16:23 +08:00
},
// Footer
new Container
{
RelativeSizeAxes = Axes.X,
Height = 70,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Children = new Drawable[]
{
new Box
{
RelativeSizeAxes = Axes.Both,
Colour = new Color4(172, 20, 116, 255),
Alpha = 0.5f,
},
footerContainer = new FillFlowContainer
2017-02-23 10:16:23 +08:00
{
Origin = Anchor.BottomCentre,
Anchor = Anchor.BottomCentre,
AutoSizeAxes = Axes.Y,
RelativeSizeAxes = Axes.X,
Width = content_width,
2017-03-04 18:00:17 +08:00
Direction = FillDirection.Horizontal,
2017-02-23 10:16:23 +08:00
Padding = new MarginPadding
{
Vertical = 15
2017-02-23 10:16:23 +08:00
},
Children = new Drawable[]
{
DeselectAllButton = new TriangleButton
{
Width = 180,
Text = "Deselect All",
Action = DeselectAll,
Margin = new MarginPadding
{
Right = 20
}
},
new OsuSpriteText
2017-02-23 10:16:23 +08:00
{
Text = @"Score Multiplier: ",
2017-02-23 10:16:23 +08:00
TextSize = 30,
Shadow = true,
Margin = new MarginPadding
{
Top = 5
}
2017-02-23 10:16:23 +08:00
},
MultiplierLabel = new OsuSpriteText
2018-03-25 07:00:18 +08:00
{
Font = @"Exo2.0-Bold",
TextSize = 30,
Shadow = true,
Margin = new MarginPadding
{
Top = 5
}
},
RankedLabel = new OsuSpriteText
2017-02-23 10:16:23 +08:00
{
Font = @"Exo2.0-Bold",
TextSize = 30,
Shadow = true,
Margin = new MarginPadding
{
Top = 5
}
}
}
}
2017-02-23 10:16:23 +08:00
},
},
},
},
};
}
}
}