1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-20 11:03:05 +08:00

Combine Judgement.HitResults into one.

This commit is contained in:
Dean Herbert 2017-09-05 19:44:59 +09:00 committed by smoogipooo
parent d69b8d7784
commit 84c22df3f5
46 changed files with 265 additions and 467 deletions

View File

@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using OpenTK;
@ -110,10 +109,7 @@ namespace osu.Desktop.Tests.Visual
h.Depth = depth++;
if (auto)
{
h.State = ArmedState.Hit;
h.Judgement = new OsuJudgement { Result = HitResult.Hit };
}
playfieldContainer.Add(h);
var proxyable = h as IDrawableHitObjectWithProxiedApproach;

View File

@ -185,7 +185,7 @@ namespace osu.Desktop.Tests.Visual
});
}
protected override TestJudgement CreateJudgement() => new TestJudgement();
protected TestJudgement CreateJudgement() => new TestJudgement();
protected override void UpdateState(ArmedState state)
{
@ -221,8 +221,6 @@ namespace osu.Desktop.Tests.Visual
private class TestJudgement : Judgement
{
public override string ResultString { get { throw new NotImplementedException(); } }
public override string MaxResultString { get { throw new NotImplementedException(); } }
}
}
}

View File

@ -128,7 +128,7 @@ namespace osu.Desktop.Tests.Visual
private void addHitJudgement(bool kiai)
{
TaikoHitResult hitResult = RNG.Next(2) == 0 ? TaikoHitResult.Good : TaikoHitResult.Great;
HitResult hitResult = RNG.Next(2) == 0 ? HitResult.Good : HitResult.Great;
var cpi = new ControlPointInfo();
cpi.EffectPoints.Add(new EffectControlPoint
@ -141,11 +141,10 @@ namespace osu.Desktop.Tests.Visual
var h = new DrawableTestHit(hit)
{
X = RNG.NextSingle(hitResult == TaikoHitResult.Good ? -0.1f : -0.05f, hitResult == TaikoHitResult.Good ? 0.1f : 0.05f),
X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f),
Judgement = new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = hitResult,
Result = hitResult,
TimeOffset = 0
}
};
@ -237,7 +236,7 @@ namespace osu.Desktop.Tests.Visual
{
}
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
protected TaikoJudgement CreateJudgement() => new TaikoJudgement();
protected override void UpdateState(ArmedState state)
{

View File

@ -7,8 +7,6 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
public class CatchJudgement : Judgement
{
public override string ResultString => string.Empty;
public override string MaxResultString => string.Empty;
// todo: wangs
}
}

View File

@ -98,14 +98,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
};
}
protected override CatchJudgement CreateJudgement() => new CatchJudgement();
private const float preempt = 1000;
protected override void CheckJudgement(bool userTriggered)
{
if (Judgement.TimeOffset > 0)
Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Hit : HitResult.Miss;
Judgement.Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss;
}
protected override void UpdateState(ArmedState state)

View File

