autoswing

some game implementations, most games already work fine
This commit is contained in:
minenice55 2024-04-05 23:52:45 -04:00
parent 317b3413f3
commit b88280cfe3
17 changed files with 1571 additions and 145 deletions

File diff suppressed because it is too large Load diff

View file

@ -23,11 +23,11 @@ namespace HeavenStudio
// Song beats per minute
// This is determined by the song you're trying to sync up to
public float songBpm;
public float songBpm { get; private set; }
// The number of seconds for each song beat
public float secPerBeat => (float)secPerBeatAsDouble;
public double secPerBeatAsDouble;
public double secPerBeatAsDouble { get; private set; }
// The number of seconds for each song beat, inversely scaled to song pitch (higer pitch = shorter time)
public float pitchedSecPerBeat => (float)pitchedSecPerBeatAsDouble;
@ -39,9 +39,11 @@ namespace HeavenStudio
public double songPositionAsDouble => songPos;
// Current song position, in beats
public double songPosBeat; // for Conductor use only
public float songPositionInBeats => (float)songPosBeat;
public double songPositionInBeatsAsDouble => songPosBeat;
public double songPosBeat { get; private set; }
public float songPositionInBeats => (float)songPositionInBeatsAsDouble;
public double songPositionInBeatsAsDouble { get; private set; }
public float unswungSongPositionInBeats => (float)songPosBeat;
public double unswungSongPositionInBeatsAsDouble => songPosBeat;
// Current time of the song
private double time;
@ -80,7 +82,7 @@ namespace HeavenStudio
// Metronome tick sound enabled
public bool metronome = false;
Util.Sound metronomeSound;
Util.MultiSound metronomeSound;
private int _metronomeTally = 0;
// pitch values
@ -99,7 +101,7 @@ namespace HeavenStudio
if (isPaused || deferTimeKeeping) return;
if (pitch != 0 && pitch != timelinePitch)
{
Debug.Log("added pitch change " + pitch * minigamePitch + " at " + absTime);
// Debug.Log("added pitch change " + pitch * minigamePitch + " at " + absTime);
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * minigamePitch });
}
@ -107,10 +109,13 @@ namespace HeavenStudio
if (musicSource != null && musicSource.clip != null)
{
musicSource.pitch = SongPitch;
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset);
if (isPlaying)
{
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset);
}
}
}
@ -119,7 +124,7 @@ namespace HeavenStudio
if (isPaused || deferTimeKeeping || !isPlaying) return;
if (pitch != 0 && pitch != minigamePitch)
{
Debug.Log("added pitch change " + pitch * timelinePitch + " at " + absTime);
// Debug.Log("added pitch change " + pitch * timelinePitch + " at " + absTime);
addedPitchChanges.Add(new AddedPitchChange { time = absTime, pitch = pitch * timelinePitch });
}
@ -127,10 +132,13 @@ namespace HeavenStudio
if (musicSource != null && musicSource.clip != null)
{
musicSource.pitch = SongPitch;
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset);
if (isPlaying)
{
time = MapTimeToPitchChanges(absTime + absTimeAdjust);
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
SeekMusicToTime(songPos, firstBeatOffset);
}
}
}
@ -170,6 +178,8 @@ namespace HeavenStudio
{
deferTimeKeeping = true;
songPosBeat = beat;
absTime = 0;
startTime = DateTime.Now;
}
public void Play(double beat)
@ -224,6 +234,7 @@ namespace HeavenStudio
_metronomeTally = 0;
startTime = DateTime.Now;
absTime = 0;
absTimeAdjust = 0;
deferTimeKeeping = musicSource.clip != null;
@ -241,7 +252,8 @@ namespace HeavenStudio
{
deferTimeKeeping = false;
// Debug.Log($"dsptime: {dsp}, deferred timekeeping for {DateTime.Now - startTime} seconds (delta dsp {dsp - dspStart})");
startTime += TimeSpan.FromSeconds(dsp - dspStart);
startTime = DateTime.Now;
absTime = 0;
absTimeAdjust = 0;
dspStart = dsp;
}
@ -400,6 +412,7 @@ namespace HeavenStudio
songPos = startPos + time;
songPosBeat = GetBeatFromSongPos(songPos);
songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat);
}
}
@ -431,7 +444,14 @@ namespace HeavenStudio
{
if (songPositionInBeatsAsDouble >= Math.Ceiling(startBeat) + _metronomeTally)
{
if (metronome) metronomeSound = Util.SoundByte.PlayOneShot("metronome", Math.Ceiling(startBeat) + _metronomeTally);
// if (metronome) metronomeSound = Util.SoundByte.PlayOneShot("metronome", Math.Ceiling(startBeat) + _metronomeTally);
if (metronome)
{
metronomeSound = Util.MultiSound.Play(new List<Util.MultiSound.Sound> {
new Util.MultiSound.Sound("metronome", Math.Ceiling(startBeat) + _metronomeTally),
new Util.MultiSound.Sound("metronome", Math.Ceiling(startBeat) + _metronomeTally + 0.5, 1.5f, 0.5f)
}, false, true);
}
_metronomeTally++;
}
}
@ -439,7 +459,7 @@ namespace HeavenStudio
{
if (metronomeSound != null)
{
metronomeSound.Stop();
// metronomeSound.StopAll();
metronomeSound = null;
}
}
@ -460,9 +480,9 @@ namespace HeavenStudio
return result;
}
public float GetLoopPositionFromBeat(float beatOffset, float length, bool beatClamp = true)
public float GetLoopPositionFromBeat(float beatOffset, float length, bool beatClamp = true, bool ignoreSwing = true)
{
float beat = songPositionInBeats;
float beat = ignoreSwing ? unswungSongPositionInBeats : songPositionInBeats;
if (beatClamp)
{
beat = Mathf.Max(beat, 0);
@ -470,9 +490,9 @@ namespace HeavenStudio
return Mathf.Repeat((beat / length) + beatOffset, 1);
}
public float GetPositionFromBeat(double startBeat, double length, bool beatClamp = true)
public float GetPositionFromBeat(double startBeat, double length, bool beatClamp = true, bool ignoreSwing = true)
{
float beat = songPositionInBeats;
float beat = ignoreSwing ? unswungSongPositionInBeats : songPositionInBeats;
if (beatClamp)
{
beat = Mathf.Max(beat, 0);
@ -493,20 +513,11 @@ namespace HeavenStudio
var chart = gameManager.Beatmap;
if (chart.TempoChanges.Count == 0)
return 120f;
float bpm = chart.TempoChanges[0]["tempo"];
swingRatio = chart.TempoChanges[0]["swing"] + 0.5f;
foreach (RiqEntity t in chart.TempoChanges)
{
if (t.beat > beat)
{
break;
}
bpm = t["tempo"];
swingRatio = t["swing"] + 0.5f;
}
return bpm;
RiqEntity tempoChange = chart.TempoChanges.FindLast(t => t.beat <= beat);
tempoChange ??= chart.TempoChanges[0];
swingRatio = tempoChange["swing"] + 0.5f;
return tempoChange["tempo"];
}
public float GetBpmAtBeat(double beat)
@ -521,25 +532,53 @@ namespace HeavenStudio
return swingRatio;
}
public double GetSwungBeat(double beat)
{
return Math.Floor(beat) + GetSwingOffset(beat, GetSwingRatioAtBeat(beat));
}
public double GetSwungBeat(double beat, float ratio)
{
return beat + GetSwingOffset(beat, ratio);
return Math.Floor(beat) + GetSwingOffset(beat, ratio);
}
public double GetSwingOffset(double beatFrac, float ratio)
{
beatFrac %= 1;
if (beatFrac <= 0.5)
if (beatFrac <= ratio)
{
return 0.5 / ratio * beatFrac;
}
else
{
return 0.5 + (0.5 / (1f - ratio) * (beatFrac - ratio));
return 0.5 + 0.5 / (1 - ratio) * (beatFrac - ratio);
}
}
public double GetSongPosFromBeat(double beat)
public double GetUnSwungBeat(double beat)
{
return Math.Floor(beat) + GetUnSwingOffset(beat, GetSwingRatioAtBeat(beat));
}
public double GetUnSwungBeat(double beat, float ratio)
{
return Math.Floor(beat) + GetUnSwingOffset(beat, ratio);
}
public double GetUnSwingOffset(double beatFrac, float ratio)
{
beatFrac %= 1;
if (beatFrac <= ratio)
{
return 2 * ratio * beatFrac;
}
else
{
return 2 * (beatFrac - 0.5f) * (1f - ratio) + ratio;
}
}
public double GetSongPosFromBeat(double beat, bool ignoreSwing = false)
{
var chart = gameManager.Beatmap;
float bpm = 120f;
@ -548,6 +587,11 @@ namespace HeavenStudio
double lastTempoChangeBeat = 0f;
if (!ignoreSwing)
{
beat = GetUnSwungBeat(beat);
}
foreach (RiqEntity t in chart.TempoChanges)
{
if (t.beat > beat)

View file

@ -236,7 +236,6 @@ namespace HeavenStudio
public void NewRemix()
{
Debug.Log("Creating new remix");
AudioLoadDone = false;
Beatmap = new("1", "HeavenStudio");
Beatmap.data.properties = new(Minigames.propertiesModel);
@ -447,7 +446,7 @@ namespace HeavenStudio
var inf = GetGameInfo(gameName);
if (inf != null && inf.usesAssetBundle && inf.AssetsLoaded && !inf.SequencesPreloaded)
{
Debug.Log($"Preparing game {gameName}");
// Debug.Log($"Preparing game {gameName}");
PreloadGameSequences(gameName);
}
eventCaller.CallPreEvent(entity);
@ -462,32 +461,31 @@ namespace HeavenStudio
{
if (BeatmapEntities() < 1)
return;
if (!conductor.isPlaying)
if (conductor.WaitingForDsp || !conductor.isPlaying)
return;
Conductor cond = conductor;
double clampedBeat = Math.Max(cond.songPositionInBeatsAsDouble, 0);
double clampedBeat = Math.Max(conductor.songPositionInBeatsAsDouble, 0);
if (currentTempoEvent < Beatmap.TempoChanges.Count && currentTempoEvent >= 0)
{
if (cond.songPositionInBeatsAsDouble >= tempoBeats[currentTempoEvent])
if (conductor.songPositionInBeatsAsDouble >= tempoBeats[currentTempoEvent])
{
cond.SetBpm(Beatmap.TempoChanges[currentTempoEvent]["tempo"]);
conductor.SetBpm(Beatmap.TempoChanges[currentTempoEvent]["tempo"]);
currentTempoEvent++;
}
}
if (currentVolumeEvent < Beatmap.VolumeChanges.Count && currentVolumeEvent >= 0)
{
if (cond.songPositionInBeatsAsDouble >= volumeBeats[currentVolumeEvent])
if (conductor.songPositionInBeatsAsDouble >= volumeBeats[currentVolumeEvent])
{
cond.SetVolume(Beatmap.VolumeChanges[currentVolumeEvent]["volume"]);
conductor.SetVolume(Beatmap.VolumeChanges[currentVolumeEvent]["volume"]);
currentVolumeEvent++;
}
}
if (currentSectionEvent < Beatmap.SectionMarkers.Count && currentSectionEvent >= 0)
{
if (cond.songPositionInBeatsAsDouble >= sectionBeats[currentSectionEvent])
if (conductor.songPositionInBeatsAsDouble >= sectionBeats[currentSectionEvent])
{
RiqEntity marker = Beatmap.SectionMarkers[currentSectionEvent];
if (!string.IsNullOrEmpty(marker["sectionName"]))
@ -529,7 +527,7 @@ namespace HeavenStudio
}
}
if (cond.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _pulseTally)
if (conductor.songPositionInBeatsAsDouble >= Math.Ceiling(_playStartBeat) + _pulseTally)
{
if (minigame != null) minigame.OnBeatPulse(Math.Ceiling(_playStartBeat) + _pulseTally);
onBeatPulse?.Invoke(Math.Ceiling(_playStartBeat) + _pulseTally);
@ -546,7 +544,7 @@ namespace HeavenStudio
List<RiqEntity> entitiesInRange = ListPool<RiqEntity>.Get();
List<RiqEntity> fxEntities = ListPool<RiqEntity>.Get();
// allows for multiple events on the same beat to be executed on the same frame, so no more 1-frame delay
while (currentEvent < eventBeats.Count && clampedBeat >= eventBeats[currentEvent] && conductor.isPlaying)
while (currentEvent < eventBeats.Count && clampedBeat >= eventBeats[currentEvent] && this.conductor.isPlaying)
{
fxEntities.Clear();
entitiesInRange.Clear();
@ -602,9 +600,9 @@ namespace HeavenStudio
}
else
{
double currectSectionStart = cond.GetSongPosFromBeat(currentSection.beat);
double currectSectionStart = conductor.GetSongPosFromBeat(currentSection.beat);
SectionProgress = (cond.songPosition - currectSectionStart) / (cond.GetSongPosFromBeat(nextSectionBeat) - currectSectionStart);
SectionProgress = (conductor.songPosition - currectSectionStart) / (conductor.GetSongPosFromBeat(nextSectionBeat) - currectSectionStart);
}
}
@ -672,7 +670,6 @@ namespace HeavenStudio
public void Play(double beat, float delay = 0f)
{
bool paused = conductor.isPaused;
Debug.Log("Playing at " + beat);
_playStartBeat = beat;
_pulseTally = 0;
_latePulseTally = 0;
@ -721,7 +718,9 @@ namespace HeavenStudio
conductor.SetBpm(Beatmap.TempoChanges[0]["tempo"]);
conductor.SetVolume(Beatmap.VolumeChanges[0]["volume"]);
conductor.firstBeatOffset = Beatmap.data.offset;
conductor.PlaySetup(beat);
SetCurrentEventToClosest(beat);
Debug.Log("Playing at " + beat);
KillAllSounds();
if (delay > 0)
@ -729,7 +728,6 @@ namespace HeavenStudio
yield return new WaitForSeconds(delay);
}
conductor.PlaySetup(beat);
Minigame miniGame = null;
if (minigameObj != null && minigameObj.TryGetComponent<Minigame>(out miniGame))
{
@ -819,6 +817,10 @@ namespace HeavenStudio
GlobalGameManager.LoadScene("Judgement", 0.35f, 0f, DestroyGame);
CircleCursor.LockCursor(false);
}
else
{
conductor.SetBeat(beat);
}
Application.backgroundLoadingPriority = ThreadPriority.Normal;
}
@ -833,6 +835,8 @@ namespace HeavenStudio
SoundByte.PreloadAudioClipAsync("skillStar");
SoundByte.PreloadAudioClipAsync("perfectMiss");
conductor.SetBeat(beat);
WaitUntil yieldOverlays = new WaitUntil(() => OverlaysManager.OverlaysReady);
WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && BeatmapEntities() > 0);
WaitUntil yieldAudio = new WaitUntil(() => AudioLoadDone || (ChartLoadError && !GlobalGameManager.IsShowingDialog));
@ -845,16 +849,16 @@ namespace HeavenStudio
}
// wait for overlays to be ready
Debug.Log("waiting for overlays");
// Debug.Log("waiting for overlays");
yield return yieldOverlays;
// wait for beatmap to be loaded
Debug.Log("waiting for beatmap");
// Debug.Log("waiting for beatmap");
yield return yieldBeatmap;
//wait for audio clip to be loaded
Debug.Log("waiting for audio");
// Debug.Log("waiting for audio");
yield return yieldAudio;
//wait for games to be loaded
Debug.Log("waiting for minigames");
// Debug.Log("waiting for minigames");
if (yieldGame != null)
yield return yieldGame;
@ -874,7 +878,7 @@ namespace HeavenStudio
public void KillAllSounds()
{
Debug.Log("Killing all sounds");
// Debug.Log("Killing all sounds");
SoundObjects.Clear();
SoundByte.KillOneShots();
}
@ -898,9 +902,10 @@ namespace HeavenStudio
allGameSwitches = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame" });
preSequenceBeats = new List<double>();
string[] seekEntityDatamodel;
foreach (RiqEntity entity in Beatmap.Entities)
{
string[] seekEntityDatamodel = entity.datamodel.Split('/');
seekEntityDatamodel = entity.datamodel.Split('/');
double seekTime = eventCaller.GetGameAction(seekEntityDatamodel[0], seekEntityDatamodel[1]).preFunctionLength;
preSequenceBeats.Add(entity.beat - seekTime);
}
@ -1168,7 +1173,7 @@ namespace HeavenStudio
{
if (!(inf.AssetsLoaded || inf.AlreadyLoading))
{
Debug.Log($"ASYNC loading assetbundles for game {game}");
// Debug.Log($"ASYNC loading assetbundles for game {game}");
inf.LoadAssetsAsync().Forget();
}
yield return new WaitUntil(() => inf.AssetsLoaded);

View file

@ -390,7 +390,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;
@ -580,7 +580,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

@ -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

@ -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

@ -293,7 +293,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;
}
@ -306,7 +306,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;
}
@ -333,7 +333,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;
}
@ -358,7 +358,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

