fix timing display when pitched

This commit is contained in:
minenice55 2023-12-23 19:31:56 -05:00
parent 966e58b363
commit 080ba11858
4 changed files with 84 additions and 225 deletions

View file

@ -405,11 +405,14 @@ namespace HeavenStudio
{ {
string gameName = allGameSwitches[currentPreSwitch].datamodel.Split('/')[2]; string gameName = allGameSwitches[currentPreSwitch].datamodel.Split('/')[2];
inf = GetGameInfo(gameName); inf = GetGameInfo(gameName);
if (inf != null && inf.usesAssetBundle && !inf.AssetsLoaded) if (inf != null && !(inf.inferred || inf.fxOnly))
{ {
gamesToPreload.Add(inf); if (inf.usesAssetBundle && !inf.AssetsLoaded)
Debug.Log($"ASYNC loading assetbundles for game {gameName}"); {
inf.LoadAssetsAsync().Forget(); gamesToPreload.Add(inf);
Debug.Log($"ASYNC loading assetbundles for game {gameName}");
inf.LoadAssetsAsync().Forget();
}
} }
currentPreSwitch++; currentPreSwitch++;
} }
@ -431,11 +434,14 @@ namespace HeavenStudio
{ {
string gameName = entity.datamodel.Split('/')[0]; string gameName = entity.datamodel.Split('/')[0];
inf = GetGameInfo(gameName); inf = GetGameInfo(gameName);
if (inf != null && inf.usesAssetBundle && !inf.AssetsLoaded) if (inf != null && !(inf.inferred || inf.fxOnly))
{ {
gamesToPreload.Add(inf); if (inf.usesAssetBundle && !inf.AssetsLoaded)
Debug.Log($"ASYNC loading assetbundles for game {gameName}"); {
inf.LoadAssetsAsync().Forget(); gamesToPreload.Add(inf);
Debug.Log($"ASYNC loading assetbundles for game {gameName}");
inf.LoadAssetsAsync().Forget();
}
} }
currentPreEvent++; currentPreEvent++;
} }
@ -714,9 +720,14 @@ namespace HeavenStudio
if (!paused) if (!paused)
{ {
Minigame miniGame = currentGameO?.GetComponent<Minigame>(); Minigame miniGame = null;
if (miniGame != null) if (currentGameO != null && currentGameO.TryGetComponent<Minigame>(out miniGame))
miniGame.OnPlay(beat); {
if (miniGame != null)
{
miniGame.OnPlay(beat);
}
}
onPlay?.Invoke(beat); onPlay?.Invoke(beat);
bool hasStartPerfect = false; bool hasStartPerfect = false;
@ -769,9 +780,14 @@ namespace HeavenStudio
SectionMedalsManager.instance.OnRemixEnd(endBeat, currentSection); SectionMedalsManager.instance.OnRemixEnd(endBeat, currentSection);
} }
Minigame miniGame = currentGameO.GetComponent<Minigame>(); Minigame miniGame;
if (miniGame != null) if (currentGameO != null && currentGameO.TryGetComponent<Minigame>(out miniGame))
miniGame.OnStop(beat); {
if (miniGame != null)
{
miniGame.OnStop(beat);
}
}
Conductor.instance.Stop(beat); Conductor.instance.Stop(beat);
SetCurrentEventToClosest(beat); SetCurrentEventToClosest(beat);
@ -1061,9 +1077,14 @@ namespace HeavenStudio
SetGame(game, false); SetGame(game, false);
Minigame miniGame = currentGameO.GetComponent<Minigame>(); Minigame miniGame;
if (miniGame != null) if (currentGameO != null && currentGameO.TryGetComponent<Minigame>(out miniGame))
miniGame.OnGameSwitch(beat); {
if (miniGame != null)
{
miniGame.OnGameSwitch(beat);
}
}
while (beat + 0.25 > Math.Max(Conductor.instance.songPositionInBeatsAsDouble, 0)) while (beat + 0.25 > Math.Max(Conductor.instance.songPositionInBeatsAsDouble, 0))
{ {
@ -1125,6 +1146,10 @@ namespace HeavenStudio
var gameInfo = GetGameInfo(name); var gameInfo = GetGameInfo(name);
if (gameInfo != null) if (gameInfo != null)
{ {
if (gameInfo.inferred)
{
return Resources.Load<GameObject>($"Games/noGame");
}
if (gameInfo.fxOnly) if (gameInfo.fxOnly)
{ {
var gameInfos = Beatmap.Entities var gameInfos = Beatmap.Entities

View file

@ -12,7 +12,7 @@ namespace HeavenStudio.Games
{ {
public class Minigame : MonoBehaviour public class Minigame : MonoBehaviour
{ {
public static double ngEarlyTimeBase = 0.1, justEarlyTimeBase = 0.05, aceEarlyTimeBase = 0.0075, aceLateTimeBase = 0.0075, 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;
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;
@ -357,34 +357,46 @@ namespace HeavenStudio.Games
} }
// now should fix the fast bpm problem // now should fix the fast bpm problem
public static double NgEarlyTime() public static double NgEarlyTime(float pitch = -1)
{ {
return 1f - ngEarlyTime; if (pitch < 0)
return 1f - ngEarlyTime;
return 1f - (ngEarlyTimeBase * pitch);
} }
public static double JustEarlyTime() public static double JustEarlyTime(float pitch = -1)
{ {
return 1f - justEarlyTime; if (pitch < 0)
return 1f - justEarlyTime;
return 1f - (justEarlyTimeBase * pitch);
} }
public static double JustLateTime() public static double JustLateTime(float pitch = -1)
{ {
return 1f + justLateTime; if (pitch < 0)
return 1f + justLateTime;
return 1f + (justLateTimeBase * pitch);
} }
public static double NgLateTime() public static double NgLateTime(float pitch = -1)
{ {
return 1f + ngLateTime; if (pitch < 0)
return 1f + ngLateTime;
return 1f + (ngLateTimeBase * pitch);
} }
public static double AceEarlyTime() public static double AceEarlyTime(float pitch = -1)
{ {
return 1f - aceEarlyTime; if (pitch < 0)
return 1f - aceEarlyTime;
return 1f - (aceEarlyTimeBase * pitch);
} }
public static double AceLateTime() public static double AceLateTime(float pitch = -1)
{ {
return 1f + aceLateTime; if (pitch < 0)
return 1f + aceLateTime;
return 1f + (aceLateTimeBase * pitch);
} }
public virtual void OnGameSwitch(double beat) public virtual void OnGameSwitch(double beat)

View file

@ -35,6 +35,8 @@ namespace HeavenStudio.Games
bool lockedByEvent = false; bool lockedByEvent = false;
bool markForDeletion = false; bool markForDeletion = false;
float pitchWhenHit = 1f;
public bool autoplayOnly = false; //Indicates if the input event only triggers when it's autoplay. If set to true, NO Miss or Blank events will be triggered when you're not autoplaying. public bool autoplayOnly = false; //Indicates if the input event only triggers when it's autoplay. If set to true, NO Miss or Blank events will be triggered when you're not autoplaying.
public bool noAutoplay = false; //Indicates if this PlayerActionEvent is recognized by the autoplay. /!\ Overrides autoPlayOnly /!\ public bool noAutoplay = false; //Indicates if this PlayerActionEvent is recognized by the autoplay. /!\ Overrides autoPlayOnly /!\
@ -71,25 +73,7 @@ namespace HeavenStudio.Games
{ {
return PlayerInput.GetIsAction(InputAction, out dt); return PlayerInput.GetIsAction(InputAction, out dt);
} }
return ( return false;
//General inputs, both down and up
(PlayerInput.Pressed(out dt) && inputType.HasFlag(InputType.STANDARD_DOWN)) ||
(PlayerInput.AltPressed(out dt) && inputType.HasFlag(InputType.STANDARD_ALT_DOWN)) ||
(PlayerInput.GetAnyDirectionDown(out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN)) ||
(PlayerInput.PressedUp(out dt) && inputType.HasFlag(InputType.STANDARD_UP)) ||
(PlayerInput.AltPressedUp(out dt) && inputType.HasFlag(InputType.STANDARD_ALT_UP)) ||
(PlayerInput.GetAnyDirectionUp(out dt) && inputType.HasFlag(InputType.DIRECTION_UP)) ||
//Specific directional inputs
(PlayerInput.GetSpecificDirectionDown(PlayerInput.DOWN, out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.UP, out dt) && inputType.HasFlag(InputType.DIRECTION_UP_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.LEFT, out dt) && inputType.HasFlag(InputType.DIRECTION_LEFT_DOWN)) ||
(PlayerInput.GetSpecificDirectionDown(PlayerInput.RIGHT, out dt) && inputType.HasFlag(InputType.DIRECTION_RIGHT_DOWN)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.DOWN, out dt) && inputType.HasFlag(InputType.DIRECTION_DOWN_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.UP, out dt) && inputType.HasFlag(InputType.DIRECTION_UP_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.LEFT, out dt) && inputType.HasFlag(InputType.DIRECTION_LEFT_UP)) ||
(PlayerInput.GetSpecificDirectionUp(PlayerInput.RIGHT, out dt) && inputType.HasFlag(InputType.DIRECTION_RIGHT_UP))
);
} }
public void CanHit(bool canHit) public void CanHit(bool canHit)
@ -104,8 +88,9 @@ namespace HeavenStudio.Games
public void Update() public void Update()
{ {
Conductor cond = Conductor.instance;
if (markForDeletion) CleanUp(); if (markForDeletion) CleanUp();
if (!Conductor.instance.NotStopped()) CleanUp(); // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates if (!cond.NotStopped()) CleanUp(); // If the song is stopped entirely in the editor, destroy itself as we don't want duplicates
if (noAutoplay && autoplayOnly) autoplayOnly = false; if (noAutoplay && autoplayOnly) autoplayOnly = false;
if (noAutoplay && triggersAutoplay) triggersAutoplay = false; if (noAutoplay && triggersAutoplay) triggersAutoplay = false;
@ -119,7 +104,7 @@ namespace HeavenStudio.Games
} }
//BUGFIX: ActionEvents destroyed too early //BUGFIX: ActionEvents destroyed too early
if (normalizedTime > Minigame.NgLateTime()) Miss(); if (normalizedTime > Minigame.NgLateTime(cond.SongPitch)) Miss();
if (lockedByEvent) if (lockedByEvent)
{ {
@ -135,10 +120,6 @@ namespace HeavenStudio.Games
normalizedTime -= dt; normalizedTime -= dt;
if (IsExpectingInputNow()) if (IsExpectingInputNow())
{ {
// if (InputAction != null)
// {
// Debug.Log("Hit " + InputAction.name);
// }
double stateProg = ((normalizedTime - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2; double stateProg = ((normalizedTime - Minigame.JustEarlyTime()) / (Minigame.JustLateTime() - Minigame.JustEarlyTime()) - 0.5f) * 2;
Hit(stateProg, normalizedTime); Hit(stateProg, normalizedTime);
} }
@ -262,15 +243,15 @@ namespace HeavenStudio.Games
if (canHit) if (canHit)
{ {
CleanUp(); CleanUp();
pitchWhenHit = Conductor.instance.SongPitch;
double normalized = time - 1f; double normalized = time - 1f;
int offset = Mathf.CeilToInt((float)normalized * 1000); int offset = Mathf.CeilToInt((float)normalized * 1000);
GameManager.instance.AvgInputOffset = offset; GameManager.instance.AvgInputOffset = offset;
state = System.Math.Max(-1.0, System.Math.Min(1.0, state)); state = System.Math.Max(-1.0, System.Math.Min(1.0, state));
OnHit(this, (float)state);
if (countsForAccuracy && !(noAutoplay || autoplayOnly) && isEligible) if (countsForAccuracy && !(noAutoplay || autoplayOnly) && isEligible)
{ {
GameManager.instance.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time), time > 1.0, time, weight, true); GameManager.instance.ScoreInputAccuracy(startBeat + timer, TimeToAccuracy(time, pitchWhenHit), time > 1.0, time, weight, true);
if (state >= 1f || state <= -1f) if (state >= 1f || state <= -1f)
{ {
GoForAPerfect.instance.Miss(); GoForAPerfect.instance.Miss();
@ -281,6 +262,7 @@ namespace HeavenStudio.Games
GoForAPerfect.instance.Hit(); GoForAPerfect.instance.Hit();
} }
} }
OnHit(this, (float)state);
} }
else else
{ {
@ -289,29 +271,30 @@ namespace HeavenStudio.Games
} }
} }
double TimeToAccuracy(double time) double TimeToAccuracy(double time, float pitch = -1)
{ {
if (time >= Minigame.AceEarlyTime() && time <= Minigame.AceLateTime()) if (pitch < 0) pitch = pitchWhenHit;
if (time >= Minigame.AceEarlyTime(pitch) && time <= Minigame.AceLateTime(pitch))
{ {
// Ace // Ace
return 1.0; return 1.0;
} }
double state = 0; double state = 0;
if (time >= Minigame.JustEarlyTime() && time <= Minigame.JustLateTime()) if (time >= Minigame.JustEarlyTime(pitch) && time <= Minigame.JustLateTime(pitch))
{ {
// 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()) / (Minigame.JustLateTime() - Minigame.AceLateTime())); state = 1.0 - ((time - Minigame.AceLateTime(pitch)) / (Minigame.JustLateTime(pitch) - Minigame.AceLateTime(pitch)));
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()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime())); state = ((time - Minigame.JustEarlyTime(pitch)) / (Minigame.AceEarlyTime(pitch) - Minigame.JustEarlyTime(pitch)));
state *= 1.0 - Minigame.rankHiThreshold; state *= 1.0 - Minigame.rankHiThreshold;
state += Minigame.rankHiThreshold; state += Minigame.rankHiThreshold;
} }
@ -321,13 +304,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()) / (Minigame.NgLateTime() - Minigame.JustLateTime())); state = 1.0 - ((time - Minigame.JustLateTime(pitch)) / (Minigame.NgLateTime(pitch) - Minigame.JustLateTime(pitch)));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
else else
{ {
//early half of timing window //early half of timing window
state = ((time - Minigame.JustEarlyTime()) / (Minigame.AceEarlyTime() - Minigame.JustEarlyTime())); state = ((time - Minigame.JustEarlyTime(pitch)) / (Minigame.AceEarlyTime(pitch) - Minigame.JustEarlyTime(pitch)));
state *= Minigame.rankOkThreshold; state *= Minigame.rankOkThreshold;
} }
} }

View file

@ -389,166 +389,5 @@ namespace HeavenStudio
bool a = GetInputController(1).GetFlick(out dt); bool a = GetInputController(1).GetFlick(out dt);
return a && PlayerHasControl(); return a && PlayerHasControl();
} }
#region Deprecated Input Methods
[Obsolete("Use GetPadDown instead")]
public static bool Pressed()
{
bool keyDown = GetInputController(1).GetActionDown(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.East, out _);
return keyDown && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool Pressed(out double dt)
{
bool keyDown = GetInputController(1).GetActionDown(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.East, out dt);
return keyDown && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool PressedUp()
{
bool keyUp = GetInputController(1).GetActionUp(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.East, out _);
return keyUp && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool PressedUp(out double dt)
{
bool keyUp = GetInputController(1).GetActionUp(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.East, out dt);
return keyUp && PlayerHasControl();
}
[Obsolete("Use GetPad instead")]
public static bool Pressing()
{
bool pressing = GetInputController(1).GetAction(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.East);
return pressing && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool AltPressed()
{
bool down = GetInputController(1).GetActionDown(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.South, out _);
return down && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool AltPressed(out double dt)
{
bool down = GetInputController(1).GetActionDown(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.South, out dt);
return down && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool AltPressedUp()
{
bool up = GetInputController(1).GetActionUp(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.South, out _);
return up && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool AltPressedUp(out double dt)
{
bool up = GetInputController(1).GetActionUp(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.South, out dt);
return up && PlayerHasControl();
}
[Obsolete("Use GetPad instead")]
public static bool AltPressing()
{
bool pressing = GetInputController(1).GetAction(InputController.ControlStyles.Pad, (int)InputController.ActionsPad.South);
return pressing && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool GetAnyDirectionDown()
{
InputController c = GetInputController(1);
return (c.GetHatDirectionDown((InputController.InputDirection)UP, out _)
|| c.GetHatDirectionDown((InputController.InputDirection)DOWN, out _)
|| c.GetHatDirectionDown((InputController.InputDirection)LEFT, out _)
|| c.GetHatDirectionDown((InputController.InputDirection)RIGHT, out _)
) && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool GetAnyDirectionDown(out double dt)
{
InputController c = GetInputController(1);
bool r1 = c.GetHatDirectionDown((InputController.InputDirection)UP, out double d1);
bool r2 = c.GetHatDirectionDown((InputController.InputDirection)DOWN, out double d2);
bool r3 = c.GetHatDirectionDown((InputController.InputDirection)LEFT, out double d3);
bool r4 = c.GetHatDirectionDown((InputController.InputDirection)RIGHT, out double d4);
bool r = (r1 || r2 || r3 || r4) && PlayerHasControl();
dt = Math.Max(Math.Max(Math.Max(d1, d2), d3), d4);
return r;
}
[Obsolete("Use GetPadUp instead")]
public static bool GetAnyDirectionUp()
{
InputController c = GetInputController(1);
return (c.GetHatDirectionUp((InputController.InputDirection)UP, out _)
|| c.GetHatDirectionUp((InputController.InputDirection)DOWN, out _)
|| c.GetHatDirectionUp((InputController.InputDirection)LEFT, out _)
|| c.GetHatDirectionUp((InputController.InputDirection)RIGHT, out _)
) && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool GetAnyDirectionUp(out double dt)
{
InputController c = GetInputController(1);
bool r1 = c.GetHatDirectionUp((InputController.InputDirection)UP, out double d1);
bool r2 = c.GetHatDirectionUp((InputController.InputDirection)DOWN, out double d2);
bool r3 = c.GetHatDirectionUp((InputController.InputDirection)LEFT, out double d3);
bool r4 = c.GetHatDirectionUp((InputController.InputDirection)RIGHT, out double d4);
bool r = (r1 || r2 || r3 || r4) && PlayerHasControl();
dt = Math.Max(Math.Max(Math.Max(d1, d2), d3), d4);
return r;
}
[Obsolete("Use GetPad instead")]
public static bool GetAnyDirection()
{
InputController c = GetInputController(1);
return (c.GetHatDirection((InputController.InputDirection)UP)
|| c.GetHatDirection((InputController.InputDirection)DOWN)
|| c.GetHatDirection((InputController.InputDirection)LEFT)
|| c.GetHatDirection((InputController.InputDirection)RIGHT)
) && PlayerHasControl();
}
[Obsolete("Use GetPad instead")]
public static bool GetSpecificDirection(int direction)
{
return GetInputController(1).GetHatDirection((InputController.InputDirection)direction) && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool GetSpecificDirectionDown(int direction)
{
return GetInputController(1).GetHatDirectionDown((InputController.InputDirection)direction, out _) && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool GetSpecificDirectionUp(int direction)
{
return GetInputController(1).GetHatDirectionUp((InputController.InputDirection)direction, out _) && PlayerHasControl();
}
[Obsolete("Use GetPadDown instead")]
public static bool GetSpecificDirectionDown(int direction, out double dt)
{
return GetInputController(1).GetHatDirectionDown((InputController.InputDirection)direction, out dt) && PlayerHasControl();
}
[Obsolete("Use GetPadUp instead")]
public static bool GetSpecificDirectionUp(int direction, out double dt)
{
return GetInputController(1).GetHatDirectionUp((InputController.InputDirection)direction, out dt) && PlayerHasControl();
}
#endregion
} }
} }