@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.UI
private void Fruit_OnJudgement(DrawableHitObject<CatchBaseHit, CatchJudgement> obj)
{
if (obj.Judgement.Result == HitResult.Hit)
if (obj.Judgement.Result > HitResult.Miss)
{
Vector2 screenPosition = obj.ScreenSpaceDrawQuad.Centre;
Remove(obj);

View File

@ -2,6 +2,7 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Judgements
{
@ -145,18 +146,18 @@ namespace osu.Game.Rulesets.Mania.Judgements
/// </summary>
/// <param name="hitOffset">The time offset.</param>
/// <returns>The hit result, or null if the time offset results in a miss.</returns>
public ManiaHitResult? ResultFor(double hitOffset)
public HitResult? ResultFor(double hitOffset)
{
if (hitOffset <= Perfect / 2)
return ManiaHitResult.Perfect;
return HitResult.Perfect;
if (hitOffset <= Great / 2)
return ManiaHitResult.Great;
return HitResult.Great;
if (hitOffset <= Good / 2)
return ManiaHitResult.Good;
return HitResult.Good;
if (hitOffset <= Ok / 2)
return ManiaHitResult.Ok;
return HitResult.Ok;
if (hitOffset <= Bad / 2)
return ManiaHitResult.Bad;
return HitResult.Meh;
return null;
}

View File

@ -1,6 +1,8 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Judgements
{
public class HoldNoteTailJudgement : ManiaJudgement
@ -10,27 +12,27 @@ namespace osu.Game.Rulesets.Mania.Judgements
/// </summary>
public bool HasBroken;
public override int NumericResultForScore(ManiaHitResult result)
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
default:
return base.NumericResultForScore(result);
case ManiaHitResult.Great:
case ManiaHitResult.Perfect:
return base.NumericResultForScore(HasBroken ? ManiaHitResult.Good : result);
return base.NumericResultFor(result);
case HitResult.Great:
case HitResult.Perfect:
return base.NumericResultFor(HasBroken ? HitResult.Good : result);
}
}
public override int NumericResultForAccuracy(ManiaHitResult result)
protected override int NumericResultForAccuracy(HitResult result)
{
switch (result)
{
default:
return base.NumericResultForAccuracy(result);
case ManiaHitResult.Great:
case ManiaHitResult.Perfect:
return base.NumericResultForAccuracy(HasBroken ? ManiaHitResult.Good : result);
case HitResult.Great:
case HitResult.Perfect:
return base.NumericResultForAccuracy(HasBroken ? HitResult.Good : result);
}
}
}

View File

@ -1,13 +1,15 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Judgements
{
public class HoldNoteTickJudgement : ManiaJudgement
{
public override bool AffectsCombo => false;
public override int NumericResultForScore(ManiaHitResult result) => 20;
public override int NumericResultForAccuracy(ManiaHitResult result) => 0; // Don't count ticks into accuracy
protected override int NumericResultFor(HitResult result) => 20;
protected override int NumericResultForAccuracy(HitResult result) => 0; // Don't count ticks into accuracy
}
}

View File

@ -1,21 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
namespace osu.Game.Rulesets.Mania.Judgements
{
public enum ManiaHitResult
{
[Description("PERFECT")]
Perfect,
[Description("GREAT")]
Great,
[Description("GOOD")]
Good,
[Description("OK")]
Ok,
[Description("BAD")]
Bad
}
}

View File

@ -8,73 +8,49 @@ namespace osu.Game.Rulesets.Mania.Judgements
{
public class ManiaJudgement : Judgement
{
/// <summary>
/// The maximum possible hit result.
/// </summary>
public const ManiaHitResult MAX_HIT_RESULT = ManiaHitResult.Perfect;
/// <summary>
/// The result value for the combo portion of the score.
/// </summary>
public int ResultValueForScore => Result == HitResult.Miss ? 0 : NumericResultForScore(ManiaResult);
/// <summary>
/// The result value for the accuracy portion of the score.
/// </summary>
public int ResultValueForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(ManiaResult);
/// <summary>
/// The maximum result value for the combo portion of the score.
/// </summary>
public int MaxResultValueForScore => NumericResultForScore(MAX_HIT_RESULT);
/// <summary>
/// The maximum result value for the accuracy portion of the score.
/// </summary>
public int MaxResultValueForAccuracy => NumericResultForAccuracy(MAX_HIT_RESULT);
public int MaxNumericAccuracyResult => NumericResultForAccuracy(HitResult.Perfect);
public override string ResultString => string.Empty;
public override string MaxResultString => string.Empty;
/// <summary>
/// The hit result.
/// </summary>
public ManiaHitResult ManiaResult;
public virtual int NumericResultForScore(ManiaHitResult result)
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
default:
return 0;
case ManiaHitResult.Bad:
case HitResult.Meh:
return 50;
case ManiaHitResult.Ok:
case HitResult.Ok:
return 100;
case ManiaHitResult.Good:
case HitResult.Good:
return 200;
case ManiaHitResult.Great:
case ManiaHitResult.Perfect:
case HitResult.Great:
case HitResult.Perfect:
return 300;
}
}
public virtual int NumericResultForAccuracy(ManiaHitResult result)
public int NumericAccuracyResult => NumericResultForAccuracy(Result);
/// <summary>
/// The result value for the accuracy portion of the score.
/// </summary>
protected virtual int NumericResultForAccuracy(HitResult result)
{
switch (result)
{
default:
return 0;
case ManiaHitResult.Bad:
case HitResult.Meh:
return 50;
case ManiaHitResult.Ok:
case HitResult.Ok:
return 100;
case ManiaHitResult.Good:
case HitResult.Good:
return 200;
case ManiaHitResult.Great:
case HitResult.Great:
return 300;
case ManiaHitResult.Perfect:
case HitResult.Perfect:
return 305;
}
}

View File

@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Y = 0;
}
protected override ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement();
protected ManiaJudgement CreateJudgement() => new HoldNoteTailJudgement();
protected override void CheckJudgement(bool userTriggered)
{

View File

@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
}
}
protected override ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement();
protected ManiaJudgement CreateJudgement() => new HoldNoteTickJudgement();
protected override void CheckJudgement(bool userTriggered)
{
@ -93,8 +93,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (HoldStartTime?.Invoke() > HitObject.StartTime)
return;
Judgement.ManiaResult = ManiaHitResult.Perfect;
Judgement.Result = HitResult.Hit;
Judgement.Result = HitResult.Perfect;
}
protected override void UpdateState(ArmedState state)

View File

@ -36,7 +36,5 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
base.AccentColour = value;
}
}
protected override ManiaJudgement CreateJudgement() => new ManiaJudgement();
}
}

View File

@ -5,7 +5,6 @@ using System;
using OpenTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Objects.Drawables;
@ -58,15 +57,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
if (offset > HitObject.HitWindows.Miss / 2)
return;
ManiaHitResult? tmpResult = HitObject.HitWindows.ResultFor(offset);
if (tmpResult.HasValue)
{
Judgement.Result = HitResult.Hit;
Judgement.ManiaResult = tmpResult.Value;
}
else
Judgement.Result = HitResult.Miss;
Judgement.Result = HitObject.HitWindows.ResultFor(offset) ?? HitResult.Miss;
}
protected override void UpdateState(ArmedState state)

View File

