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

370 lines
15 KiB
C#
Raw Normal View History

2017-02-23 10:16:23 +08:00
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
2017-03-02 20:14:06 +08:00
using System;
using System.Linq;
2017-02-23 10:16:23 +08:00
using System.Collections.Generic;
2017-02-17 04:05:03 +08:00
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Configuration;
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.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Sprites;
2017-02-28 14:25:38 +08:00
using osu.Framework.Graphics.Transforms;
using osu.Framework.Allocation;
2017-02-17 04:05:03 +08:00
using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
using osu.Game.Graphics.Sprites;
using osu.Game.Modes;
2017-02-23 10:16:23 +08:00
namespace osu.Game.Overlays.Mods
{
public class ModSelectOverlay : WaveOverlayContainer
{
private const int button_duration = 700;
private const int ranked_multiplier_duration = 700;
private const float content_width = 0.8f;
private Color4 lowMultiplierColour, highMultiplierColour;
private OsuSpriteText rankedLabel, multiplierLabel;
private FillFlowContainer rankedMultiplerContainer;
2017-02-23 10:16:23 +08:00
private FillFlowContainer<ModSection> modSectionsContainer;
2017-02-23 10:16:23 +08:00
public Bindable<Mod[]> SelectedMods = new Bindable<Mod[]>();
2017-03-02 20:14:06 +08:00
public readonly Bindable<PlayMode> PlayMode = new Bindable<PlayMode>();
private void modeChanged(object sender, EventArgs eventArgs)
2017-02-23 10:16:23 +08:00
{
2017-03-02 20:14:06 +08:00
var ruleset = Ruleset.GetRuleset(PlayMode);
2017-02-23 10:16:23 +08:00
2017-03-02 20:14:06 +08:00
modSectionsContainer.Children = new ModSection[]
{
new DifficultyReductionSection
2017-02-23 10:16:23 +08:00
{
2017-03-02 20:14:06 +08:00
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
Buttons = ruleset.GetModsFor(ModType.DifficultyReduction).Select(m => new ModButton(m)).ToArray(),
},
new DifficultyIncreaseSection
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
Buttons = ruleset.GetModsFor(ModType.DifficultyIncrease).Select(m => new ModButton(m)).ToArray(),
},
new AssistedSection
{
RelativeSizeAxes = Axes.X,
Origin = Anchor.TopCentre,
Anchor = Anchor.TopCentre,
Action = modButtonPressed,
Buttons = ruleset.GetModsFor(ModType.Special).Select(m => new ModButton(m)).ToArray(),
},
};
2017-02-23 10:16:23 +08:00
}
2017-03-02 20:14:06 +08:00
[BackgroundDependencyLoader(permitNulls:true)]
private void load(OsuColour colours, OsuGame osu)
2017-02-23 10:16:23 +08:00
{
lowMultiplierColour = colours.Red;
highMultiplierColour = colours.Green;
2017-03-02 20:14:06 +08:00
if (osu != null)
PlayMode.BindTo(osu.PlayMode);
PlayMode.ValueChanged += modeChanged;
PlayMode.TriggerChange();
2017-02-23 10:16:23 +08:00
}
protected override void PopOut()
{
2017-02-23 10:16:23 +08:00
base.PopOut();
2017-02-23 11:42:31 +08:00
rankedMultiplerContainer.MoveToX(rankedMultiplerContainer.DrawSize.X, APPEAR_DURATION, EasingTypes.InSine);
rankedMultiplerContainer.FadeOut(APPEAR_DURATION, EasingTypes.InSine);
2017-02-23 11:42:31 +08:00
2017-02-23 19:36:31 +08:00
foreach (ModSection section in modSectionsContainer.Children)
2017-02-23 11:42:31 +08:00
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(100f, 0f), APPEAR_DURATION, EasingTypes.InSine);
section.ButtonsContainer.MoveToX(100f, APPEAR_DURATION, EasingTypes.InSine);
section.ButtonsContainer.FadeOut(APPEAR_DURATION, EasingTypes.InSine);
2017-02-23 11:42:31 +08:00
}
TriggerFocusLost();
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
2017-02-23 10:16:23 +08:00
rankedMultiplerContainer.MoveToX(0, ranked_multiplier_duration, EasingTypes.OutQuint);
rankedMultiplerContainer.FadeIn(ranked_multiplier_duration, EasingTypes.OutQuint);
2017-02-23 19:36:31 +08:00
foreach (ModSection section in modSectionsContainer.Children)
2017-02-23 10:16:23 +08:00
{
section.ButtonsContainer.TransformSpacingTo(new Vector2(50f, 0f), button_duration, EasingTypes.OutQuint);
section.ButtonsContainer.MoveToX(0, button_duration, EasingTypes.OutQuint);
section.ButtonsContainer.FadeIn(button_duration, EasingTypes.OutQuint);
}
2017-02-23 19:36:31 +08:00
2017-02-23 11:42:31 +08:00
Schedule(TriggerFocusContention);
2017-02-23 10:16:23 +08:00
}
public void DeselectAll()
{
2017-02-23 19:36:31 +08:00
foreach (ModSection section in modSectionsContainer.Children)
2017-02-23 10:16:23 +08:00
{
foreach (ModButton button in section.Buttons)
{
button.Deselect();
}
}
}
public void DeselectMod(Modes.Mods modName)
{
foreach (ModSection section in modSectionsContainer.Children)
{
foreach (ModButton button in section.Buttons)
{
foreach (Mod mod in button.Mods)
{
if (mod.Name == modName)
{
button.Deselect();
return;
}
}
}
}
}
2017-02-23 10:16:23 +08:00
private void modButtonPressed(Mod selectedMod)
{
if (selectedMod != null)
2017-02-22 23:34:22 +08:00
{
2017-03-02 08:57:33 +08:00
foreach (Modes.Mods disableMod in selectedMod.DisablesMods)
2017-02-17 04:05:03 +08:00
{
2017-02-22 23:34:22 +08:00
DeselectMod(disableMod);
2017-02-17 04:05:03 +08:00
}
2017-02-23 10:16:23 +08:00
}
refreshSelectedMods();
double multiplier = 1.0;
2017-02-23 10:16:23 +08:00
bool ranked = true;
2017-02-17 04:05:03 +08:00
foreach (Mod mod in SelectedMods.Value)
{
2017-03-02 08:57:33 +08:00
multiplier *= mod.ScoreMultiplier;
2017-02-23 10:16:23 +08:00
if (ranked)
2017-03-02 08:57:33 +08:00
ranked = mod.Ranked;
2017-02-23 10:16:23 +08:00
}
// 1.00x
// 1.05x
// 1.20x
multiplierLabel.Text = string.Format("{0:N2}x", multiplier);
string rankedString = ranked ? "Ranked" : "Unranked";
rankedLabel.Text = $@"{rankedString}, Score Multiplier: ";
2017-02-23 10:16:23 +08:00
if (multiplier > 1.0)
{
multiplierLabel.FadeColour(highMultiplierColour, 200);
}
else if (multiplier < 1.0)
{
multiplierLabel.FadeColour(lowMultiplierColour, 200);
}
else
{
multiplierLabel.FadeColour(Color4.White, 200);
}
}
private void refreshSelectedMods()
{
2017-02-17 04:05:03 +08:00
List<Mod> selectedMods = new List<Mod>();
2017-02-23 10:16:23 +08:00
2017-02-23 19:36:31 +08:00
foreach (ModSection section in modSectionsContainer.Children)
2017-02-23 10:16:23 +08:00
{
foreach (Mod mod in section.SelectedMods)
{
selectedMods.Add(mod);
}
}
SelectedMods.Value = selectedMods.ToArray();
}
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,
Direction = FillDirection.Down,
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,
Direction = FillDirection.Down,
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",
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,
},
// 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,
},
rankedMultiplerContainer = 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,
Direction = FillDirection.Right,
2017-02-23 10:16:23 +08:00
Padding = new MarginPadding
{
Top = 20,
Bottom = 20,
},
Children = new Drawable[]
{
rankedLabel = new OsuSpriteText
{
Text = @"Ranked, Score Multiplier: ",
TextSize = 30,
Shadow = true,
},
multiplierLabel = new OsuSpriteText
{
Font = @"Exo2.0-Bold",
Text = @"1.00x",
TextSize = 30,
Shadow = true,
},
},
},
},
},
},
},
};
}
}
}