diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
index f38009263f..d89d987f95 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
@@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
index 0df2305339..1fbf1db7f7 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
index 8a51867899..b20bc43886 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
@@ -22,29 +22,17 @@ namespace osu.Game.Rulesets.Catch.Judgements
}
}
- ///
- /// Retrieves the numeric health increase of a .
- ///
- /// The to find the numeric health increase for.
- /// The numeric health increase of .
- protected virtual float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
return 0;
case HitResult.Perfect:
- return 10.2f;
+ return 10.2;
}
}
- ///
- /// Retrieves the numeric health increase of a .
- ///
- /// The to find the numeric health increase for.
- /// The numeric health increase of .
- public float HealthIncreaseFor(JudgementResult result) => HealthIncreaseFor(result.Type);
-
///
/// Whether fruit on the platter should explode or drop.
/// Note that this is only checked if the owning object is also
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
index 8b77351027..fc933020d3 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
@@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
index 403cedde8c..778d972b52 100644
--- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
@@ -3,7 +3,6 @@
using System;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
@@ -40,8 +39,7 @@ namespace osu.Game.Rulesets.Catch.Scoring
return;
}
- if (result.Judgement is CatchJudgement catchJudgement)
- Health.Value += Math.Max(catchJudgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
+ Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
}
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
index 063b626af1..ad0c04b4cc 100644
--- a/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
+++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
@@ -20,11 +20,10 @@ namespace osu.Game.Rulesets.Mania.Objects
{ HitResult.Miss, (376, 346, 316) },
};
+ public override bool IsHitResultAllowed(HitResult result) => true;
+
public override void SetDifficulty(double difficulty)
{
- AllowsPerfect = true;
- AllowsOk = true;
-
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs
new file mode 100644
index 0000000000..8c88d6d073
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollJudgement.cs
@@ -0,0 +1,24 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Taiko.Judgements
+{
+ public class TaikoDrumRollJudgement : TaikoJudgement
+ {
+ public override bool AffectsCombo => false;
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ // Drum rolls can be ignored with no health penalty
+ switch (result)
+ {
+ case HitResult.Miss:
+ return 0;
+ default:
+ return base.HealthIncreaseFor(result);
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
index 446dd0d11b..e11bdf225f 100644
--- a/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoDrumRollTickJudgement.cs
@@ -13,10 +13,21 @@ namespace osu.Game.Rulesets.Taiko.Judgements
{
switch (result)
{
- default:
- return 0;
case HitResult.Great:
return 200;
+ default:
+ return 0;
+ }
+ }
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Great:
+ return 0.15;
+ default:
+ return 0;
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoIntermediateSwellJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoIntermediateSwellJudgement.cs
deleted file mode 100644
index 81a1bd1344..0000000000
--- a/osu.Game.Rulesets.Taiko/Judgements/TaikoIntermediateSwellJudgement.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Rulesets.Scoring;
-
-namespace osu.Game.Rulesets.Taiko.Judgements
-{
- public class TaikoIntermediateSwellJudgement : TaikoJudgement
- {
- public override HitResult MaxResult => HitResult.Great;
-
- public override bool AffectsCombo => false;
-
- ///
- /// Computes the numeric result value for the combo portion of the score.
- ///
- /// The result to compute the value for.
- /// The numeric result value.
- protected override int NumericResultFor(HitResult result) => 0;
- }
-}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
index 9b1f7a08b5..4f397cda09 100644
--- a/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoJudgement.cs
@@ -10,21 +10,31 @@ namespace osu.Game.Rulesets.Taiko.Judgements
{
public override HitResult MaxResult => HitResult.Great;
- ///
- /// Computes the numeric result value for the combo portion of the score.
- ///
- /// The result to compute the value for.
- /// The numeric result value.
protected override int NumericResultFor(HitResult result)
{
switch (result)
{
- default:
- return 0;
case HitResult.Good:
return 100;
case HitResult.Great:
return 300;
+ default:
+ return 0;
+ }
+ }
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Miss:
+ return -1.0;
+ case HitResult.Good:
+ return 1.1;
+ case HitResult.Great:
+ return 3.0;
+ default:
+ return 0;
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongJudgement.cs
index ccfdeb5b0e..81dfaf4cc3 100644
--- a/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoStrongJudgement.cs
@@ -1,10 +1,15 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using osu.Game.Rulesets.Scoring;
+
namespace osu.Game.Rulesets.Taiko.Judgements
{
public class TaikoStrongJudgement : TaikoJudgement
{
+ // MainObject already changes the HP
+ protected override double HealthIncreaseFor(HitResult result) => 0;
+
public override bool AffectsCombo => false;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs
new file mode 100644
index 0000000000..024e0e618f
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellJudgement.cs
@@ -0,0 +1,23 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Taiko.Judgements
+{
+ public class TaikoSwellJudgement : TaikoJudgement
+ {
+ public override bool AffectsCombo => false;
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Miss:
+ return -0.65;
+ default:
+ return 0;
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs
new file mode 100644
index 0000000000..448c16dad6
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Judgements/TaikoSwellTickJudgement.cs
@@ -0,0 +1,16 @@
+// Copyright (c) 2007-2018 ppy Pty Ltd .
+// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Taiko.Judgements
+{
+ public class TaikoSwellTickJudgement : TaikoJudgement
+ {
+ public override bool AffectsCombo => false;
+
+ protected override int NumericResultFor(HitResult result) => 0;
+
+ protected override double HealthIncreaseFor(HitResult result) => 0;
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index 6f7264e23b..d4f0360b40 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -173,13 +173,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
if (!userTriggered)
{
- if (timeOffset > second_hit_window)
+ if (timeOffset - MainObject.Result.TimeOffset > second_hit_window)
ApplyResult(r => r.Type = HitResult.Miss);
return;
}
- if (Math.Abs(MainObject.Result.TimeOffset - timeOffset) < second_hit_window)
- ApplyResult(r => r.Type = HitResult.Great);
+ if (Math.Abs(timeOffset - MainObject.Result.TimeOffset) <= second_hit_window)
+ ApplyResult(r => r.Type = MainObject.Result.Type);
}
public override bool OnPressed(TaikoAction action)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
index 36c468c6d6..0a73474cf3 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
@@ -6,11 +6,11 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
- public class DrawableSwellTick : DrawableTaikoHitObject
+ public class DrawableSwellTick : DrawableTaikoHitObject
{
public override bool DisplayResult => false;
- public DrawableSwellTick(TaikoHitObject hitObject)
+ public DrawableSwellTick(SwellTick hitObject)
: base(hitObject)
{
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
index 405ea85f0d..89d0512e9c 100644
--- a/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/DrumRoll.cs
@@ -5,6 +5,8 @@ using osu.Game.Rulesets.Objects.Types;
using System;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Taiko.Judgements;
namespace osu.Game.Rulesets.Taiko.Objects
{
@@ -81,5 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
first = false;
}
}
+
+ public override Judgement CreateJudgement() => new TaikoDrumRollJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Swell.cs b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
index 702bf63bf5..68433429c6 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Swell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Swell.cs
@@ -3,6 +3,8 @@
using System;
using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Taiko.Judgements;
namespace osu.Game.Rulesets.Taiko.Objects
{
@@ -26,5 +28,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
for (int i = 0; i < RequiredHits; i++)
AddNested(new SwellTick());
}
+
+ public override Judgement CreateJudgement() => new TaikoSwellJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
index 49eb6d2a15..38f77fa1e7 100644
--- a/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/SwellTick.cs
@@ -1,9 +1,13 @@
// Copyright (c) 2007-2018 ppy Pty Ltd .
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Taiko.Judgements;
+
namespace osu.Game.Rulesets.Taiko.Objects
{
public class SwellTick : TaikoHitObject
{
+ public override Judgement CreateJudgement() => new TaikoSwellTickJudgement();
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs b/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs
index 289f084a45..9199e6f141 100644
--- a/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/TaikoHitWindows.cs
@@ -14,15 +14,26 @@ namespace osu.Game.Rulesets.Taiko.Objects
{
{ HitResult.Great, (100, 70, 40) },
{ HitResult.Good, (240, 160, 100) },
- { HitResult.Meh, (270, 190, 140) },
- { HitResult.Miss, (400, 400, 400) },
+ { HitResult.Miss, (270, 190, 140) },
};
+ public override bool IsHitResultAllowed(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Great:
+ case HitResult.Good:
+ case HitResult.Miss:
+ return true;
+ default:
+ return false;
+ }
+ }
+
public override void SetDifficulty(double difficulty)
{
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
- Meh = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Meh]);
Miss = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Miss]);
}
}
diff --git a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
index cf33141027..318efdbf3e 100644
--- a/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
+++ b/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs
@@ -4,7 +4,6 @@
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
-using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.UI;
@@ -13,51 +12,24 @@ namespace osu.Game.Rulesets.Taiko.Scoring
internal class TaikoScoreProcessor : ScoreProcessor
{
///
- /// The HP awarded by a hit.
+ /// A value used for calculating .
///
- private const double hp_hit_great = 0.03;
-
- ///
- /// The HP awarded for a hit.
- ///
- private const double hp_hit_good = 0.011;
-
- ///
- /// The minimum HP deducted for a .
- /// This occurs when HP Drain = 0.
- ///
- private const double hp_miss_min = -0.0018;
-
- ///
- /// The median HP deducted for a .
- /// This occurs when HP Drain = 5.
- ///
- private const double hp_miss_mid = -0.0075;
-
- ///
- /// The maximum HP deducted for a .
- /// This occurs when HP Drain = 10.
- ///
- private const double hp_miss_max = -0.12;
-
- ///
- /// The HP awarded for a hit.
- ///
- /// hits award less HP as they're more spammable, although in hindsight
- /// this probably awards too little HP and is kept at this value for now for compatibility.
- ///
- ///
- private const double hp_hit_tick = 0.00000003;
+ private const double object_count_factor = 3;
///
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
///
protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value <= 0.5;
- private double hpIncreaseTick;
- private double hpIncreaseGreat;
- private double hpIncreaseGood;
- private double hpIncreaseMiss;
+ ///
+ /// HP multiplier for a successful .
+ ///
+ private double hpMultiplier;
+
+ ///
+ /// HP multiplier for a .
+ ///
+ private double hpMissMultiplier;
public TaikoScoreProcessor(RulesetContainer rulesetContainer)
: base(rulesetContainer)
@@ -68,38 +40,23 @@ namespace osu.Game.Rulesets.Taiko.Scoring
{
base.ApplyBeatmap(beatmap);
- double hpMultiplierNormal = 1 / (hp_hit_great * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
+ hpMultiplier = 1 / (object_count_factor * beatmap.HitObjects.FindAll(o => o is Hit).Count * BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.5, 0.75, 0.98));
- hpIncreaseTick = hp_hit_tick;
- hpIncreaseGreat = hpMultiplierNormal * hp_hit_great;
- hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
- hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
+ hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
}
protected override void ApplyResult(JudgementResult result)
{
base.ApplyResult(result);
- bool isTick = result.Judgement is TaikoDrumRollTickJudgement;
+ double hpIncrease = result.Judgement.HealthIncreaseFor(result);
- // Apply HP changes
- switch (result.Type)
- {
- case HitResult.Miss:
- // Missing ticks shouldn't drop HP
- if (!isTick)
- Health.Value += hpIncreaseMiss;
- break;
- case HitResult.Good:
- Health.Value += hpIncreaseGood;
- break;
- case HitResult.Great:
- if (isTick)
- Health.Value += hpIncreaseTick;
- else
- Health.Value += hpIncreaseGreat;
- break;
- }
+ if (result.Type == HitResult.Miss)
+ hpIncrease *= hpMissMultiplier;
+ else
+ hpIncrease *= hpMultiplier;
+
+ Health.Value += hpIncrease;
}
protected override void Reset(bool storeResults)
diff --git a/osu.Game/Overlays/WaveOverlayContainer.cs b/osu.Game/Overlays/WaveOverlayContainer.cs
index 5f7cf17a9d..c5a4953c5e 100644
--- a/osu.Game/Overlays/WaveOverlayContainer.cs
+++ b/osu.Game/Overlays/WaveOverlayContainer.cs
@@ -25,20 +25,13 @@ namespace osu.Game.Overlays
protected override void PopIn()
{
base.PopIn();
-
Waves.Show();
-
- this.FadeIn();
}
protected override void PopOut()
{
base.PopOut();
-
Waves.Hide();
-
- // this is required or we will remain present even though our waves are hidden.
- this.Delay(WaveContainer.DISAPPEAR_DURATION).FadeOut();
}
}
}
diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs
index c679df5900..86a41a08ff 100644
--- a/osu.Game/Rulesets/Judgements/Judgement.cs
+++ b/osu.Game/Rulesets/Judgements/Judgement.cs
@@ -44,5 +44,19 @@ namespace osu.Game.Rulesets.Judgements
/// The to find the numeric score representation for.
/// The numeric score representation of .
public int NumericResultFor(JudgementResult result) => NumericResultFor(result.Type);
+
+ ///
+ /// Retrieves the numeric health increase of a .
+ ///
+ /// The to find the numeric health increase for.
+ /// The numeric health increase of .
+ protected virtual double HealthIncreaseFor(HitResult result) => 0;
+
+ ///
+ /// Retrieves the numeric health increase of a .
+ ///
+ /// The to find the numeric health increase for.
+ /// The numeric health increase of .
+ public double HealthIncreaseFor(JudgementResult result) => HealthIncreaseFor(result.Type);
}
}
diff --git a/osu.Game/Rulesets/Objects/HitWindows.cs b/osu.Game/Rulesets/Objects/HitWindows.cs
index 3717209860..40fb98a997 100644
--- a/osu.Game/Rulesets/Objects/HitWindows.cs
+++ b/osu.Game/Rulesets/Objects/HitWindows.cs
@@ -22,7 +22,6 @@ namespace osu.Game.Rulesets.Objects
///
/// Hit window for a result.
- /// The user can only achieve receive this result if is true.
///
public double Perfect { get; protected set; }
@@ -38,7 +37,6 @@ namespace osu.Game.Rulesets.Objects
///
/// Hit window for an result.
- /// The user can only achieve this result if is true.
///
public double Ok { get; protected set; }
@@ -53,14 +51,36 @@ namespace osu.Game.Rulesets.Objects
public double Miss { get; protected set; }
///
- /// Whether it's possible to achieve a result.
+ /// Retrieves the with the largest hit window that produces a successful hit.
///
- public bool AllowsPerfect;
+ /// The lowest allowed successful .
+ protected HitResult LowestSuccessfulHitResult()
+ {
+ for (var result = HitResult.Meh; result <= HitResult.Perfect; ++result)
+ {
+ if (IsHitResultAllowed(result))
+ return result;
+ }
+
+ return HitResult.None;
+ }
///
- /// Whether it's possible to achieve a result.
+ /// Check whether it is possible to achieve the provided .
///
- public bool AllowsOk;
+ /// The result type to check.
+ /// Whether the can be achieved.
+ public virtual bool IsHitResultAllowed(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Perfect:
+ case HitResult.Ok:
+ return false;
+ default:
+ return true;
+ }
+ }
///
/// Sets hit windows with values that correspond to a difficulty parameter.
@@ -85,18 +105,11 @@ namespace osu.Game.Rulesets.Objects
{
timeOffset = Math.Abs(timeOffset);
- if (AllowsPerfect && timeOffset <= HalfWindowFor(HitResult.Perfect))
- return HitResult.Perfect;
- if (timeOffset <= HalfWindowFor(HitResult.Great))
- return HitResult.Great;
- if (timeOffset <= HalfWindowFor(HitResult.Good))
- return HitResult.Good;
- if (AllowsOk && timeOffset <= HalfWindowFor(HitResult.Ok))
- return HitResult.Ok;
- if (timeOffset <= HalfWindowFor(HitResult.Meh))
- return HitResult.Meh;
- if (timeOffset <= HalfWindowFor(HitResult.Miss))
- return HitResult.Miss;
+ for (var result = HitResult.Perfect; result >= HitResult.Miss; --result)
+ {
+ if (IsHitResultAllowed(result) && timeOffset <= HalfWindowFor(result))
+ return result;
+ }
return HitResult.None;
}
@@ -130,10 +143,10 @@ namespace osu.Game.Rulesets.Objects
///
/// Given a time offset, whether the can ever be hit in the future with a non- result.
- /// This happens if is less than what is required for a result.
+ /// This happens if is less than what is required for a result.
///
/// The time offset.
/// Whether the can be hit at any point in the future from this time offset.
- public bool CanBeHit(double timeOffset) => timeOffset <= HalfWindowFor(HitResult.Meh);
+ public bool CanBeHit(double timeOffset) => timeOffset <= HalfWindowFor(LowestSuccessfulHitResult());
}
}