Auto-Swing (#827)

* BurstLinq

make BGM resync when changing pitch (to test)

* autoswing

some game implementations, most games already work fine

* more game tweaks

* 16th note swing

more game fixes
make pitch change resync optional in the API

* suppress some common warnings

* Update Credits.txt
This commit is contained in:
minenice55
2024-04-07 00:54:06 -04:00
committed by minenice55
parent 47905fffc2
commit a3f33e5279
49 changed files with 2372 additions and 242 deletions

View File

@ -41,6 +41,7 @@ namespace HeavenStudio.Games.Scripts_BlueBear
path.positions[0].height = pathToCopy.positions[0].height;
path.positions[1].pos = pathToCopy.positions[1].pos;
game.ScheduleInput(startBeat, flyBeats, isCake ? BlueBear.InputAction_Left : BlueBear.InputAction_Right, Just, Out, Out);
startBeat = Conductor.instance.GetUnSwungBeat(startBeat);
Update();
}
@ -52,7 +53,7 @@ namespace HeavenStudio.Games.Scripts_BlueBear
private void Update()
{
var cond = Conductor.instance;
transform.localPosition = GetPathPositionFromBeat(path, cond.songPositionInBeatsAsDouble, startBeat);
transform.localPosition = GetPathPositionFromBeat(path, cond.unswungSongPositionInBeatsAsDouble, startBeat);
float flyPos = cond.GetPositionFromBeat(startBeat, flyBeats);
if (flyPos > 2f)
@ -75,7 +76,7 @@ namespace HeavenStudio.Games.Scripts_BlueBear
SoundByte.PlayOneShotGame("blueBear/chompDonut");
}
game.Bite(Conductor.instance.songPositionInBeatsAsDouble, isCake, hold);
game.Bite(Conductor.instance.unswungSongPositionInBeatsAsDouble, isCake, hold);
game.EatTreat();
SpawnCrumbs();
@ -100,7 +101,7 @@ namespace HeavenStudio.Games.Scripts_BlueBear
path.positions[0].height = barelyHeight;
path.positions[0].duration = 1;
path.positions[1].pos = new Vector3(path.positions[0].pos.x + (isCake ? -barelyDistX : barelyDistX), path.positions[0].pos.y + barelyDistY);
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
Update();
return;
}

View File