@ -174,37 +174,19 @@ namespace osu.Game.Rulesets.Mania.Scoring
if (obj is Note)
{
AddJudgement(new ManiaJudgement
{
Result = HitResult.Hit,
ManiaResult = ManiaHitResult.Perfect
});
AddJudgement(new ManiaJudgement { Result = HitResult.Perfect });
}
else if (holdNote != null)
{
// Head
AddJudgement(new ManiaJudgement
{
Result = HitResult.Hit,
ManiaResult = ManiaJudgement.MAX_HIT_RESULT
});
AddJudgement(new ManiaJudgement { Result = HitResult.Perfect });
// Ticks
int tickCount = holdNote.Ticks.Count();
for (int i = 0; i < tickCount; i++)
{
AddJudgement(new HoldNoteTickJudgement
{
Result = HitResult.Hit,
ManiaResult = ManiaJudgement.MAX_HIT_RESULT,
});
}
AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect });
AddJudgement(new HoldNoteTailJudgement
{
Result = HitResult.Hit,
ManiaResult = ManiaJudgement.MAX_HIT_RESULT
});
AddJudgement(new HoldNoteTailJudgement { Result = HitResult.Perfect });
}
}
@ -225,46 +207,46 @@ namespace osu.Game.Rulesets.Mania.Scoring
{
bool isTick = judgement is HoldNoteTickJudgement;
if (!isTick)
if (isTick)
{
if (judgement.IsHit)
{
Health.Value += hpMultiplier * hp_increase_tick;
bonusScore += judgement.NumericResult;
}
}
else
{
totalHits++;
switch (judgement.Result)
{
case HitResult.Miss:
Health.Value += hpMissMultiplier * hp_increase_miss;
break;
case HitResult.Hit:
if (isTick)
{
Health.Value += hpMultiplier * hp_increase_tick;
bonusScore += judgement.ResultValueForScore;
}
else
{
switch (judgement.ManiaResult)
{
case ManiaHitResult.Bad:
Health.Value += hpMultiplier * hp_increase_bad;
break;
case ManiaHitResult.Ok:
Health.Value += hpMultiplier * hp_increase_ok;
break;
case ManiaHitResult.Good:
Health.Value += hpMultiplier * hp_increase_good;
break;
case ManiaHitResult.Great:
Health.Value += hpMultiplier * hp_increase_great;
break;
case ManiaHitResult.Perfect:
Health.Value += hpMultiplier * hp_increase_perfect;
break;
}
switch (judgement.Result)
{
case HitResult.Miss:
Health.Value += hpMissMultiplier * hp_increase_miss;
break;
case HitResult.Meh:
Health.Value += hpMultiplier * hp_increase_bad;
break;
case HitResult.Ok:
Health.Value += hpMultiplier * hp_increase_ok;
break;
case HitResult.Good:
Health.Value += hpMultiplier * hp_increase_good;
break;
case HitResult.Great:
Health.Value += hpMultiplier * hp_increase_great;
break;
case HitResult.Perfect:
Health.Value += hpMultiplier * hp_increase_perfect;
break;
}
// A factor that is applied to make higher combos more relevant
double comboRelevance = Math.Min(Math.Max(0.5, Math.Log(Combo.Value, combo_base)), Math.Log(combo_relevance_cap, combo_base));
comboPortion += judgement.ResultValueForScore * comboRelevance;
}
break;
if (judgement.IsHit)
{
// A factor that is applied to make higher combos more relevant
double comboRelevance = Math.Min(Math.Max(0.5, Math.Log(Combo.Value, combo_base)), Math.Log(combo_relevance_cap, combo_base));
comboPortion += judgement.NumericResult * comboRelevance;
}
}
int scoreForAccuracy = 0;
@ -272,8 +254,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
foreach (var j in Judgements)
{
scoreForAccuracy += j.ResultValueForAccuracy;
maxScoreForAccuracy += j.MaxResultValueForAccuracy;
scoreForAccuracy += j.NumericAccuracyResult;
maxScoreForAccuracy += j.MaxNumericAccuracyResult;
}
Accuracy.Value = (double)scoreForAccuracy / maxScoreForAccuracy;

View File

@ -60,7 +60,6 @@
<Compile Include="Judgements\HitWindows.cs" />
<Compile Include="Judgements\HoldNoteTailJudgement.cs" />
<Compile Include="Judgements\HoldNoteTickJudgement.cs" />
<Compile Include="Judgements\ManiaHitResult.cs" />
<Compile Include="Judgements\ManiaJudgement.cs" />
<Compile Include="ManiaDifficultyCalculator.cs" />
<Compile Include="Mods\IGenerateSpeedAdjustments.cs" />

View File

@ -4,10 +4,14 @@
using OpenTK;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Framework.Extensions;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Judgements
{
public class SliderTickJudgement : OsuJudgement
{
}
public class OsuJudgement : Judgement
{
/// <summary>
@ -15,38 +19,18 @@ namespace osu.Game.Rulesets.Osu.Judgements
/// </summary>
public Vector2 PositionOffset;
/// <summary>
/// The score the user achieved.
/// </summary>
public OsuScoreResult Score;
/// <summary>
/// The score which would be achievable on a perfect hit.
/// </summary>
public OsuScoreResult MaxScore = OsuScoreResult.Hit300;
public override string ResultString => Score.GetDescription();
public override string MaxResultString => MaxScore.GetDescription();
public int ScoreValue => scoreToInt(Score);
public int MaxScoreValue => scoreToInt(MaxScore);
private int scoreToInt(OsuScoreResult result)
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
default:
return 0;
case OsuScoreResult.Hit50:
case HitResult.Meh:
return 50;
case OsuScoreResult.Hit100:
case HitResult.Good:
return 100;
case OsuScoreResult.Hit300:
case HitResult.Great:
return 300;
case OsuScoreResult.SliderTick:
return 10;
}
}

View File

@ -69,20 +69,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
if (!userTriggered)
{
if (Judgement.TimeOffset > HitObject.HitWindowFor(OsuScoreResult.Hit50))
if (Judgement.TimeOffset > HitObject.HitWindowFor(HitResult.Meh))
Judgement.Result = HitResult.Miss;
return;
}
double hitOffset = Math.Abs(Judgement.TimeOffset);
if (hitOffset < HitObject.HitWindowFor(OsuScoreResult.Hit50))
{
Judgement.Result = HitResult.Hit;
Judgement.Score = HitObject.ScoreResultForOffset(hitOffset);
}
else
Judgement.Result = HitResult.Miss;
Judgement.Result = HitObject.ScoreResultForOffset(Math.Abs(Judgement.TimeOffset));
}
protected override void UpdateInitialState()

View File

@ -21,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Alpha = 0;
}
protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.Hit300 };
protected sealed override void UpdateState(ArmedState state)
{
FinishTransforms();
@ -65,18 +63,4 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
[Description(@"Amazing")]
Perfect
}
public enum OsuScoreResult
{
[Description(@"Miss")]
Miss,
[Description(@"50")]
Hit50,
[Description(@"100")]
Hit100,
[Description(@"300")]
Hit300,
[Description(@"10")]
SliderTick
}
}

