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

View File

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