1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 15:07:44 +08:00

Merge pull request #10956 from ekrctb/palpable-catch-hit-object

Move some members from `CatchHitObject` to `PalpableCatchHitObject` to make it more specific
This commit is contained in:
ekrctb 2020-11-26 15:18:05 +09:00 committed by GitHub
commit 5889b74eba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 111 additions and 112 deletions

View File

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

View File

@ -5,11 +5,11 @@ using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.MathUtils;
using osu.Game.Rulesets.Catch.Objects;
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.Objects.Types;
namespace osu.Game.Rulesets.Catch.Beatmaps
{
@ -192,24 +192,24 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
private static void initialiseHyperDash(IBeatmap beatmap)
{
List<CatchHitObject> objectWithDroplets = new List<CatchHitObject>();
List<PalpableCatchHitObject> palpableObjects = new List<PalpableCatchHitObject>();
foreach (var currentObject in beatmap.HitObjects)
{
if (currentObject is Fruit fruitObject)
objectWithDroplets.Add(fruitObject);
palpableObjects.Add(fruitObject);
if (currentObject is JuiceStream)
{
foreach (var currentJuiceElement in currentObject.NestedHitObjects)
foreach (var juice in currentObject.NestedHitObjects)
{
if (!(currentJuiceElement is TinyDroplet))
objectWithDroplets.Add((CatchHitObject)currentJuiceElement);
if (juice is PalpableCatchHitObject palpableObject && !(juice is TinyDroplet))
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;
@ -221,10 +221,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
int lastDirection = 0;
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];
CatchHitObject nextObject = objectWithDroplets[i + 1];
var currentObject = palpableObjects[i];
var nextObject = palpableObjects[i + 1];
// Reset variables in-case values have changed (e.g. after applying HR)
currentObject.HyperDashTarget = null;

View File

@ -12,9 +12,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
{
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 LastNormalizedPosition;

View File

@ -27,11 +27,6 @@ namespace osu.Game.Rulesets.Catch.Objects
set => x = value;
}
/// <summary>
/// Whether this object can be placed on the catcher's plate.
/// </summary>
public virtual bool CanBePlated => false;
/// <summary>
/// A random offset applied to <see cref="X"/>, set by the <see cref="CatchBeatmapProcessor"/>.
/// </summary>
@ -63,13 +58,6 @@ namespace osu.Game.Rulesets.Catch.Objects
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>();
/// <summary>
@ -83,16 +71,6 @@ namespace osu.Game.Rulesets.Catch.Objects
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)
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
@ -105,14 +83,6 @@ namespace osu.Game.Rulesets.Catch.Objects
protected override HitWindows CreateHitWindows() => HitWindows.Empty;
}
/// <summary>
/// Represents a single object that can be caught by the catcher.
/// </summary>
public abstract class PalpableCatchHitObject : CatchHitObject
{
public override bool CanBePlated => true;
}
public enum FruitVisualRepresentation
{
Pear,

View File

@ -2,55 +2,16 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects.Drawables;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
public abstract class PalpableDrawableCatchHitObject : DrawableCatchHitObject
{
protected Container ScaleContainer { get; private set; }
protected PalpableDrawableCatchHitObject(CatchHitObject hitObject)
: base(hitObject)
{
Origin = Anchor.Centre;
Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2);
Masking = false;
}
[BackgroundDependencyLoader]
private void load()
{
AddRangeInternal(new Drawable[]
{
ScaleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
}
});
ScaleContainer.Scale = new Vector2(HitObject.Scale);
}
protected override Color4 GetComboColour(IReadOnlyList<Color4> comboColours) =>
comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count];
}
public abstract class DrawableCatchHitObject : DrawableHitObject<CatchHitObject>
{
protected override double InitialLifetimeOffset => HitObject.TimePreempt;
public virtual bool StaysOnPlate => HitObject.CanBePlated;
public float DisplayRadius => DrawSize.X / 2 * Scale.X * HitObject.Scale;
protected override float SamplePlaybackPosition => HitObject.X / CatchPlayfield.WIDTH;

View File

@ -8,7 +8,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
public class DrawableDroplet : PalpableDrawableCatchHitObject
public class DrawableDroplet : DrawablePalpableCatchHitObject
{
public override bool StaysOnPlate => false;

View File

@ -8,7 +8,7 @@ using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
public class DrawableFruit : PalpableDrawableCatchHitObject
public class DrawableFruit : DrawablePalpableCatchHitObject
{
public DrawableFruit(CatchHitObject h)
: base(h)

View File

@ -0,0 +1,47 @@
// 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.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.Objects.Drawables
{
public abstract class DrawablePalpableCatchHitObject : DrawableCatchHitObject
{
public new PalpableCatchHitObject HitObject => (PalpableCatchHitObject)base.HitObject;
/// <summary>
/// Whether this hit object should stay on the catcher plate when the object is caught by the catcher.
/// </summary>
public virtual bool StaysOnPlate => true;
protected readonly Container ScaleContainer;
protected DrawablePalpableCatchHitObject(CatchHitObject h)
: base(h)
{
Origin = Anchor.Centre;
Size = new Vector2(CatchHitObject.OBJECT_RADIUS * 2);
AddInternal(ScaleContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
});
}
[BackgroundDependencyLoader]
private void load()
{
ScaleContainer.Scale = new Vector2(HitObject.Scale);
}
protected override Color4 GetComboColour(IReadOnlyList<Color4> comboColours) =>
comboColours[(HitObject.IndexInBeatmap + 1) % comboColours.Count];
}
}

View File

@ -22,8 +22,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject)
{
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
var hitObject = drawableCatchObject.HitObject;
var drawableCatchObject = (DrawablePalpableCatchHitObject)drawableObject;
InternalChild = new Pulp
{
@ -31,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
AccentColour = { BindTarget = drawableObject.AccentColour }
};
if (hitObject.HyperDash)
if (drawableCatchObject.HitObject.HyperDash)
{
AddInternal(new Container
{

View File

@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public const float RADIUS_ADJUST = 1.1f;
private Circle border;
private CatchHitObject hitObject;
private PalpableCatchHitObject hitObject;
public FruitPiece()
{
@ -30,12 +30,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject)
{
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
var drawableCatchObject = (DrawablePalpableCatchHitObject)drawableObject;
hitObject = drawableCatchObject.HitObject;
AddRangeInternal(new[]
{
getFruitFor(drawableCatchObject.HitObject.VisualRepresentation),
getFruitFor(hitObject.VisualRepresentation),
border = new Circle
{
RelativeSizeAxes = Axes.Both,

View File

@ -0,0 +1,29 @@
// 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.
namespace osu.Game.Rulesets.Catch.Objects
{
/// <summary>
/// Represents a single object that can be caught by the catcher.
/// This includes normal fruits, droplets, and bananas but excludes objects that act only as a container of nested hit objects.
/// </summary>
public abstract class PalpableCatchHitObject : CatchHitObject
{
/// <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;
}
}

View File

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

View File

@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Skinning
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject, ISkinSource skin)
{
DrawableCatchHitObject drawableCatchObject = (DrawableCatchHitObject)drawableObject;
var drawableCatchObject = (DrawablePalpableCatchHitObject)drawableObject;
accentColour.BindTo(drawableCatchObject.AccentColour);

View File

@ -220,11 +220,11 @@ namespace osu.Game.Rulesets.Catch.UI
/// <summary>
/// Let the catcher attempt to catch a fruit.
/// </summary>
/// <param name="fruit">The fruit to catch.</param>
/// <param name="hitObject">The fruit to catch.</param>
/// <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;
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())
return;
@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Catch.UI
lastPlateableFruit.OnLoadComplete += _ => action();
}
if (result.IsHit && fruit.HitObject.CanBePlated)
if (result.IsHit && hitObject is DrawablePalpableCatchHitObject fruit)
{
// create a new (cloned) fruit to stay on the plate. the original is faded out immediately.
var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);
@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Catch.UI
if (caughtFruit == null) return;
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.Anchor = Anchor.TopCentre;
@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.Catch.UI
runAfterLoaded(() => MovableCatcher.Explode(caughtFruit));
}
if (fruit.HitObject.LastInCombo)
if (hitObject.HitObject.LastInCombo)
{
if (result.Judgement is CatchJudgement catchJudgement && catchJudgement.ShouldExplodeFor(result))
runAfterLoaded(() => MovableCatcher.Explode());
@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Catch.UI
MovableCatcher.Drop();
}
comboDisplay.OnNewResult(fruit, result);
comboDisplay.OnNewResult(hitObject, result);
}
public void OnRevertResult(DrawableCatchHitObject fruit, JudgementResult result)