From d74652a4f700a168ebcd8482f74a7b105240f04f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 09:38:02 +0900 Subject: [PATCH 01/22] Replace piecewise linear function --- .../Difficulty/Skills/Speed.cs | 18 ++---------------- 1 file changed, 2 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 1cde03624b..06470e7fac 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; namespace osu.Game.Rulesets.Osu.Difficulty.Skills @@ -14,26 +15,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double StrainDecayBase => 0.3; private const double single_spacing_threshold = 125; - private const double stream_spacing_threshold = 110; - private const double almost_diameter = 90; protected override double StrainValueOf(OsuDifficultyHitObject current) { double distance = current.TravelDistance + current.JumpDistance; - - double speedValue; - if (distance > single_spacing_threshold) - speedValue = 2.5; - else if (distance > stream_spacing_threshold) - speedValue = 1.6 + 0.9 * (distance - stream_spacing_threshold) / (single_spacing_threshold - stream_spacing_threshold); - else if (distance > almost_diameter) - speedValue = 1.2 + 0.4 * (distance - almost_diameter) / (stream_spacing_threshold - almost_diameter); - else if (distance > almost_diameter / 2) - speedValue = 0.95 + 0.25 * (distance - almost_diameter / 2) / (almost_diameter / 2); - else - speedValue = 0.95; - - return speedValue / current.StrainTime; + return (1 + Math.Pow(distance / single_spacing_threshold, 4)) / current.StrainTime; } } } From 47721f7a079f9e2e19fd1611347b478c7aafc97a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 09:49:54 +0900 Subject: [PATCH 02/22] Adjust base value --- osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs | 3 +++ osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 4 +--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs index 47037c1503..cf6114978a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Skill.cs @@ -15,6 +15,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public abstract class Skill { + protected const double SINGLE_SPACING_THRESHOLD = 125; + protected const double STREAM_SPACING_THRESHOLD = 110; + /// /// Strain values are multiplied by this number for the given skill. Used to balance the value of different skills between each other. /// diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 06470e7fac..a5ead317fa 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -14,12 +14,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; - private const double single_spacing_threshold = 125; - protected override double StrainValueOf(OsuDifficultyHitObject current) { double distance = current.TravelDistance + current.JumpDistance; - return (1 + Math.Pow(distance / single_spacing_threshold, 4)) / current.StrainTime; + return (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } } } From 00a4d60e8910869457d3e70ec04b6727b705d15f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 10:29:36 +0900 Subject: [PATCH 03/22] Make sure distance is clamped to sane values --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index a5ead317fa..c585a14dd0 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double StrainValueOf(OsuDifficultyHitObject current) { - double distance = current.TravelDistance + current.JumpDistance; + double distance = Math.Min(SINGLE_SPACING_THRESHOLD, current.TravelDistance + current.JumpDistance); return (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } } From e7da5b0400e3d388529c9eaa1c9b1dd3423c7971 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 18 Dec 2018 09:51:49 +0900 Subject: [PATCH 04/22] Add the [200 .. 300] bpm speed bonus --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index c585a14dd0..788dab37d3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -14,10 +14,20 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; + private const double min_speed_bonus = 75; // ~200BPM + private const double max_speed_bonus = 45; // ~330BPM + private const double speed_balancing_factor = 40; + protected override double StrainValueOf(OsuDifficultyHitObject current) { double distance = Math.Min(SINGLE_SPACING_THRESHOLD, current.TravelDistance + current.JumpDistance); - return (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; + double deltaTime = Math.Max(max_speed_bonus, current.DeltaTime); + + double speedBonus = 1.0; + if (deltaTime < min_speed_bonus) + speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2); + + return speedBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } } } From f4eabacd1568c075cba7990cac2b03923b5e0294 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 8 Dec 2018 15:01:26 +0900 Subject: [PATCH 05/22] Implement angle assessment --- .../Preprocessing/OsuDifficultyBeatmap.cs | 8 +++++- .../Preprocessing/OsuDifficultyHitObject.cs | 26 ++++++++++++++++++- .../Difficulty/Skills/Aim.cs | 23 +++++++++++++++- .../Difficulty/Skills/Speed.cs | 14 +++++++++- 4 files changed, 67 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs index 24d4677981..53f9d6d5f1 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -38,7 +38,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing // The first jump is formed by the first two hitobjects of the map. // If the map has less than two OsuHitObjects, the enumerator will not return anything. for (int i = 1; i < objects.Count; i++) - yield return new OsuDifficultyHitObject(objects[i], objects[i - 1], timeRate); + { + var prev = objects[i - 1]; + var current = objects[i]; + var next = i < objects.Count - 1 ? objects[i + 1] : null; + + yield return new OsuDifficultyHitObject(prev, current, next, timeRate); + } } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index d8e3b340c9..5657f0008e 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -40,15 +40,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing /// public double StrainTime { get; private set; } + public double? Angle { get; private set; } + private readonly OsuHitObject lastObject; + private readonly OsuHitObject nextObject; private readonly double timeRate; /// /// Initializes the object calculating extra data required for difficulty calculation. /// - public OsuDifficultyHitObject(OsuHitObject currentObject, OsuHitObject lastObject, double timeRate) + public OsuDifficultyHitObject(OsuHitObject lastObject, OsuHitObject currentObject, OsuHitObject nextObject, double timeRate) { this.lastObject = lastObject; + this.nextObject = nextObject; this.timeRate = timeRate; BaseObject = currentObject; @@ -82,6 +86,26 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing // Don't need to jump to reach spinners if (!(BaseObject is Spinner)) JumpDistance = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor).Length; + + if (nextObject != null) + { + var endCursorPosition = BaseObject.StackedPosition; + + var currentSlider = BaseObject as Slider; + if (currentSlider != null) + { + computeSliderCursorPosition(currentSlider); + endCursorPosition = currentSlider.LazyEndPosition ?? endCursorPosition; + } + + Vector2 v1 = lastCursorPosition - BaseObject.StackedPosition; + Vector2 v2 = nextObject.StackedPosition - endCursorPosition; + + float dot = Vector2.Dot(v1, v2); + float det = v1.X * v2.Y - v1.Y * v2.X; + + Angle = Math.Atan2(det, dot); + } } private void setTimingValues() diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index f11b6d66f6..7ba373fcff 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -15,6 +15,27 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double StrainDecayBase => 0.15; protected override double StrainValueOf(OsuDifficultyHitObject current) - => (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime; + { + double angleBonus = 1.0; + + if (current.Angle != null) + { + double angle = current.Angle.Value * 180 / Math.PI; + + if (current.JumpDistance > SINGLE_SPACING_THRESHOLD) + { + if (angle > 75) + angleBonus = (angle / 45 - 75) / 2; + else if (angle > 120) + angleBonus = 0.5; + } + } + + return angleBonus * ( + Math.Pow(current.JumpDistance - SINGLE_SPACING_THRESHOLD, 0.99) + + Math.Pow(current.TravelDistance, 0.99) + + Math.Pow(current.JumpDistance, 0.99) + ) / current.StrainTime; + } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 788dab37d3..0c943c786a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -27,7 +27,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills if (deltaTime < min_speed_bonus) speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2); - return speedBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; + double angleBonus = 1.0; + + if (current.Angle != null) + { + double angle = current.Angle.Value * 180 / Math.PI; + + if (angle < 135) + angleBonus = (135 - angle / 45) * 0.25 + 1.0; + else if (angle <= 90) + angleBonus = 1.25; + } + + return angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } } } From 9ad7970167937ce9847b9b3300fa1ae7ed4c6bc8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 8 Dec 2018 15:52:12 +0900 Subject: [PATCH 06/22] Adjust computations to return sane values --- .../Difficulty/Skills/Aim.cs | 23 ++++++++----------- .../Difficulty/Skills/Speed.cs | 15 ++++++------ 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 7ba373fcff..3d69f3b4eb 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -3,6 +3,7 @@ using System; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; +using osuTK; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { @@ -11,28 +12,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Aim : Skill { + private const double min_angle_bonus = 0; + private const double max_angle_bonus = 0.5; + private const double angle_bonus_begin = 5 * Math.PI / 12; + private const double pi_over_2 = Math.PI / 2; + protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; protected override double StrainValueOf(OsuDifficultyHitObject current) { - double angleBonus = 1.0; + double angleBonus = 0; if (current.Angle != null) - { - double angle = current.Angle.Value * 180 / Math.PI; + angleBonus = MathHelper.Clamp((current.Angle.Value - angle_bonus_begin) / pi_over_2, min_angle_bonus, max_angle_bonus); - if (current.JumpDistance > SINGLE_SPACING_THRESHOLD) - { - if (angle > 75) - angleBonus = (angle / 45 - 75) / 2; - else if (angle > 120) - angleBonus = 0.5; - } - } - - return angleBonus * ( - Math.Pow(current.JumpDistance - SINGLE_SPACING_THRESHOLD, 0.99) + return (angleBonus * Math.Pow(Math.Max(0, current.JumpDistance - SINGLE_SPACING_THRESHOLD), 0.99) + Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99) ) / current.StrainTime; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 0c943c786a..e089713aa8 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -3,6 +3,7 @@ using System; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; +using osuTK; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { @@ -11,6 +12,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Speed : Skill { + private const double min_angle_bonus = 1.0; + private const double max_angle_bonus = 1.25; + private const double angle_bonus_begin = 3 * Math.PI / 4; + private const double pi_over_4 = Math.PI / 4; + protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; @@ -30,14 +36,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills double angleBonus = 1.0; if (current.Angle != null) - { - double angle = current.Angle.Value * 180 / Math.PI; - - if (angle < 135) - angleBonus = (135 - angle / 45) * 0.25 + 1.0; - else if (angle <= 90) - angleBonus = 1.25; - } + angleBonus = MathHelper.Clamp((angle_bonus_begin - current.Angle.Value) / pi_over_4 * 0.25 + 1.0, min_angle_bonus, max_angle_bonus); return angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } From 434d7d1809d1c72436fa41aeb15088522bb030de Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 9 Dec 2018 15:05:58 +0900 Subject: [PATCH 07/22] Replace piecewise linear function + rebalance --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index e089713aa8..db653deed7 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills double angleBonus = 1.0; if (current.Angle != null) - angleBonus = MathHelper.Clamp((angle_bonus_begin - current.Angle.Value) / pi_over_4 * 0.25 + 1.0, min_angle_bonus, max_angle_bonus); + angleBonus = MathHelper.Clamp((angle_bonus_begin - current.Angle.Value) / pi_over_4 * 0.5 + 1.0, min_angle_bonus, max_angle_bonus); return angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } From 162774ce2724fc0ae0d41b50f653bf1f26c9aaaa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 9 Dec 2018 20:31:04 +0900 Subject: [PATCH 08/22] Make angles unsigned --- .../Difficulty/Preprocessing/OsuDifficultyHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 5657f0008e..6a0dd206ff 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -104,7 +104,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing float dot = Vector2.Dot(v1, v2); float det = v1.X * v2.Y - v1.Y * v2.X; - Angle = Math.Atan2(det, dot); + Angle = Math.Abs(Math.Atan2(det, dot)); } } From 1972f1f27918486881a3ad92bea56091621eb297 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 9 Dec 2018 20:42:27 +0900 Subject: [PATCH 09/22] Fix incorrect angle being used (at object vs into object) --- .../Preprocessing/OsuDifficultyBeatmap.cs | 6 +-- .../Preprocessing/OsuDifficultyHitObject.cs | 51 ++++++++++--------- 2 files changed, 31 insertions(+), 26 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs index 53f9d6d5f1..d10cd869b3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyBeatmap.cs @@ -39,11 +39,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing // If the map has less than two OsuHitObjects, the enumerator will not return anything. for (int i = 1; i < objects.Count; i++) { - var prev = objects[i - 1]; + var lastLast = i > 1 ? objects[i - 2] : null; + var last = objects[i - 1]; var current = objects[i]; - var next = i < objects.Count - 1 ? objects[i + 1] : null; - yield return new OsuDifficultyHitObject(prev, current, next, timeRate); + yield return new OsuDifficultyHitObject(lastLast, last, current, timeRate); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 6a0dd206ff..6275ac45fa 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -40,19 +40,23 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing /// public double StrainTime { get; private set; } + /// + /// Angle the player has to take to hit this . + /// Calculated as the angle between the circles (current-2, current-1, current). + /// public double? Angle { get; private set; } + private readonly OsuHitObject lastLastObject; private readonly OsuHitObject lastObject; - private readonly OsuHitObject nextObject; private readonly double timeRate; /// /// Initializes the object calculating extra data required for difficulty calculation. /// - public OsuDifficultyHitObject(OsuHitObject lastObject, OsuHitObject currentObject, OsuHitObject nextObject, double timeRate) + public OsuDifficultyHitObject(OsuHitObject lastLastObject, OsuHitObject lastObject, OsuHitObject currentObject, double timeRate) { + this.lastLastObject = lastLastObject; this.lastObject = lastObject; - this.nextObject = nextObject; this.timeRate = timeRate; BaseObject = currentObject; @@ -72,34 +76,21 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing scalingFactor *= 1 + smallCircleBonus; } - Vector2 lastCursorPosition = lastObject.StackedPosition; - - var lastSlider = lastObject as Slider; - if (lastSlider != null) - { - computeSliderCursorPosition(lastSlider); - lastCursorPosition = lastSlider.LazyEndPosition ?? lastCursorPosition; - + if (lastObject is Slider lastSlider) TravelDistance = lastSlider.LazyTravelDistance * scalingFactor; - } + + Vector2 lastCursorPosition = getEndCursorPosition(lastObject); // Don't need to jump to reach spinners if (!(BaseObject is Spinner)) JumpDistance = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor).Length; - if (nextObject != null) + if (lastLastObject != null) { - var endCursorPosition = BaseObject.StackedPosition; + Vector2 lastLastCursorPosition = getEndCursorPosition(lastLastObject); - var currentSlider = BaseObject as Slider; - if (currentSlider != null) - { - computeSliderCursorPosition(currentSlider); - endCursorPosition = currentSlider.LazyEndPosition ?? endCursorPosition; - } - - Vector2 v1 = lastCursorPosition - BaseObject.StackedPosition; - Vector2 v2 = nextObject.StackedPosition - endCursorPosition; + Vector2 v1 = lastLastCursorPosition - lastObject.StackedPosition; + Vector2 v2 = BaseObject.StackedPosition - lastCursorPosition; float dot = Vector2.Dot(v1, v2); float det = v1.X * v2.Y - v1.Y * v2.X; @@ -151,5 +142,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing computeVertex(time); computeVertex(slider.EndTime); } + + private Vector2 getEndCursorPosition(OsuHitObject hitObject) + { + Vector2 pos = hitObject.StackedPosition; + + var slider = hitObject as Slider; + if (slider != null) + { + computeSliderCursorPosition(slider); + pos = slider.LazyEndPosition ?? pos; + } + + return pos; + } } } From 0fee76c95c3bf1d7078d865b8bd22412f8ef21f1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 13:30:55 +0900 Subject: [PATCH 10/22] Fix merge error --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index db653deed7..25afebea3a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -34,11 +34,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2); double angleBonus = 1.0; - if (current.Angle != null) angleBonus = MathHelper.Clamp((angle_bonus_begin - current.Angle.Value) / pi_over_4 * 0.5 + 1.0, min_angle_bonus, max_angle_bonus); - return angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; + return speedBonus * angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } } } From 1c44e19066cf43a8262d79c1c2bf4bda851e5d6c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 19 Dec 2018 13:53:47 +0900 Subject: [PATCH 11/22] Adjust scaling factor --- .../Difficulty/Preprocessing/OsuDifficultyHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 6275ac45fa..b349b7f006 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing float scalingFactor = normalized_radius / (float)BaseObject.Radius; if (BaseObject.Radius < 30) { - float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50; + float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 30; scalingFactor *= 1 + smallCircleBonus; } From 3acbf75bebbeb85d259ed67d19cf854afb8b8e47 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 13:48:10 +0900 Subject: [PATCH 12/22] Adjust threshold --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 3d69f3b4eb..876f431ced 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills if (current.Angle != null) angleBonus = MathHelper.Clamp((current.Angle.Value - angle_bonus_begin) / pi_over_2, min_angle_bonus, max_angle_bonus); - return (angleBonus * Math.Pow(Math.Max(0, current.JumpDistance - SINGLE_SPACING_THRESHOLD), 0.99) + return (angleBonus * Math.Pow(Math.Max(0, current.JumpDistance - STREAM_SPACING_THRESHOLD), 0.99) + Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99) ) / current.StrainTime; From 38441759a78b448313729a2b6b8bf9464f4c1f94 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 14:52:43 +0900 Subject: [PATCH 13/22] Use angle projections --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 876f431ced..cf9c4249f3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -12,10 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Aim : Skill { - private const double min_angle_bonus = 0; - private const double max_angle_bonus = 0.5; private const double angle_bonus_begin = 5 * Math.PI / 12; - private const double pi_over_2 = Math.PI / 2; protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; @@ -24,13 +21,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { double angleBonus = 0; - if (current.Angle != null) - angleBonus = MathHelper.Clamp((current.Angle.Value - angle_bonus_begin) / pi_over_2, min_angle_bonus, max_angle_bonus); + double result = 0; - return (angleBonus * Math.Pow(Math.Max(0, current.JumpDistance - STREAM_SPACING_THRESHOLD), 0.99) - + Math.Pow(current.TravelDistance, 0.99) - + Math.Pow(current.JumpDistance, 0.99) - ) / current.StrainTime; + if (Previous.Count > 0) + { + if (current.Angle != null) + angleBonus = (Previous[0].JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin); + result = Math.Pow(Math.Max(0, angleBonus), 0.99) / Previous[0].StrainTime; + } + + return result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime; } } } From 5bd16f9a7ca3f8fd9f3a6fb9897d30e5d7fbc60f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 15:16:00 +0900 Subject: [PATCH 14/22] Add scaling factor --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index cf9c4249f3..0830e5dfd5 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { if (current.Angle != null) angleBonus = (Previous[0].JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin); - result = Math.Pow(Math.Max(0, angleBonus), 0.99) / Previous[0].StrainTime; + result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Previous[0].StrainTime; } return result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime; From be476c58d713ed5d98e7eebf76299281f3927526 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 21 Dec 2018 22:52:27 +0900 Subject: [PATCH 15/22] Adjust with latest rebalancings --- .../Difficulty/Preprocessing/OsuDifficultyHitObject.cs | 2 +- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 8 +++++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index b349b7f006..6275ac45fa 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -72,7 +72,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing float scalingFactor = normalized_radius / (float)BaseObject.Radius; if (BaseObject.Radius < 30) { - float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 30; + float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50; scalingFactor *= 1 + smallCircleBonus; } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 0830e5dfd5..9e3041b5fd 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -26,7 +26,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills if (Previous.Count > 0) { if (current.Angle != null) - angleBonus = (Previous[0].JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin); + { + angleBonus = Math.Min( + (Previous[0].JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin), + (current.JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin) + ); + } + result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Previous[0].StrainTime; } From 8546fedd4f97c5d1e8c01c362e00cb71db66f7af Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 09:31:30 +0900 Subject: [PATCH 16/22] Implement vinxis/xexxar's adjustments --- .../Difficulty/Skills/Aim.cs | 30 ++++++++++++------- .../Difficulty/Skills/Speed.cs | 13 ++++---- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 9e3041b5fd..87d561b38f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; -using osuTK; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { @@ -13,30 +12,39 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills public class Aim : Skill { private const double angle_bonus_begin = 5 * Math.PI / 12; + private const double timing_threshold = 107; + private const double min_distance_for_bonus = 90; + + private const double angle_threshold = Math.PI / 4; protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; protected override double StrainValueOf(OsuDifficultyHitObject current) { - double angleBonus = 0; - double result = 0; if (Previous.Count > 0) { - if (current.Angle != null) + if (current.Angle != null && current.Angle.Value > angle_bonus_begin) { - angleBonus = Math.Min( - (Previous[0].JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin), - (current.JumpDistance - STREAM_SPACING_THRESHOLD) * Math.Sin(current.Angle.Value - angle_bonus_begin) - ); - } + var angleBonus = Math.Sqrt( + Math.Max(0, Previous[0].JumpDistance + Previous[0].TravelDistance - min_distance_for_bonus) + * Math.Min( + Math.Sin(current.Angle.Value - angle_bonus_begin), + Math.Sin(angle_threshold)) + * (Math.Max(0, current.JumpDistance - min_distance_for_bonus) + * Math.Min( + Math.Sin(current.Angle.Value - angle_bonus_begin), + Math.Sin(angle_threshold)))); - result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Previous[0].StrainTime; + result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Math.Max(Previous[0].StrainTime, timing_threshold); + } } - return result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime; + return Math.Max( + result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / Math.Max(current.StrainTime, timing_threshold), + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 25afebea3a..daa77d8872 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -3,7 +3,6 @@ using System; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; -using osuTK; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { @@ -12,8 +11,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Speed : Skill { - private const double min_angle_bonus = 1.0; - private const double max_angle_bonus = 1.25; private const double angle_bonus_begin = 3 * Math.PI / 4; private const double pi_over_4 = Math.PI / 4; @@ -34,8 +31,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2); double angleBonus = 1.0; - if (current.Angle != null) - angleBonus = MathHelper.Clamp((angle_bonus_begin - current.Angle.Value) / pi_over_4 * 0.5 + 1.0, min_angle_bonus, max_angle_bonus); + if (current.Angle != null && current.Angle.Value < angle_bonus_begin) + { + angleBonus = 1 + Math.Min(Math.Sin(angle_bonus_begin - current.Angle.Value), Math.Sin(Math.PI / 4)) / 2.5; + if (distance < 90 && current.Angle.Value < Math.PI / 4) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1); + else if (distance < 90 && current.Angle.Value < Math.PI / 2) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1) * Math.Sin((Math.PI / 2 - current.Angle.Value) / pi_over_4); + } return speedBonus * angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; } From c848c83d0daa5e26cf82bb8c245613e98802d15c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 22 Dec 2018 09:56:33 +0900 Subject: [PATCH 17/22] Refactor for readability + performance --- .../Difficulty/Skills/Aim.cs | 33 ++++++++++++------- .../Difficulty/Skills/Speed.cs | 27 ++++++++++++--- 2 files changed, 44 insertions(+), 16 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 87d561b38f..d6137dff82 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -14,9 +14,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills private const double angle_bonus_begin = 5 * Math.PI / 12; private const double timing_threshold = 107; private const double min_distance_for_bonus = 90; - private const double angle_threshold = Math.PI / 4; + private static readonly double sin_angle_threshold = Math.Sin(angle_threshold); + protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; @@ -28,23 +29,33 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { if (current.Angle != null && current.Angle.Value > angle_bonus_begin) { - var angleBonus = Math.Sqrt( + var sinDiffAngle = Math.Sin(current.Angle.Value - angle_bonus_begin); + + var angleBonus = Math.Sqrt + ( Math.Max(0, Previous[0].JumpDistance + Previous[0].TravelDistance - min_distance_for_bonus) - * Math.Min( - Math.Sin(current.Angle.Value - angle_bonus_begin), - Math.Sin(angle_threshold)) - * (Math.Max(0, current.JumpDistance - min_distance_for_bonus) - * Math.Min( - Math.Sin(current.Angle.Value - angle_bonus_begin), - Math.Sin(angle_threshold)))); + * Math.Min + ( + sinDiffAngle, + sin_angle_threshold + ) + * Math.Max(0, current.JumpDistance - min_distance_for_bonus) + * Math.Min + ( + sinDiffAngle, + sin_angle_threshold + ) + ); result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Math.Max(Previous[0].StrainTime, timing_threshold); } } - return Math.Max( + return Math.Max + ( result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / Math.Max(current.StrainTime, timing_threshold), - (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime); + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime + ); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index daa77d8872..f63013b2af 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -13,6 +13,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { private const double angle_bonus_begin = 3 * Math.PI / 4; private const double pi_over_4 = Math.PI / 4; + private const double pi_over_2 = Math.PI / 2; + private const double max_distance_for_bonus = 90; + + private static readonly double sin_pi_over_4 = Math.Sin(pi_over_4); protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; @@ -33,11 +37,24 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills double angleBonus = 1.0; if (current.Angle != null && current.Angle.Value < angle_bonus_begin) { - angleBonus = 1 + Math.Min(Math.Sin(angle_bonus_begin - current.Angle.Value), Math.Sin(Math.PI / 4)) / 2.5; - if (distance < 90 && current.Angle.Value < Math.PI / 4) - angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1); - else if (distance < 90 && current.Angle.Value < Math.PI / 2) - angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1) * Math.Sin((Math.PI / 2 - current.Angle.Value) / pi_over_4); + angleBonus = 1 + Math.Min(Math.Sin(angle_bonus_begin - current.Angle.Value), sin_pi_over_4) / 2.5; + + if (distance < max_distance_for_bonus) + { + if (current.Angle.Value < pi_over_4) + { + angleBonus += + (1 - angleBonus) + * Math.Min((max_distance_for_bonus - distance) / 10, 1); + } + else if (current.Angle.Value < pi_over_2) + { + angleBonus += + (1 - angleBonus) + * Math.Min((max_distance_for_bonus - distance) / 10, 1) + * Math.Sin((pi_over_2 - current.Angle.Value) / pi_over_4); + } + } } return speedBonus * angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; From 9fcc727e0d375156f02436b31040c8674d57e31c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 23 Dec 2018 16:26:23 +0900 Subject: [PATCH 18/22] Fix TravelDistance not being calculated --- .../Difficulty/Preprocessing/OsuDifficultyHitObject.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs index 6275ac45fa..a04fb8371f 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Preprocessing/OsuDifficultyHitObject.cs @@ -77,7 +77,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing } if (lastObject is Slider lastSlider) + { + computeSliderCursorPosition(lastSlider); TravelDistance = lastSlider.LazyTravelDistance * scalingFactor; + } Vector2 lastCursorPosition = getEndCursorPosition(lastObject); From c43c15a557e3cd5badfc4d6cf1606b8363bab213 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 23 Dec 2018 16:28:19 +0900 Subject: [PATCH 19/22] Multiply previous travel distance by 8 --- osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index d6137dff82..a3f4ddb752 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills var angleBonus = Math.Sqrt ( - Math.Max(0, Previous[0].JumpDistance + Previous[0].TravelDistance - min_distance_for_bonus) + Math.Max(0, Previous[0].JumpDistance + 8 * Previous[0].TravelDistance - min_distance_for_bonus) * Math.Min ( sinDiffAngle, From 5f0ab0ed7fb1294ce2e7914df2d5163ad7340759 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 24 Dec 2018 12:41:04 +0900 Subject: [PATCH 20/22] Update with vinxis' latest code --- .../Difficulty/Skills/Aim.cs | 47 +++++++------------ .../Difficulty/Skills/Speed.cs | 28 ++++------- 2 files changed, 26 insertions(+), 49 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index a3f4ddb752..7c6e855cb3 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -11,12 +11,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Aim : Skill { - private const double angle_bonus_begin = 5 * Math.PI / 12; + private const double angle_bonus_begin = Math.PI / 3; private const double timing_threshold = 107; - private const double min_distance_for_bonus = 90; - private const double angle_threshold = Math.PI / 4; - - private static readonly double sin_angle_threshold = Math.Sin(angle_threshold); protected override double SkillMultiplier => 26.25; protected override double StrainDecayBase => 0.15; @@ -25,37 +21,30 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills { double result = 0; + const double scale = 90; + if (Previous.Count > 0) { if (current.Angle != null && current.Angle.Value > angle_bonus_begin) { - var sinDiffAngle = Math.Sin(current.Angle.Value - angle_bonus_begin); - - var angleBonus = Math.Sqrt - ( - Math.Max(0, Previous[0].JumpDistance + 8 * Previous[0].TravelDistance - min_distance_for_bonus) - * Math.Min - ( - sinDiffAngle, - sin_angle_threshold - ) - * Math.Max(0, current.JumpDistance - min_distance_for_bonus) - * Math.Min - ( - sinDiffAngle, - sin_angle_threshold - ) - ); - - result = 2 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Math.Max(Previous[0].StrainTime, timing_threshold); + var angleBonus = Math.Sqrt( + Math.Max(Previous[0].JumpDistance - scale, 0) + * Math.Pow(Math.Sin(current.Angle.Value - angle_bonus_begin), 2) + * Math.Max(current.JumpDistance - scale, 0)); + result = 1.5 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Math.Max(timing_threshold, Previous[0].StrainTime); } } - return Math.Max - ( - result + (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / Math.Max(current.StrainTime, timing_threshold), - (Math.Pow(current.TravelDistance, 0.99) + Math.Pow(current.JumpDistance, 0.99)) / current.StrainTime - ); + return Math.Max( + result + ( + Math.Pow(current.JumpDistance, 0.99) + + Math.Pow(current.TravelDistance, 0.99) + + Math.Sqrt(Math.Pow(current.TravelDistance, 0.99) * Math.Pow(current.JumpDistance, 0.99))) + / Math.Max(current.StrainTime, timing_threshold), + (Math.Sqrt(Math.Pow(current.TravelDistance, 0.99) * Math.Pow(current.JumpDistance, 0.99)) + + Math.Pow(current.JumpDistance, 0.99) + + Math.Pow(current.TravelDistance, 0.99)) + / current.StrainTime); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index f63013b2af..734d74edf4 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -11,12 +11,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills /// public class Speed : Skill { - private const double angle_bonus_begin = 3 * Math.PI / 4; + private const double angle_bonus_begin = 5 * Math.PI / 6; private const double pi_over_4 = Math.PI / 4; private const double pi_over_2 = Math.PI / 2; - private const double max_distance_for_bonus = 90; - - private static readonly double sin_pi_over_4 = Math.Sin(pi_over_4); protected override double SkillMultiplier => 1400; protected override double StrainDecayBase => 0.3; @@ -37,23 +34,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills double angleBonus = 1.0; if (current.Angle != null && current.Angle.Value < angle_bonus_begin) { - angleBonus = 1 + Math.Min(Math.Sin(angle_bonus_begin - current.Angle.Value), sin_pi_over_4) / 2.5; - - if (distance < max_distance_for_bonus) + angleBonus = 1 + Math.Pow(Math.Sin(1.5 * (angle_bonus_begin - current.Angle.Value)), 2) / 3.57; + if (current.Angle.Value < pi_over_2) { - if (current.Angle.Value < pi_over_4) - { - angleBonus += - (1 - angleBonus) - * Math.Min((max_distance_for_bonus - distance) / 10, 1); - } - else if (current.Angle.Value < pi_over_2) - { - angleBonus += - (1 - angleBonus) - * Math.Min((max_distance_for_bonus - distance) / 10, 1) - * Math.Sin((pi_over_2 - current.Angle.Value) / pi_over_4); - } + angleBonus = 1.28; + if (distance < 90 && current.Angle.Value < pi_over_4) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1); + else if (distance < 90) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1) * Math.Sin((pi_over_2 - current.Angle.Value) / pi_over_4); } } From 77e6f4ab92e64bfcccefa8b6463dd8e2bd49d5e1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 27 Dec 2018 18:41:42 +0900 Subject: [PATCH 21/22] Rebalance --- osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 734d74edf4..e0896f75d8 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills } } - return speedBonus * angleBonus * (0.95 + Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 4)) / current.StrainTime; + return (1 + (speedBonus - 1) * .75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 3.5)) / current.StrainTime; } } } From 8d4232af45757b755dc2f8475cabc236bf258e4c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 29 Jan 2019 16:35:20 +0900 Subject: [PATCH 22/22] Formatting and minor optimisations --- .../Difficulty/Skills/Aim.cs | 19 +++++++++---------- .../Difficulty/Skills/Speed.cs | 2 +- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs index 03761a7d86..b5e57985e9 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Aim.cs @@ -23,6 +23,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills const double scale = 90; + double applyDiminishingExp(double val) => Math.Pow(val, 0.99); + if (Previous.Count > 0) { if (current.Angle != null && current.Angle.Value > angle_bonus_begin) @@ -31,20 +33,17 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills Math.Max(Previous[0].JumpDistance - scale, 0) * Math.Pow(Math.Sin(current.Angle.Value - angle_bonus_begin), 2) * Math.Max(current.JumpDistance - scale, 0)); - result = 1.5 * Math.Pow(Math.Max(0, angleBonus), 0.99) / Math.Max(timing_threshold, Previous[0].StrainTime); + result = 1.5 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, Previous[0].StrainTime); } } + double jumpDistanceExp = applyDiminishingExp(current.JumpDistance); + double travelDistanceExp = applyDiminishingExp(current.TravelDistance); + return Math.Max( - result + ( - Math.Pow(current.JumpDistance, 0.99) - + Math.Pow(current.TravelDistance, 0.99) - + Math.Sqrt(Math.Pow(current.TravelDistance, 0.99) * Math.Pow(current.JumpDistance, 0.99))) - / Math.Max(current.StrainTime, timing_threshold), - (Math.Sqrt(Math.Pow(current.TravelDistance, 0.99) * Math.Pow(current.JumpDistance, 0.99)) - + Math.Pow(current.JumpDistance, 0.99) - + Math.Pow(current.TravelDistance, 0.99)) - / current.StrainTime); + result + (jumpDistanceExp + travelDistanceExp + Math.Sqrt(travelDistanceExp * jumpDistanceExp)) / Math.Max(current.StrainTime, timing_threshold), + (Math.Sqrt(travelDistanceExp * jumpDistanceExp) + jumpDistanceExp + travelDistanceExp) / current.StrainTime + ); } } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 4faff2b75e..e78691ce53 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills } } - return (1 + (speedBonus - 1) * .75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 3.5)) / current.StrainTime; + return (1 + (speedBonus - 1) * 0.75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / SINGLE_SPACING_THRESHOLD, 3.5)) / current.StrainTime; } } }