mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 09:27:29 +08:00
Merge branch 'master' into drawable-hit-object-hit-state-fix
This commit is contained in:
commit
71a1165209
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1029.1" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.1105.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -17,9 +17,11 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
private const double fade_out_offset_multiplier = 0.6;
|
private const double fade_out_offset_multiplier = 0.6;
|
||||||
private const double fade_out_duration_multiplier = 0.44;
|
private const double fade_out_duration_multiplier = 0.44;
|
||||||
|
|
||||||
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
if (!(drawable is DrawableCatchHitObject catchDrawable))
|
base.ApplyNormalVisibilityState(hitObject, state);
|
||||||
|
|
||||||
|
if (!(hitObject is DrawableCatchHitObject catchDrawable))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (catchDrawable.NestedHitObjects.Any())
|
if (catchDrawable.NestedHitObjects.Any())
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -23,28 +22,38 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
private const double fade_in_duration_multiplier = 0.4;
|
private const double fade_in_duration_multiplier = 0.4;
|
||||||
private const double fade_out_duration_multiplier = 0.3;
|
private const double fade_out_duration_multiplier = 0.3;
|
||||||
|
|
||||||
protected override bool IsFirstHideableObject(DrawableHitObject hitObject) => !(hitObject is DrawableSpinner);
|
protected override bool IsFirstAdjustableObject(HitObject hitObject) => !(hitObject is Spinner);
|
||||||
|
|
||||||
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public override void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
static void adjustFadeIn(OsuHitObject h) => h.TimeFadeIn = h.TimePreempt * fade_in_duration_multiplier;
|
foreach (var d in drawables)
|
||||||
|
d.ApplyCustomUpdateState += applyFadeInAdjustment;
|
||||||
foreach (var d in drawables.OfType<DrawableOsuHitObject>())
|
|
||||||
{
|
|
||||||
adjustFadeIn(d.HitObject);
|
|
||||||
foreach (var h in d.HitObject.NestedHitObjects.OfType<OsuHitObject>())
|
|
||||||
adjustFadeIn(h);
|
|
||||||
}
|
|
||||||
|
|
||||||
base.ApplyToDrawableHitObjects(drawables);
|
base.ApplyToDrawableHitObjects(drawables);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applyFadeInAdjustment(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
if (!(hitObject is DrawableOsuHitObject d))
|
||||||
|
return;
|
||||||
|
|
||||||
|
d.HitObject.TimeFadeIn = d.HitObject.TimePreempt * fade_in_duration_multiplier;
|
||||||
|
}
|
||||||
|
|
||||||
private double lastSliderHeadFadeOutStartTime;
|
private double lastSliderHeadFadeOutStartTime;
|
||||||
private double lastSliderHeadFadeOutDuration;
|
private double lastSliderHeadFadeOutDuration;
|
||||||
|
|
||||||
protected override void ApplyFirstObjectIncreaseVisibilityState(DrawableHitObject drawable, ArmedState state) => applyState(drawable, true);
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
base.ApplyIncreasedVisibilityState(hitObject, state);
|
||||||
|
applyState(hitObject, true);
|
||||||
|
}
|
||||||
|
|
||||||
protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) => applyState(drawable, false);
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
base.ApplyNormalVisibilityState(hitObject, state);
|
||||||
|
applyState(hitObject, false);
|
||||||
|
}
|
||||||
|
|
||||||
private void applyState(DrawableHitObject drawable, bool increaseVisibility)
|
private void applyState(DrawableHitObject drawable, bool increaseVisibility)
|
||||||
{
|
{
|
||||||
|
@ -2,11 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@ -17,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adjusts the size of hit objects during their fade in animation.
|
/// Adjusts the size of hit objects during their fade in animation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class OsuModObjectScaleTween : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
public abstract class OsuModObjectScaleTween : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
|
|
||||||
@ -27,33 +24,19 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
protected virtual float EndScale => 1;
|
protected virtual float EndScale => 1;
|
||||||
|
|
||||||
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpinIn), typeof(OsuModTraceable) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpinIn), typeof(OsuModTraceable) };
|
||||||
|
|
||||||
public void ReadFromConfig(OsuConfigManager config)
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyCustomState(hitObject, state);
|
||||||
{
|
|
||||||
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
|
|
||||||
{
|
|
||||||
switch (drawable)
|
|
||||||
{
|
|
||||||
case DrawableSpinner _:
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
private void applyCustomState(DrawableHitObject drawable, ArmedState state)
|
||||||
drawable.ApplyCustomUpdateState += ApplyCustomState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected virtual void ApplyCustomState(DrawableHitObject drawable, ArmedState state)
|
|
||||||
{
|
{
|
||||||
|
if (drawable is DrawableSpinner)
|
||||||
|
return;
|
||||||
|
|
||||||
var h = (OsuHitObject)drawable.HitObject;
|
var h = (OsuHitObject)drawable.HitObject;
|
||||||
|
|
||||||
// apply grow effect
|
// apply grow effect
|
||||||
|
@ -2,12 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@ -16,7 +12,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModSpinIn : Mod, IApplicableToDrawableHitObjects, IReadFromConfig
|
public class OsuModSpinIn : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override string Name => "Spin In";
|
public override string Name => "Spin In";
|
||||||
public override string Acronym => "SI";
|
public override string Acronym => "SI";
|
||||||
@ -31,31 +27,17 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
private const int rotate_offset = 360;
|
private const int rotate_offset = 360;
|
||||||
private const float rotate_starting_width = 2;
|
private const float rotate_starting_width = 2;
|
||||||
|
|
||||||
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
|
||||||
public void ReadFromConfig(OsuConfigManager config)
|
|
||||||
{
|
{
|
||||||
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyZoomState(hitObject, state);
|
||||||
{
|
|
||||||
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
|
|
||||||
{
|
|
||||||
switch (drawable)
|
|
||||||
{
|
|
||||||
case DrawableSpinner _:
|
|
||||||
continue;
|
|
||||||
|
|
||||||
default:
|
|
||||||
drawable.ApplyCustomUpdateState += applyZoomState;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyZoomState(DrawableHitObject drawable, ArmedState state)
|
private void applyZoomState(DrawableHitObject drawable, ArmedState state)
|
||||||
{
|
{
|
||||||
|
if (drawable is DrawableSpinner)
|
||||||
|
return;
|
||||||
|
|
||||||
var h = (OsuHitObject)drawable.HitObject;
|
var h = (OsuHitObject)drawable.HitObject;
|
||||||
|
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
|
@ -2,12 +2,8 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Configuration;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
@ -15,7 +11,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModTraceable : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
internal class OsuModTraceable : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override string Name => "Traceable";
|
public override string Name => "Traceable";
|
||||||
public override string Acronym => "TC";
|
public override string Acronym => "TC";
|
||||||
@ -24,20 +20,14 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModHidden), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModHidden), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween) };
|
||||||
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
|
||||||
|
|
||||||
public void ReadFromConfig(OsuConfigManager config)
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyTraceableState(hitObject, state);
|
||||||
{
|
|
||||||
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
|
|
||||||
drawable.ApplyCustomUpdateState += ApplyTraceableState;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void ApplyTraceableState(DrawableHitObject drawable, ArmedState state)
|
private void applyTraceableState(DrawableHitObject drawable, ArmedState state)
|
||||||
{
|
{
|
||||||
if (!(drawable is DrawableOsuHitObject))
|
if (!(drawable is DrawableOsuHitObject))
|
||||||
return;
|
return;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -13,7 +12,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModTransform : Mod, IApplicableToDrawableHitObjects
|
internal class OsuModTransform : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override string Name => "Transform";
|
public override string Name => "Transform";
|
||||||
public override string Acronym => "TR";
|
public override string Acronym => "TR";
|
||||||
@ -25,11 +24,9 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
private float theta;
|
private float theta;
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyTransform(hitObject, state);
|
||||||
{
|
|
||||||
foreach (var drawable in drawables)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => applyTransform(hitObject, state);
|
||||||
drawable.ApplyCustomUpdateState += applyTransform;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void applyTransform(DrawableHitObject drawable, ArmedState state)
|
private void applyTransform(DrawableHitObject drawable, ArmedState state)
|
||||||
{
|
{
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -13,7 +12,7 @@ using osuTK;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModWiggle : Mod, IApplicableToDrawableHitObjects
|
internal class OsuModWiggle : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override string Name => "Wiggle";
|
public override string Name => "Wiggle";
|
||||||
public override string Acronym => "WG";
|
public override string Acronym => "WG";
|
||||||
@ -26,11 +25,9 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
private const int wiggle_duration = 90; // (ms) Higher = fewer wiggles
|
private const int wiggle_duration = 90; // (ms) Higher = fewer wiggles
|
||||||
private const int wiggle_strength = 10; // Higher = stronger wiggles
|
private const int wiggle_strength = 10; // Higher = stronger wiggles
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state) => drawableOnApplyCustomUpdateState(hitObject, state);
|
||||||
{
|
|
||||||
foreach (var drawable in drawables)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state) => drawableOnApplyCustomUpdateState(hitObject, state);
|
||||||
drawable.ApplyCustomUpdateState += drawableOnApplyCustomUpdateState;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void drawableOnApplyCustomUpdateState(DrawableHitObject drawable, ArmedState state)
|
private void drawableOnApplyCustomUpdateState(DrawableHitObject drawable, ArmedState state)
|
||||||
{
|
{
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Configuration;
|
using System;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
{
|
{
|
||||||
public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects, IApplicableToScoreProcessor
|
public abstract class ModHidden : ModWithVisibilityAdjustment, IApplicableToScoreProcessor
|
||||||
{
|
{
|
||||||
public override string Name => "Hidden";
|
public override string Name => "Hidden";
|
||||||
public override string Acronym => "HD";
|
public override string Acronym => "HD";
|
||||||
@ -21,37 +18,14 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public override ModType Type => ModType.DifficultyIncrease;
|
public override ModType Type => ModType.DifficultyIncrease;
|
||||||
public override bool Ranked => true;
|
public override bool Ranked => true;
|
||||||
|
|
||||||
protected Bindable<bool> IncreaseFirstObjectVisibility = new Bindable<bool>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Check whether the provided hitobject should be considered the "first" hideable object.
|
/// Check whether the provided hitobject should be considered the "first" hideable object.
|
||||||
/// Can be used to skip spinners, for instance.
|
/// Can be used to skip spinners, for instance.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The hitobject to check.</param>
|
/// <param name="hitObject">The hitobject to check.</param>
|
||||||
|
[Obsolete("Use IsFirstAdjustableObject() instead.")] // Can be removed 20210506
|
||||||
protected virtual bool IsFirstHideableObject(DrawableHitObject hitObject) => true;
|
protected virtual bool IsFirstHideableObject(DrawableHitObject hitObject) => true;
|
||||||
|
|
||||||
public void ReadFromConfig(OsuConfigManager config)
|
|
||||||
{
|
|
||||||
IncreaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
|
||||||
}
|
|
||||||
|
|
||||||
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
|
||||||
{
|
|
||||||
if (IncreaseFirstObjectVisibility.Value)
|
|
||||||
{
|
|
||||||
drawables = drawables.SkipWhile(h => !IsFirstHideableObject(h));
|
|
||||||
|
|
||||||
var firstObject = drawables.FirstOrDefault();
|
|
||||||
if (firstObject != null)
|
|
||||||
firstObject.ApplyCustomUpdateState += ApplyFirstObjectIncreaseVisibilityState;
|
|
||||||
|
|
||||||
drawables = drawables.Skip(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var dho in drawables)
|
|
||||||
dho.ApplyCustomUpdateState += ApplyHiddenState;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
||||||
{
|
{
|
||||||
// Default value of ScoreProcessor's Rank in Hidden Mod should be SS+
|
// Default value of ScoreProcessor's Rank in Hidden Mod should be SS+
|
||||||
@ -73,11 +47,26 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
#pragma warning disable 618
|
||||||
|
ApplyFirstObjectIncreaseVisibilityState(hitObject, state);
|
||||||
|
#pragma warning restore 618
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
|
{
|
||||||
|
#pragma warning disable 618
|
||||||
|
ApplyHiddenState(hitObject, state);
|
||||||
|
#pragma warning restore 618
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Apply a special visibility state to the first object in a beatmap, if the user chooses to turn on the "increase first object visibility" setting.
|
/// Apply a special visibility state to the first object in a beatmap, if the user chooses to turn on the "increase first object visibility" setting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
||||||
/// <param name="state">The state of the hit object.</param>
|
/// <param name="state">The state of the hit object.</param>
|
||||||
|
[Obsolete("Use ApplyIncreasedVisibilityState() instead.")] // Can be removed 20210506
|
||||||
protected virtual void ApplyFirstObjectIncreaseVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
protected virtual void ApplyFirstObjectIncreaseVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -87,6 +76,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
||||||
/// <param name="state">The state of the hit object.</param>
|
/// <param name="state">The state of the hit object.</param>
|
||||||
|
[Obsolete("Use ApplyNormalVisibilityState() instead.")] // Can be removed 20210506
|
||||||
protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state)
|
protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
114
osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs
Normal file
114
osu.Game/Rulesets/Mods/ModWithVisibilityAdjustment.cs
Normal file
@ -0,0 +1,114 @@
|
|||||||
|
// 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.Collections.Generic;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mods
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A <see cref="Mod"/> which applies visibility adjustments to <see cref="DrawableHitObject"/>s
|
||||||
|
/// with an optional increased visibility adjustment depending on the user's "increase first object visibility" setting.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class ModWithVisibilityAdjustment : Mod, IReadFromConfig, IApplicableToBeatmap, IApplicableToDrawableHitObjects
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The first adjustable object.
|
||||||
|
/// </summary>
|
||||||
|
protected HitObject FirstObject { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Whether the visibility of <see cref="FirstObject"/> should be increased.
|
||||||
|
/// </summary>
|
||||||
|
protected readonly Bindable<bool> IncreaseFirstObjectVisibility = new Bindable<bool>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Check whether the provided hitobject should be considered the "first" adjustable object.
|
||||||
|
/// Can be used to skip spinners, for instance.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The hitobject to check.</param>
|
||||||
|
protected virtual bool IsFirstAdjustableObject(HitObject hitObject) => true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply a special increased-visibility state to the first adjustable object.
|
||||||
|
/// Only applicable if the user chooses to turn on the "increase first object visibility" setting.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
||||||
|
/// <param name="state">The state of the hitobject.</param>
|
||||||
|
protected abstract void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Apply a normal visibility state adjustment to an object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The hit object to apply the state change to.</param>
|
||||||
|
/// <param name="state">The state of the hitobject.</param>
|
||||||
|
protected abstract void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state);
|
||||||
|
|
||||||
|
public virtual void ReadFromConfig(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
config.BindWith(OsuSetting.IncreaseFirstObjectVisibility, IncreaseFirstObjectVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
FirstObject = getFirstAdjustableObjectRecursive(beatmap.HitObjects);
|
||||||
|
|
||||||
|
HitObject getFirstAdjustableObjectRecursive(IReadOnlyList<HitObject> hitObjects)
|
||||||
|
{
|
||||||
|
foreach (var h in hitObjects)
|
||||||
|
{
|
||||||
|
if (IsFirstAdjustableObject(h))
|
||||||
|
return h;
|
||||||
|
|
||||||
|
var nestedResult = getFirstAdjustableObjectRecursive(h.NestedHitObjects);
|
||||||
|
if (nestedResult != null)
|
||||||
|
return nestedResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
|
{
|
||||||
|
foreach (var dho in drawables)
|
||||||
|
{
|
||||||
|
dho.ApplyCustomUpdateState += (o, state) =>
|
||||||
|
{
|
||||||
|
// Increased visibility is applied to the entire first object, including all of its nested hitobjects.
|
||||||
|
if (IncreaseFirstObjectVisibility.Value && isObjectEqualToOrNestedIn(o.HitObject, FirstObject))
|
||||||
|
ApplyIncreasedVisibilityState(o, state);
|
||||||
|
else
|
||||||
|
ApplyNormalVisibilityState(o, state);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Checks whether a given object is nested within a target.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="toCheck">The <see cref="HitObject"/> to check.</param>
|
||||||
|
/// <param name="target">The <see cref="HitObject"/> which may be equal to or contain <paramref name="toCheck"/> as a nested object.</param>
|
||||||
|
/// <returns>Whether <paramref name="toCheck"/> is equal to or nested within <paramref name="target"/>.</returns>
|
||||||
|
private bool isObjectEqualToOrNestedIn(HitObject toCheck, HitObject target)
|
||||||
|
{
|
||||||
|
if (target == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (toCheck == target)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
foreach (var h in target.NestedHitObjects)
|
||||||
|
{
|
||||||
|
if (isObjectEqualToOrNestedIn(toCheck, h))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -65,17 +65,15 @@ namespace osu.Game.Tests.Visual
|
|||||||
private Drawable createProvider(Skin skin, Func<Drawable> creationFunction, IBeatmap beatmap)
|
private Drawable createProvider(Skin skin, Func<Drawable> creationFunction, IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var created = creationFunction();
|
var created = creationFunction();
|
||||||
|
|
||||||
createdDrawables.Add(created);
|
createdDrawables.Add(created);
|
||||||
|
|
||||||
var autoSize = created.RelativeSizeAxes == Axes.None;
|
SkinProvidingContainer mainProvider;
|
||||||
|
Container childContainer;
|
||||||
|
OutlineBox outlineBox;
|
||||||
|
SkinProvidingContainer skinProvider;
|
||||||
|
|
||||||
var mainProvider = new SkinProvidingContainer(skin)
|
var children = new Container
|
||||||
{
|
|
||||||
RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None,
|
|
||||||
AutoSizeAxes = autoSize ? Axes.Both : Axes.None,
|
|
||||||
};
|
|
||||||
|
|
||||||
return new Container
|
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
BorderColour = Color4.White,
|
BorderColour = Color4.White,
|
||||||
@ -96,27 +94,47 @@ namespace osu.Game.Tests.Visual
|
|||||||
Scale = new Vector2(1.5f),
|
Scale = new Vector2(1.5f),
|
||||||
Padding = new MarginPadding(5),
|
Padding = new MarginPadding(5),
|
||||||
},
|
},
|
||||||
new Container
|
childContainer = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None,
|
|
||||||
AutoSizeAxes = autoSize ? Axes.Both : Axes.None,
|
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new OutlineBox { Alpha = autoSize ? 1 : 0 },
|
outlineBox = new OutlineBox(),
|
||||||
mainProvider.WithChild(
|
(mainProvider = new SkinProvidingContainer(skin)).WithChild(
|
||||||
new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider, beatmap))
|
skinProvider = new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider, beatmap))
|
||||||
{
|
{
|
||||||
Child = created,
|
Child = created,
|
||||||
RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None,
|
|
||||||
AutoSizeAxes = autoSize ? Axes.Both : Axes.None,
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// run this once initially to bring things into a sane state as early as possible.
|
||||||
|
updateSizing();
|
||||||
|
|
||||||
|
// run this once after construction to handle the case the changes are made in a BDL/LoadComplete call.
|
||||||
|
Schedule(updateSizing);
|
||||||
|
|
||||||
|
return children;
|
||||||
|
|
||||||
|
void updateSizing()
|
||||||
|
{
|
||||||
|
var autoSize = created.RelativeSizeAxes == Axes.None;
|
||||||
|
|
||||||
|
foreach (var c in new[] { mainProvider, childContainer, skinProvider })
|
||||||
|
{
|
||||||
|
c.RelativeSizeAxes = Axes.None;
|
||||||
|
c.AutoSizeAxes = Axes.None;
|
||||||
|
|
||||||
|
c.RelativeSizeAxes = !autoSize ? Axes.Both : Axes.None;
|
||||||
|
c.AutoSizeAxes = autoSize ? Axes.Both : Axes.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
outlineBox.Alpha = autoSize ? 1 : 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.1029.1" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1105.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
||||||
<PackageReference Include="Sentry" Version="2.1.6" />
|
<PackageReference Include="Sentry" Version="2.1.6" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
||||||
|
@ -70,7 +70,7 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.1029.1" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2020.1105.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1030.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
@ -88,7 +88,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2020.1029.1" />
|
<PackageReference Include="ppy.osu.Framework" Version="2020.1105.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
<PackageReference Include="SharpCompress" Version="0.26.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user