Move members to PalpableCatchHitObject

This commit is contained in:
ekrctb
2020-11-24 19:57:37 +09:00
parent 4f7aa7e541
commit ab7251d742
14 changed files with 66 additions and 78 deletions

View File

@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Catch.Tests
hitObject.Scale = 1.5f; hitObject.Scale = 1.5f;
if (hyperdash) if (hyperdash)
hitObject.HyperDashTarget = new Banana(); ((PalpableCatchHitObject)hitObject).HyperDashTarget = new Banana();
d.Anchor = Anchor.Centre; d.Anchor = Anchor.Centre;
d.RelativePositionAxes = Axes.None; d.RelativePositionAxes = Axes.None;

View File

@ -5,11 +5,11 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.MathUtils;
using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Catch.MathUtils;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Rulesets.Catch.Beatmaps namespace osu.Game.Rulesets.Catch.Beatmaps
{ {
@ -192,24 +192,24 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
private static void initialiseHyperDash(IBeatmap beatmap) private static void initialiseHyperDash(IBeatmap beatmap)
{ {
List<CatchHitObject> objectWithDroplets = new List<CatchHitObject>(); List<PalpableCatchHitObject> palpableObjects = new List<PalpableCatchHitObject>();
foreach (var currentObject in beatmap.HitObjects) foreach (var currentObject in beatmap.HitObjects)
{ {
if (currentObject is Fruit fruitObject) if (currentObject is Fruit fruitObject)
objectWithDroplets.Add(fruitObject); palpableObjects.Add(fruitObject);
if (currentObject is JuiceStream) if (currentObject is JuiceStream)
{ {
foreach (var currentJuiceElement in currentObject.NestedHitObjects) foreach (var juice in currentObject.NestedHitObjects)
{ {
if (!(currentJuiceElement is TinyDroplet)) if (juice is PalpableCatchHitObject palpableObject && !(juice is TinyDroplet))
objectWithDroplets.Add((CatchHitObject)currentJuiceElement); palpableObjects.Add(palpableObject);
} }
} }
} }
objectWithDroplets.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); palpableObjects.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime));
double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) / 2; double halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) / 2;
@ -221,10 +221,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
int lastDirection = 0; int lastDirection = 0;
double lastExcess = halfCatcherWidth; double lastExcess = halfCatcherWidth;
for (int i = 0; i < objectWithDroplets.Count - 1; i++) for (int i = 0; i < palpableObjects.Count - 1; i++)
{ {
CatchHitObject currentObject = objectWithDroplets[i]; var currentObject = palpableObjects[i];
CatchHitObject nextObject = objectWithDroplets[i + 1]; var nextObject = palpableObjects[i + 1];
// Reset variables in-case values have changed (e.g. after applying HR) // Reset variables in-case values have changed (e.g. after applying HR)
currentObject.HyperDashTarget = null; currentObject.HyperDashTarget = null;

View File

@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
{ {
private const float normalized_hitobject_radius = 41.0f; private const float normalized_hitobject_radius = 41.0f;
public new CatchHitObject BaseObject => (CatchHitObject)base.BaseObject; public new PalpableCatchHitObject BaseObject => (PalpableCatchHitObject)base.BaseObject;
public new CatchHitObject LastObject => (CatchHitObject)base.LastObject; public new PalpableCatchHitObject LastObject => (PalpableCatchHitObject)base.LastObject;
public readonly float NormalizedPosition; public readonly float NormalizedPosition;
public readonly float LastNormalizedPosition; public readonly float LastNormalizedPosition;

View File

@ -27,11 +27,6 @@ namespace osu.Game.Rulesets.Catch.Objects
set => x = value; set => x = value;
} }
/// <summary>
/// Whether this object can be placed on the catcher's plate.
/// </summary>
public virtual bool CanBePlated => false;
/// <summary> /// <summary>
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>. /// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
/// </summary> /// </summary>
@ -63,13 +58,6 @@ namespace osu.Game.Rulesets.Catch.Objects
set => ComboIndexBindable.Value = value; set => ComboIndexBindable.Value = value;
} }
/// <summary>
/// Difference between the distance to the next object
/// and the distance that would have triggered a hyper dash.
/// A value close to 0 indicates a difficult jump (for difficulty calculation).
/// </summary>
public float DistanceToHyperDash { get; set; }
public Bindable<bool> LastInComboBindable { get; } = new Bindable<bool>(); public Bindable<bool> LastInComboBindable { get; } = new Bindable<bool>();
/// <summary> /// <summary>
@ -83,16 +71,6 @@ namespace osu.Game.Rulesets.Catch.Objects
public float Scale { get; set; } = 1; public float Scale { get; set; } = 1;
/// <summary>
/// Whether this fruit can initiate a hyperdash.
/// </summary>
public bool HyperDash => HyperDashTarget != null;
/// <summary>
/// The target fruit if we are to initiate a hyperdash.
/// </summary>
public CatchHitObject HyperDashTarget;
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty) protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{ {
base.ApplyDefaultsToSelf(controlPointInfo, difficulty); base.ApplyDefaultsToSelf(controlPointInfo, difficulty);

View File

@ -12,8 +12,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
protected override double InitialLifetimeOffset => HitObject.TimePreempt; protected override double InitialLifetimeOffset => HitObject.TimePreempt;
public virtual bool StaysOnPlate => HitObject.CanBePlated;
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale; public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
protected override float SamplePlaybackPosition => HitObject.X / CatchPlayfield.WIDTH; protected override float SamplePlaybackPosition => HitObject.X / CatchPlayfield.WIDTH;

View File

@ -10,6 +10,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
public class DrawableFruit : DrawablePalpableCatchHitObject public class DrawableFruit : DrawablePalpableCatchHitObject
{ {
public override bool StaysOnPlate => true;
public DrawableFruit(CatchHitObject h) public DrawableFruit(CatchHitObject h)
: base(h) : base(h)
{ {

View File

@ -12,29 +12,27 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
{ {
public abstract class DrawablePalpableCatchHitObject : DrawableCatchHitObject public abstract class DrawablePalpableCatchHitObject : DrawableCatchHitObject
{ {
protected Container ScaleContainer { get; private set; } public virtual bool StaysOnPlate => true;
protected DrawablePalpableCatchHitObject(CatchHitObject hitObject) protected readonly Container ScaleContainer;
: base(hitObject)
protected DrawablePalpableCatchHitObject(CatchHitObject h)
: base(h)
{ {
Origin = Anchor.Centre; Origin = Anchor.Centre;
Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2); Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2);
Masking = false;
AddInternal(ScaleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
});
} }
[BackgroundDependencyLoader] [BackgroundDependencyLoader]
private void load() private void load()
{ {
AddRangeInternal(new Drawable[]
{
ScaleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
}
});
ScaleContainer.Scale = new Vector2(HitObject.Scale); ScaleContainer.Scale = new Vector2(HitObject.Scale);
} }

View File

@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private void load(DrawableHitObject drawableObject) private void load(DrawableHitObject drawableObject)
{ {
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
var hitObject = drawableCatchObject.HitObject; var hitObject = (PalpableCatchHitObject)drawableCatchObject.HitObject;
InternalChild = new Pulp InternalChild = new Pulp
{ {

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public const float RADIUS_ADJUST = 1.1f; public const float RADIUS_ADJUST = 1.1f;
private Circle border; private Circle border;
private CatchHitObject hitObject; private PalpableCatchHitObject hitObject;
public FruitPiece() public FruitPiece()
{ {
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private void load(DrawableHitObject drawableObject) private void load(DrawableHitObject drawableObject)
{ {
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject; DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
hitObject = drawableCatchObject.HitObject; hitObject = (PalpableCatchHitObject)drawableCatchObject.HitObject;
AddRangeInternal(new[] AddRangeInternal(new[]
{ {

View File

@ -5,9 +5,27 @@ namespace osu.Game.Rulesets.Catch.Objects
{ {
/// <summary> /// <summary>
/// Represents a single object that can be caught by the catcher. /// Represents a single object that can be caught by the catcher.
/// This includes normal fruits, droplets, and bananas but excludes objects that acts only as a container of nested hit objects.
/// </summary> /// </summary>
public abstract class PalpableCatchHitObject : CatchHitObject public abstract class PalpableCatchHitObject : CatchHitObject
{ {
public override bool CanBePlated => true; /// <summary>
/// Difference between the distance to the next object
/// and the distance that would have triggered a hyper dash.
/// A value close to 0 indicates a difficult jump (for difficulty calculation).
/// </summary>
public float DistanceToHyperDash { get; set; }
/// <summary>
/// Whether this fruit can initiate a hyperdash.
/// </summary>
public bool HyperDash => HyperDashTarget != null;
/// <summary>
/// The target fruit if we are to initiate a hyperdash.
/// </summary>
public CatchHitObject HyperDashTarget;
public virtual bool StaysOnPlate => true;
} }
} }

View File

@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Replays
float lastPosition = CatchPlayfield.CENTER_X; float lastPosition = CatchPlayfield.CENTER_X;
double lastTime = 0; double lastTime = 0;
void moveToNext(CatchHitObject h) void moveToNext(PalpableCatchHitObject h)
{ {
float positionChange = Math.Abs(lastPosition - h.X); float positionChange = Math.Abs(lastPosition - h.X);
double timeAvailable = h.StartTime - lastTime; double timeAvailable = h.StartTime - lastTime;
@ -101,23 +101,16 @@ namespace osu.Game.Rulesets.Catch.Replays
foreach (var obj in Beatmap.HitObjects) foreach (var obj in Beatmap.HitObjects)
{ {
switch (obj) if (obj is PalpableCatchHitObject palpableObject)
{ {
case Fruit _: moveToNext(palpableObject);
moveToNext(obj);
break;
} }
foreach (var nestedObj in obj.NestedHitObjects.Cast<CatchHitObject>()) foreach (var nestedObj in obj.NestedHitObjects.Cast<CatchHitObject>())
{ {
switch (nestedObj) if (nestedObj is PalpableCatchHitObject palpableNestedObject)
{ {
case Banana _: moveToNext(palpableNestedObject);
case TinyDroplet _:
case Droplet _:
case Fruit _:
moveToNext(nestedObj);
break;
} }
} }
} }

View File

@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawables; using osu.Game.Rulesets.Catch.Objects.Drawables;
using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Drawables;
@ -51,7 +52,7 @@ namespace osu.Game.Rulesets.Catch.Skinning
}, },
}; };
if (drawableCatchObject.HitObject.HyperDash) if (((PalpableCatchHitObject)drawableCatchObject.HitObject).HyperDash)
{ {
var hyperDash = new Sprite var hyperDash = new Sprite
{ {

View File

@ -220,11 +220,11 @@ namespace osu.Game.Rulesets.Catch.UI
/// <summary> /// <summary>
/// Let the catcher attempt to catch a fruit. /// Let the catcher attempt to catch a fruit.
/// </summary> /// </summary>
/// <param name="fruit">The fruit to catch.</param> /// <param name="hitObject">The fruit to catch.</param>
/// <returns>Whether the catch is possible.</returns> /// <returns>Whether the catch is possible.</returns>
public bool AttemptCatch(CatchHitObject fruit) public bool AttemptCatch(CatchHitObject hitObject)
{ {
if (!fruit.CanBePlated) if (!(hitObject is PalpableCatchHitObject fruit))
return false; return false;
var halfCatchWidth = catchWidth * 0.5f; var halfCatchWidth = catchWidth * 0.5f;

View File

@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.UI
}; };
} }
public void OnNewResult(DrawableCatchHitObject fruit, JudgementResult result) public void OnNewResult(DrawableCatchHitObject hitObject, JudgementResult result)
{ {
if (!result.Type.IsScorable()) if (!result.Type.IsScorable())
return; return;
@ -69,15 +69,15 @@ namespace osu.Game.Rulesets.Catch.UI
lastPlateableFruit.OnLoadComplete += _ => action(); lastPlateableFruit.OnLoadComplete += _ => action();
} }
if (result.IsHit && fruit.HitObject.CanBePlated) if (result.IsHit && hitObject.HitObject is PalpableCatchHitObject fruit)
{ {
// create a new (cloned) fruit to stay on the plate. the original is faded out immediately. // create a new (cloned) fruit to stay on the plate. the original is faded out immediately.
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject); var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit);
if (caughtFruit == null) return; if (caughtFruit == null) return;
caughtFruit.RelativePositionAxes = Axes.None; caughtFruit.RelativePositionAxes = Axes.None;
caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(hitObject.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0);
caughtFruit.IsOnPlate = true; caughtFruit.IsOnPlate = true;
caughtFruit.Anchor = Anchor.TopCentre; caughtFruit.Anchor = Anchor.TopCentre;
@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.UI
runAfterLoaded(() => MovableCatcher.Explode(caughtFruit)); runAfterLoaded(() => MovableCatcher.Explode(caughtFruit));
} }
if (fruit.HitObject.LastInCombo) if (hitObject.HitObject.LastInCombo)
{ {
if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result)) if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result))
runAfterLoaded(() => MovableCatcher.Explode()); runAfterLoaded(() => MovableCatcher.Explode());
@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Catch.UI
MovableCatcher.Drop(); MovableCatcher.Drop();
} }
comboDisplay.OnNewResult(fruit, result); comboDisplay.OnNewResult(hitObject, result);
} }
public void OnRevertResult(DrawableCatchHitObject fruit, JudgementResult result) public void OnRevertResult(DrawableCatchHitObject fruit, JudgementResult result)