osu/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs
Dean Herbert 04f5563238 Match HP drain harshness closer to stable
Based on number of misses before fail on two arbitrary tests. Obviously not final, just making the game more playable for the time being.
2018-03-07 19:37:26 +09:00

110 lines
3.9 KiB
C#

// 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.Collections.Generic;
using System.Linq;
using osu.Framework.Extensions;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu.Judgements;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Osu.Scoring
{
internal class OsuScoreProcessor : ScoreProcessor<OsuHitObject>
{
public OsuScoreProcessor(RulesetContainer<OsuHitObject> rulesetContainer)
: base(rulesetContainer)
{
}
private float hpDrainRate;
private readonly Dictionary<HitResult, int> scoreResultCounts = new Dictionary<HitResult, int>();
private readonly Dictionary<ComboResult, int> comboResultCounts = new Dictionary<ComboResult, int>();
protected override void SimulateAutoplay(Beatmap<OsuHitObject> beatmap)
{
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
foreach (var obj in beatmap.HitObjects)
{
if (obj is Slider slider)
{
// Head
AddJudgement(new OsuJudgement { Result = HitResult.Great });
// Ticks
foreach (var unused in slider.NestedHitObjects.OfType<SliderTick>())
AddJudgement(new OsuJudgement { Result = HitResult.Great });
//Repeats
foreach (var unused in slider.NestedHitObjects.OfType<RepeatPoint>())
AddJudgement(new OsuJudgement { Result = HitResult.Great });
}
AddJudgement(new OsuJudgement { Result = HitResult.Great });
}
}
protected override void Reset(bool storeResults)
{
base.Reset(storeResults);
scoreResultCounts.Clear();
comboResultCounts.Clear();
}
public override void PopulateScore(Score score)
{
base.PopulateScore(score);
score.Statistics[HitResult.Great] = scoreResultCounts.GetOrDefault(HitResult.Great);
score.Statistics[HitResult.Good] = scoreResultCounts.GetOrDefault(HitResult.Good);
score.Statistics[HitResult.Meh] = scoreResultCounts.GetOrDefault(HitResult.Meh);
score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss);
}
private const double harshness = 0.01;
protected override void OnNewJudgement(Judgement judgement)
{
base.OnNewJudgement(judgement);
var osuJudgement = (OsuJudgement)judgement;
if (judgement.Result != HitResult.None)
{
scoreResultCounts[judgement.Result] = scoreResultCounts.GetOrDefault(judgement.Result) + 1;
comboResultCounts[osuJudgement.Combo] = comboResultCounts.GetOrDefault(osuJudgement.Combo) + 1;
}
switch (judgement.Result)
{
case HitResult.Great:
Health.Value += (10.2 - hpDrainRate) * harshness;
break;
case HitResult.Good:
Health.Value += (8 - hpDrainRate) * harshness;
break;
case HitResult.Meh:
Health.Value += (4 - hpDrainRate) * harshness;
break;
/*case HitResult.SliderTick:
Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01;
break;*/
case HitResult.Miss:
Health.Value -= hpDrainRate * (harshness * 2);
break;
}
}
}
}