View File

@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
bouncer2.Position = slider.Curve.PositionAt(body.SnakedEnd ?? 0);
//todo: we probably want to reconsider this before adding scoring, but it looks and feels nice.
if (initialCircle.Judgement?.Result != HitResult.Hit)
if (initialCircle.Judgement?.Result <= HitResult.Miss)
initialCircle.Position = slider.Curve.PositionAt(progress);
foreach (var c in components) c.UpdateProgress(progress, repeat);
@ -126,21 +126,19 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (!userTriggered && Time.Current >= slider.EndTime)
{
var ticksCount = ticks.Children.Count + 1;
var ticksHit = ticks.Children.Count(t => t.Judgement.Result == HitResult.Hit);
if (initialCircle.Judgement.Result == HitResult.Hit)
var ticksHit = ticks.Children.Count(t => t.Judgement.Result > HitResult.Miss);
if (initialCircle.Judgement.Result > HitResult.Miss)
ticksHit++;
var hitFraction = (double)ticksHit / ticksCount;
if (hitFraction == 1 && initialCircle.Judgement.Score == OsuScoreResult.Hit300)
Judgement.Score = OsuScoreResult.Hit300;
else if (hitFraction >= 0.5 && initialCircle.Judgement.Score >= OsuScoreResult.Hit100)
Judgement.Score = OsuScoreResult.Hit100;
if (hitFraction == 1 && initialCircle.Judgement.Result == HitResult.Great)
Judgement.Result = HitResult.Great;
else if (hitFraction >= 0.5 && initialCircle.Judgement.Result >= HitResult.Good)
Judgement.Result = HitResult.Good;
else if (hitFraction > 0)
Judgement.Score = OsuScoreResult.Hit50;
Judgement.Result = HitResult.Meh;
else
Judgement.Score = OsuScoreResult.Miss;
Judgement.Result = Judgement.Score != OsuScoreResult.Miss ? HitResult.Hit : HitResult.Miss;
Judgement.Result = HitResult.Miss;
}
}

View File

@ -4,7 +4,6 @@
using System;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Osu.Judgements;
using OpenTK;
using OpenTK.Graphics;
using osu.Framework.Graphics.Shapes;
@ -22,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
public override bool RemoveWhenNotAlive => false;
protected override OsuJudgement CreateJudgement() => new OsuJudgement { MaxScore = OsuScoreResult.SliderTick };
public DrawableSliderTick(SliderTick sliderTick) : base(sliderTick)
{
this.sliderTick = sliderTick;
@ -52,10 +49,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
protected override void CheckJudgement(bool userTriggered)
{
if (Judgement.TimeOffset >= 0)
{
Judgement.Result = Tracking ? HitResult.Hit : HitResult.Miss;
Judgement.Score = Tracking ? OsuScoreResult.SliderTick : OsuScoreResult.Miss;
}
Judgement.Result = Tracking ? HitResult.Perfect : HitResult.Miss;
}
protected override void UpdatePreemptState()

View File

@ -129,26 +129,13 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
if (!userTriggered && Time.Current >= spinner.EndTime)
{
if (Progress >= 1)
{
Judgement.Score = OsuScoreResult.Hit300;
Judgement.Result = HitResult.Hit;
}
Judgement.Result = HitResult.Great;
else if (Progress > .9)
{
Judgement.Score = OsuScoreResult.Hit100;
Judgement.Result = HitResult.Hit;
}
Judgement.Result = HitResult.Good;
else if (Progress > .75)
{
Judgement.Score = OsuScoreResult.Hit50;
Judgement.Result = HitResult.Hit;
}
else
{
Judgement.Score = OsuScoreResult.Miss;
if (Time.Current >= spinner.EndTime)
Judgement.Result = HitResult.Miss;
}
Judgement.Result = HitResult.Meh;
else if (Time.Current >= spinner.EndTime)
Judgement.Result = HitResult.Miss;
}
}

View File

