fix bugs related to timing windows

add ability to adjust timing window size per-input
made rockers suck less
This commit is contained in:
minenice55 2024-05-12 18:45:23 -04:00
parent 423bf2e067
commit 087de8fab4
6 changed files with 86 additions and 64 deletions

View file

@ -322,11 +322,11 @@ namespace HeavenStudio
} }
} }
public void ScoreInputAccuracy(double beat, double accuracy, bool late, double time, float weight = 1, bool doDisplay = true) public void ScoreInputAccuracy(double beat, double accuracy, bool late, double time, float pitch = 1, double margin = 0, float weight = 1, bool doDisplay = true)
{ {
// push the hit event to the timing display // push the hit event to the timing display
if (doDisplay) if (doDisplay)
TimingAccuracyDisplay.instance.MakeAccuracyVfx(time, late); TimingAccuracyDisplay.instance.MakeAccuracyVfx(time, pitch, margin, late);
if (weight > 0 && MarkerWeight > 0) if (weight > 0 && MarkerWeight > 0)
{ {

View file

@ -14,7 +14,10 @@ namespace HeavenStudio.Games
{ {
public class Minigame : MonoBehaviour public class Minigame : MonoBehaviour
{ {
// root timing window values
public static double ngEarlyTimeBase = 0.1, justEarlyTimeBase = 0.05, aceEarlyTimeBase = 0.01, aceLateTimeBase = 0.01, justLateTimeBase = 0.05, ngLateTimeBase = 0.1; public static double ngEarlyTimeBase = 0.1, justEarlyTimeBase = 0.05, aceEarlyTimeBase = 0.01, aceLateTimeBase = 0.01, justLateTimeBase = 0.05, ngLateTimeBase = 0.1;
// recommended added margin for release inputs
public static double releaseMargin = 0.01;
public static double rankHiThreshold = 0.8, rankOkThreshold = 0.6; public static double rankHiThreshold = 0.8, rankOkThreshold = 0.6;
public static double ngEarlyTime => ngEarlyTimeBase * Conductor.instance?.SongPitch ?? 1; public static double ngEarlyTime => ngEarlyTimeBase * Conductor.instance?.SongPitch ?? 1;
@ -110,7 +113,7 @@ namespace HeavenStudio.Games
IA_PadBasicRelease, IA_TouchFlick, IA_BatonBasicRelease); IA_PadBasicRelease, IA_TouchFlick, IA_BatonBasicRelease);
#endregion #endregion
public List<PlayerActionEvent> scheduledInputs = new List<PlayerActionEvent>(); [NonSerialized] public List<PlayerActionEvent> scheduledInputs = new List<PlayerActionEvent>();
/// <summary> /// <summary>
/// Schedule an Input for a later time in the minigame. Executes the methods put in parameters /// Schedule an Input for a later time in the minigame. Executes the methods put in parameters
@ -166,6 +169,22 @@ namespace HeavenStudio.Games
return evt; return evt;
} }
public PlayerActionEvent ScheduleInput(
double startBeat,
double timer,
double margin,
PlayerInput.InputAction inputAction,
PlayerActionEvent.ActionEventCallbackState OnHit,
PlayerActionEvent.ActionEventCallback OnMiss,
PlayerActionEvent.ActionEventCallback OnBlank,
PlayerActionEvent.ActionEventHittableQuery HittableQuery = null
)
{
PlayerActionEvent evt = ScheduleInput(startBeat, timer, inputAction, OnHit, OnMiss, OnBlank, HittableQuery);
evt.margin = margin;
return evt;
}
public PlayerActionEvent ScheduleAutoplayInput(double startBeat, public PlayerActionEvent ScheduleAutoplayInput(double startBeat,
double timer, double timer,
PlayerInput.InputAction inputAction, PlayerInput.InputAction inputAction,
@ -236,7 +255,7 @@ namespace HeavenStudio.Games
{ {
PlayerActionEvent input = GetClosestScheduledInput(wantActionCategory); PlayerActionEvent input = GetClosestScheduledInput(wantActionCategory);
if (input == null) return false; if (input == null) return false;
return input.IsExpectingInputNow(); return input.IsExpectingInputNow(conductor);
} }
public bool IsExpectingInputNow(PlayerInput.InputAction wantAction) public bool IsExpectingInputNow(PlayerInput.InputAction wantAction)
@ -245,46 +264,46 @@ namespace HeavenStudio.Games
} }
// now should fix the fast bpm problem // now should fix the fast bpm problem
public static double NgEarlyTime(float pitch = -1) public static double NgEarlyTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 - ngEarlyTime; return 1 - (ngEarlyTime + margin);
return 1 - (ngEarlyTimeBase * pitch); return 1 - ((ngEarlyTime + margin) * pitch);
} }
public static double JustEarlyTime(float pitch = -1) public static double NgLateTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 - justEarlyTime; return 1 + (ngLateTime + margin);
return 1 - (justEarlyTimeBase * pitch); return 1 + ((ngLateTime + margin) * pitch);
} }
public static double JustLateTime(float pitch = -1) public static double JustEarlyTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 + justLateTime; return 1 - (justEarlyTime + margin);
return 1 + (justLateTimeBase * pitch); return 1 - ((justEarlyTime + margin) * pitch);
} }
public static double NgLateTime(float pitch = -1) public static double JustLateTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 + ngLateTime; return 1 + (justLateTime + margin);
return 1 + (ngLateTimeBase * pitch); return 1 + ((justLateTime + margin) * pitch);
} }
public static double AceEarlyTime(float pitch = -1) public static double AceEarlyTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 - aceEarlyTime; return 1 - (aceEarlyTime + margin);
return 1 - (aceEarlyTimeBase * pitch); return 1 - ((aceEarlyTime + margin) * pitch);
} }
public static double AceLateTime(float pitch = -1) public static double AceLateTime(float pitch = -1, double margin = 0)
{ {
if (pitch < 0) if (pitch < 0)
return 1 + aceLateTime; return 1 + (aceLateTime + margin);
return 1 + (aceLateTimeBase * pitch); return 1 + ((aceLateTime + margin) * pitch);
} }
public virtual void OnGameSwitch(double beat) public virtual void OnGameSwitch(double beat)
@ -340,7 +359,7 @@ namespace HeavenStudio.Games
public void ScoreMiss(float weight = 1f) public void ScoreMiss(float weight = 1f)
{ {
double beat = Conductor.instance?.songPositionInBeatsAsDouble ?? -1; double beat = Conductor.instance?.songPositionInBeatsAsDouble ?? -1;
GameManager.instance.ScoreInputAccuracy(beat, 0, true, NgLateTime(), weight, false); GameManager.instance.ScoreInputAccuracy(beat, 0, true, NgLateTime(), weight: weight, doDisplay: false);
} }
public void ToggleSplitColoursDisplay(bool on) public void ToggleSplitColoursDisplay(bool on)
@ -442,14 +461,17 @@ namespace HeavenStudio.Games
public Color GetColor() => MakeNewColor(startBeat, length, startColor, endColor, easeFunc); public Color GetColor() => MakeNewColor(startBeat, length, startColor, endColor, easeFunc);
public static Color MakeNewColor(double beat, float length, Color start, Color end, Util.EasingFunction.Function func) public static Color MakeNewColor(double beat, float length, Color start, Color end, Util.EasingFunction.Function func)
{ {
if (length != 0) { if (length != 0)
{
float normalizedBeat = length == 0 ? 1 : Mathf.Clamp01(Conductor.instance.GetPositionFromBeat(beat, length)); float normalizedBeat = length == 0 ? 1 : Mathf.Clamp01(Conductor.instance.GetPositionFromBeat(beat, length));
float newR = func(start.r, end.r, normalizedBeat); float newR = func(start.r, end.r, normalizedBeat);
float newG = func(start.g, end.g, normalizedBeat); float newG = func(start.g, end.g, normalizedBeat);
float newB = func(start.b, end.b, normalizedBeat); float newB = func(start.b, end.b, normalizedBeat);
return new Color(newR, newG, newB); return new Color(newR, newG, newB);
} else { }
else
{
return end; return end;
} }
} }
@ -471,7 +493,8 @@ namespace HeavenStudio.Games
/// The ease to use to transition between <paramref name="startColor"/> and <paramref name="endColor"/>.<br/> /// The ease to use to transition between <paramref name="startColor"/> and <paramref name="endColor"/>.<br/>
/// Should be derived from <c>Util.EasingFunction.Ease</c>, /// Should be derived from <c>Util.EasingFunction.Ease</c>,
/// </param> /// </param>
public ColorEase(double startBeat, float length, Color startColor, Color endColor, int ease) { public ColorEase(double startBeat, float length, Color startColor, Color endColor, int ease)
{
this.startBeat = startBeat; this.startBeat = startBeat;
this.length = length; this.length = length;
(this.startColor, this.endColor) = (startColor, endColor); (this.startColor, this.endColor) = (startColor, endColor);
@ -483,7 +506,8 @@ namespace HeavenStudio.Games
/// The constructor to use when initializing the ColorEase variable. /// The constructor to use when initializing the ColorEase variable.
/// </summary> /// </summary>
/// <param name="defaultColor">The default color to initialize with.</param> /// <param name="defaultColor">The default color to initialize with.</param>
public ColorEase(Color? defaultColor = null) { public ColorEase(Color? defaultColor = null)
{
startColor = endColor = defaultColor ?? Color.white; startColor = endColor = defaultColor ?? Color.white;
easeFunc = Util.EasingFunction.Instant; easeFunc = Util.EasingFunction.Instant;
} }

View file

@ -27,6 +27,7 @@ namespace HeavenStudio.Games
public double startBeat; public double startBeat;
public double timer; public double timer;
public float weight = 1f; public float weight = 1f;
public double margin = 0;
public bool isEligible = true; public bool isEligible = true;
public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss public bool canHit = true; //Indicates if you can still hit the cue or not. If set to false, it'll guarantee a miss
@ -108,7 +109,7 @@ namespace HeavenStudio.Games
} }
//BUGFIX: ActionEvents destroyed too early //BUGFIX: ActionEvents destroyed too early
if (normalizedTime > Minigame.NgLateTime(cond.SongPitch)) Miss(); if (normalizedTime > Minigame.NgLateTime(cond.SongPitch, margin)) Miss();
if (lockedByEvent) if (lockedByEvent)
{ {
@ -122,10 +123,10 @@ namespace HeavenStudio.Games
if (!autoplayOnly && (IsHittable == null || IsHittable != null && IsHittable()) && IsCorrectInput(out double dt)) if (!autoplayOnly && (IsHittable == null || IsHittable != null && IsHittable()) && IsCorrectInput(out double dt))
{ {
normalizedTime -= dt; normalizedTime -= dt;
if (IsExpectingInputNow()) if (IsExpectingInputNow(cond))
{ {
double stateProg = ((normalizedTime - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2; double stateProg = ((normalizedTime - Minigame.JustEarlyTime(cond.SongPitch, margin)) / (Minigame.JustLateTime(cond.SongPitch, margin) - Minigame.JustEarlyTime(cond.SongPitch, margin)) - 0.5f) * 2;
Hit(stateProg, normalizedTime); Hit(stateProg, normalizedTime, cond.SongPitch);
} }
else else
{ {
@ -198,7 +199,7 @@ namespace HeavenStudio.Games
} }
} }
public bool IsExpectingInputNow() public bool IsExpectingInputNow(Conductor cond)
{ {
if (IsHittable != null) if (IsHittable != null)
{ {
@ -208,7 +209,7 @@ namespace HeavenStudio.Games
if (!isEligible) return false; if (!isEligible) return false;
double normalizedBeat = GetNormalizedTime(); double normalizedBeat = GetNormalizedTime();
return normalizedBeat > Minigame.NgEarlyTime() && normalizedBeat < Minigame.NgLateTime(); return normalizedBeat > Minigame.NgEarlyTime(cond.SongPitch, margin) && normalizedBeat < Minigame.NgLateTime(cond.SongPitch, margin);
} }
double GetNormalizedTime() double GetNormalizedTime()
@ -242,7 +243,7 @@ namespace HeavenStudio.Games
} }
//The state parameter is either -1 -> Early, 0 -> Perfect, 1 -> Late //The state parameter is either -1 -> Early, 0 -> Perfect, 1 -> Late
public void Hit(double state, double time) public void Hit(double state, double time, float pitch = 1)
{ {
GameManager gm = GameManager.instance; GameManager gm = GameManager.instance;
if (OnHit != null && enabled) if (OnHit != null && enabled)
@ -261,7 +262,7 @@ namespace HeavenStudio.Games
if (countsForAccuracy && gm.canInput && !(noAutoplay || autoplayOnly) && isEligible) if (countsForAccuracy && gm.canInput && !(noAutoplay || autoplayOnly) && isEligible)
{ {
gm.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time, pitchWhenHit), time > 1.0, time, weight, true); gm.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time, pitchWhenHit), time > 1.0, time, pitch, margin, weight, true);
if (state >= 1f || state <= -1f) if (state >= 1f || state <= -1f)
{ {
GoForAPerfect.instance.Miss(); GoForAPerfect.instance.Miss();
@ -284,27 +285,27 @@ namespace HeavenStudio.Games
double TimeToAccuracy(double time, float pitch = -1) double TimeToAccuracy(double time, float pitch = -1)
{ {
if (pitch < 0) pitch = pitchWhenHit; if (pitch < 0) pitch = pitchWhenHit;
if (time >= Minigame.AceEarlyTime(pitch) && time <= Minigame.AceLateTime(pitch)) if (time >= Minigame.AceEarlyTime(pitch, margin) && time <= Minigame.AceLateTime(pitch, margin))
{ {
// Ace // Ace
return 1.0; return 1.0;
} }
double state = 0; double state = 0;
if (time >= Minigame.JustEarlyTime(pitch) && time <= Minigame.JustLateTime(pitch)) if (time >= Minigame.JustEarlyTime(pitch, margin) && time <= Minigame.JustLateTime(pitch, margin))
{ {
// Good Hit // Good Hit
if (time > 1.0) if (time > 1.0)
{ {
// late half of timing window // late half of timing window
state = 1.0 - ((time - Minigame.AceLateTime(pitch)) / (Minigame.JustLateTime(pitch) - Minigame.AceLateTime(pitch))); state = 1.0 - ((time - Minigame.AceLateTime(pitch, margin)) / (Minigame.JustLateTime(pitch, margin) - Minigame.AceLateTime(pitch, margin)));
state *= 1.0 - Minigame.rankHiThreshold; state *= 1.0 - Minigame.rankHiThreshold;
state += Minigame.rankHiThreshold; state += Minigame.rankHiThreshold;
} }
else else
{ {
//early half of timing window //early half of timing window
state = ((time - Minigame.JustEarlyTime(pitch)) / (Minigame.AceEarlyTime(pitch) - Minigame.JustEarlyTime(pitch))); state = (time - Minigame.JustEarlyTime(pitch, margin)) / (Minigame.AceEarlyTime(pitch, margin) - Minigame.JustEarlyTime(pitch, margin));
state *= 1.0 - Minigame.rankHiThreshold; state *= 1.0 - Minigame.rankHiThreshold;
state += Minigame.rankHiThreshold; state += Minigame.rankHiThreshold;
} }
@ -314,13 +315,13 @@ namespace HeavenStudio.Games
if (time > 1.0) if (time > 1.0)
{ {
// late half of timing window // late half of timing window
state = 1.0 - ((time - Minigame.JustLateTime(pitch)) / (Minigame.NgLateTime(pitch) - Minigame.JustLateTime(pitch))); state = 1.0 - ((time - Minigame.JustLateTime(pitch, margin)) / (Minigame.NgLateTime(pitch, margin) - Minigame.JustLateTime(pitch, margin)));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
else else
{ {
//early half of timing window //early half of timing window
state = ((time - Minigame.JustEarlyTime(pitch)) / (Minigame.AceEarlyTime(pitch) - Minigame.JustEarlyTime(pitch))); state = (time - Minigame.JustEarlyTime(pitch, margin)) / (Minigame.AceEarlyTime(pitch, margin) - Minigame.JustEarlyTime(pitch, margin));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
} }
@ -338,7 +339,7 @@ namespace HeavenStudio.Games
if (countsForAccuracy && !missable && gm.canInput && !(noAutoplay || autoplayOnly)) if (countsForAccuracy && !missable && gm.canInput && !(noAutoplay || autoplayOnly))
{ {
gm.ScoreInputAccuracy(startBeat + timer, 0, true, 2.0, weight, false); gm.ScoreInputAccuracy(startBeat + timer, 0, true, 2.0, weight: weight, doDisplay: false);
GoForAPerfect.instance.Miss(); GoForAPerfect.instance.Miss();
SectionMedalsManager.instance.MakeIneligible(); SectionMedalsManager.instance.MakeIneligible();
} }

View file

@ -777,15 +777,15 @@ namespace HeavenStudio.Games
}); });
RockersInput riffComp = Instantiate(rockerInputRef, transform); RockersInput riffComp = Instantiate(rockerInputRef, transform);
riffComp.Init(false, new int[6], beat, 3, GetSample(SoshiSamples[0]), SoshiPitches[0]); riffComp.Init(false, new int[6], beat, 3, GetSample(SoshiSamples[0]), SoshiPitches[0]);
ScheduleInput(beat, 3.5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, 3.5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty);
RockersInput riffComp2 = Instantiate(rockerInputRef, transform); RockersInput riffComp2 = Instantiate(rockerInputRef, transform);
riffComp2.Init(false, new int[6], beat, 4.5f, GetSample(SoshiSamples[1]), SoshiPitches[1]); riffComp2.Init(false, new int[6], beat, 4.5f, GetSample(SoshiSamples[1]), SoshiPitches[1]);
ScheduleInput(beat, 5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, 5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty);
RockersInput riffComp3 = Instantiate(rockerInputRef, transform); RockersInput riffComp3 = Instantiate(rockerInputRef, transform);
riffComp3.Init(false, new int[6], beat, 6, GetSample(SoshiSamples[2]), SoshiPitches[2]); riffComp3.Init(false, new int[6], beat, 6, GetSample(SoshiSamples[2]), SoshiPitches[2]);
ScheduleInput(beat, 6.5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, 6.5f, InputAction_TriggerDown, JustMute, MuteMiss, Empty);
} }
public void DefaultCmon(double beat, int[] JJSamples, int[] JJPitches, int[] SoshiSamples, int[] SoshiPitches, bool moveCamera) public void DefaultCmon(double beat, int[] JJSamples, int[] JJPitches, int[] SoshiSamples, int[] SoshiPitches, bool moveCamera)
@ -848,7 +848,7 @@ namespace HeavenStudio.Games
RockersInput riffComp3 = Instantiate(rockerInputRef, transform); RockersInput riffComp3 = Instantiate(rockerInputRef, transform);
riffComp3.Init(false, new int[6], beat, 6, GetSample(SoshiSamples[2]), SoshiPitches[2]); riffComp3.Init(false, new int[6], beat, 6, GetSample(SoshiSamples[2]), SoshiPitches[2]);
ScheduleInput(beat, 6.5f, InputAction_BasicPress, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, 6.5f, InputAction_BasicPress, JustMute, MuteMiss, Empty);
RockersInput riffComp4 = Instantiate(rockerInputRef, transform); RockersInput riffComp4 = Instantiate(rockerInputRef, transform);
riffComp4.Init(false, new int[6], beat, 7, GetSample(SoshiSamples[3]), SoshiPitches[3], true); riffComp4.Init(false, new int[6], beat, 7, GetSample(SoshiSamples[3]), SoshiPitches[3], true);
@ -903,8 +903,7 @@ namespace HeavenStudio.Games
RockersInput riffComp = Instantiate(rockerInputRef, transform); RockersInput riffComp = Instantiate(rockerInputRef, transform);
riffComp.Init(e["gcS"], new int[6] { e["1S"], e["2S"], e["3S"], e["4S"], e["5S"], e["6S"] }, beat, e.beat - beat, riffComp.Init(e["gcS"], new int[6] { e["1S"], e["2S"], e["3S"], e["4S"], e["5S"], e["6S"] }, beat, e.beat - beat,
GetSample(e["sampleS"]), e["pitchSampleS"]); GetSample(e["sampleS"]), e["pitchSampleS"]);
if (e.length <= 0.5f) ScheduleInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
else ScheduleAutoplayInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
} }
else else
{ {
@ -924,8 +923,7 @@ namespace HeavenStudio.Games
RockersInput riffComp = Instantiate(rockerInputRef, transform); RockersInput riffComp = Instantiate(rockerInputRef, transform);
riffComp.Init(e["gcS"], new int[6] { e["1S"], e["2S"], e["3S"], e["4S"], e["5S"], e["6S"] }, beat, e.beat - beat, riffComp.Init(e["gcS"], new int[6] { e["1S"], e["2S"], e["3S"], e["4S"], e["5S"], e["6S"] }, beat, e.beat - beat,
GetSample(e["sampleS"]), e["pitchSampleS"], true); GetSample(e["sampleS"]), e["pitchSampleS"], true);
if (e.length <= 0.5f) ScheduleInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
else ScheduleAutoplayInput(beat, e.beat - beat + e.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
break; break;
} }
} }
@ -1139,8 +1137,7 @@ namespace HeavenStudio.Games
RockersInput riffComp = Instantiate(rockerInputRef, transform); RockersInput riffComp = Instantiate(rockerInputRef, transform);
riffComp.Init(crEvent["gcS"], new int[6] { crEvent["1S"], crEvent["2S"], crEvent["3S"], crEvent["4S"], crEvent["5S"], crEvent["6S"] }, beat, relativeBeat, riffComp.Init(crEvent["gcS"], new int[6] { crEvent["1S"], crEvent["2S"], crEvent["3S"], crEvent["4S"], crEvent["5S"], crEvent["6S"] }, beat, relativeBeat,
GetSample(crEvent["sampleS"]), crEvent["pitchSampleS"]); GetSample(crEvent["sampleS"]), crEvent["pitchSampleS"]);
if (crEvent.length > 0.5f) ScheduleAutoplayInput(beat, relativeBeat + crEvent.length, InputAction_BasicPress, JustMute, MuteMiss, Empty); ScheduleAutoplayInput(beat, relativeBeat + crEvent.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
else ScheduleInput(beat, relativeBeat + crEvent.length, InputAction_BasicPress, JustMute, MuteMiss, Empty);
} }
else else
{ {

View file

@ -26,7 +26,7 @@ namespace HeavenStudio.Games.Scripts_Rockers
this.sample = sample; this.sample = sample;
this.sampleTones = sampleTones; this.sampleTones = sampleTones;
this.jump = jump; this.jump = jump;
game.ScheduleInput(beat, length, Rockers.InputAction_FlickRelease, Just, Miss, Empty); game.ScheduleInput(beat, length, Rockers.releaseMargin, Rockers.InputAction_FlickRelease, Just, Miss, Empty);
} }
private void Just(PlayerActionEvent caller, float state) private void Just(PlayerActionEvent caller, float state)

View file

@ -70,7 +70,7 @@ namespace HeavenStudio.Common
MetreAnim.Play("NoPose", -1, 0f); MetreAnim.Play("NoPose", -1, 0f);
} }
public void MakeAccuracyVfx(double time, bool late = false) public void MakeAccuracyVfx(double time, float pitch, double margin, bool late = false)
{ {
if (!OverlaysManager.OverlaysEnabled) return; if (!OverlaysManager.OverlaysEnabled) return;
GameObject it; GameObject it;
@ -87,12 +87,12 @@ namespace HeavenStudio.Common
// SetArrowPos(time); // SetArrowPos(time);
// no Clamp() because double // no Clamp() because double
time = System.Math.Max(Minigame.NgEarlyTime(), System.Math.Min(Minigame.NgLateTime(), time)); time = System.Math.Max(Minigame.NgEarlyTime(pitch, margin), System.Math.Min(Minigame.NgLateTime(pitch, margin), time));
if (time >= Minigame.AceEarlyTime() && time <= Minigame.AceLateTime()) if (time >= Minigame.AceEarlyTime(pitch, margin) && time <= Minigame.AceLateTime(pitch, margin))
{ {
type = Rating.Just; type = Rating.Just;
frac = (float)((time - Minigame.AceEarlyTime()) / (Minigame.AceLateTime() - Minigame.AceEarlyTime())); frac = (float)((time - Minigame.AceEarlyTime(pitch, margin)) / (Minigame.AceLateTime(pitch, margin) - Minigame.AceEarlyTime(pitch, margin)));
y = barJustTransform.localScale.y * frac - (barJustTransform.localScale.y * 0.5f); y = barJustTransform.localScale.y * frac - (barJustTransform.localScale.y * 0.5f);
} }
else else
@ -100,32 +100,32 @@ namespace HeavenStudio.Common
if (time > 1.0) if (time > 1.0)
{ {
// goes "down" // goes "down"
if (time <= Minigame.JustLateTime()) if (time <= Minigame.JustLateTime(pitch, margin))
{ {
type = Rating.OK; type = Rating.OK;
frac = (float)((time - Minigame.AceLateTime()) / (Minigame.JustLateTime() - Minigame.AceLateTime())); frac = (float)((time - Minigame.AceLateTime(pitch, margin)) / (Minigame.JustLateTime(pitch, margin) - Minigame.AceLateTime(pitch, margin)));
y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * frac) + barJustTransform.localScale.y; y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * frac) + barJustTransform.localScale.y;
} }
else else
{ {
type = Rating.NG; type = Rating.NG;
frac = (float)((time - Minigame.JustLateTime()) / (Minigame.NgLateTime() - Minigame.JustLateTime())); frac = (float)((time - Minigame.JustLateTime(pitch, margin)) / (Minigame.NgLateTime(pitch, margin) - Minigame.JustLateTime(pitch, margin)));
y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * frac) + barOKTransform.localScale.y; y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * frac) + barOKTransform.localScale.y;
} }
} }
else else
{ {
// goes "up" // goes "up"
if (time >= Minigame.JustEarlyTime()) if (time >= Minigame.JustEarlyTime(pitch, margin))
{ {
type = Rating.OK; type = Rating.OK;
frac = (float)((time - Minigame.JustEarlyTime()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime())); frac = (float)((time - Minigame.JustEarlyTime(pitch, margin)) / (Minigame.AceEarlyTime(pitch, margin) - Minigame.JustEarlyTime(pitch, margin)));
y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * -frac) - barJustTransform.localScale.y; y = ((barOKTransform.localScale.y - barJustTransform.localScale.y) * -frac) - barJustTransform.localScale.y;
} }
else else
{ {
type = Rating.NG; type = Rating.NG;
frac = (float)((time - Minigame.NgEarlyTime()) / (Minigame.JustEarlyTime() - Minigame.NgEarlyTime())); frac = (float)((time - Minigame.NgEarlyTime(pitch, margin)) / (Minigame.JustEarlyTime(pitch, margin) - Minigame.NgEarlyTime(pitch, margin)));
y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * -frac) - barOKTransform.localScale.y; y = ((barNGTransform.localScale.y - barOKTransform.localScale.y) * -frac) - barOKTransform.localScale.y;
} }
} }