Skip to content

Commit

Permalink
ppy#21072: WIP Hit types seems like successfully splitted into two
Browse files Browse the repository at this point in the history
DrawableHit & Hit types splitted into two

TODO:
* correct way (currently not working) for TaikoModSwap
* correct way (currently exception ^~^) for editor
* remove `ChangeType` (at least current realization)
* fix Tests XD
* run benchmarks -- is the changes useful at all?
  • Loading branch information
Nikita-str committed Dec 24, 2024
1 parent 269b0b0 commit 08d19b4
Show file tree
Hide file tree
Showing 17 changed files with 162 additions and 89 deletions.
17 changes: 6 additions & 11 deletions osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,9 @@ protected override IEnumerable<TaikoHitObject> ConvertHitObject(HitObject obj, I
{
IList<HitSampleInfo> currentSamples = allSamples[i];

yield return new Hit
{
StartTime = j,
Samples = currentSamples,
};
Hit hit = Hit.CreateConcreteBySample(currentSamples);
hit.StartTime = j;
yield return hit;

i = (i + 1) % allSamples.Count;

Expand Down Expand Up @@ -161,12 +159,9 @@ protected override IEnumerable<TaikoHitObject> ConvertHitObject(HitObject obj, I

default:
{
yield return new Hit
{
StartTime = obj.StartTime,
Samples = samples,
};

Hit hit = Hit.CreateConcreteBySample(samples);
hit.StartTime = obj.StartTime;
yield return hit;
break;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public partial class HitPlacementBlueprint : HitObjectPlacementBlueprint
public new Hit HitObject => (Hit)base.HitObject;

public HitPlacementBlueprint()
: base(new Hit())
: base(new Hit(HitType.Centre))
{
InternalChild = piece = new HitPiece
{
Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Rulesets.Taiko/Edit/TaikoSelectionHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ public void SetRimState(bool state)
{
if (h is Hit taikoHit)
{
taikoHit.Type = state ? HitType.Rim : HitType.Centre;
// TODO: seems like we should to change type (and pass all fileds between them ://)
taikoHit.ChangeType(state ? HitType.Rim : HitType.Centre);
EditorBeatmap.Update(h);
}
});
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Taiko/Mods/TaikoModRandom.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public void ApplyToBeatmap(IBeatmap beatmap)
foreach (var obj in taikoBeatmap.HitObjects)
{
if (obj is Hit hit)
hit.Type = rng.Next(2) == 0 ? HitType.Centre : HitType.Rim;
hit.ChangeType(rng.Next(2) == 0 ? HitType.Centre : HitType.Rim); // TODO: seems like we should to change type (and pass all fileds between them ://)
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@ public class TaikoModRelax : ModRelax, IApplicableToDrawableHitObject

public void ApplyToDrawableHitObject(DrawableHitObject drawable)
{
var allActions = Enum.GetValues<TaikoAction>();

drawable.HitObjectApplied += dho =>
{
switch (dho)
{
case DrawableHit hit:
hit.HitActions = allActions;
hit.RelaxMod = true;
break;

case DrawableSwell swell:
Expand Down
3 changes: 2 additions & 1 deletion osu.Game.Rulesets.Taiko/Mods/TaikoModSwap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,9 @@ public void ApplyToBeatmap(IBeatmap beatmap)

foreach (var obj in taikoBeatmap.HitObjects)
{
// TODO: seems like we should to change type (and pass all fileds between them ://)
if (obj is Hit hit)
hit.Type = hit.Type == HitType.Centre ? HitType.Rim : HitType.Centre;
hit.ChangeType(hit.Type == HitType.Centre ? HitType.Rim : HitType.Centre);
}
}
}
Expand Down
8 changes: 4 additions & 4 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,9 +77,9 @@ protected override void LoadComplete()
OnNewResult += onNewResult;
}

protected override void RecreatePieces()
protected override void RestorePieceState()
{
base.RecreatePieces();
//base.RestorePieceState(); // TODO:STOP HERE
updateColour();
Height = HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE;
}
Expand Down Expand Up @@ -119,8 +119,8 @@ protected override DrawableHitObject CreateNestedHitObject(HitObject hitObject)
return base.CreateNestedHitObject(hitObject);
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody),
_ => new ElongatedCirclePiece());
protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody), _ => new ElongatedCirclePiece());

public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e) => false;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public DrawableDrumRollTick([CanBeNull] DrumRollTick tick)
FillMode = FillMode.Fit;
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());
protected override SkinnableDrawable OnLoadCreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());