@ -4,10 +4,10 @@
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using OpenTK;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using OpenTK.Graphics;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Objects
{
@ -42,30 +42,30 @@ namespace osu.Game.Rulesets.Osu.Objects
public virtual bool NewCombo { get; set; }
public int ComboIndex { get; set; }
public double HitWindowFor(OsuScoreResult result)
public double HitWindowFor(HitResult result)
{
switch (result)
{
default:
return 300;
case OsuScoreResult.Hit50:
case HitResult.Meh:
return 150;
case OsuScoreResult.Hit100:
case HitResult.Good:
return 80;
case OsuScoreResult.Hit300:
case HitResult.Great:
return 30;
}
}
public OsuScoreResult ScoreResultForOffset(double offset)
public HitResult ScoreResultForOffset(double offset)
{
if (offset < HitWindowFor(OsuScoreResult.Hit300))
return OsuScoreResult.Hit300;
if (offset < HitWindowFor(OsuScoreResult.Hit100))
return OsuScoreResult.Hit100;
if (offset < HitWindowFor(OsuScoreResult.Hit50))
return OsuScoreResult.Hit50;
return OsuScoreResult.Miss;
if (offset < HitWindowFor(HitResult.Great))
return HitResult.Great;
if (offset < HitWindowFor(HitResult.Good))
return HitResult.Good;
if (offset < HitWindowFor(HitResult.Meh))
return HitResult.Meh;
return HitResult.Miss;
}
public override void ApplyDefaults(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)

View File

@ -9,6 +9,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables;
using System;
using System.Diagnostics;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Replays;
@ -89,20 +90,20 @@ namespace osu.Game.Rulesets.Osu.Replays
double endTime = (prev as IHasEndTime)?.EndTime ?? prev.StartTime;
// Make the cursor stay at a hitObject as long as possible (mainly for autopilot).
if (h.StartTime - h.HitWindowFor(OsuScoreResult.Miss) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50)
if (h.StartTime - h.HitWindowFor(HitResult.Miss) > endTime + h.HitWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Miss), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Meh), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Miss), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
}
else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50) > endTime + h.HitWindowFor(OsuScoreResult.Hit50) + 50)
else if (h.StartTime - h.HitWindowFor(HitResult.Meh) > endTime + h.HitWindowFor(HitResult.Meh) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit50), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit50), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Meh), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Meh), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
}
else if (h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100) > endTime + h.HitWindowFor(OsuScoreResult.Hit100) + 50)
else if (h.StartTime - h.HitWindowFor(HitResult.Good) > endTime + h.HitWindowFor(HitResult.Good) + 50)
{
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(OsuScoreResult.Hit100), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(OsuScoreResult.Hit100), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
if (!(prev is Spinner) && h.StartTime - endTime < 1000) AddFrameToReplay(new ReplayFrame(endTime + h.HitWindowFor(HitResult.Good), prev.StackedEndPosition.X, prev.StackedEndPosition.Y, ReplayButtonState.None));
if (!(h is Spinner)) AddFrameToReplay(new ReplayFrame(h.StartTime - h.HitWindowFor(HitResult.Good), h.StackedPosition.X, h.StackedPosition.Y, ReplayButtonState.None));
}
}

View File

@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
private int totalAccurateJudgements;
private readonly Dictionary<OsuScoreResult, int> scoreResultCounts = new Dictionary<OsuScoreResult, int>();
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
private readonly Dictionary<ComboResult, int> comboResultCounts = new Dictionary<ComboResult, int>();
private double comboMaxScore;
@ -45,12 +45,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
foreach (var h in beatmap.HitObjects)
{
// TODO: add support for other object types.
AddJudgement(new OsuJudgement
{
MaxScore = OsuScoreResult.Hit300,
Score = OsuScoreResult.Hit300,
Result = HitResult.Hit
});
AddJudgement(new OsuJudgement { Result = HitResult.Great });
}
}
@ -69,10 +64,10 @@ namespace osu.Game.Rulesets.Osu.Scoring
{
base.PopulateScore(score);
score.Statistics[@"300"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit300);
score.Statistics[@"100"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit100);
score.Statistics[@"50"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Hit50);
score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(OsuScoreResult.Miss);
score.Statistics[@"300"] = scoreResultCounts.GetOrDefault(HitResult.Great);
score.Statistics[@"100"] = scoreResultCounts.GetOrDefault(HitResult.Good);
score.Statistics[@"50"] = scoreResultCounts.GetOrDefault(HitResult.Meh);
score.Statistics[@"x"] = scoreResultCounts.GetOrDefault(HitResult.Miss);
}
protected override void OnNewJudgement(OsuJudgement judgement)
@ -81,29 +76,29 @@ namespace osu.Game.Rulesets.Osu.Scoring
{
if (judgement.Result != HitResult.None)
{
scoreResultCounts[judgement.Score] = scoreResultCounts.GetOrDefault(judgement.Score) + 1;
scoreResultCounts[judgement.Result] = scoreResultCounts.GetOrDefault(judgement.Result) + 1;
comboResultCounts[judgement.Combo] = comboResultCounts.GetOrDefault(judgement.Combo) + 1;
}
switch (judgement.Score)
switch (judgement.Result)
{
case OsuScoreResult.Hit300:
case HitResult.Great:
Health.Value += (10.2 - hpDrainRate) * 0.02;
break;
case OsuScoreResult.Hit100:
case HitResult.Good:
Health.Value += (8 - hpDrainRate) * 0.02;
break;
case OsuScoreResult.Hit50:
case HitResult.Meh:
Health.Value += (4 - hpDrainRate) * 0.02;
break;
case OsuScoreResult.SliderTick:
/*case HitResult.SliderTick:
Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01;
break;
break;*/
case OsuScoreResult.Miss:
case HitResult.Miss:
Health.Value -= hpDrainRate * 0.04;
break;
}
@ -123,10 +118,10 @@ namespace osu.Game.Rulesets.Osu.Scoring
foreach (var j in Judgements)
{
baseScore += j.ScoreValue;
baseMaxScore += j.MaxScoreValue;
baseScore += j.NumericResult;
baseMaxScore += j.MaxNumericResult;
comboScore += j.ScoreValue * (1 + Combo.Value / 10d);
comboScore += j.NumericResult * (1 + Combo.Value / 10d);
}
Accuracy.Value = (double)baseScore / baseMaxScore;

View File

@ -1,34 +1,26 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoDrumRollTickJudgement : TaikoJudgement
{
/// <summary>
/// Drum roll ticks don't display judgement text.
/// </summary>
public override string ResultString => string.Empty;
/// <summary>
/// Drum roll ticks don't display judgement text.
/// </summary>
public override string MaxResultString => string.Empty;
public override bool AffectsCombo => false;
protected override int NumericResultForScore(TaikoHitResult result)
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
default:
return 0;
case TaikoHitResult.Great:
case HitResult.Great:
return 200;
}
}
protected override int NumericResultForAccuracy(TaikoHitResult result)
protected override int NumericResultForAccuracy(HitResult result)
{
return 0;
}

