Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider opacity of hit objects in Flashlight skill #15665

Merged
merged 32 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
131e64e
Add bonus based on opacity of hit objects
MBmasher Nov 12, 2021
5a3be77
Resolve conflicts with recent slider hotfix
MBmasher Nov 12, 2021
efac11e
Add extra bonus for hidden+flashlight
MBmasher Nov 12, 2021
f2d05ea
Remove strain being multiplied by max opacity bonus
MBmasher Nov 17, 2021
63c5f7d
Balancing opacity and hidden bonus
MBmasher Nov 17, 2021
6a444b9
Further balancing opacity/hidden bonus
MBmasher Nov 17, 2021
8e85715
Removing unnecessary file
MBmasher Nov 17, 2021
92cf447
Remove unnecessary braces
MBmasher Nov 17, 2021
30e18f1
Change mods and preemptTime to readonly
MBmasher Nov 17, 2021
f4b23f0
Remove setting preempt in CreateDifficultyAttributes
MBmasher Nov 17, 2021
fe83b8f
Add line break
MBmasher Nov 17, 2021
afbec94
Move opacity function to OsuDifficultyHitObject
MBmasher Nov 21, 2021
a57c277
Move preempt back to CreateDifficultyAttributes
MBmasher Nov 21, 2021
e9a4ee6
Cleaning up code
MBmasher Nov 21, 2021
e9745a3
Fix wrong opacity formula
MBmasher Nov 21, 2021
7833fab
Balancing bonuses to adjust for corrected opacity formula
MBmasher Nov 21, 2021
65ef030
Further balancing
MBmasher Nov 21, 2021
e6e6e2d
Merge branch 'master' into fl-opacity
smoogipoo Nov 30, 2021
383bf7c
Only allow HD combination alongside FL
smoogipoo Nov 30, 2021
b0dc8bf
Change Opacity function to take in absolute map time rather than rela…
MBmasher Nov 30, 2021
3339afd
Change input variable name in Opacity function
MBmasher Nov 30, 2021
5884b05
Add blank line
MBmasher Nov 30, 2021
9824d80
Remove unnecessary clockRate in Opacity function
MBmasher Nov 30, 2021
0a33f33
Merge branch 'master' into fl-opacity
MBmasher Dec 21, 2021
a7aea49
Rename `osuPreviousHitObject` to `currentHitObject`
MBmasher Dec 21, 2021
3d3de00
Move `hidden` initialisation to Flashlight constructor
MBmasher Dec 21, 2021
5d89684
Adjust `skillMultiplier` after merging #15728, #15867
MBmasher Dec 21, 2021
c5de203
Multiply `opacityBonus` to base strain
MBmasher Dec 21, 2021
2aafcd3
Refactor code regarding `hidden` boolean
MBmasher Dec 21, 2021
36d1cdb
Merge branch 'master' into fl-opacity
smoogipoo Jan 20, 2022
ce095d6
Merge branch 'master' into fl-opacity
smoogipoo Apr 26, 2022
4463a26
Refactor opacity computation algorithm
smoogipoo May 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ public class OsuDifficultyCalculator : DifficultyCalculator
{
private const double difficulty_multiplier = 0.0675;
private double hitWindowGreat;
private double preempt;

public OsuDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
Expand Down Expand Up @@ -59,7 +60,6 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat

double starRating = basePerformance > 0.00001 ? Math.Cbrt(1.12) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4) : 0;

double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
double drainRate = beatmap.Difficulty.DrainRate;

int maxCombo = beatmap.HitObjects.Count;
Expand Down Expand Up @@ -110,12 +110,14 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo

hitWindowGreat = hitWindows.WindowFor(HitResult.Great) / clockRate;

preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;

return new Skill[]
{
new Aim(mods, true),
new Aim(mods, false),
new Speed(mods, hitWindowGreat),
new Flashlight(mods)
new Flashlight(mods, preempt)
};
}

Expand All @@ -126,6 +128,7 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo
new OsuModEasy(),
new OsuModHardRock(),
new OsuModFlashlight(),
new OsuModHidden()
};
}
}
}
4 changes: 0 additions & 4 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,10 +234,6 @@ private double computeFlashlightValue()

double flashlightValue = Math.Pow(rawFlashlight, 2.0) * 25.0;

// Add an additional bonus for HDFL.
if (mods.Any(h => h is OsuModHidden))
flashlightValue *= 1.3;

// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
Expand Down
38 changes: 34 additions & 4 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Flashlight.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@
// 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.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Objects;

Expand All @@ -14,23 +16,34 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// </summary>
public class Flashlight : OsuStrainSkill
{
public Flashlight(Mod[] mods)
public Flashlight(Mod[] mods, double preemptTime)
: base(mods)
{
this.mods = mods;
this.preemptTime = preemptTime;
}

private double skillMultiplier => 0.15;
private double skillMultiplier => 0.09;
private double strainDecayBase => 0.15;
protected override double DecayWeight => 1.0;
protected override int HistoryLength => 10; // Look back for 10 notes is added for the sake of flashlight calculations.

private readonly Mod[] mods;
private bool hidden;
private readonly double preemptTime;

private const double max_opacity_bonus = 0.7;
private const double hidden_bonus = 0.5;

private double currentStrain;

private double strainValueOf(DifficultyHitObject current)
{
if (current.BaseObject is Spinner)
return 0;

hidden = mods.Any(m => m is OsuModHidden);

var osuCurrent = (OsuDifficultyHitObject)current;
var osuHitObject = (OsuHitObject)(osuCurrent.BaseObject);

Expand Down Expand Up @@ -58,11 +71,28 @@ private double strainValueOf(DifficultyHitObject current)
// We also want to nerf stacks so that only the first object of the stack is accounted for.
double stackNerf = Math.Min(1.0, (osuPrevious.JumpDistance / scalingFactor) / 25.0);

result += Math.Pow(0.8, i) * stackNerf * scalingFactor * jumpDistance / cumulativeStrainTime;
// Bonus based on how visible the object is.
double opacityBonus = 1.0 + max_opacity_bonus * (1.0 - opacity(cumulativeStrainTime, preemptTime, hidden));

result += Math.Pow(0.8, i) * stackNerf * opacityBonus * scalingFactor * jumpDistance / cumulativeStrainTime;
}
}

return Math.Pow(smallDistNerf * result, 2.0);
result = Math.Pow(smallDistNerf * result, 2.0);

// Additional bonus for Hidden due to there being no approach circles.
if (hidden)
result *= 1.0 + hidden_bonus;

return result;
}

private double opacity(double ms, double preemptTime, bool hidden)
{
if (hidden)
return Math.Clamp(Math.Min((1 - ms / preemptTime) * 2.5, (ms / preemptTime) * (1.0 / 0.3)), 0.0, 1.0);
else
return Math.Clamp((1.0 - ms / preemptTime) * 1.5, 0.0, 1.0);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be moved into OsuDifficultyHitObject.cs, since future skills could use this (most notably a visual/reading skill)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just clarified on pp dev discord that this method's ms argument means milliseconds before the object is clicked, which I think could be more flexible if it took the raw map time - the current means needing clockrate in skills to calculate time difference.

The method could also do with an xmldoc thingy btw

}

private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
Expand Down