1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 11:42:56 +08:00

Move incompatibility icon logic to local player mod select overlays

This commit is contained in:
Salman Ahmed 2021-08-28 02:37:46 +03:00
parent 69f5705ca0
commit e527bfd4bf
4 changed files with 96 additions and 50 deletions

View File

@ -0,0 +1,69 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.Play.HUD;
using osu.Game.Utils;
using osuTK;
namespace osu.Game.Overlays.Mods
{
public class LocalPlayerModButton : ModButton
{
private readonly CompositeDrawable incompatibleIcon;
[Resolved]
private Bindable<IReadOnlyList<Mod>> selectedMods { get; set; }
public LocalPlayerModButton(Mod mod)
: base(mod)
{
ButtonContent.Add(incompatibleIcon = new IncompatibleIcon
{
Anchor = Anchor.BottomRight,
Origin = Anchor.Centre,
Position = new Vector2(-13),
});
}
protected override void LoadComplete()
{
base.LoadComplete();
selectedMods.BindValueChanged(_ => Scheduler.AddOnce(updateCompatibility), true);
}
protected override void DisplayMod(Mod mod)
{
base.DisplayMod(mod);
Scheduler.AddOnce(updateCompatibility);
}
private void updateCompatibility()
{
var m = SelectedMod ?? Mods.First();
bool isIncompatible = false;
if (selectedMods.Value.Count > 0 && !selectedMods.Value.Contains(m))
isIncompatible = !ModUtils.CheckCompatibleSet(selectedMods.Value.Append(m));
if (isIncompatible)
incompatibleIcon.Show();
else
incompatibleIcon.Hide();
}
}
}

View File

@ -14,5 +14,17 @@ namespace osu.Game.Overlays.Mods
foreach (var section in ModSectionsContainer.Children)
section.DeselectTypes(mod.IncompatibleMods, true, mod);
}
protected override ModSection CreateModSection(ModType type) => new LocalPlayerModSection(type);
private class LocalPlayerModSection : ModSection
{
public LocalPlayerModSection(ModType type)
: base(type)
{
}
protected override ModButton CreateModButton(Mod mod) => new LocalPlayerModButton(mod);
}
}
}

View File

@ -11,16 +11,12 @@ using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Cursor;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Utils;
namespace osu.Game.Overlays.Mods
{
@ -33,7 +29,6 @@ namespace osu.Game.Overlays.Mods
private ModIcon backgroundIcon;
private readonly SpriteText text;
private readonly Container<ModIcon> iconsContainer;
private readonly CompositeDrawable incompatibleIcon;
/// <summary>
/// Fired when the selection changes.
@ -48,9 +43,6 @@ namespace osu.Game.Overlays.Mods
// A selected index of -1 means not selected.
private int selectedIndex = -1;
[Resolved]
private Bindable<IReadOnlyList<Mod>> selectedMods { get; set; }
/// <summary>
/// Change the selected mod index of this button.
/// </summary>
@ -109,7 +101,7 @@ namespace osu.Game.Overlays.Mods
.RotateTo(rotate_angle * direction)
.RotateTo(0f, mod_switch_duration, mod_switch_easing);
Schedule(() => displayMod(newSelection));
Schedule(() => DisplayMod(newSelection));
}
}
@ -138,7 +130,8 @@ namespace osu.Game.Overlays.Mods
}
private Mod mod;
private readonly Container scaleContainer;
protected readonly Container ButtonContent;
public Mod Mod
{
@ -162,7 +155,7 @@ namespace osu.Game.Overlays.Mods
if (Mods.Length > 0)
{
displayMod(Mods[0]);
DisplayMod(Mods[0]);
}
}
}
@ -173,13 +166,13 @@ namespace osu.Game.Overlays.Mods
protected override bool OnMouseDown(MouseDownEvent e)
{
scaleContainer.ScaleTo(0.9f, 800, Easing.Out);
ButtonContent.ScaleTo(0.9f, 800, Easing.Out);
return base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseUpEvent e)
{
scaleContainer.ScaleTo(1, 500, Easing.OutElastic);
ButtonContent.ScaleTo(1, 500, Easing.OutElastic);
// only trigger the event if we are inside the area of the button
if (Contains(e.ScreenSpaceMousePosition))
@ -238,30 +231,13 @@ namespace osu.Game.Overlays.Mods
public void Deselect() => changeSelectedIndex(-1);
private void displayMod(Mod mod)
protected virtual void DisplayMod(Mod mod)
{
if (backgroundIcon != null)
backgroundIcon.Mod = foregroundIcon.Mod;
foregroundIcon.Mod = mod;
text.Text = mod.Name;
Colour = mod.HasImplementation ? Color4.White : Color4.Gray;
Scheduler.AddOnce(updateCompatibility);
}
private void updateCompatibility()
{
var m = SelectedMod ?? Mods.First();
bool isIncompatible = false;
if (selectedMods.Value.Count > 0 && !selectedMods.Value.Contains(m))
isIncompatible = !ModUtils.CheckCompatibleSet(selectedMods.Value.Append(m));
if (isIncompatible)
incompatibleIcon.Show();
else
incompatibleIcon.Hide();
}
private void createIcons()
@ -307,7 +283,7 @@ namespace osu.Game.Overlays.Mods
Anchor = Anchor.TopCentre,
Children = new Drawable[]
{
scaleContainer = new Container
ButtonContent = new Container
{
Children = new Drawable[]
{
@ -317,12 +293,6 @@ namespace osu.Game.Overlays.Mods
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
},
incompatibleIcon = new IncompatibleIcon
{
Origin = Anchor.Centre,
Anchor = Anchor.BottomRight,
Position = new Vector2(-13),
}
},
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
@ -342,14 +312,7 @@ namespace osu.Game.Overlays.Mods
Mod = mod;
}
protected override void LoadComplete()
{
base.LoadComplete();
selectedMods.BindValueChanged(_ => Scheduler.AddOnce(updateCompatibility), true);
}
public ITooltip GetCustomTooltip() => new ModButtonTooltip();
public virtual ITooltip GetCustomTooltip() => new ModButtonTooltip();
public object TooltipContent => SelectedMod ?? Mods.FirstOrDefault();
}

View File

@ -51,14 +51,14 @@ namespace osu.Game.Overlays.Mods
if (m == null)
return new ModButtonEmpty();
return new ModButton(m)
return CreateModButton(m).With(b =>
{
SelectionChanged = mod =>
b.SelectionChanged = mod =>
{
ModButtonStateChanged(mod);
Action?.Invoke(mod);
},
};
};
});
}).ToArray();
modsLoadCts?.Cancel();
@ -247,6 +247,8 @@ namespace osu.Game.Overlays.Mods
Text = text
};
protected virtual ModButton CreateModButton(Mod mod) => new ModButton(mod);
/// <summary>
/// Play out all remaining animations immediately to leave mods in a good (final) state.
/// </summary>