@ -74,11 +74,11 @@ namespace HeavenStudio.Games.Scripts_CatchyTune
{
if (barelyStart > 0f)
{
anim.DoScaledAnimation("barely", barelyStart, isPineapple ? 2f : 1f, clamp: true);
anim.DoScaledAnimation("barely", Conductor.instance.GetUnSwungBeat(barelyStart), isPineapple ? 2f : 1f, clamp: true);
}
else
{
anim.DoScaledAnimation("fruit bounce", startBeat, beatLength + (isPineapple ? 4f : 2f), clamp: true);
anim.DoScaledAnimation("fruit bounce", Conductor.instance.GetUnSwungBeat(startBeat), beatLength + (isPineapple ? 4f : 2f), clamp: true);
}
}
@ -136,7 +136,7 @@ namespace HeavenStudio.Games.Scripts_CatchyTune
if (state <= -1f || state >= 1f)
{
//near miss (barely)
barelyStart = Conductor.instance.songPositionInBeatsAsDouble;
barelyStart = Conductor.instance.unswungSongPositionInBeatsAsDouble;
game.catchBarely(side);

View File

@ -131,7 +131,7 @@ namespace HeavenStudio.Games.Scripts_CropStomp
// var key2Pos = key2.Position;
// key2.Position = new Vector3(key2Pos.x, veggieTrans.position.y + 2f, key2Pos.z);
pickedBeat = Conductor.instance.songPositionInBeatsAsDouble;
pickedBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
SoundByte.PlayOneShot("miss");
@ -222,11 +222,11 @@ namespace HeavenStudio.Games.Scripts_CropStomp
veggieState = 1;
game.ScheduleInput(targetBeat, isMole ? 0.5f : 1f, CropStomp.InputAction_FlickRelease, PickJust, PickMiss, Out);
targetBeat = targetBeat + (isMole ? 0.5f : 1f);
targetBeat = cond.GetUnSwungBeat(targetBeat + (isMole ? 0.5f : 1f));
stompedBeat = cond.songPositionInBeatsAsDouble;
stompedBeat = cond.unswungSongPositionInBeatsAsDouble;
landBeat = targetBeat + (float)cond.SecsToBeats(Minigame.NgLateTime() - 1, cond.GetBpmAtBeat(targetBeat));
landBeat = targetBeat + cond.SecsToBeats(Minigame.NgLateTime() - 1, cond.GetBpmAtBeat(targetBeat));
if (autoTriggered)
{
@ -261,12 +261,12 @@ namespace HeavenStudio.Games.Scripts_CropStomp
game.bodyAnim.DoScaledAnimationAsync("Pick", 0.5f);
game.isFlicking = true;
}
var key1 = game.pickCurve.KeyPoints[0];
var keyPos = key1.Position;
key1.Position = new Vector3(keyPos.x, veggieTrans.position.y, keyPos.z);
pickedBeat = Conductor.instance.songPositionInBeatsAsDouble;
pickedBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
if (!isMole)
{

View File

@ -25,7 +25,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Update()
{
double beat = conductor.songPositionInBeatsAsDouble;
double beat = conductor.unswungSongPositionInBeatsAsDouble;
double height = 0f;
if (pathStartBeat > double.MinValue)
{
@ -44,7 +44,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
game.ScheduleInput(beat, 1f, DoubleDate.InputAction_FlickPress, Just, Miss, Empty);
path = game.GetPath("BasketBallIn");
UpdateLastRealPos();
pathStartBeat = beat - 1f;
pathStartBeat = Conductor.instance.GetUnSwungBeat(beat - 1f);
Vector3 pos = GetPathPositionFromBeat(path, pathStartBeat, pathStartBeat);
transform.position = pos;
@ -65,7 +65,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
}),
});
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
if (state >= 1f || state <= -1f)
{
path = game.GetPath("BasketBallNg" + (state > 0 ? "Late" : "Early"));
@ -80,7 +80,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Hit()
{
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
path = game.GetPath("BasketBallJust");
game.Kick(true, false, true, _jump);
SoundByte.PlayOneShotGame("doubleDate/kick");

View File

@ -261,8 +261,7 @@ namespace HeavenStudio.Games
void Update()
{
var cond = Conductor.instance;
if (cond.isPlaying && !cond.isPaused)
if (conductor.isPlaying && !conductor.isPaused)
{
if (queuedBalls.Count != 0)
{
@ -286,7 +285,7 @@ namespace HeavenStudio.Games
}
else
{
if ((!cond.isPaused) && queuedBalls.Count != 0)
if ((!conductor.isPaused) && queuedBalls.Count != 0)
{
queuedBalls.Clear();
}
@ -352,7 +351,7 @@ namespace HeavenStudio.Games
{
boyAnim.DoScaledAnimationAsync(_isStaring ? "IdleBop2" : "IdleBop", _animSpeed);
}
if (Conductor.instance.songPositionInBeatsAsDouble > lastGirlGacha)
if (conductor.songPositionInBeatsAsDouble > lastGirlGacha)
girlAnim.DoScaledAnimationAsync("GirlBop", _animSpeed);
weasels.Bop();
}
@ -365,7 +364,7 @@ namespace HeavenStudio.Games
if (jump)
{
weasels.Jump();
lastGirlGacha = Conductor.instance.songPositionInBeatsAsDouble + 0.5f;
lastGirlGacha = conductor.songPositionInBeatsAsDouble + 0.5f;
girlAnim.DoScaledAnimationAsync("GirlLookUp", _animSpeed);
}
else if (weaselsHappy) weasels.Happy();
@ -373,7 +372,7 @@ namespace HeavenStudio.Games
{
BeatAction.New(instance, new List<BeatAction.Action>()
{
new BeatAction.Action(Conductor.instance.songPositionInBeatsAsDouble + 1f, delegate
new BeatAction.Action(conductor.songPositionInBeatsAsDouble + 1f, delegate
{
leaves.Play();
treeAnim.DoScaledAnimationAsync("TreeRustle", _animSpeed);
@ -470,11 +469,11 @@ namespace HeavenStudio.Games
public void MissKick(double beat, bool hit = false)
{
lastGirlGacha = Conductor.instance.songPositionInBeatsAsDouble + 1.5f;
lastGirlGacha = conductor.songPositionInBeatsAsDouble + 1.5f;
girlAnim.DoScaledAnimationAsync("GirlSad", _animSpeed);
if (hit)
{
lastHitWeasel = Conductor.instance.songPositionInBeatsAsDouble;
lastHitWeasel = conductor.songPositionInBeatsAsDouble;
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(beat - (0.25f/3f), delegate { weasels.Hit(beat); }),
@ -482,7 +481,7 @@ namespace HeavenStudio.Games
}
else
{
lastHitWeasel = Conductor.instance.songPositionInBeatsAsDouble;
lastHitWeasel = conductor.songPositionInBeatsAsDouble;
BeatAction.New(this, new List<BeatAction.Action>()
{
new BeatAction.Action(beat + 0.25, delegate { weasels.Hide(beat + 0.25f); }),

View File

@ -25,7 +25,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Update()
{
double beat = conductor.songPositionInBeatsAsDouble;
double beat = conductor.unswungSongPositionInBeatsAsDouble;
double height = 0f;
if (pathStartBeat > double.MinValue)
{
@ -44,7 +44,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
game.ScheduleInput(beat, 1.5f, DoubleDate.InputAction_FlickPress, Just, Miss, Empty);
path = game.GetPath("FootBallInNoHit"); // there's a second path for footballs that hit the weasels, use that if the weasels haven't been hit recently
UpdateLastRealPos();
pathStartBeat = beat - 1f;
pathStartBeat = Conductor.instance.GetUnSwungBeat(beat - 1f);
Vector3 pos = GetPathPositionFromBeat(path, pathStartBeat, pathStartBeat);
transform.position = pos;
@ -60,7 +60,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
if (state >= 1f || state <= -1f)
{
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
path = game.GetPath("FootBallNg" + (state > 0 ? "Late" : "Early"));
SoundByte.PlayOneShot("miss");
game.Kick(false);
@ -84,7 +84,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
transform.localScale *= 0.25f;
path = game.GetPath("FootBallFall");
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble + 1f;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble + 1f;
}),
new BeatAction.Action(conductor.songPositionInBeatsAsDouble + 12f, delegate
{
@ -96,7 +96,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Hit()
{
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
path = game.GetPath("FootBallJust");
game.Kick(true, true, jump: _jump);
SoundByte.PlayOneShotGame("doubleDate/footballKick");

View File

@ -25,7 +25,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Update()
{
double beat = conductor.songPositionInBeatsAsDouble;
double beat = conductor.unswungSongPositionInBeatsAsDouble;
double height = 0f;
if (pathStartBeat > double.MinValue)
{
@ -44,7 +44,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
game.ScheduleInput(beat, 1f, DoubleDate.InputAction_FlickPress, Just, Miss, Empty);
path = game.GetPath("SoccerIn");
UpdateLastRealPos();
pathStartBeat = beat - 1f;
pathStartBeat = Conductor.instance.GetUnSwungBeat(beat - 1f);
Vector3 pos = GetPathPositionFromBeat(path, pathStartBeat, pathStartBeat);
transform.position = pos;
@ -65,7 +65,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
}),
});
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
if (state >= 1f || state <= -1f)
{
path = game.GetPath("SoccerNg" + (state > 0 ? "Late" : "Early"));
@ -80,7 +80,7 @@ namespace HeavenStudio.Games.Scripts_DoubleDate
void Hit()
{
UpdateLastRealPos();
pathStartBeat = conductor.songPositionInBeatsAsDouble;
pathStartBeat = conductor.unswungSongPositionInBeatsAsDouble;
path = game.GetPath("SoccerJust");
game.Kick(true, false, true, _jump);
SoundByte.PlayOneShotGame("doubleDate/kick");

View File

@ -389,7 +389,7 @@ namespace HeavenStudio.Games
//idol jumping physics
float jumpPos = conductor.GetPositionFromBeat(idolJumpStartTime, 1f);
float IDOL_SHADOW_SCALE = 1.18f;
if (conductor.songPositionInBeatsAsDouble >= idolJumpStartTime && conductor.songPositionInBeatsAsDouble < idolJumpStartTime + 1f)
if (conductor.unswungSongPositionInBeatsAsDouble >= idolJumpStartTime && conductor.unswungSongPositionInBeatsAsDouble < idolJumpStartTime + 1f)
{
hasJumped = true;
float yMul = jumpPos * 2f - 1f;
@ -579,7 +579,7 @@ namespace HeavenStudio.Games
{
DisableBop(beat, length);
DisableResponse(beat, length);
idolJumpStartTime = beat;
idolJumpStartTime = conductor.GetUnSwungBeat(beat);
//play anim
BeatAction.New(instance, new List<BeatAction.Action>()

View File

@ -69,7 +69,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
//idol jumping physics
float jumpPos = cond.GetPositionFromBeat(startJumpTime, 1f);
float IDOL_SHADOW_SCALE = 1.18f;
if (cond.songPositionInBeatsAsDouble >= startJumpTime && cond.songPositionInBeatsAsDouble < startJumpTime + 1f)
if (cond.unswungSongPositionInBeatsAsDouble >= startJumpTime && cond.unswungSongPositionInBeatsAsDouble < startJumpTime + 1f)
{
hasJumped = true;
float yMul = jumpPos * 2f - 1f;
@ -77,7 +77,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
rootTransform.transform.localPosition = new Vector3(startPostion + stepDistance * AnimCount, rootYPos + (2f * yWeight + 0.25f));
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, (1f-yWeight*0.8f) * IDOL_SHADOW_SCALE, 1f);
anim.DoScaledAnimation("Jump", startJumpTime, 1f);
anim.DoScaledAnimation("Jump", startJumpTime, 1f, ignoreSwing: true);
}
else
{
@ -160,12 +160,11 @@ namespace HeavenStudio.Games.Scripts_FanClub
{
if (startStepBeat != double.MaxValue) return;
if (!gameObject.activeInHierarchy) return;
startJumpTime = beat;
startJumpTime = Conductor.instance.GetUnSwungBeat(beat);
//play anim
BeatAction.New(this, new List<BeatAction.Action>()
{
// new BeatAction.Action(beat, delegate { anim.Play("Jump", -1, 0); }),
new BeatAction.Action(beat + 1f, delegate { anim.Play("Land", -1, 0); }),
});
}

View File

@ -116,7 +116,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
}
if (PlayerInput.GetIsAction(FanClub.InputAction_BasicPressing))
{
if (clappingStartTime != double.MinValue && cond.songPositionInBeatsAsDouble > clappingStartTime + 2f && !stopCharge)
if (clappingStartTime != double.MinValue && cond.unswungSongPositionInBeatsAsDouble > clappingStartTime + 2f && !stopCharge)
{
animator.speed = 1f;
animator.Play("FanClapCharge", -1, 0);
@ -131,7 +131,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
nonTouchDelay = 0f;
stopCharge = true;
}
if (clappingStartTime != double.MinValue && cond.songPositionInBeatsAsDouble > clappingStartTime + nonTouchDelay && stopCharge
if (clappingStartTime != double.MinValue && cond.unswungSongPositionInBeatsAsDouble > clappingStartTime + nonTouchDelay && stopCharge
&& !FanClub.instance.IsExpectingInputNow(FanClub.InputAction_FlickRelease.inputLockCategory))
{
if (FanClub.instance.JudgementPaused)
@ -163,14 +163,14 @@ namespace HeavenStudio.Games.Scripts_FanClub
}
float jumpPos = cond.GetPositionFromBeat(jumpStartTime, 1f);
if (cond.songPositionInBeatsAsDouble >= jumpStartTime && cond.songPositionInBeatsAsDouble < jumpStartTime + 1f)
if (cond.unswungSongPositionInBeatsAsDouble >= jumpStartTime && cond.unswungSongPositionInBeatsAsDouble < jumpStartTime + 1f)
{
hasJumped = true;
float yMul = jumpPos * 2f - 1f;
float yWeight = -(yMul*yMul) + 1f;
motionRoot.transform.localPosition = new Vector3(0, 3f * yWeight);
shadow.transform.localScale = new Vector3((1f-yWeight*0.8f) * 1.4f, (1f-yWeight*0.8f) * 1.4f, 1f);
animator.DoScaledAnimation("FanJump", jumpStartTime);
animator.DoScaledAnimation("FanJump", jumpStartTime, ignoreSwing: true);
}
else
{
@ -205,12 +205,12 @@ namespace HeavenStudio.Games.Scripts_FanClub
var cond = Conductor.instance;
hasJumped = false;
stopBeat = true;
jumpStartTime = -99f;
jumpStartTime = double.MinValue;
animator.speed = 1f;
animator.Play("FanClap", -1, 0);
SoundByte.PlayOneShotGame("fanClub/play_clap");
SoundByte.PlayOneShotGame("fanClub/crap_impact");
clappingStartTime = cond.songPositionInBeatsAsDouble;
clappingStartTime = cond.unswungSongPositionInBeatsAsDouble;
if (doCharge)
BeatAction.New(this, new List<BeatAction.Action>()
@ -247,7 +247,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
var cond = Conductor.instance;
animator.Play("FanJump", -1, 0);
SoundByte.PlayOneShotGame("fanClub/play_jump");
jumpStartTime = cond.songPositionInBeatsAsDouble;
jumpStartTime = cond.unswungSongPositionInBeatsAsDouble;
clappingStartTime = double.MinValue;
stopCharge = false;
}
@ -255,7 +255,7 @@ namespace HeavenStudio.Games.Scripts_FanClub
public bool IsJumping()
{
var cond = Conductor.instance;
return (cond.songPositionInBeatsAsDouble >= jumpStartTime && cond.songPositionInBeatsAsDouble < jumpStartTime + 1f);
return (cond.unswungSongPositionInBeatsAsDouble >= jumpStartTime && cond.unswungSongPositionInBeatsAsDouble < jumpStartTime + 1f);
}
public void Bop()

View File

@ -7,6 +7,7 @@ using HeavenStudio.Util;
using HeavenStudio.InputSystem;
using Jukebox;
using System.Linq;
using BurstLinq;
namespace HeavenStudio.Games.Loaders
{

View File

@ -38,7 +38,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
public bool KickBarrelContent = false;
public bool ShouldGlow = false;
public int OnHitExpression = (int) KarateMan.KarateManFaces.Normal;
public int OnHitExpression = (int)KarateMan.KarateManFaces.Normal;
public int comboId = -1;
static int _lastCombo = -1;
@ -266,8 +266,6 @@ namespace HeavenStudio.Games.Scripts_KarateMan
transform.rotation = Quaternion.Euler(0, 0, transform.rotation.eulerAngles.z + (-360f * Time.deltaTime) + UnityEngine.Random.Range(0f, 360f));
ShadowInstance = Instantiate(Shadow, KarateMan.instance.ItemHolder);
shadowRenderer = ShadowInstance.GetComponent<SpriteRenderer>();
shadowRenderer.color = KarateMan.instance.Joe.Shadows[0].color;
@ -350,7 +348,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
}
else if (type == ItemType.KickBall && cond.songPositionInBeatsAsDouble < startBeat + curveTargetBeat + 1f)
return;
Destroy(ShadowInstance.gameObject);
Destroy(gameObject);
return;
@ -585,9 +583,12 @@ namespace HeavenStudio.Games.Scripts_KarateMan
p.Play();
break;
case ItemType.KickBarrel:
if (KickBarrelContent) {
if (KickBarrelContent)
{
game.CreateItemInstance(startBeat + 1f, "Item03", OnHitExpression, ItemType.KickBall);
} else {
}
else
{
if (ShouldGlow) game.Joe.ApplyBombGlow();
game.CreateItemInstance(startBeat + 1f, "Item04", OnHitExpression, ItemType.KickBomb);
}
@ -629,7 +630,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
break;
}
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
status = FlyStatus.Hit;
}
@ -765,7 +766,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
if (state <= -1f || state >= 1f)
{
bool straight = joe.Punch(ItemPunchHand(), false, ItemPunchHand() == 2);
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -788,7 +789,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
if (ItemNeedNori() && KarateMan.instance.NoriPerformance < 0.6f)
{
CreateHitMark(false);
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
status = FlyStatus.HitWeak;
SoundByte.PlayOneShotGame("karateman/hitNoNori", forcePlay: true);
joe.Punch(3);
@ -815,7 +816,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.ForceFailCombo(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -885,7 +886,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.SetShouldComboId(comboId);
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -932,7 +933,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
bool straight = joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -962,7 +963,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.ComboSequence(3);
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[5];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -1052,7 +1053,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.Punch(ItemPunchHand());
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[6];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -1114,7 +1115,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
joe.Kick(Conductor.instance.songPositionInBeatsAsDouble);
if (state <= -1f || state >= 1f)
{
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
CurrentCurve = ItemCurves[8];
curveTargetBeat = 1f;
SoundByte.PlayOneShot("miss");
@ -1140,7 +1141,7 @@ namespace HeavenStudio.Games.Scripts_KarateMan
ItemHitEffect();
status = FlyStatus.Hit;
CurrentCurve = ItemCurves[7];
startBeat = Conductor.instance.songPositionInBeatsAsDouble;
startBeat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
curveTargetBeat = 3f;
KarateMan.instance.Nori.DoHit();
}

View File

@ -7,6 +7,7 @@ using HeavenStudio.Common;
using HeavenStudio.InputSystem;
using System;
using System.Linq;
using BurstLinq;
using Jukebox;
namespace HeavenStudio.Games

View File

@ -167,6 +167,8 @@ namespace HeavenStudio.Games
public int stepIterate = 0;
private static double startSteppingBeat = double.MaxValue;
private static double startBlippingBeat = double.MaxValue;
private string currentMetronomeDir = "Right";
private static double metronomeBeat = double.MaxValue;
private bool stopStepping;
public bool stopBlipping;
@ -240,6 +242,16 @@ namespace HeavenStudio.Games
man.RecursiveBlipping(startBlippingBeat);
startBlippingBeat = double.MaxValue;
}
if (songPos > metronomeBeat + 1)
{
metronomeAnim.Play("MetronomeGo" + currentMetronomeDir, -1, 1);
metronomeAnim.speed = 0;
}
else if (songPos >= metronomeBeat)
{
metronomeAnim.DoScaledAnimation("MetronomeGo" + currentMetronomeDir, metronomeBeat, 1, ignoreSwing: false);
}
}
}
@ -290,9 +302,9 @@ namespace HeavenStudio.Games
stopStepping = false;
return;
}
string dir = (stepIterate % 2 == 1) ? "Right" : "Left";
metronomeAnim.DoScaledAnimationAsync("MetronomeGo" + dir, 0.5f);
SoundByte.PlayOneShotGame("mrUpbeat/metronome" + dir);
currentMetronomeDir = (stepIterate % 2 == 1) ? "Right" : "Left";
SoundByte.PlayOneShotGame($"mrUpbeat/metronome{currentMetronomeDir}");
metronomeBeat = beat;
ScheduleStep(beat);
BeatAction.New(this, new List<BeatAction.Action>() {
new(beat + 1, delegate { RecursiveStepping(beat + 1); })
@ -305,11 +317,11 @@ namespace HeavenStudio.Games
var actions = new List<BeatAction.Action>();
for (int i = 0; i < length; i++)
{
ScheduleStep(beat);
ScheduleStep(beat + i);
actions.Add(new BeatAction.Action(beat + i, delegate {
string dir = (stepIterate % 2 == 1) ? "Right" : "Left";
metronomeAnim.DoScaledAnimationAsync("MetronomeGo" + dir, 0.5f);
SoundByte.PlayOneShotGame("mrUpbeat/metronome" + dir);
currentMetronomeDir = (stepIterate % 2 == 1) ? "Right" : "Left";
SoundByte.PlayOneShotGame($"mrUpbeat/metronome{currentMetronomeDir}");
metronomeBeat = beat + i;
stepIterate++;
}));
}

View File

@ -123,7 +123,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
public void Jump(double beat, int alt = 1)
{
startJumpTime = beat;
startJumpTime = Conductor.instance.GetUnSwungBeat(beat);
jumpAlt = 0;
if (alt > 1)
{
@ -140,7 +140,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
public void Throw(double beat, bool highCheck)
{
anim.DoUnscaledAnimation("MonkeyThrow" + animSuffix);
startThrowTime = beat;
startThrowTime = Conductor.instance.GetUnSwungBeat(beat);
Projectile.SetActive(true);
if (highCheck)

View File

@ -182,7 +182,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
{
throwType = false;
throwLength = 0.5;
Projectile.GetComponent<Animator>().DoScaledAnimation("ThrowOut", startThrowTime, throwLength);
Projectile.GetComponent<Animator>().DoScaledAnimation("ThrowOut", Conductor.instance.GetUnSwungBeat(startThrowTime), throwLength);
Projectile.transform.rotation = Quaternion.Euler(0, 0, 360f * UnityEngine.Random.Range(0f, 1f));
}
else
@ -310,12 +310,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (state <= -1f || state >= 1f)
{
SoundByte.PlayOneShot("miss");
PlayerJump(cond.songPositionInBeatsAsDouble, false, true);
PlayerJump(cond.unswungSongPositionInBeatsAsDouble, false, true);
}
else
{
SoundByte.PlayOneShotGame("pajamaParty/jumpJust");
PlayerJump(cond.songPositionInBeatsAsDouble, false, false);
PlayerJump(cond.unswungSongPositionInBeatsAsDouble, false, false);
}
caller.CanHit(false);
}
@ -328,7 +328,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (canJump)
{
var cond = Conductor.instance;
PlayerThrough(cond.songPositionInBeatsAsDouble);
PlayerThrough(cond.unswungSongPositionInBeatsAsDouble);
}
}
//////
@ -359,12 +359,12 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
{
SoundByte.PlayOneShot("miss");
throwNg = true;
EndCharge(cond.songPositionInBeatsAsDouble, true, throwNg);
EndCharge(cond.unswungSongPositionInBeatsAsDouble, true, throwNg);
}
else
{
SoundByte.PlayOneShotGame("pajamaParty/throw5");
EndCharge(cond.songPositionInBeatsAsDouble, true, throwNg);
EndCharge(cond.unswungSongPositionInBeatsAsDouble, true, throwNg);
}
caller.CanHit(false);
}
@ -374,7 +374,7 @@ namespace HeavenStudio.Games.Scripts_PajamaParty
if (canCharge)
{
var cond = Conductor.instance;
PlayerThrough(cond.songPositionInBeatsAsDouble);
PlayerThrough(cond.unswungSongPositionInBeatsAsDouble);
}
}
//

View File

@ -147,6 +147,7 @@ namespace HeavenStudio.Games
private bool CheckEventLock()
{
Conductor cond = Conductor.instance;
foreach (PlayerActionEvent toCompare in allEvents)
{
if (toCompare == this) continue;
@ -159,9 +160,9 @@ namespace HeavenStudio.Games
&& toCompare.InputAction.inputLockCategory[catIdx] != InputAction.inputLockCategory[catIdx]) continue;
}
double t1 = this.startBeat + this.timer;
double t2 = toCompare.startBeat + toCompare.timer;
double songPos = Conductor.instance.songPositionInBeatsAsDouble;
double t1 = cond.GetUnSwungBeat(this.startBeat + this.timer);
double t2 = cond.GetUnSwungBeat(toCompare.startBeat + toCompare.timer);
double songPos = cond.unswungSongPositionInBeatsAsDouble;
// compare distance between current time and the events
// events that happen at the exact same time with the exact same inputs will return true
@ -211,7 +212,7 @@ namespace HeavenStudio.Games
{
var cond = Conductor.instance;
double currTime = cond.songPositionAsDouble;
double targetTime = cond.GetSongPosFromBeat(startBeat + timer);
double targetTime = cond.GetSongPosFromBeat(cond.GetUnSwungBeat(startBeat + timer), true);
// HS timing window uses 1 as the middle point instead of 0
return 1 + (currTime - targetTime);

View File

@ -43,7 +43,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
var hairDirection = new Vector3(tst.x + 0.173f, tst.y) - holder.transform.position;
holder.transform.rotation = Quaternion.FromToRotation(Vector3.down, hairDirection);
float normalizedBeat = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f);
float normalizedBeat = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f, ignoreSwing: false);
anim.Play("LoopPull", 0, normalizedBeat);
tweezers.anim.Play("Tweezers_LongPluck", 0, normalizedBeat);
if (!game.IsExpectingInputNow(RhythmTweezers.InputAction_Release) && PlayerInput.GetIsAction(RhythmTweezers.InputAction_Release) && normalizedBeat < 1f)
@ -73,7 +73,7 @@ namespace HeavenStudio.Games.Scripts_RhythmTweezers
public void EndEarly()
{
var normalized = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f);
var normalized = Conductor.instance.GetPositionFromBeat(inputBeat, 0.5f, ignoreSwing: false);
anim.Play("LoopPullReverse", 0, normalized);
tweezers.anim.Play("Tweezers_Idle", 0, 0);

View File

@ -292,7 +292,7 @@ namespace HeavenStudio.Games
spawnedHairs.Add(hair);
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("SmallAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
}
@ -305,7 +305,7 @@ namespace HeavenStudio.Games
spawnedLongs.Add(hair);
hair.gameObject.SetActive(true);
hair.GetComponent<Animator>().Play("LongAppear", 0, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
}
@ -332,7 +332,7 @@ namespace HeavenStudio.Games
})
});
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
}
@ -357,7 +357,7 @@ namespace HeavenStudio.Games
})
});
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(beat, 1);
float rot = -58f + 116 * crHandlerInstance.GetIntervalProgressFromBeat(conductor.GetUnSwungBeat(beat), 1);
hair.transform.eulerAngles = new Vector3(0, 0, rot);
hair.createBeat = beat;
}

View File

@ -68,7 +68,7 @@ namespace HeavenStudio.Games.Scripts_SeeSaw
{
var cond = Conductor.instance;
double currentBeat = cond.songPositionInBeatsAsDouble;
double currentBeat = cond.unswungSongPositionInBeatsAsDouble;
if (cond.isPlaying && !cond.isPaused)
{
@ -298,7 +298,7 @@ namespace HeavenStudio.Games.Scripts_SeeSaw
{
lastState = currentState;
currentState = state;
startBeat = beat;
startBeat = Conductor.instance.GetUnSwungBeat(beat);
heightLastFrame = 0;
hasChangedAnimMidAir = false;
switch (currentState)

View File

@ -101,7 +101,7 @@ namespace HeavenStudio.Games
}
if (Conductor.instance.isPlaying)
{
Conductor.instance.SetMinigamePitch(1f);
Conductor.instance.SetMinigamePitch(1f, true);
}
}

View File

@ -39,10 +39,11 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
}
public void Init(Kicker kicker, double dispensedBeat)
{
Conductor conductor = Conductor.instance;
this.kicker = kicker;
kicker.ball = this;
kicker.dispenserBeat = dispensedBeat;
double currentBeat = Conductor.instance.songPositionInBeatsAsDouble;
double currentBeat = conductor.unswungSongPositionInBeatsAsDouble;
kickPath = SpaceSoccer.instance.GetPath("Kick");
dispensePath = SpaceSoccer.instance.GetPath("Dispense");
highKickPath = SpaceSoccer.instance.GetPath("HighKick");
@ -53,7 +54,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
{
//Debug.Log("Dispensing");
state = State.Dispensing;
startBeat = dispensedBeat;
startBeat = conductor.GetUnSwungBeat(dispensedBeat);
nextAnimBeat = startBeat + GetAnimLength(State.Dispensing);
kicker.kickTimes = 0;
return;
@ -74,31 +75,32 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
//Debug.Log("Setting state to kicked");
state = State.Kicked;
double relativeBeat = currentBeat - dispensedBeat;
startBeat = dispensedBeat + (int)(relativeBeat - 0.1); //this makes the startBeat be for the kick that is currently in progress, but it won't play the kicker's animation for that kick. the -0.1 makes it so that if playback is started right when the kicker kicks, it still plays the kicker's animation.
startBeat = conductor.GetUnSwungBeat(dispensedBeat) + (int)(relativeBeat - 0.1); //this makes the startBeat be for the kick that is currently in progress, but it won't play the kicker's animation for that kick. the -0.1 makes it so that if playback is started right when the kicker kicks, it still plays the kicker's animation.
nextAnimBeat = startBeat + GetAnimLength(State.Kicked);
kicker.kickTimes = (int)(relativeBeat - 0.1) - numHighKicks - 1; //every high kick has 2 kicks in the same time a regular keep-up does 3 kicks.
break;
}
else
{
highKickSwing = 0.5f;
if (highKicks[i].beat + GetAnimLength(State.HighKicked) > currentBeat)
{
highKickSwing = conductor.GetSwingRatioAtBeat(highKicks[i].beat, out _);
//Debug.Log("Setting state to high kick");
state = State.HighKicked;
double relativeBeat = highKicks[i].beat - dispensedBeat;
startBeat = dispensedBeat + Math.Ceiling(relativeBeat); //there is a chance this makes startBeat later than the current beat, but it shouldn't matter too much. It would only happen if the user places the high kicks incorrectly.
startBeat = conductor.GetUnSwungBeat(dispensedBeat) + Math.Ceiling(relativeBeat); //there is a chance this makes startBeat later than the current beat, but it shouldn't matter too much. It would only happen if the user places the high kicks incorrectly.
nextAnimBeat = startBeat + GetAnimLength(State.HighKicked);
kicker.kickTimes = (int)Math.Ceiling(relativeBeat) - numHighKicks - 1;
break;
}
else
{
highKickSwing = conductor.GetSwingRatioAtBeat(highKicks[i].beat + GetAnimLength(State.HighKicked), out _);
//Debug.Log("Setting state to toe");
state = State.Toe;
double relativeBeat = Math.Ceiling(highKicks[i].beat - dispensedBeat) + GetAnimLength(State.HighKicked); //there is a chance this makes startBeat later than the current beat, but it shouldn't matter too much. It would only happen if the user places the high kicks incorrectly.
startBeat = dispensedBeat + relativeBeat;
startBeat = conductor.GetUnSwungBeat(dispensedBeat) + relativeBeat;
nextAnimBeat = startBeat + GetAnimLength(State.Toe);
kicker.kickTimes = (int)(relativeBeat - GetAnimLength(State.HighKicked)) - numHighKicks;
break;
@ -110,7 +112,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
//Debug.Log("Defaulting to kicked state");
state = State.Kicked;
double relativeBeat = currentBeat - dispensedBeat;
startBeat = dispensedBeat + (int)(relativeBeat - 0.1); //this makes the startBeat be for the kick that is currently in progress, but it won't play the kicker's animation for that kick. the -0.1 makes it so that if playback is started right when the kicker kicks, it still plays the kicker's animation.
startBeat = conductor.GetUnSwungBeat(dispensedBeat) + (int)(relativeBeat - 0.1); //this makes the startBeat be for the kick that is currently in progress, but it won't play the kicker's animation for that kick. the -0.1 makes it so that if playback is started right when the kicker kicks, it still plays the kicker's animation.
nextAnimBeat = startBeat + GetAnimLength(State.Kicked);
kicker.kickTimes = (int)(relativeBeat - 0.1) - numHighKicks - 1;
}
@ -178,7 +180,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
private void Update()
{
double beat = Conductor.instance.songPositionInBeatsAsDouble;
double beat = Conductor.instance.unswungSongPositionInBeatsAsDouble;
switch (state) //handle animations
{
case State.None: //the only time any ball should ever have this state is if it's the unused offscreen ball (which is the only reason this state exists)
@ -270,7 +272,7 @@ namespace HeavenStudio.Games.Scripts_SpaceSoccer
case State.Kicked:
return 1f;
case State.HighKicked:
return 2f - highKickSwing;
return 1f + highKickSwing;
case State.Toe:
return 2f - (1f - highKickSwing);
default:

View File

@ -20,7 +20,7 @@ namespace HeavenStudio.Games.Scripts_WizardsWaltz
void Update()
{
songPos = (float)(Conductor.instance.songPositionInBeatsAsDouble - game.wizardBeatOffset);
songPos = (float)(Conductor.instance.unswungSongPositionInBeatsAsDouble - game.wizardBeatOffset);
var am = game.beatInterval / 2f;
var x = Mathf.Sin(Mathf.PI * songPos / am) * game.xRange;
var y = Mathf.Cos(Mathf.PI * songPos / am) * game.yRange;

View File

@ -223,7 +223,7 @@ namespace HeavenStudio.Games
intervalStartBeat = beat;
foreach (var plant in currentPlants)
{
var songPos = (float)(plant.createBeat - wizardBeatOffset);
var songPos = (float)(conductor.GetUnSwungBeat(plant.createBeat) - wizardBeatOffset);
var am = (beatInterval / 2f);
var x = Mathf.Sin(Mathf.PI * songPos / am) * xRange;
var y = plantYOffset + Mathf.Cos(Mathf.PI * songPos / am) * (yRange * 1.5f);
@ -260,7 +260,7 @@ namespace HeavenStudio.Games
if (!spawnedInactive) SoundByte.PlayOneShotGame("wizardsWaltz/plant", beat);
Plant plant = Instantiate(plantBase, plantHolder.transform).GetComponent<Plant>();
currentPlants.Add(plant);
var songPos = (float)(beat - wizardBeatOffset);
var songPos = (float)(conductor.GetUnSwungBeat(beat) - wizardBeatOffset);
var am = (beatInterval / 2f);
var x = Mathf.Sin(Mathf.PI * songPos / am) * xRange;
var y = plantYOffset + Mathf.Cos(Mathf.PI * songPos / am) * (yRange * 1.5f);