View File

@ -1,15 +0,0 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.ComponentModel;
namespace osu.Game.Rulesets.Taiko.Judgements
{
public enum TaikoHitResult
{
[Description("GOOD")]
Good,
[Description("GREAT")]
Great
}
}

View File

@ -2,46 +2,21 @@
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using osu.Game.Rulesets.Judgements;
using osu.Framework.Extensions;
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoJudgement : Judgement
{
/// <summary>
/// The maximum result.
/// </summary>
public const TaikoHitResult MAX_HIT_RESULT = TaikoHitResult.Great;
/// <summary>
/// The result.
/// </summary>
public TaikoHitResult TaikoResult;
/// <summary>
/// The result value for the combo portion of the score.
/// </summary>
public int ResultValueForScore => Result == HitResult.Miss ? 0 : NumericResultForScore(TaikoResult);
/// <summary>
/// The result value for the accuracy portion of the score.
/// </summary>
public int ResultValueForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(TaikoResult);
/// <summary>
/// The maximum result value for the combo portion of the score.
/// </summary>
public int MaxResultValueForScore => NumericResultForScore(MAX_HIT_RESULT);
public int ResultNumericForAccuracy => Result == HitResult.Miss ? 0 : NumericResultForAccuracy(Result);
/// <summary>
/// The maximum result value for the accuracy portion of the score.
/// </summary>
public int MaxResultValueForAccuracy => NumericResultForAccuracy(MAX_HIT_RESULT);
public override string ResultString => TaikoResult.GetDescription();
public override string MaxResultString => MAX_HIT_RESULT.GetDescription();
public int MaxResultValueForAccuracy => NumericResultForAccuracy(HitResult.Great);
/// <summary>
/// Whether this Judgement has a secondary hit in the case of strong hits.
@ -50,38 +25,38 @@ namespace osu.Game.Rulesets.Taiko.Judgements
/// <summary>
/// Computes the numeric result value for the combo portion of the score.
/// For the accuracy portion of the score (including accuracy percentage), see <see cref="NumericResultForAccuracy(TaikoHitResult)"/>.
/// For the accuracy portion of the score (including accuracy percentage), see <see cref="NumericResultForAccuracy(HitResult)"/>.
/// </summary>
/// <param name="result">The result to compute the value for.</param>
/// <returns>The numeric result value.</returns>
protected virtual int NumericResultForScore(TaikoHitResult result)
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
default:
return 0;
case TaikoHitResult.Good:
case HitResult.Good:
return 100;
case TaikoHitResult.Great:
case HitResult.Great:
return 300;
}
}
/// <summary>
/// Computes the numeric result value for the accuracy portion of the score.
/// For the combo portion of the score, see <see cref="NumericResultForScore(TaikoHitResult)"/>.
/// For the combo portion of the score, see <see cref="NumericResultFor(HitResult)"/>.
/// </summary>
/// <param name="result">The result to compute the value for.</param>
/// <returns>The numeric result value.</returns>
protected virtual int NumericResultForAccuracy(TaikoHitResult result)
protected virtual int NumericResultForAccuracy(HitResult result)
{
switch (result)
{
default:
return 0;
case TaikoHitResult.Good:
case HitResult.Good:
return 150;
case TaikoHitResult.Great:
case HitResult.Great:
return 300;
}
}

View File

@ -58,8 +58,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
};
}
protected override TaikoJudgement CreateJudgement() => null;
protected override void UpdateState(ArmedState state)
{
}

View File

@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
}
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
protected TaikoJudgement CreateJudgement() => new TaikoJudgement { SecondHit = HitObject.IsStrong };
protected override TaikoPiece CreateMainPiece() => new ElongatedCirclePiece();
@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
private void onTickJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> obj)
{
if (obj.Judgement.Result == HitResult.Hit)
if (obj.Judgement.Result > HitResult.Miss)
rollingHits++;
else
rollingHits--;
@ -86,12 +86,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
if (Judgement.TimeOffset < 0)
return;
int countHit = NestedHitObjects.Count(o => o.Judgement.Result == HitResult.Hit);
int countHit = NestedHitObjects.Count(o => o.Judgement.Result > HitResult.Miss);
if (countHit > HitObject.RequiredGoodHits)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = countHit >= HitObject.RequiredGreatHits ? TaikoHitResult.Great : TaikoHitResult.Good;
Judgement.Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good;
}
else
Judgement.Result = HitResult.Miss;

View File

@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
Filled = HitObject.FirstTick
};
protected override TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = HitObject.IsStrong };
protected TaikoJudgement CreateJudgement() => new TaikoDrumRollTickJudgement { SecondHit = HitObject.IsStrong };
protected override void CheckJudgement(bool userTriggered)
{
@ -42,10 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return;
if (Math.Abs(Judgement.TimeOffset) < HitObject.HitWindow)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = TaikoHitResult.Great;
}
Judgement.Result = HitResult.Great;
}
protected override void UpdateState(ArmedState state)

