mirror of
https://github.com/osukey/osukey.git
synced 2025-05-29 17:37:23 +09:00
Add Flashlight skill
This commit is contained in:
parent
c8a0b6058f
commit
acdd08c966
@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
{
|
{
|
||||||
public double AimStrain { get; set; }
|
public double AimStrain { get; set; }
|
||||||
public double SpeedStrain { get; set; }
|
public double SpeedStrain { get; set; }
|
||||||
|
public double FlashlightStrain { get; set; }
|
||||||
public double ApproachRate { get; set; }
|
public double ApproachRate { get; set; }
|
||||||
public double OverallDifficulty { get; set; }
|
public double OverallDifficulty { get; set; }
|
||||||
public int HitCircleCount { get; set; }
|
public int HitCircleCount { get; set; }
|
||||||
|
@ -34,6 +34,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
||||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||||
|
double flashlightRating = Math.Sqrt(skills[2].DifficultyValue()) * difficulty_multiplier;
|
||||||
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2;
|
||||||
|
|
||||||
HitWindows hitWindows = new OsuHitWindows();
|
HitWindows hitWindows = new OsuHitWindows();
|
||||||
@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
Mods = mods,
|
Mods = mods,
|
||||||
AimStrain = aimRating,
|
AimStrain = aimRating,
|
||||||
SpeedStrain = speedRating,
|
SpeedStrain = speedRating,
|
||||||
|
FlashlightStrain = flashlightRating,
|
||||||
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
||||||
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
||||||
MaxCombo = maxCombo,
|
MaxCombo = maxCombo,
|
||||||
@ -82,7 +84,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
|
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
|
||||||
{
|
{
|
||||||
new Aim(mods),
|
new Aim(mods),
|
||||||
new Speed(mods)
|
new Speed(mods),
|
||||||
|
new Flashlight(mods)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
protected override Mod[] DifficultyAdjustmentMods => new Mod[]
|
||||||
|
@ -52,11 +52,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
double aimValue = computeAimValue();
|
double aimValue = computeAimValue();
|
||||||
double speedValue = computeSpeedValue();
|
double speedValue = computeSpeedValue();
|
||||||
double accuracyValue = computeAccuracyValue();
|
double accuracyValue = computeAccuracyValue();
|
||||||
|
double flashlightValue = computeFlashlightValue();
|
||||||
double totalValue =
|
double totalValue =
|
||||||
Math.Pow(
|
Math.Pow(
|
||||||
Math.Pow(aimValue, 1.1) +
|
Math.Pow(aimValue, 1.1) +
|
||||||
Math.Pow(speedValue, 1.1) +
|
Math.Pow(speedValue, 1.1) +
|
||||||
Math.Pow(accuracyValue, 1.1), 1.0 / 1.1
|
Math.Pow(accuracyValue, 1.1) +
|
||||||
|
Math.Pow(flashlightValue, 1.1), 1.0 / 1.1
|
||||||
) * multiplier;
|
) * multiplier;
|
||||||
|
|
||||||
if (categoryRatings != null)
|
if (categoryRatings != null)
|
||||||
@ -64,6 +66,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
categoryRatings.Add("Aim", aimValue);
|
categoryRatings.Add("Aim", aimValue);
|
||||||
categoryRatings.Add("Speed", speedValue);
|
categoryRatings.Add("Speed", speedValue);
|
||||||
categoryRatings.Add("Accuracy", accuracyValue);
|
categoryRatings.Add("Accuracy", accuracyValue);
|
||||||
|
categoryRatings.Add("Flashlight", flashlightValue);
|
||||||
categoryRatings.Add("OD", Attributes.OverallDifficulty);
|
categoryRatings.Add("OD", Attributes.OverallDifficulty);
|
||||||
categoryRatings.Add("AR", Attributes.ApproachRate);
|
categoryRatings.Add("AR", Attributes.ApproachRate);
|
||||||
categoryRatings.Add("Max Combo", Attributes.MaxCombo);
|
categoryRatings.Add("Max Combo", Attributes.MaxCombo);
|
||||||
@ -109,19 +112,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
if (mods.Any(h => h is OsuModHidden))
|
if (mods.Any(h => h is OsuModHidden))
|
||||||
aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate);
|
aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate);
|
||||||
|
|
||||||
double flashlightBonus = 1.0;
|
aimValue *= approachRateBonus;
|
||||||
|
|
||||||
if (mods.Any(h => h is OsuModFlashlight))
|
|
||||||
{
|
|
||||||
// Apply object-based bonus for flashlight.
|
|
||||||
flashlightBonus = 1.0 + 0.35 * Math.Min(1.0, totalHits / 200.0) +
|
|
||||||
(totalHits > 200
|
|
||||||
? 0.3 * Math.Min(1.0, (totalHits - 200) / 300.0) +
|
|
||||||
(totalHits > 500 ? (totalHits - 500) / 1200.0 : 0.0)
|
|
||||||
: 0.0);
|
|
||||||
}
|
|
||||||
|
|
||||||
aimValue *= Math.Max(flashlightBonus, approachRateBonus);
|
|
||||||
|
|
||||||
// Scale the aim value with accuracy _slightly_
|
// Scale the aim value with accuracy _slightly_
|
||||||
aimValue *= 0.5 + accuracy / 2.0;
|
aimValue *= 0.5 + accuracy / 2.0;
|
||||||
@ -197,6 +188,38 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
return accuracyValue;
|
return accuracyValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private double computeFlashlightValue()
|
||||||
|
{
|
||||||
|
double flashlightValue = 0.0;
|
||||||
|
|
||||||
|
if (mods.Any(h => h is OsuModFlashlight)) {
|
||||||
|
flashlightValue = Math.Pow(Attributes.FlashlightStrain, 2.0) * 25.0;
|
||||||
|
|
||||||
|
// Add an additional bonus for HDFL.
|
||||||
|
if (mods.Any(h => h is OsuModHidden))
|
||||||
|
flashlightValue *= 1.2;
|
||||||
|
|
||||||
|
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
|
||||||
|
if (countMiss > 0)
|
||||||
|
flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)countMiss / totalHits, 0.775), Math.Pow(countMiss, .875));
|
||||||
|
|
||||||
|
// Combo scaling
|
||||||
|
if (Attributes.MaxCombo > 0)
|
||||||
|
flashlightValue *= Math.Min(Math.Pow(scoreMaxCombo, 0.8) / Math.Pow(Attributes.MaxCombo, 0.8), 1.0);
|
||||||
|
|
||||||
|
// Account for shorter maps having a higher ratio of 0 combo/100 combo flashlight radius.
|
||||||
|
flashlightValue *= 0.5 + 0.15 * Math.Min(1.0, totalHits / 200.0) +
|
||||||
|
(totalHits > 200 ? 0.35 * Math.Min(1.0, (totalHits - 200) / 600.0) : 0.0);
|
||||||
|
|
||||||
|
// Scale the aim value with accuracy _slightly_
|
||||||
|
flashlightValue *= 0.5 + accuracy / 2.0;
|
||||||
|
// It is important to also consider accuracy difficulty when doing that
|
||||||
|
flashlightValue *= 0.98 + Math.Pow(Attributes.OverallDifficulty, 2) / 2500;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flashlightValue;
|
||||||
|
}
|
||||||
|
|
||||||
private int totalHits => countGreat + countOk + countMeh + countMiss;
|
private int totalHits => countGreat + countOk + countMeh + countMiss;
|
||||||
private int totalSuccessfulHits => countGreat + countOk + countMeh;
|
private int totalSuccessfulHits => countGreat + countOk + countMeh;
|
||||||
}
|
}
|
||||||
|
67
osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
Normal file
67
osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the skill required to memorise and hit every object in a map with the Flashlight mod enabled.
|
||||||
|
/// </summary>
|
||||||
|
public class Flashlight : OsuStrainSkill
|
||||||
|
{
|
||||||
|
public Flashlight(Mod[] mods)
|
||||||
|
: base(mods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double SkillMultiplier => 0.065;
|
||||||
|
protected override double StrainDecayBase => 0.15;
|
||||||
|
protected override double DecayWeight => 1.0;
|
||||||
|
|
||||||
|
protected override double StrainValueOf(DifficultyHitObject current)
|
||||||
|
{
|
||||||
|
if (current.BaseObject is Spinner)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
var osuCurrent = (OsuDifficultyHitObject)current;
|
||||||
|
var osuHitObject = (OsuHitObject)(osuCurrent.BaseObject);
|
||||||
|
|
||||||
|
double scalingFactor = 52.0 / osuHitObject.Radius;
|
||||||
|
double smallDistNerf = 1.0;
|
||||||
|
|
||||||
|
double result = 0.0;
|
||||||
|
|
||||||
|
if (Previous.Count > 0)
|
||||||
|
{
|
||||||
|
double cumulativeStrainTime = 0.0;
|
||||||
|
|
||||||
|
for (int i = 0; i < Previous.Count; i++) {
|
||||||
|
var osuPrevious = (OsuDifficultyHitObject)Previous[i];
|
||||||
|
var osuPreviousHitObject = (OsuHitObject)(osuPrevious.BaseObject);
|
||||||
|
|
||||||
|
if (!(osuPrevious.BaseObject is Spinner)) {
|
||||||
|
double JumpDistance = (osuHitObject.StackedPosition - osuPreviousHitObject.EndPosition).Length;
|
||||||
|
|
||||||
|
cumulativeStrainTime += osuPrevious.StrainTime;
|
||||||
|
|
||||||
|
// We want to nerf objects that can be easily seen within the Flashlight circle radius.
|
||||||
|
if (i == 0 && JumpDistance < 50.0) {
|
||||||
|
smallDistNerf = JumpDistance / 50.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result += Math.Pow(0.8, i) * scalingFactor * JumpDistance / cumulativeStrainTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.Pow(smallDistNerf * result, 2.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -28,6 +28,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual double DifficultyMultiplier => 1.06;
|
protected virtual double DifficultyMultiplier => 1.06;
|
||||||
|
|
||||||
|
protected override int HistoryLength => 10; // Look back for 10 notes is added for the sake of flashlight calculations.
|
||||||
|
|
||||||
protected OsuStrainSkill(Mod[] mods)
|
protected OsuStrainSkill(Mod[] mods)
|
||||||
: base(mods)
|
: base(mods)
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user