1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-15 23:23:04 +08:00
osu-lazer/osu.Game.Rulesets.Taiko/Scoring/TaikoScoreProcessor.cs

145 lines
5.3 KiB
C#
Raw Normal View History

2018-01-05 19:21:19 +08:00
// Copyright (c) 2007-2018 ppy Pty Ltd <contact@ppy.sh>.
// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
using System.Linq;
2017-03-23 18:24:23 +08:00
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
2017-04-18 15:05:58 +08:00
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Judgements;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.UI;
2017-04-18 15:05:58 +08:00
namespace osu.Game.Rulesets.Taiko.Scoring
{
2017-09-06 17:05:51 +08:00
internal class TaikoScoreProcessor : ScoreProcessor<TaikoHitObject>
{
2017-03-23 18:24:23 +08:00
/// <summary>
2017-09-05 18:44:59 +08:00
/// The HP awarded by a <see cref="HitResult.Great"/> hit.
2017-03-23 18:24:23 +08:00
/// </summary>
private const double hp_hit_great = 0.03;
/// <summary>
2017-09-05 18:44:59 +08:00
/// The HP awarded for a <see cref="HitResult.Good"/> hit.
2017-03-23 18:24:23 +08:00
/// </summary>
private const double hp_hit_good = 0.011;
2017-03-23 18:24:23 +08:00
/// <summary>
/// The minimum HP deducted for a <see cref="HitResult.Miss"/>.
/// This occurs when HP Drain = 0.
2017-03-23 18:24:23 +08:00
/// </summary>
private const double hp_miss_min = -0.0018;
/// <summary>
/// The median HP deducted for a <see cref="HitResult.Miss"/>.
/// This occurs when HP Drain = 5.
2017-03-23 18:24:23 +08:00
/// </summary>
private const double hp_miss_mid = -0.0075;
/// <summary>
/// The maximum HP deducted for a <see cref="HitResult.Miss"/>.
/// This occurs when HP Drain = 10.
2017-03-23 18:24:23 +08:00
/// </summary>
private const double hp_miss_max = -0.12;
/// <summary>
/// The HP awarded for a <see cref="DrumRollTick"/> hit.
/// <para>
/// <see cref="DrumRollTick"/> 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.
/// </para>
/// </summary>
private const double hp_hit_tick = 0.00000003;
/// <summary>
/// Taiko fails at the end of the map if the player has not half-filled their HP bar.
/// </summary>
2018-02-01 16:48:26 +08:00
protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value <= 0.5;
2017-03-23 18:24:23 +08:00
private double hpIncreaseTick;
private double hpIncreaseGreat;
private double hpIncreaseGood;
private double hpIncreaseMiss;
public TaikoScoreProcessor()
{
}
2017-09-06 17:05:51 +08:00
public TaikoScoreProcessor(RulesetContainer<TaikoHitObject> rulesetContainer)
2017-08-09 12:28:29 +08:00
: base(rulesetContainer)
{
}
protected override void SimulateAutoplay(Beatmap<TaikoHitObject> beatmap)
2017-03-23 18:24:23 +08:00
{
2017-10-19 13:05:11 +08:00
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));
2017-03-23 18:24:23 +08:00
hpIncreaseTick = hp_hit_tick;
hpIncreaseGreat = hpMultiplierNormal * hp_hit_great;
hpIncreaseGood = hpMultiplierNormal * hp_hit_good;
2017-10-19 13:05:11 +08:00
hpIncreaseMiss = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, hp_miss_min, hp_miss_mid, hp_miss_max);
2017-03-23 18:24:23 +08:00
2017-03-23 18:39:30 +08:00
foreach (var obj in beatmap.HitObjects)
2017-03-23 18:24:23 +08:00
{
if (obj is Hit)
{
AddJudgement(new TaikoJudgement { Result = HitResult.Great });
if (obj.IsStrong)
AddJudgement(new TaikoStrongHitJudgement());
2017-03-23 18:24:23 +08:00
}
else if (obj is DrumRoll)
{
for (int i = 0; i < ((DrumRoll)obj).NestedHitObjects.OfType<DrumRollTick>().Count(); i++)
2017-03-23 18:24:23 +08:00
{
AddJudgement(new TaikoDrumRollTickJudgement { Result = HitResult.Great });
if (obj.IsStrong)
AddJudgement(new TaikoStrongHitJudgement());
2017-03-23 18:24:23 +08:00
}
AddJudgement(new TaikoJudgement { Result = HitResult.Great });
if (obj.IsStrong)
AddJudgement(new TaikoStrongHitJudgement());
2017-03-23 18:24:23 +08:00
}
2017-03-25 19:57:49 +08:00
else if (obj is Swell)
2017-03-23 18:24:23 +08:00
{
2017-09-05 18:44:59 +08:00
AddJudgement(new TaikoJudgement { Result = HitResult.Great });
2017-03-23 18:24:23 +08:00
}
}
}
protected override void OnNewJudgement(Judgement judgement)
{
base.OnNewJudgement(judgement);
bool isTick = judgement is TaikoDrumRollTickJudgement;
2017-03-23 18:24:23 +08:00
// Apply HP changes
switch (judgement.Result)
2017-03-23 18:24:23 +08:00
{
case HitResult.Miss:
// Missing ticks shouldn't drop HP
2017-03-24 10:24:07 +08:00
if (!isTick)
2017-03-23 18:24:23 +08:00
Health.Value += hpIncreaseMiss;
break;
2017-09-05 18:44:59 +08:00
case HitResult.Good:
Health.Value += hpIncreaseGood;
break;
case HitResult.Great:
if (isTick)
Health.Value += hpIncreaseTick;
else
Health.Value += hpIncreaseGreat;
2017-03-23 18:24:23 +08:00
break;
}
}
protected override void Reset(bool storeResults)
2017-03-23 18:24:23 +08:00
{
base.Reset(storeResults);
2017-03-23 18:24:23 +08:00
Health.Value = 0;
}
}
}