View File

@ -5,7 +5,6 @@ using System;
using System.Linq;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
@ -45,10 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
if (!validKeyPressed)
Judgement.Result = HitResult.Miss;
else if (hitOffset < HitObject.HitWindowGood)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = hitOffset < HitObject.HitWindowGreat ? TaikoHitResult.Great : TaikoHitResult.Good;
}
Judgement.Result = hitOffset < HitObject.HitWindowGreat ? HitResult.Great : HitResult.Good;
else
Judgement.Result = HitResult.Miss;
}

View File

@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
}
protected override TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement();
protected TaikoJudgement CreateJudgement() => new TaikoStrongHitJudgement();
protected override void CheckJudgement(bool userTriggered)
{

View File

@ -9,7 +9,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects.Drawables.Pieces;
using OpenTK;
using OpenTK.Graphics;
@ -153,10 +152,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
expandingRing.ScaleTo(1f + Math.Min(target_ring_scale - 1f, (target_ring_scale - 1f) * completion * 1.3f), 260, Easing.OutQuint);
if (userHits == HitObject.RequiredHits)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = TaikoHitResult.Great;
}
Judgement.Result = HitResult.Great;
}
else
{
@ -165,10 +161,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
//TODO: THIS IS SHIT AND CAN'T EXIST POST-TAIKO WORLD CUP
if (userHits > HitObject.RequiredHits / 2)
{
Judgement.Result = HitResult.Hit;
Judgement.TaikoResult = TaikoHitResult.Good;
}
Judgement.Result = HitResult.Good;
else
Judgement.Result = HitResult.Miss;
}

View File

@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
MainPiece.KiaiMode = HitObject.Kiai;
}
protected override TaikoJudgement CreateJudgement() => new TaikoJudgement();
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
public abstract bool OnPressed(TaikoAction action);

View File

