1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-14 19:22:54 +08:00

Integrate PeriodTracker changes

This commit is contained in:
Bartłomiej Dach 2020-05-10 18:32:38 +02:00
parent ee2ff77b89
commit 1d999bb634

View File

@ -5,9 +5,9 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using osu.Game.Beatmaps; using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Timing;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects;
using osu.Game.Utils;
namespace osu.Game.Rulesets.Scoring namespace osu.Game.Rulesets.Scoring
{ {
@ -49,33 +49,7 @@ namespace osu.Game.Rulesets.Scoring
private double targetMinimumHealth; private double targetMinimumHealth;
private double drainRate = 1; private double drainRate = 1;
private readonly List<(double startTime, double endTime)> nonDrainSections = new List<(double, double)>(); private PeriodTracker noDrainPeriodTracker;
private int currentNonDrainSection;
private bool isInNonDrainSection
{
get
{
if (nonDrainSections.Count == 0)
return false;
var time = Time.Current;
if (time > nonDrainSections[currentNonDrainSection].endTime)
{
while (time > nonDrainSections[currentNonDrainSection].endTime && currentNonDrainSection < nonDrainSections.Count - 1)
currentNonDrainSection++;
}
else
{
while (time < nonDrainSections[currentNonDrainSection].startTime && currentNonDrainSection > 0)
currentNonDrainSection--;
}
var closestSection = nonDrainSections[currentNonDrainSection];
return time >= closestSection.startTime && time <= closestSection.endTime;
}
}
/// <summary> /// <summary>
/// Creates a new <see cref="DrainingHealthProcessor"/>. /// Creates a new <see cref="DrainingHealthProcessor"/>.
@ -90,7 +64,7 @@ namespace osu.Game.Rulesets.Scoring
{ {
base.Update(); base.Update();
if (isInNonDrainSection) if (noDrainPeriodTracker?.IsInAny(Time.Current) == true)
return; return;
// When jumping in and out of gameplay time within a single frame, health should only be drained for the period within the gameplay time // When jumping in and out of gameplay time within a single frame, health should only be drained for the period within the gameplay time
@ -102,23 +76,23 @@ namespace osu.Game.Rulesets.Scoring
public override void ApplyBeatmap(IBeatmap beatmap) public override void ApplyBeatmap(IBeatmap beatmap)
{ {
nonDrainSections.Clear();
this.beatmap = beatmap; this.beatmap = beatmap;
if (beatmap.HitObjects.Count > 0) if (beatmap.HitObjects.Count > 0)
gameplayEndTime = beatmap.HitObjects[^1].GetEndTime(); gameplayEndTime = beatmap.HitObjects[^1].GetEndTime();
// Ranges between the end of last hit object before a break noDrainPeriodTracker = new PeriodTracker(beatmap.Breaks.Select(breakPeriod => new Period(
// and the start of first hit object after a break should beatmap.HitObjects
// not allow HP draining. (with break periods in) .Select(hitObject => hitObject.GetEndTime())
foreach (BreakPeriod b in beatmap.Breaks) .Where(endTime => endTime < breakPeriod.StartTime)
{ .DefaultIfEmpty(double.MinValue)
var startTime = beatmap.HitObjects.LastOrDefault(h => h.GetEndTime() < b.StartTime)?.GetEndTime() ?? double.MinValue; .Last(),
var endTime = beatmap.HitObjects.FirstOrDefault(h => h.StartTime > b.EndTime)?.StartTime ?? double.MaxValue; beatmap.HitObjects
.Select(hitObject => hitObject.StartTime)
nonDrainSections.Add((startTime, endTime)); .Where(startTime => startTime > breakPeriod.EndTime)
} .DefaultIfEmpty(double.MaxValue)
.First()
)));
targetMinimumHealth = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, min_health_target, mid_health_target, max_health_target); targetMinimumHealth = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, min_health_target, mid_health_target, max_health_target);