mirror of
https://github.com/ppy/osu
synced 2024-12-25 08:12:41 +00:00
129 lines
4.2 KiB
C#
129 lines
4.2 KiB
C#
// 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;
|
|
using osu.Game.Beatmaps;
|
|
using osu.Game.Rulesets.Judgements;
|
|
using osu.Game.Rulesets.Objects.Types;
|
|
using osu.Game.Rulesets.Osu.Judgements;
|
|
using osu.Game.Rulesets.Osu.Objects;
|
|
using osu.Game.Rulesets.Scoring;
|
|
|
|
namespace osu.Game.Rulesets.Osu.Scoring
|
|
{
|
|
public partial class OsuHealthProcessor : DrainingHealthProcessor
|
|
{
|
|
private ComboResult currentComboResult = ComboResult.Perfect;
|
|
|
|
public OsuHealthProcessor(double drainStartTime, double drainLenience = 0)
|
|
: base(drainStartTime, drainLenience)
|
|
{
|
|
}
|
|
|
|
protected override double GetHealthIncreaseFor(JudgementResult result)
|
|
{
|
|
if (IsSimulating)
|
|
return getHealthIncreaseFor(result);
|
|
|
|
if (result.HitObject is not IHasComboInformation combo)
|
|
return getHealthIncreaseFor(result);
|
|
|
|
if (combo.NewCombo)
|
|
currentComboResult = ComboResult.Perfect;
|
|
|
|
switch (result.Type)
|
|
{
|
|
case HitResult.LargeTickMiss:
|
|
case HitResult.Ok:
|
|
setComboResult(ComboResult.Good);
|
|
break;
|
|
|
|
case HitResult.Meh:
|
|
case HitResult.Miss:
|
|
setComboResult(ComboResult.None);
|
|
break;
|
|
}
|
|
|
|
// The slider tail has a special judgement that can't accurately be described above.
|
|
if (result.HitObject is SliderTailCircle && !result.IsHit)
|
|
setComboResult(ComboResult.Good);
|
|
|
|
if (combo.LastInCombo && result.Type.IsHit())
|
|
{
|
|
switch (currentComboResult)
|
|
{
|
|
case ComboResult.Perfect:
|
|
return getHealthIncreaseFor(result) + 0.07;
|
|
|
|
case ComboResult.Good:
|
|
return getHealthIncreaseFor(result) + 0.05;
|
|
|
|
default:
|
|
return getHealthIncreaseFor(result) + 0.03;
|
|
}
|
|
}
|
|
|
|
return getHealthIncreaseFor(result);
|
|
|
|
void setComboResult(ComboResult comboResult) => currentComboResult = (ComboResult)Math.Min((int)currentComboResult, (int)comboResult);
|
|
}
|
|
|
|
protected override void Reset(bool storeResults)
|
|
{
|
|
base.Reset(storeResults);
|
|
currentComboResult = ComboResult.Perfect;
|
|
}
|
|
|
|
private double getHealthIncreaseFor(JudgementResult result)
|
|
{
|
|
switch (result.Type)
|
|
{
|
|
case HitResult.SmallTickMiss:
|
|
return IBeatmapDifficultyInfo.DifficultyRange(Beatmap.Difficulty.DrainRate, -0.02, -0.075, -0.14);
|
|
|
|
case HitResult.LargeTickMiss:
|
|
return IBeatmapDifficultyInfo.DifficultyRange(Beatmap.Difficulty.DrainRate, -0.02, -0.075, -0.14);
|
|
|
|
case HitResult.Miss:
|
|
return IBeatmapDifficultyInfo.DifficultyRange(Beatmap.Difficulty.DrainRate, -0.03, -0.125, -0.2);
|
|
|
|
case HitResult.SmallTickHit:
|
|
// When classic slider mechanics are enabled, this result comes from the tail.
|
|
return 0.02;
|
|
|
|
case HitResult.SliderTailHit:
|
|
case HitResult.LargeTickHit:
|
|
switch (result.HitObject)
|
|
{
|
|
case SliderTick:
|
|
return 0.015;
|
|
|
|
case SliderHeadCircle:
|
|
case SliderTailCircle:
|
|
case SliderRepeat:
|
|
return 0.02;
|
|
}
|
|
|
|
break;
|
|
|
|
case HitResult.Meh:
|
|
return 0.002;
|
|
|
|
case HitResult.Ok:
|
|
return 0.011;
|
|
|
|
case HitResult.Great:
|
|
return 0.03;
|
|
|
|
case HitResult.SmallBonus:
|
|
return 0.0085;
|
|
|
|
case HitResult.LargeBonus:
|
|
return 0.01;
|
|
}
|
|
|
|
return base.GetHealthIncreaseFor(result);
|
|
}
|
|
}
|
|
}
|