protected override void OnApply()
{
Expand All @@ -45,9 +45,8 @@ protected override void OnApply()
IsFirstTick.Value = HitObject.FirstTick;
}

protected override void RecreatePieces()
protected override void RestorePieceState()
{
base.RecreatePieces();
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
}

Expand Down
34 changes: 32 additions & 2 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableFlyingHit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;

namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
Expand All @@ -12,26 +14,54 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public partial class DrawableFlyingHit : DrawableHit
{
public DrawableFlyingHit(DrawableDrumRollTick drumRollTick)
: base(new IgnoreHit
: base(new IgnoreHit(drumRollTick.JudgementType)
{
StartTime = drumRollTick.HitObject.StartTime + drumRollTick.Result.TimeOffset,
IsStrong = drumRollTick.HitObject.IsStrong,
Type = drumRollTick.JudgementType
})
{
HitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
}

private static float degree = 0f;

protected override void LoadComplete()
{
base.LoadComplete();
ApplyMaxResult();
Size = new osuTK.Vector2(0.3f);
}

protected override void PrepareForUse()
{
const float single_rotation_degree = 7f;

base.PrepareForUse();
degree = (degree + single_rotation_degree) % 360f;
Rotation = degree;
}

protected override void LoadSamples()
{
// block base call - flying hits are not supposed to play samples
// the base call could overwrite the type of this hit
}


//public override TaikoAction[] HitActions { get; protected set; } = Array.Empty<TaikoAction>();
public override TaikoAction[] HitActions
{
//get => HitObject.Type == HitType.Centre ? [TaikoAction.LeftCentre, TaikoAction.RightCentre] : [TaikoAction.LeftRim, TaikoAction.RightRim];
get => [TaikoAction.LeftCentre, TaikoAction.RightCentre, TaikoAction.LeftRim, TaikoAction.RightRim];
protected set { }
}

protected override SkinnableDrawable? OnLoadCreateMainPiece()
//=> null;
//=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece(), confineMode: ConfineMode.ScaleToFit);
//
// TODO: idk, seems like there need to be added new skin component & in it's Animation should be changed it's collor in depends of `hit / this_drum_roll_hits`
// | just like in stable version
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell), _ => new SwellCirclePiece(), confineMode: ConfineMode.ScaleToFit);
}
}
79 changes: 49 additions & 30 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
using System.Diagnostics;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Objects.Drawables;
Expand All @@ -18,12 +17,17 @@

namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public partial class DrawableHit : DrawableTaikoStrongableHitObject<Hit, Hit.StrongNestedHit>
public abstract partial class DrawableHit : DrawableTaikoStrongableHitObject<Hit, Hit.StrongNestedHit>
{
/// <summary>
/// A list of keys which can result in hits for this HitObject.
/// </summary>
public TaikoAction[] HitActions { get; internal set; }
public abstract TaikoAction[] HitActions { get; protected set; }

/// <summary>
/// When this is true any hit is valid.
/// </summary>
public bool RelaxMod = false;

/// <summary>
/// The action that caused this <see cref="DrawableHit"/> to be hit.
Expand All @@ -38,8 +42,6 @@ public TaikoAction? HitAction

private double? lastPressHandleTime;

private readonly Bindable<HitType> type = new Bindable<HitType>();

public DrawableHit()
: this(null)
{
Expand All @@ -53,47 +55,26 @@ public DrawableHit([CanBeNull] Hit hit)

protected override void OnApply()
{
type.BindTo(HitObject.TypeBindable);
// this doesn't need to be run inline as RecreatePieces is called by the base call below.
type.BindValueChanged(_ => Scheduler.AddOnce(RecreatePieces));

base.OnApply();
}

protected override void RecreatePieces()
protected override void RestorePieceState()
{
updateActionsFromType();
base.RecreatePieces();
Size = new Vector2(HitObject.IsStrong ? TaikoStrongableHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE);
}

protected override void OnFree()
{
base.OnFree();

type.UnbindFrom(HitObject.TypeBindable);
type.UnbindEvents();

UnproxyContent();

HitActions = null;
RelaxMod = false;
HitAction = null;
validActionPressed = false;
lastPressHandleTime = null;
}

private void updateActionsFromType()
{
HitActions =
HitObject.Type == HitType.Centre
? new[] { TaikoAction.LeftCentre, TaikoAction.RightCentre }
: new[] { TaikoAction.LeftRim, TaikoAction.RightRim };
}

protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre
? new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
: new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);

protected override void CheckForResult(bool userTriggered, double timeOffset)
{
Debug.Assert(HitObject.HitWindows != null);
Expand All @@ -115,14 +96,16 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)
ApplyResult(result);
}

public bool IsValidAction(TaikoAction action) => RelaxMod || HitActions.Contains(action);

public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
{
if (lastPressHandleTime == Time.Current)
return true;
if (Judged)
return false;

validActionPressed = HitActions.Contains(e.Action);
validActionPressed = IsValidAction(e.Action);

// Only count this as handled if the new judgement is a hit
bool result = UpdateResult(true);
Expand Down Expand Up @@ -237,11 +220,47 @@ public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e)
return false;

// Don't handle invalid hit action presses
if (!ParentHitObject.HitActions.Contains(e.Action))
if (!ParentHitObject.IsValidAction(e.Action))
return false;

return UpdateResult(true);
}
}
}

public partial class DrawableHitCenter : DrawableHit
{
public override TaikoAction[] HitActions { get; protected set; } = { TaikoAction.LeftCentre, TaikoAction.RightCentre };

/// <summary> This constructor exsits only to satisfy Pool where constraints </summary>
public DrawableHitCenter() : base(null) { }

public DrawableHitCenter([CanBeNull] Hit hit)
: base(hit)
{
if (hit != null && hit.Type != HitType.Centre)
throw new ArgumentException("hit must be `Centre`");
}

protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
}

public partial class DrawableHitRim : DrawableHit
{
public override TaikoAction[] HitActions { get; protected set; } = { TaikoAction.LeftRim, TaikoAction.RightRim };

/// <summary> This constructor exsits only to satisfy Pool where constraints </summary>
public DrawableHitRim() : base(null) { }

public DrawableHitRim([CanBeNull] Hit hit)
: base(hit)
{
if (hit != null && hit.Type != HitType.Rim)
throw new ArgumentException("hit must be `Rim`");
}
protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);

}
}
5 changes: 2 additions & 3 deletions osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -136,17 +136,16 @@ private void load(OsuColour colours)
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
}

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell),
protected override SkinnableDrawable OnLoadCreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell),
_ => new SwellCirclePiece
{
// to allow for rotation transform
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
});

protected override void RecreatePieces()
protected override void RestorePieceState()
{
base.RecreatePieces();
Size = baseSize = new Vector2(TaikoHitObject.DEFAULT_SIZE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ protected override void CheckForResult(bool userTriggered, double timeOffset)

public override bool OnPressed(KeyBindingPressEvent<TaikoAction> e) => false;

protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick),
_ => new TickPiece());
protected override SkinnableDrawable OnLoadCreateMainPiece()
=> new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());

protected override void RestorePieceState() { }
}
}
Loading

0 comments on commit 08d19b4

Please sign in to comment.