@ -14,6 +14,8 @@ public class TempoDialog : Dialog
[SerializeField] Button deleteButton;
[SerializeField] TMP_InputField tempoInput;
[SerializeField] TMP_InputField swingInput;
[SerializeField] Slider swingSlider;
public void SwitchTempoDialog()
{
@ -28,6 +30,9 @@ public class TempoDialog : Dialog
Editor.instance.inAuthorativeMenu = true;
ResetAllDialogs();
dialog.SetActive(true);
swingSlider.maxValue = 0.25f;
swingSlider.minValue = 0;
}
}
@ -45,6 +50,8 @@ public class TempoDialog : Dialog
deleteButton.gameObject.SetActive(!tempoObj.first);
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F");
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
}
public void DeleteTempo()
@ -86,4 +93,25 @@ public class TempoDialog : Dialog
tempoInput.text = tempoObj.chartEntity["tempo"].ToString("F");
}
}
public void SwingSliderUpdate()
{
if (tempoObj != null)
{
tempoObj.SetSwing(System.MathF.Round(swingSlider.value, 4));
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
}
}
public void SetSwing()
{
if (tempoObj != null)
{
float swing = float.Parse(swingInput.text);
tempoObj.SetSwing(swing * 0.25f / 100f);
swingInput.text = (tempoObj.chartEntity["swing"] * 400).ToString("F");
swingSlider.value = tempoObj.chartEntity["swing"];
}
}
}

