mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 09:42:54 +08:00
Merge branch 'master' into screen-breadcrumbs
This commit is contained in:
commit
452564d0e0
@ -5,8 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -14,7 +12,7 @@ using osu.Game.Tests.Beatmaps;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
{
|
{
|
||||||
internal class CatchBeatmapConversionTest : BeatmapConversionTest<TestCatchRuleset, ConvertValue>
|
internal class CatchBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
|
||||||
|
|
||||||
@ -47,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
protected override Ruleset CreateRuleset() => new CatchRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct ConvertValue : IEquatable<ConvertValue>
|
internal struct ConvertValue : IEquatable<ConvertValue>
|
||||||
@ -64,8 +62,4 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
=> Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience)
|
=> Precision.AlmostEquals(StartTime, other.StartTime, conversion_lenience)
|
||||||
&& Precision.AlmostEquals(Position, other.Position, conversion_lenience);
|
&& Precision.AlmostEquals(Position, other.Position, conversion_lenience);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestCatchRuleset : CatchRuleset
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -14,7 +12,7 @@ using osu.Game.Tests.Beatmaps;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
{
|
{
|
||||||
internal class ManiaBeatmapConversionTest : BeatmapConversionTest<TestManiaRuleset, ConvertValue>
|
internal class ManiaBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
protected override Ruleset CreateRuleset() => new ManiaRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct ConvertValue : IEquatable<ConvertValue>
|
internal struct ConvertValue : IEquatable<ConvertValue>
|
||||||
@ -54,8 +52,4 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
&& Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
|
&& Precision.AlmostEquals(EndTime, other.EndTime, conversion_lenience)
|
||||||
&& Column == other.Column;
|
&& Column == other.Column;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestManiaRuleset : ManiaRuleset
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,15 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
using OpenTK;
|
using OpenTK;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
internal class OsuBeatmapConversionTest : BeatmapConversionTest<TestOsuRuleset, ConvertValue>
|
internal class OsuBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
|
||||||
|
|
||||||
@ -42,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new OsuBeatmapConverter(beatmap);
|
protected override Ruleset CreateRuleset() => new OsuRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct ConvertValue : IEquatable<ConvertValue>
|
internal struct ConvertValue : IEquatable<ConvertValue>
|
||||||
@ -67,8 +65,4 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
&& Precision.AlmostEquals(EndX, other.EndX, conversion_lenience)
|
&& Precision.AlmostEquals(EndX, other.EndX, conversion_lenience)
|
||||||
&& Precision.AlmostEquals(EndY, other.EndY, conversion_lenience);
|
&& Precision.AlmostEquals(EndY, other.EndY, conversion_lenience);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestOsuRuleset : OsuRuleset
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -36,18 +36,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
new Speed()
|
new Speed()
|
||||||
};
|
};
|
||||||
|
|
||||||
double sectionEnd = section_length / TimeRate;
|
double sectionLength = section_length * TimeRate;
|
||||||
|
|
||||||
|
// The first object doesn't generate a strain, so we begin with an incremented section end
|
||||||
|
double currentSectionEnd = 2 * sectionLength;
|
||||||
|
|
||||||
foreach (OsuDifficultyHitObject h in beatmap)
|
foreach (OsuDifficultyHitObject h in beatmap)
|
||||||
{
|
{
|
||||||
while (h.BaseObject.StartTime > sectionEnd)
|
while (h.BaseObject.StartTime > currentSectionEnd)
|
||||||
{
|
{
|
||||||
foreach (Skill s in skills)
|
foreach (Skill s in skills)
|
||||||
{
|
{
|
||||||
s.SaveCurrentPeak();
|
s.SaveCurrentPeak();
|
||||||
s.StartNewSectionFrom(sectionEnd);
|
s.StartNewSectionFrom(currentSectionEnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
sectionEnd += section_length;
|
currentSectionEnd += sectionLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (Skill s in skills)
|
foreach (Skill s in skills)
|
||||||
|
@ -14,7 +14,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
public class OsuDifficultyBeatmap : IEnumerable<OsuDifficultyHitObject>
|
public class OsuDifficultyBeatmap : IEnumerable<OsuDifficultyHitObject>
|
||||||
{
|
{
|
||||||
private readonly IEnumerator<OsuDifficultyHitObject> difficultyObjects;
|
private readonly IEnumerator<OsuDifficultyHitObject> difficultyObjects;
|
||||||
private readonly Queue<OsuDifficultyHitObject> onScreen = new Queue<OsuDifficultyHitObject>();
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an enumerator, which preprocesses a list of <see cref="OsuHitObject"/>s recieved as input, wrapping them as
|
/// Creates an enumerator, which preprocesses a list of <see cref="OsuHitObject"/>s recieved as input, wrapping them as
|
||||||
@ -30,65 +29,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns an enumerator that enumerates all <see cref="OsuDifficultyHitObject"/>s in the <see cref="OsuDifficultyBeatmap"/>.
|
/// Returns an enumerator that enumerates all <see cref="OsuDifficultyHitObject"/>s in the <see cref="OsuDifficultyBeatmap"/>.
|
||||||
/// The inner loop adds objects that appear on screen into a queue until we need to hit the next object.
|
|
||||||
/// The outer loop returns objects from this queue one at a time, only after they had to be hit, and should no longer be on screen.
|
|
||||||
/// This means that we can loop through every object that is on screen at the time when a new one appears,
|
|
||||||
/// allowing us to determine a reading strain for the object that just appeared.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public IEnumerator<OsuDifficultyHitObject> GetEnumerator()
|
public IEnumerator<OsuDifficultyHitObject> GetEnumerator() => difficultyObjects;
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
// Add upcoming objects to the queue until we have at least one object that had been hit and can be dequeued.
|
|
||||||
// This means there is always at least one object in the queue unless we reached the end of the map.
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if (!difficultyObjects.MoveNext())
|
|
||||||
break; // New objects can't be added anymore, but we still need to dequeue and return the ones already on screen.
|
|
||||||
|
|
||||||
OsuDifficultyHitObject latest = difficultyObjects.Current;
|
|
||||||
// Calculate flow values here
|
|
||||||
|
|
||||||
foreach (OsuDifficultyHitObject h in onScreen)
|
|
||||||
{
|
|
||||||
// ReSharper disable once PossibleNullReferenceException (resharper not smart enough to understand IEnumerator.MoveNext())
|
|
||||||
h.TimeUntilHit -= latest.DeltaTime;
|
|
||||||
// Calculate reading strain here
|
|
||||||
}
|
|
||||||
|
|
||||||
onScreen.Enqueue(latest);
|
|
||||||
}
|
|
||||||
while (onScreen.Peek().TimeUntilHit > 0); // Keep adding new objects on screen while there is still time before we have to hit the next one.
|
|
||||||
|
|
||||||
if (onScreen.Count == 0) break; // We have reached the end of the map and enumerated all the objects.
|
|
||||||
yield return onScreen.Dequeue(); // Remove and return objects one by one that had to be hit before the latest one appeared.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
|
|
||||||
private IEnumerator<OsuDifficultyHitObject> createDifficultyObjectEnumerator(List<OsuHitObject> objects, double timeRate)
|
private IEnumerator<OsuDifficultyHitObject> createDifficultyObjectEnumerator(List<OsuHitObject> objects, double timeRate)
|
||||||
{
|
{
|
||||||
// We will process OsuHitObjects in groups of three to form a triangle, so we can calculate an angle for each object.
|
// The first jump is formed by the first two hitobjects of the map.
|
||||||
OsuHitObject[] triangle = new OsuHitObject[3];
|
|
||||||
|
|
||||||
// OsuDifficultyHitObject construction requires three components, an extra copy of the first OsuHitObject is used at the beginning.
|
|
||||||
if (objects.Count > 1)
|
|
||||||
{
|
|
||||||
triangle[1] = objects[0]; // This copy will get shifted to the last spot in the triangle.
|
|
||||||
triangle[0] = objects[0]; // This component corresponds to the real first OsuHitOject.
|
|
||||||
}
|
|
||||||
|
|
||||||
// The final component of the first triangle will be the second OsuHitOject of the map, which forms the first jump.
|
|
||||||
// If the map has less than two OsuHitObjects, the enumerator will not return anything.
|
// If the map has less than two OsuHitObjects, the enumerator will not return anything.
|
||||||
for (int i = 1; i < objects.Count; ++i)
|
for (int i = 1; i < objects.Count; i++)
|
||||||
{
|
yield return new OsuDifficultyHitObject(objects[i], objects[i - 1], timeRate);
|
||||||
triangle[2] = triangle[1];
|
|
||||||
triangle[1] = triangle[0];
|
|
||||||
triangle[0] = objects[i];
|
|
||||||
|
|
||||||
yield return new OsuDifficultyHitObject(triangle, timeRate);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class OsuDifficultyHitObject
|
public class OsuDifficultyHitObject
|
||||||
{
|
{
|
||||||
|
private const int normalized_radius = 52;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The <see cref="OsuHitObject"/> this <see cref="OsuDifficultyHitObject"/> refers to.
|
/// The <see cref="OsuHitObject"/> this <see cref="OsuDifficultyHitObject"/> refers to.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -28,26 +30,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public double DeltaTime { get; private set; }
|
public double DeltaTime { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
private readonly OsuHitObject lastObject;
|
||||||
/// Number of milliseconds until the <see cref="OsuDifficultyHitObject"/> has to be hit.
|
|
||||||
/// </summary>
|
|
||||||
public double TimeUntilHit { get; set; }
|
|
||||||
|
|
||||||
private const int normalized_radius = 52;
|
|
||||||
|
|
||||||
private readonly double timeRate;
|
private readonly double timeRate;
|
||||||
|
|
||||||
private readonly OsuHitObject[] t;
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the object calculating extra data required for difficulty calculation.
|
/// Initializes the object calculating extra data required for difficulty calculation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public OsuDifficultyHitObject(OsuHitObject[] triangle, double timeRate)
|
public OsuDifficultyHitObject(OsuHitObject currentObject, OsuHitObject lastObject, double timeRate)
|
||||||
{
|
{
|
||||||
|
this.lastObject = lastObject;
|
||||||
this.timeRate = timeRate;
|
this.timeRate = timeRate;
|
||||||
|
|
||||||
t = triangle;
|
BaseObject = currentObject;
|
||||||
BaseObject = t[0];
|
|
||||||
setDistances();
|
setDistances();
|
||||||
setTimingValues();
|
setTimingValues();
|
||||||
// Calculate angle here
|
// Calculate angle here
|
||||||
@ -63,10 +58,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
scalingFactor *= 1 + smallCircleBonus;
|
scalingFactor *= 1 + smallCircleBonus;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 lastCursorPosition = t[1].StackedPosition;
|
Vector2 lastCursorPosition = lastObject.StackedPosition;
|
||||||
float lastTravelDistance = 0;
|
float lastTravelDistance = 0;
|
||||||
|
|
||||||
var lastSlider = t[1] as Slider;
|
var lastSlider = lastObject as Slider;
|
||||||
if (lastSlider != null)
|
if (lastSlider != null)
|
||||||
{
|
{
|
||||||
computeSliderCursorPosition(lastSlider);
|
computeSliderCursorPosition(lastSlider);
|
||||||
@ -80,8 +75,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
private void setTimingValues()
|
private void setTimingValues()
|
||||||
{
|
{
|
||||||
// Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure.
|
// Every timing inverval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure.
|
||||||
DeltaTime = Math.Max(40, (t[0].StartTime - t[1].StartTime) / timeRate);
|
DeltaTime = Math.Max(50, (BaseObject.StartTime - lastObject.StartTime) / timeRate);
|
||||||
TimeUntilHit = 450; // BaseObject.PreEmpt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void computeSliderCursorPosition(Slider slider)
|
private void computeSliderCursorPosition(Slider slider)
|
||||||
@ -107,7 +101,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
var scoringTimes = slider.NestedHitObjects.Select(t => t.StartTime);
|
// Skip the head circle
|
||||||
|
var scoringTimes = slider.NestedHitObjects.Skip(1).Select(t => t.StartTime);
|
||||||
foreach (var time in scoringTimes)
|
foreach (var time in scoringTimes)
|
||||||
computeVertex(time);
|
computeVertex(time);
|
||||||
computeVertex(slider.EndTime);
|
computeVertex(slider.EndTime);
|
||||||
|
@ -32,9 +32,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
|
|
||||||
private double accuracy;
|
private double accuracy;
|
||||||
private int scoreMaxCombo;
|
private int scoreMaxCombo;
|
||||||
private int count300;
|
private int countGreat;
|
||||||
private int count100;
|
private int countGood;
|
||||||
private int count50;
|
private int countMeh;
|
||||||
private int countMiss;
|
private int countMiss;
|
||||||
|
|
||||||
public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score)
|
public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score)
|
||||||
@ -52,9 +52,9 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
mods = Score.Mods;
|
mods = Score.Mods;
|
||||||
accuracy = Score.Accuracy;
|
accuracy = Score.Accuracy;
|
||||||
scoreMaxCombo = Score.MaxCombo;
|
scoreMaxCombo = Score.MaxCombo;
|
||||||
count300 = Convert.ToInt32(Score.Statistics[HitResult.Great]);
|
countGreat = Convert.ToInt32(Score.Statistics[HitResult.Great]);
|
||||||
count100 = Convert.ToInt32(Score.Statistics[HitResult.Good]);
|
countGood = Convert.ToInt32(Score.Statistics[HitResult.Good]);
|
||||||
count50 = Convert.ToInt32(Score.Statistics[HitResult.Meh]);
|
countMeh = Convert.ToInt32(Score.Statistics[HitResult.Meh]);
|
||||||
countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]);
|
countMiss = Convert.ToInt32(Score.Statistics[HitResult.Miss]);
|
||||||
|
|
||||||
// Don't count scores made with supposedly unranked mods
|
// Don't count scores made with supposedly unranked mods
|
||||||
@ -71,10 +71,10 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
ar = Math.Max(0, ar / 2);
|
ar = Math.Max(0, ar / 2);
|
||||||
|
|
||||||
double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate;
|
double preEmpt = BeatmapDifficulty.DifficultyRange(ar, 1800, 1200, 450) / TimeRate;
|
||||||
double hitWindow300 = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate;
|
double hitWindowGreat = (Beatmap.HitObjects.First().HitWindows.Great / 2 - 0.5) / TimeRate;
|
||||||
|
|
||||||
realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5;
|
realApproachRate = preEmpt > 1200 ? (1800 - preEmpt) / 120 : (1200 - preEmpt) / 150 + 5;
|
||||||
realOverallDifficulty = (80 - 0.5 - hitWindow300) / 6;
|
realOverallDifficulty = (80 - 0.5 - hitWindowGreat) / 6;
|
||||||
|
|
||||||
// Custom multipliers for NoFail and SpunOut.
|
// Custom multipliers for NoFail and SpunOut.
|
||||||
double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things
|
double multiplier = 1.12f; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things
|
||||||
@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
int amountHitObjectsWithAccuracy = countHitCircles;
|
int amountHitObjectsWithAccuracy = countHitCircles;
|
||||||
|
|
||||||
if (amountHitObjectsWithAccuracy > 0)
|
if (amountHitObjectsWithAccuracy > 0)
|
||||||
betterAccuracyPercentage = ((count300 - (totalHits - amountHitObjectsWithAccuracy)) * 6 + count100 * 2 + count50) / (amountHitObjectsWithAccuracy * 6);
|
betterAccuracyPercentage = ((countGreat - (totalHits - amountHitObjectsWithAccuracy)) * 6 + countGood * 2 + countMeh) / (amountHitObjectsWithAccuracy * 6);
|
||||||
else
|
else
|
||||||
betterAccuracyPercentage = 0;
|
betterAccuracyPercentage = 0;
|
||||||
|
|
||||||
@ -213,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
return accuracyValue;
|
return accuracyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double totalHits => count300 + count100 + count50 + countMiss;
|
private double totalHits => countGreat + countGood + countMeh + countMiss;
|
||||||
private double totalSuccessfulHits => count300 + count100 + count50;
|
private double totalSuccessfulHits => countGreat + countGood + countMeh;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,16 +5,14 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
{
|
{
|
||||||
internal class TaikoBeatmapConversionTest : BeatmapConversionTest<TestTaikoRuleset, ConvertValue>
|
internal class TaikoBeatmapConversionTest : BeatmapConversionTest<ConvertValue>
|
||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
||||||
|
|
||||||
@ -40,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmapConverter CreateConverter(IBeatmap beatmap) => new TaikoBeatmapConverter(beatmap);
|
protected override Ruleset CreateRuleset() => new TaikoRuleset();
|
||||||
}
|
}
|
||||||
|
|
||||||
internal struct ConvertValue : IEquatable<ConvertValue>
|
internal struct ConvertValue : IEquatable<ConvertValue>
|
||||||
@ -67,8 +65,4 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
&& IsSwell == other.IsSwell
|
&& IsSwell == other.IsSwell
|
||||||
&& IsStrong == other.IsStrong;
|
&& IsStrong == other.IsStrong;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class TestTaikoRuleset : TaikoRuleset
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -19,10 +19,10 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
|
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
|
||||||
{
|
{
|
||||||
const float ratio = 1.4f;
|
const float ratio = 1.4f;
|
||||||
difficulty.CircleSize *= 1.3f; // CS uses a custom 1.3 ratio.
|
difficulty.CircleSize = Math.Min(difficulty.CircleSize * 1.3f, 10.0f); // CS uses a custom 1.3 ratio.
|
||||||
difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f);
|
difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f);
|
||||||
difficulty.DrainRate *= ratio;
|
difficulty.DrainRate = Math.Min(difficulty.DrainRate * ratio, 10.0f);
|
||||||
difficulty.OverallDifficulty *= ratio;
|
difficulty.OverallDifficulty = Math.Min(difficulty.OverallDifficulty * ratio, 10.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
namespace osu.Game.Tests.Beatmaps
|
namespace osu.Game.Tests.Beatmaps
|
||||||
{
|
{
|
||||||
[TestFixture]
|
[TestFixture]
|
||||||
public abstract class BeatmapConversionTest<TRuleset, TConvertValue>
|
public abstract class BeatmapConversionTest<TConvertValue>
|
||||||
where TRuleset : Ruleset, new()
|
|
||||||
where TConvertValue : IEquatable<TConvertValue>
|
where TConvertValue : IEquatable<TConvertValue>
|
||||||
{
|
{
|
||||||
private const string resource_namespace = "Testing.Beatmaps";
|
private const string resource_namespace = "Testing.Beatmaps";
|
||||||
@ -81,12 +80,12 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
{
|
{
|
||||||
var beatmap = getBeatmap(name);
|
var beatmap = getBeatmap(name);
|
||||||
|
|
||||||
var rulesetInstance = new TRuleset();
|
var rulesetInstance = CreateRuleset();
|
||||||
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
|
beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo();
|
||||||
|
|
||||||
var result = new ConvertResult();
|
var result = new ConvertResult();
|
||||||
|
|
||||||
var converter = CreateConverter(beatmap);
|
var converter = rulesetInstance.CreateBeatmapConverter(beatmap);
|
||||||
converter.ObjectConverted += (orig, converted) =>
|
converter.ObjectConverted += (orig, converted) =>
|
||||||
{
|
{
|
||||||
converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty));
|
converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty));
|
||||||
@ -130,7 +129,7 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected abstract IEnumerable<TConvertValue> CreateConvertValue(HitObject hitObject);
|
protected abstract IEnumerable<TConvertValue> CreateConvertValue(HitObject hitObject);
|
||||||
protected abstract IBeatmapConverter CreateConverter(IBeatmap beatmap);
|
protected abstract Ruleset CreateRuleset();
|
||||||
|
|
||||||
private class ConvertMapping
|
private class ConvertMapping
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user