@ -36,12 +36,12 @@ namespace osu.Game.Rulesets.Taiko.Scoring
private const double combo_base = 4;
/// <summary>
/// The HP awarded by a <see cref="TaikoHitResult.Great"/> hit.
/// The HP awarded by a <see cref="HitResult.Great"/> hit.
/// </summary>
private const double hp_hit_great = 0.03;
/// <summary>
/// The HP awarded for a <see cref="TaikoHitResult.Good"/> hit.
/// The HP awarded for a <see cref="HitResult.Good"/> hit.
/// </summary>
private const double hp_hit_good = 0.011;
@ -140,8 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
{
AddJudgement(new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = TaikoHitResult.Great,
Result = HitResult.Great,
SecondHit = obj.IsStrong
});
}
@ -151,26 +150,20 @@ namespace osu.Game.Rulesets.Taiko.Scoring
{
AddJudgement(new TaikoDrumRollTickJudgement
{
Result = HitResult.Hit,
TaikoResult = TaikoHitResult.Great,
Result = HitResult.Great,
SecondHit = obj.IsStrong
});
}
AddJudgement(new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = TaikoHitResult.Great,
Result = HitResult.Great,
SecondHit = obj.IsStrong
});
}
else if (obj is Swell)
{
AddJudgement(new TaikoJudgement
{
Result = HitResult.Hit,
TaikoResult = TaikoHitResult.Great
});
AddJudgement(new TaikoJudgement { Result = HitResult.Great });
}
}
@ -197,19 +190,14 @@ namespace osu.Game.Rulesets.Taiko.Scoring
if (!isTick)
Health.Value += hpIncreaseMiss;
break;
case HitResult.Hit:
switch (judgement.TaikoResult)
{
case TaikoHitResult.Good:
Health.Value += hpIncreaseGood;
break;
case TaikoHitResult.Great:
if (isTick)
Health.Value += hpIncreaseTick;
else
Health.Value += hpIncreaseGreat;
break;
}
case HitResult.Good:
Health.Value += hpIncreaseGood;
break;
case HitResult.Great:
if (isTick)
Health.Value += hpIncreaseTick;
else
Health.Value += hpIncreaseGreat;
break;
}
@ -226,10 +214,10 @@ namespace osu.Game.Rulesets.Taiko.Scoring
private void addHitScore(TaikoJudgement judgement)
{
if (judgement.Result != HitResult.Hit)
if (!judgement.IsHit)
return;
double baseValue = judgement.ResultValueForScore;
double baseValue = judgement.NumericResult;
// Add increased score for hitting a strong hit object with the second key
if (judgement.SecondHit)
@ -255,7 +243,7 @@ namespace osu.Game.Rulesets.Taiko.Scoring
foreach (var j in Judgements)
{
scoreForAccuracy += j.ResultValueForAccuracy;
scoreForAccuracy += j.ResultNumericForAccuracy;
maxScoreForAccuracy += j.MaxResultValueForAccuracy;
}

View File

@ -29,28 +29,19 @@ namespace osu.Game.Rulesets.Taiko.UI
{
switch (Judgement.Result)
{
case HitResult.Hit:
switch (Judgement.TaikoResult)
{
case TaikoHitResult.Good:
Colour = colours.GreenLight;
break;
case TaikoHitResult.Great:
Colour = colours.BlueLight;
break;
}
case HitResult.Good:
Colour = colours.GreenLight;
break;
case HitResult.Great:
Colour = colours.BlueLight;
break;
}
}
protected override void LoadComplete()
{
switch (Judgement.Result)
{
case HitResult.Hit:
this.MoveToY(-100, 500);
break;
}
if (Judgement.IsHit)
this.MoveToY(-100, 500);
base.LoadComplete();
}

View File

@ -220,7 +220,7 @@ namespace osu.Game.Rulesets.Taiko.UI
public override void OnJudgement(DrawableHitObject<TaikoHitObject, TaikoJudgement> judgedObject)
{
bool wasHit = judgedObject.Judgement.Result == HitResult.Hit;
bool wasHit = judgedObject.Judgement.Result > HitResult.Miss;
bool secondHit = judgedObject.Judgement.SecondHit;
judgementContainer.Add(new DrawableTaikoJudgement(judgedObject.Judgement)

View File

@ -52,7 +52,6 @@
<Compile Include="Judgements\TaikoDrumRollTickJudgement.cs" />
<Compile Include="Judgements\TaikoStrongHitJudgement.cs" />
<Compile Include="Judgements\TaikoJudgement.cs" />
<Compile Include="Judgements\TaikoHitResult.cs" />
<Compile Include="Objects\BarLine.cs" />
<Compile Include="Objects\Drawables\DrawableBarLine.cs" />
<Compile Include="Objects\Drawables\DrawableBarLineMajor.cs" />

View File

@ -34,15 +34,13 @@ namespace osu.Game.Rulesets.Judgements
AutoSizeAxes = Axes.Both;
string resultString = judgement.Result == HitResult.Hit ? judgement.ResultString : judgement.Result.GetDescription();
Children = new[]
{
JudgementText = new OsuSpriteText
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Text = resultString.ToUpper(),
Text = judgement.Result.GetDescription().ToUpper(),
Font = @"Venera",
TextSize = 16
}
@ -68,6 +66,8 @@ namespace osu.Game.Rulesets.Judgements
switch (Judgement.Result)
{
case HitResult.None:
break;
case HitResult.Miss:
this.ScaleTo(1.6f);
this.ScaleTo(1, 100, Easing.In);
@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Judgements
this.Delay(600).FadeOut(200);
break;
case HitResult.Hit:
default:
this.ScaleTo(0.9f);
this.ScaleTo(1, 500, Easing.OutElastic);

View File

@ -5,13 +5,20 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Judgements
{
public abstract class Judgement
public class Judgement
{
/// <summary>
/// Whether this judgement is the result of a hit or a miss.
/// </summary>
public HitResult Result;
/// <summary>
/// The maximum <see cref="HitResult"/> that can be achieved.
/// </summary>
public virtual HitResult MaxResult => HitResult.Perfect;
public bool IsHit => Result > HitResult.Miss;
/// <summary>
/// The offset at which this judgement occurred.
/// </summary>
@ -20,13 +27,20 @@ namespace osu.Game.Rulesets.Judgements
public virtual bool AffectsCombo => true;
/// <summary>
/// The string representation for the result achieved.
/// The numeric representation for the result achieved.
/// </summary>
public abstract string ResultString { get; }
public int NumericResult => NumericResultFor(Result);
/// <summary>
/// The string representation for the max result achievable.
/// The numeric representation for the maximum achievable result.
/// </summary>
public abstract string MaxResultString { get; }
public int MaxNumericResult => NumericResultFor(MaxResult);
/// <summary>
/// Convert a <see cref="HitResult"/> to a numeric score representation.
/// </summary>
/// <param name="result">The value to convert.</param>
/// <returns>The number.</returns>
protected virtual int NumericResultFor(HitResult result) => result > HitResult.Miss ? 1 : 0;
}
}

View File

@ -178,10 +178,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
channel.Volume.Value = sample.Volume;
Samples.Add(channel);
}
//we may be setting a custom judgement in test cases or what not.
if (Judgement == null)
Judgement = CreateJudgement();
}
private List<DrawableHitObject<TObject, TJudgement>> nestedHitObjects;
@ -196,7 +192,6 @@ namespace osu.Game.Rulesets.Objects.Drawables
nestedHitObjects.Add(h);
}
protected abstract TJudgement CreateJudgement();
protected abstract void UpdateState(ArmedState state);
}
}

View File

@ -10,17 +10,34 @@ namespace osu.Game.Rulesets.Objects.Drawables
/// <summary>
/// Indicates that the object has not been judged yet.
/// </summary>
[Description("")]
[Description(@"")]
None,
/// <summary>
/// Indicates that the object has been judged as a miss.
/// </summary>
[Description(@"Miss")]
Miss,
[Description(@"Meh")]
Meh,
/// <summary>
/// Indicates that the object has been judged as a hit.
/// Optional judgement.
/// </summary>
[Description(@"Hit")]
Hit,
[Description(@"OK")]
Ok,
[Description(@"Good")]
Good,
[Description(@"Great")]
Great,
/// <summary>
/// Optional judgement.
/// </summary>
[Description(@"Perfect")]
Perfect,
}
}
}

View File

@ -1,9 +1,11 @@
// Copyright (c) 2007-2017 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Collections.Generic;
using osu.Game.Audio;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
namespace osu.Game.Rulesets.Objects
@ -30,6 +32,10 @@ namespace osu.Game.Rulesets.Objects
/// </summary>
public SampleInfoList Samples = new SampleInfoList();
public virtual IEnumerable<Judgement> CreateJudgements() => new[] { new Judgement() };
public readonly List<HitObject> Children = new List<HitObject>();
/// <summary>
/// Applies default values to this HitObject.
/// </summary>

View File

@ -181,10 +181,12 @@ namespace osu.Game.Rulesets.Scoring
{
switch (judgement.Result)
{
case HitResult.None:
break;
case HitResult.Miss:
Combo.Value = 0;
break;
case HitResult.Hit:
default:
Combo.Value++;
break;
}