View file

@ -62,6 +62,12 @@ namespace HeavenStudio.Editor.Track
SetX(chartEntity);
}
public void SetSwing(float swing)
{
chartEntity["swing"] = Mathf.Clamp(swing, 0, 0.5f);
UpdateTempo();
}
public override void Init()
{
UpdateTempo();

View file

@ -476,7 +476,7 @@ namespace HeavenStudio.Editor.Track
if (Conductor.instance.metronome)
{
var startBeat = Mathf.FloorToInt(Conductor.instance.songPositionInBeats - 0.5f);
var nm = Conductor.instance.GetLoopPositionFromBeat(0.5f, 1f);
var nm = Conductor.instance.GetLoopPositionFromBeat(0.5f, 1f, ignoreSwing: false);
var loop = (startBeat % 2 == 0) ? Mathf.SmoothStep(-1.1f, 1f, nm) : Mathf.SmoothStep(1f, -1f, nm);
rot = loop * 45f;
@ -674,16 +674,14 @@ namespace HeavenStudio.Editor.Track
public void Play(bool fromStart, float time)
{
// if (fromStart) Stop();
GameManager.instance.SafePlay(time, 0, false);
if (!Conductor.instance.isPaused)
{
TimelineSongPosLine = Instantiate(TimelineSongPosLineRef, TimelineSongPosLineRef.parent).GetComponent<RectTransform>();
TimelineSongPosLine.gameObject.SetActive(true);
TimelineSongPosLine.transform.localPosition = new Vector3(time * PixelsPerBeat, TimelineSongPosLine.transform.localPosition.y);
}
GameManager.instance.SafePlay(time, 0, false);
SetTimeButtonColors(false, true, true);
}

View file

@ -34,10 +34,10 @@ namespace HeavenStudio.Util
/// <param name="length">duration of animation (progress 1.0)</param>
/// <param name="timeScale">multiplier for animation progress (smaller values make animation slower)</param>
/// <param name="animLayer">animator layer to play animation on</param>
public static void DoScaledAnimation(this Animator anim, string animName, double startTime, double length = 1, float timeScale = 1f, int animLayer = -1, bool clamp = false)
public static void DoScaledAnimation(this Animator anim, string animName, double startTime, double length = 1, float timeScale = 1f, int animLayer = -1, bool clamp = false, bool ignoreSwing = true)
{
if (anim == null) return;
float pos = Conductor.instance.GetPositionFromBeat(startTime, length) * timeScale;
float pos = Conductor.instance.GetPositionFromBeat(startTime, length, ignoreSwing: ignoreSwing) * timeScale;
if (clamp) pos = Mathf.Clamp01(pos);
anim.Play(animName, animLayer, pos);
anim.speed = 1f; //not 0 so these can still play their script events

View file

@ -1,7 +1,6 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BurstLinq;
using UnityEngine;
using Cysharp.Threading.Tasks;
@ -108,12 +107,16 @@ namespace HeavenStudio.Util
Destroy(gameObject);
}
public void StopAll()
public void StopAll(bool destroy = false)
{
foreach (Util.Sound sound in playingSounds)
{
sound.Stop();
}
if (destroy)
{
Destroy(gameObject);
}
}
}
}