2020-05-11 05:50:02 +00:00
|
|
|
|
// 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;
|
2020-05-22 11:50:21 +00:00
|
|
|
|
using System.Collections.Generic;
|
2020-05-11 05:50:02 +00:00
|
|
|
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
|
|
|
|
using osu.Game.Rulesets.Difficulty.Skills;
|
|
|
|
|
using osu.Game.Rulesets.Taiko.Difficulty.Preprocessing;
|
|
|
|
|
using osu.Game.Rulesets.Taiko.Objects;
|
|
|
|
|
|
|
|
|
|
namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
|
|
|
|
{
|
|
|
|
|
public class Colour : Skill
|
|
|
|
|
{
|
2020-08-12 16:35:56 +00:00
|
|
|
|
private const int mono_history_max_length = 5;
|
|
|
|
|
|
2020-05-11 05:50:02 +00:00
|
|
|
|
protected override double SkillMultiplier => 1;
|
2020-05-22 11:50:21 +00:00
|
|
|
|
protected override double StrainDecayBase => 0.4;
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-08-12 16:35:56 +00:00
|
|
|
|
private HitType? previousHitType;
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-05-22 11:50:21 +00:00
|
|
|
|
private int currentMonoLength = 1;
|
2020-06-08 07:30:26 +00:00
|
|
|
|
private readonly List<int> monoHistory = new List<int>();
|
2020-05-11 05:53:42 +00:00
|
|
|
|
|
2020-08-12 16:35:56 +00:00
|
|
|
|
protected override double StrainValueOf(DifficultyHitObject current)
|
2020-05-22 11:50:21 +00:00
|
|
|
|
{
|
2020-08-12 16:35:56 +00:00
|
|
|
|
if (!(current.LastObject is Hit && current.BaseObject is Hit && current.DeltaTime < 1000))
|
|
|
|
|
{
|
|
|
|
|
previousHitType = null;
|
|
|
|
|
return 0.0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var taikoCurrent = (TaikoDifficultyHitObject)current;
|
|
|
|
|
|
|
|
|
|
double objectStrain = 0.0;
|
|
|
|
|
|
|
|
|
|
if (taikoCurrent.HitType != null && previousHitType != null && taikoCurrent.HitType != previousHitType)
|
|
|
|
|
{
|
|
|
|
|
objectStrain = 1.0;
|
|
|
|
|
|
|
|
|
|
if (monoHistory.Count < 2)
|
|
|
|
|
objectStrain = 0.0;
|
|
|
|
|
else if ((monoHistory[^1] + currentMonoLength) % 2 == 0)
|
|
|
|
|
objectStrain *= sameParityPenalty();
|
|
|
|
|
|
|
|
|
|
objectStrain *= repetitionPenalties();
|
|
|
|
|
currentMonoLength = 1;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
currentMonoLength += 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
previousHitType = taikoCurrent.HitType;
|
|
|
|
|
return objectStrain;
|
2020-05-22 11:50:21 +00:00
|
|
|
|
}
|
2020-05-11 05:53:42 +00:00
|
|
|
|
|
2020-08-12 16:35:56 +00:00
|
|
|
|
private double sameParityPenalty()
|
2020-05-22 11:50:21 +00:00
|
|
|
|
{
|
2020-08-12 16:35:56 +00:00
|
|
|
|
return 0.0;
|
2020-05-22 11:50:21 +00:00
|
|
|
|
}
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
private double repetitionPenalties()
|
2020-05-11 05:50:02 +00:00
|
|
|
|
{
|
2020-06-08 07:30:26 +00:00
|
|
|
|
double penalty = 1.0;
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
monoHistory.Add(currentMonoLength);
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
if (monoHistory.Count > mono_history_max_length)
|
|
|
|
|
monoHistory.RemoveAt(0);
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
for (int l = 2; l <= mono_history_max_length / 2; l++)
|
|
|
|
|
{
|
|
|
|
|
for (int start = monoHistory.Count - l - 1; start >= 0; start--)
|
2020-05-11 05:50:02 +00:00
|
|
|
|
{
|
2020-06-08 07:30:26 +00:00
|
|
|
|
bool samePattern = true;
|
2020-05-22 11:50:21 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
for (int i = 0; i < l; i++)
|
2020-05-11 05:50:02 +00:00
|
|
|
|
{
|
2020-06-08 07:30:26 +00:00
|
|
|
|
if (monoHistory[start + i] != monoHistory[monoHistory.Count - l + i])
|
|
|
|
|
{
|
|
|
|
|
samePattern = false;
|
|
|
|
|
}
|
2020-05-11 05:50:02 +00:00
|
|
|
|
}
|
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
if (samePattern) // Repetition found!
|
2020-05-11 05:50:02 +00:00
|
|
|
|
{
|
2020-06-08 07:30:26 +00:00
|
|
|
|
int notesSince = 0;
|
|
|
|
|
for (int i = start; i < monoHistory.Count; i++) notesSince += monoHistory[i];
|
|
|
|
|
penalty *= repetitionPenalty(notesSince);
|
|
|
|
|
break;
|
2020-05-11 05:50:02 +00:00
|
|
|
|
}
|
2020-06-08 07:30:26 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-06-08 07:30:26 +00:00
|
|
|
|
return penalty;
|
|
|
|
|
}
|
2020-05-11 05:50:02 +00:00
|
|
|
|
|
2020-08-12 16:35:56 +00:00
|
|
|
|
private double repetitionPenalty(int notesSince)
|
2020-06-08 07:30:26 +00:00
|
|
|
|
{
|
2020-08-12 16:35:56 +00:00
|
|
|
|
double n = notesSince;
|
|
|
|
|
return Math.Min(1.0, 0.032 * n);
|
2020-06-08 07:30:26 +00:00
|
|
|
|
}
|
2020-05-11 05:50:02 +00:00
|
|
|
|
}
|
|
|
|
|
}
|