From c9f6b3edaf9b8e427bbe58491e5caa1d602bcca4 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Mon, 8 Apr 2024 22:01:18 -0400 Subject: [PATCH 1/4] Asset Loading Fix (#843) * (hopefullyt) fix asset loading issue * let mis-packed games load from res timing display tweak * fix initial pre-load not actually preloading needed games fix mr upbeat metronome * let's try this resyncing again --- Assets/Scripts/Conductor.cs | 16 ++-- Assets/Scripts/EventCaller.cs | 22 +++-- Assets/Scripts/GameManager.cs | 53 +++++++---- Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs | 87 +++++++++++-------- .../Games/SneakySpirits/SneakySpirits.cs | 2 +- Assets/Scripts/Minigames.cs | 8 +- .../UI/Overlays/TimingAccuracyDisplay.cs | 9 +- 7 files changed, 112 insertions(+), 85 deletions(-) diff --git a/Assets/Scripts/Conductor.cs b/Assets/Scripts/Conductor.cs index f2c6445dc..1ab571ab8 100644 --- a/Assets/Scripts/Conductor.cs +++ b/Assets/Scripts/Conductor.cs @@ -96,9 +96,7 @@ namespace HeavenStudio private float timelineVolume = 1f; private float minigameVolume = 1f; - const bool doPitchResync = false; - - public void SetTimelinePitch(float pitch, bool resync = false) + public void SetTimelinePitch(float pitch) { if (isPaused || deferTimeKeeping) return; if (pitch != 0 && pitch != timelinePitch) @@ -111,17 +109,17 @@ namespace HeavenStudio if (musicSource != null && musicSource.clip != null) { musicSource.pitch = SongPitch; - if (doPitchResync && isPlaying && resync && !deferTimeKeeping) + if (isPlaying && !(isPaused || deferTimeKeeping)) { time = MapTimeToPitchChanges(absTime + absTimeAdjust); songPos = startPos + time; songPosBeat = GetBeatFromSongPos(songPos); - SeekMusicToTime(songPos, firstBeatOffset); + songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat); } } } - public void SetMinigamePitch(float pitch, bool resync = false) + public void SetMinigamePitch(float pitch) { if (isPaused || deferTimeKeeping || !isPlaying) return; if (pitch != 0 && pitch != minigamePitch) @@ -134,12 +132,12 @@ namespace HeavenStudio if (musicSource != null && musicSource.clip != null) { musicSource.pitch = SongPitch; - if (doPitchResync && isPlaying && resync && !deferTimeKeeping) + if (isPlaying && !(isPaused || deferTimeKeeping)) { time = MapTimeToPitchChanges(absTime + absTimeAdjust); songPos = startPos + time; songPosBeat = GetBeatFromSongPos(songPos); - SeekMusicToTime(songPos, firstBeatOffset); + songPositionInBeatsAsDouble = GetSwungBeat(songPosBeat); } } } @@ -171,7 +169,7 @@ namespace HeavenStudio songPosBeat = GetBeatFromSongPos(time); - gameManager.SetCurrentEventToClosest(beat); + gameManager.SetCurrentEventToClosest(beat, true); } public void PlaySetup(double beat) diff --git a/Assets/Scripts/EventCaller.cs b/Assets/Scripts/EventCaller.cs index 29e67d5b4..42cecc80e 100644 --- a/Assets/Scripts/EventCaller.cs +++ b/Assets/Scripts/EventCaller.cs @@ -118,24 +118,22 @@ namespace HeavenStudio public static List GetAllInGameManagerList(string gameName, string[] include) { - List temp1 = instance.gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); - List temp2 = new List(); - foreach (string s in include) + Predicate match = c => { - temp2.AddRange(temp1.FindAll(c => c.datamodel.Split('/')[1].Equals(s))); - } - return temp2; + string[] details = c.datamodel.Split('/'); + return details[0] == gameName && include.Contains(details[1]); + }; + return instance.gameManager.Beatmap.Entities.FindAll(match); } public static List GetAllInGameManagerListExclude(string gameName, string[] exclude) { - List temp1 = instance.gameManager.Beatmap.Entities.FindAll(c => c.datamodel.Split('/')[0] == gameName); - List temp2 = new List(); - foreach (string s in exclude) + Predicate match = c => { - temp2.AddRange(temp1.FindAll(c => !c.datamodel.Split('/')[1].Equals(s))); - } - return temp2; + string[] details = c.datamodel.Split('/'); + return details[0] == gameName && !exclude.Contains(details[1]); + }; + return instance.gameManager.Beatmap.Entities.FindAll(match); } public static List FXOnlyGames() diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index a5a7b8bf3..e630566e3 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -22,7 +22,6 @@ namespace HeavenStudio [Header("Lists")] [NonSerialized] public RiqBeatmap Beatmap = new(); - private Dictionary cachedGamePrefabs = new(); [NonSerialized] public ObjectPool SoundObjects; [Header("Components")] @@ -372,7 +371,7 @@ namespace HeavenStudio List entitiesAtSameBeat = ListPool.Get(); Minigames.Minigame inf; - //seek ahead to preload games that have assetbundles + // seek ahead to preload games that have assetbundles if (currentPreSwitch < allGameSwitches.Count && currentPreSwitch >= 0) { if (start + seekTime >= allGameSwitches[currentPreSwitch].beat) @@ -723,7 +722,7 @@ namespace HeavenStudio conductor.SetVolume(Beatmap.VolumeChanges[0]["volume"]); conductor.firstBeatOffset = Beatmap.data.offset; conductor.PlaySetup(beat); - SetCurrentEventToClosest(beat); + SetCurrentEventToClosest(beat, true); Debug.Log("Playing at " + beat); KillAllSounds(); @@ -845,7 +844,7 @@ namespace HeavenStudio WaitUntil yieldBeatmap = new WaitUntil(() => Beatmap != null && BeatmapEntities() > 0); WaitUntil yieldAudio = new WaitUntil(() => AudioLoadDone || (ChartLoadError && !GlobalGameManager.IsShowingDialog)); WaitUntil yieldGame = null; - List gamesToPreload = SeekAheadAndPreload(beat, 4f); + List gamesToPreload = SetCurrentEventToClosest(beat, true); Debug.Log($"Preloading {gamesToPreload.Count} games"); if (gamesToPreload.Count > 0) { @@ -974,9 +973,10 @@ namespace HeavenStudio return 0; } - public void SetCurrentEventToClosest(double beat, bool canPreload = false) + public List SetCurrentEventToClosest(double beat, bool canPreload = false) { SortEventsList(); + List preload = new(); onBeatChanged?.Invoke(beat); if (Beatmap.Entities.Count > 0) { @@ -984,15 +984,13 @@ namespace HeavenStudio currentPreEvent = GetIndexAfter(eventBeats, beat); currentPreSequence = GetIndexAfter(eventBeats, beat); - var gameSwitchs = Beatmap.Entities.FindAll(c => c.datamodel.Split("/")[1] == "switchGame"); - string newGame = Beatmap.Entities[Math.Min(currentEvent, eventBeats.Count - 1)].datamodel.Split(0); - if (gameSwitchs.Count > 0) + if (allGameSwitches.Count > 0) { - int index = GetIndexBefore(gameSwitchs.Select(c => c.beat).ToList(), beat); + int index = GetIndexBefore(allGameSwitches.Select(c => c.beat).ToList(), beat); currentPreSwitch = index; - var closestGameSwitch = gameSwitchs[index]; + var closestGameSwitch = allGameSwitches[index]; if (closestGameSwitch.beat <= beat) { newGame = closestGameSwitch.datamodel.Split(2); @@ -1007,7 +1005,7 @@ namespace HeavenStudio { if (index - 1 >= 0) { - newGame = gameSwitchs[index - 1].datamodel.Split(2); + newGame = allGameSwitches[index - 1].datamodel.Split(2); } else { @@ -1015,13 +1013,17 @@ namespace HeavenStudio } } } - // newGame = gameSwitchs[gameSwitchs.IndexOf(gameSwitchs.Find(c => c.beat == MathUtils.GetClosestInList(gameSwitchs.Select(c => c.beat).ToList(), beat)))].datamodel.Split(2); } if (!GetGameInfo(newGame).fxOnly) { if (canPreload) { + Minigames.Minigame inf = GetGameInfo(newGame); + if (inf != null) + { + preload.Add(inf); + } StartCoroutine(WaitAndSetGame(newGame)); } else @@ -1091,7 +1093,8 @@ namespace HeavenStudio } onSectionChange?.Invoke(currentSection, lastSection); - SeekAheadAndPreload(beat); + preload.AddRange(SeekAheadAndPreload(beat)); + return preload; } #endregion @@ -1124,7 +1127,7 @@ namespace HeavenStudio } } - while (beat + 0.25 > Math.Max(conductor.songPositionInBeatsAsDouble, 0)) + while (conductor.GetUnSwungBeat(beat + 0.25) > Math.Max(conductor.unswungSongPositionInBeatsAsDouble, 0)) { if (!conductor.isPlaying) { @@ -1165,13 +1168,18 @@ namespace HeavenStudio public void DestroyGame() { - cachedGamePrefabs.Clear(); SoundByte.UnloadAudioClips(); SetGame("noGame"); } + string currentGameRequest = null; private IEnumerator WaitAndSetGame(string game, bool useMinigameColor = true) { + if (game == currentGameRequest) + { + yield break; + } + currentGameRequest = game; var inf = GetGameInfo(game); if (inf != null && inf.usesAssetBundle) { @@ -1179,13 +1187,15 @@ namespace HeavenStudio { // Debug.Log($"ASYNC loading assetbundles for game {game}"); inf.LoadAssetsAsync().Forget(); + yield return new WaitUntil(() => inf.AssetsLoaded); } - yield return new WaitUntil(() => inf.AssetsLoaded); SetGame(game, useMinigameColor); + currentGameRequest = null; } else { SetGame(game, useMinigameColor); + currentGameRequest = null; } } @@ -1200,10 +1210,14 @@ namespace HeavenStudio public GameObject GetGame(string name) { - var gameInfo = GetGameInfo(name); + if (name is null or "" or "noGame") + { + return Resources.Load($"Games/noGame"); + } + + Minigames.Minigame gameInfo = GetGameInfo(name); if (gameInfo != null) { - GameObject prefab; if (gameInfo.inferred) { return Resources.Load($"Games/noGame"); @@ -1226,6 +1240,8 @@ namespace HeavenStudio return Resources.Load($"Games/noGame"); } } + + GameObject prefab; if (gameInfo.usesAssetBundle) { //game is packed in an assetbundle, load from that instead @@ -1251,6 +1267,7 @@ namespace HeavenStudio } } } + // games with no assetbundle (usually indev games) prefab = Resources.Load($"Games/{name}"); if (prefab != null) { diff --git a/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs b/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs index 0e1c6f5de..2053c659a 100644 --- a/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs +++ b/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs @@ -10,7 +10,8 @@ namespace HeavenStudio.Games.Loaders using static Minigames; public static class AgbUpbeatLoader { - public static Minigame AddGame(EventCaller eventCaller) { + public static Minigame AddGame(EventCaller eventCaller) + { RiqEntity BackgroundUpdater(string datamodel, RiqEntity e) { if (datamodel == "mrUpbeat/changeBG" && e.dynamicData.ContainsKey("toggle") && !e.dynamicData.ContainsKey("ease")) @@ -133,9 +134,9 @@ namespace HeavenStudio.Games.Loaders resizable = true, }, }, - new List() {"agb", "keep"}, + new List() { "agb", "keep" }, "agboffbeat", "en", - new List() {}, + new List() { }, chronologicalSortKey: 101 ); } @@ -197,7 +198,8 @@ namespace HeavenStudio.Games { List prevEntities = GameManager.instance.Beatmap.Entities.FindAll(c => c.beat <= beat && c.datamodel.Split(0) == "mrUpbeat"); - if (beat >= startBlippingBeat) { + if (beat >= startBlippingBeat) + { double tempBeat = ((beat % 1 == 0.5) ? Mathf.Floor((float)beat) : Mathf.Round((float)beat)) + (startBlippingBeat % 1); BeatAction.New(instance, new List() { new BeatAction.Action(tempBeat, delegate { man.RecursiveBlipping(tempBeat); }) @@ -209,17 +211,22 @@ namespace HeavenStudio.Games var bgColorEntity = prevEntities.FindLast(x => x.datamodel.Split(1) == "changeBG" && x.beat <= beat); var upbeatColorEntity = prevEntities.FindLast(x => x.datamodel.Split(1) == "upbeatColors" && x.beat <= beat); - if (bgColorEntity != null) { + if (bgColorEntity != null) + { bg.color = bgColorEntity["end"]; } - - if (upbeatColorEntity != null) { + + if (upbeatColorEntity != null) + { blipMaterial.SetColor("_ColorBravo", upbeatColorEntity["blipColor"]); Color shadowColor = upbeatColorEntity["shadowColor"]; - if (upbeatColorEntity["setShadow"]) foreach (var shadow in shadowSr) { - shadow.color = new Color(shadowColor.r, shadowColor.g, shadowColor.b, 1); - } - } else { + if (upbeatColorEntity["setShadow"]) foreach (var shadow in shadowSr) + { + shadow.color = new Color(shadowColor.r, shadowColor.g, shadowColor.b, 1); + } + } + else + { blipMaterial.SetColor("_ColorBravo", new Color(0, 1f, 0)); } } @@ -227,31 +234,33 @@ namespace HeavenStudio.Games public void Update() { bg.color = bgColorEase.GetColor(); - if (conductor.isPlaying && !conductor.isPaused) { - var songPos = conductor.songPositionInBeatsAsDouble; + if (conductor.isPlaying && !conductor.isPaused) + { + double songPos = conductor.songPositionInBeatsAsDouble; - if (songPos >= startSteppingBeat - 2) { + if (songPos >= startSteppingBeat - 2) + { man.canStep = true; } - if (songPos >= startSteppingBeat) { + if (songPos >= startSteppingBeat) + { RecursiveStepping(startSteppingBeat); startSteppingBeat = double.MaxValue; } - if (songPos >= startBlippingBeat) { + if (songPos >= startBlippingBeat) + { man.RecursiveBlipping(startBlippingBeat); startBlippingBeat = double.MaxValue; } - if (songPos > metronomeBeat + 1) + if (metronomeBeat != double.MaxValue) { - metronomeAnim.Play("MetronomeGo" + currentMetronomeDir, -1, 1); - metronomeAnim.speed = 0; - } - else if (songPos >= metronomeBeat) - { - metronomeAnim.DoScaledAnimation("MetronomeGo" + currentMetronomeDir, metronomeBeat, 1, ignoreSwing: false); + currentMetronomeDir = songPos >= metronomeBeat && songPos <= metronomeBeat + 1 + ? (stepIterate % 2 == 0) ? "Right" : "Left" + : (stepIterate % 2 == 1) ? "Right" : "Left"; + metronomeAnim.DoScaledAnimation("MetronomeGo" + currentMetronomeDir, metronomeBeat, 1, clamp: true, ignoreSwing: false); } } } @@ -282,7 +291,8 @@ namespace HeavenStudio.Games public static void PrePrepare(double beat, float length, bool mrDownbeat) { bool isGame = GameManager.instance.currentGame == "mrUpbeat"; - if (!mrDownbeat) { + if (!mrDownbeat) + { beat = Mathf.Floor((float)beat) + 0.5; length = Mathf.Round(length); } @@ -299,12 +309,12 @@ namespace HeavenStudio.Games private void RecursiveStepping(double beat) { - if (stopStepping) { + if (stopStepping) + { stopStepping = false; return; } - currentMetronomeDir = (stepIterate % 2 == 1) ? "Right" : "Left"; - SoundByte.PlayOneShotGame($"mrUpbeat/metronome{currentMetronomeDir}"); + SoundByte.PlayOneShotGame($"mrUpbeat/metronome{((stepIterate % 2 == 1) ? "Right" : "Left")}"); metronomeBeat = beat; ScheduleStep(beat); BeatAction.New(this, new List() { @@ -319,9 +329,9 @@ namespace HeavenStudio.Games for (int i = 0; i < length; i++) { ScheduleStep(beat + i); - actions.Add(new BeatAction.Action(beat + i, delegate { - currentMetronomeDir = (stepIterate % 2 == 1) ? "Right" : "Left"; - SoundByte.PlayOneShotGame($"mrUpbeat/metronome{currentMetronomeDir}"); + actions.Add(new BeatAction.Action(beat + i, delegate + { + SoundByte.PlayOneShotGame($"mrUpbeat/metronome{((stepIterate % 2 == 1) ? "Right" : "Left")}"); metronomeBeat = beat + i; stepIterate++; })); @@ -335,7 +345,8 @@ namespace HeavenStudio.Games if (gameSwitch.beat <= beat || gameSwitch.beat >= beat + length + 1) return; List inactiveBlips = new(); - for (int i = 0; i < gameSwitch.beat - beat; i++) { + for (int i = 0; i < gameSwitch.beat - beat; i++) + { inactiveBlips.Add(new MultiSound.Sound("mrUpbeat/blip", beat + i)); } @@ -362,9 +373,10 @@ namespace HeavenStudio.Games { blipMaterial.SetColor("_ColorBravo", blipColor); - if (setShadow) foreach (var shadow in shadowSr) { - shadow.color = new Color(shadowColor.r, shadowColor.g, shadowColor.b, 1); - } + if (setShadow) foreach (var shadow in shadowSr) + { + shadow.color = new Color(shadowColor.r, shadowColor.g, shadowColor.b, 1); + } } public void BlipEvents(string inputLetter, bool shouldGrow, bool resetBlip, bool shouldBlip, int blipLength) @@ -384,11 +396,12 @@ namespace HeavenStudio.Games public static void CountIn(double beat, float length, bool a) { var sound = new List(); - if (a) sound.Add(new MultiSound.Sound("mrUpbeat/a", beat - (0.5f * (length/4)))); - for (int i = 0; i < 4; i++) { + if (a) sound.Add(new MultiSound.Sound("mrUpbeat/a", beat - (0.5f * (length / 4)))); + for (int i = 0; i < 4; i++) + { sound.Add(new MultiSound.Sound("mrUpbeat/" + (i + 1), beat + (i * (length / 4)), offset: (i == 3) ? 0.05 : 0)); } - + MultiSound.Play(sound.ToArray(), forcePlay: true); } diff --git a/Assets/Scripts/Games/SneakySpirits/SneakySpirits.cs b/Assets/Scripts/Games/SneakySpirits/SneakySpirits.cs index c2154d84e..dd1338710 100644 --- a/Assets/Scripts/Games/SneakySpirits/SneakySpirits.cs +++ b/Assets/Scripts/Games/SneakySpirits/SneakySpirits.cs @@ -102,7 +102,7 @@ namespace HeavenStudio.Games } if (Conductor.instance.isPlaying) { - Conductor.instance.SetMinigamePitch(1f, true); + Conductor.instance.SetMinigamePitch(1f); } } diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index a6d803cbe..55c359190 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -395,8 +395,10 @@ namespace HeavenStudio public bool usesAssetBundle => wantAssetBundle is not null or ""; public bool hasLocales => supportedLocales.Count > 0; - public bool AssetsLoaded => ((hasLocales && localeLoaded && currentLoadedLocale == defaultLocale) || (!hasLocales)) && commonLoaded && loadComplete; + public bool AssetsLoaded => ((hasLocales && localeLoaded && currentLoadedLocale == defaultLocale) || (!hasLocales)) && commonLoaded && (!loadingPrefab) && loadComplete; public bool AlreadyLoading => alreadyLoading; + public bool LoadingPrefab => loadingPrefab; + public bool SequencesPreloaded => soundSequences != null; public string LoadableName => inferred ? "noGame" : name; public GameObject LoadedPrefab => loadedPrefab; @@ -410,6 +412,7 @@ namespace HeavenStudio private bool localePreloaded = false; private GameObject loadedPrefab = null; + bool loadingPrefab = false; bool loadComplete = false; private SoundSequence.SequenceKeyValue[] soundSequences = null; @@ -510,6 +513,7 @@ namespace HeavenStudio if (alreadyLoading || AssetsLoaded || !usesAssetBundle) return; loadComplete = false; alreadyLoading = true; + loadingPrefab = true; await UniTask.WhenAll(LoadCommonAssetBundleAsync(), LoadLocalizedAssetBundleAsync()); await UniTask.WhenAll(LoadGamePrefabAsync(), LoadCommonAudioClips(), LoadLocalizedAudioClips()); SoundByte.PreloadGameAudioClips(this); @@ -585,6 +589,7 @@ namespace HeavenStudio soundSequences = minigame.SoundSequences; } loadedPrefab = prefab; + loadingPrefab = false; } public GameObject LoadGamePrefab() @@ -636,6 +641,7 @@ namespace HeavenStudio } SoundByte.UnloadAudioClips(name); loadComplete = false; + loadingPrefab = false; } } diff --git a/Assets/Scripts/UI/Overlays/TimingAccuracyDisplay.cs b/Assets/Scripts/UI/Overlays/TimingAccuracyDisplay.cs index 0487d077c..473415231 100644 --- a/Assets/Scripts/UI/Overlays/TimingAccuracyDisplay.cs +++ b/Assets/Scripts/UI/Overlays/TimingAccuracyDisplay.cs @@ -155,6 +155,8 @@ namespace HeavenStudio.Common { case Rating.OK: it = OK; + // makes the explosion smaller with less accurate inputs + it.transform.localScale = Vector3.one * (1f - (frac / 2f)); break; case Rating.Just: it = Just; @@ -165,13 +167,6 @@ namespace HeavenStudio.Common } } - // makes the explosion smaller with less accurate inputs - if (it == OK) - { - float okScalar = 1 - (frac / 2); - it.transform.localScale = new Vector3(okScalar, okScalar, it.transform.localScale.z); - } - it.transform.position = barTransform.position + new Vector3(0, barTransform.localScale.y * y, 0); it.GetComponent().Play(); } From be289eb48c079f8b114e1fc0d157cc715d8f207b Mon Sep 17 00:00:00 2001 From: minenice55 Date: Mon, 8 Apr 2024 22:54:25 -0400 Subject: [PATCH 2/4] Update MrUpbeat.cs (#846) --- Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs b/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs index 2053c659a..1f14665fb 100644 --- a/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs +++ b/Assets/Scripts/Games/MrUpbeat/MrUpbeat.cs @@ -254,14 +254,18 @@ namespace HeavenStudio.Games man.RecursiveBlipping(startBlippingBeat); startBlippingBeat = double.MaxValue; } + } + } - if (metronomeBeat != double.MaxValue) - { - currentMetronomeDir = songPos >= metronomeBeat && songPos <= metronomeBeat + 1 - ? (stepIterate % 2 == 0) ? "Right" : "Left" - : (stepIterate % 2 == 1) ? "Right" : "Left"; - metronomeAnim.DoScaledAnimation("MetronomeGo" + currentMetronomeDir, metronomeBeat, 1, clamp: true, ignoreSwing: false); - } + void LateUpdate() + { + if (conductor.isPlaying && !conductor.isPaused && metronomeBeat != double.MaxValue) + { + double songPos = conductor.songPositionInBeatsAsDouble; + currentMetronomeDir = songPos >= metronomeBeat && songPos <= metronomeBeat + 1 + ? (stepIterate % 2 == 0) ? "Right" : "Left" + : (stepIterate % 2 == 1) ? "Right" : "Left"; + metronomeAnim.DoScaledAnimation("MetronomeGo" + currentMetronomeDir, metronomeBeat, 1, clamp: true, ignoreSwing: false); } } From 800832134d72e72243d4475a4e8ad9226dfec184 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Tue, 9 Apr 2024 09:26:12 -0400 Subject: [PATCH 3/4] exclude non packed games from the preload check (#849) don't make multiple timeline playheads --- Assets/Scripts/GameManager.cs | 2 +- .../Scripts/LevelEditor/Timeline/Timeline.cs | 67 +++---------------- 2 files changed, 11 insertions(+), 58 deletions(-) diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index e630566e3..57c34e613 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -1020,7 +1020,7 @@ namespace HeavenStudio if (canPreload) { Minigames.Minigame inf = GetGameInfo(newGame); - if (inf != null) + if (inf != null && inf.usesAssetBundle && !inf.AssetsLoaded) { preload.Add(inf); } diff --git a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs index 2b4039ceb..b8374e5c4 100644 --- a/Assets/Scripts/LevelEditor/Timeline/Timeline.cs +++ b/Assets/Scripts/LevelEditor/Timeline/Timeline.cs @@ -165,7 +165,6 @@ namespace HeavenStudio.Editor.Track public TMP_InputField StartingVolumeSpecialVolume; public SpecialTimeline SpecialInfo; - private RectTransform TimelineSongPosLine; [Header("Timeline Playbar")] public Button PlayBTN; @@ -250,6 +249,7 @@ namespace HeavenStudio.Editor.Track TimelineSlider.GetChild(2).GetComponent().color = EditorTheme.theme.properties.BeatMarkerCol.Hex2RGB(); TimelineSlider.GetChild(3).GetComponent().color = EditorTheme.theme.properties.BeatMarkerCol.Hex2RGB(); TimelineSongPosLineRef.GetComponent().color = EditorTheme.theme.properties.CurrentTimeMarkerCol.Hex2RGB(); + TimelineSongPosLineRef.gameObject.SetActive(false); PlayBTN.onClick.AddListener(delegate { @@ -408,55 +408,10 @@ namespace HeavenStudio.Editor.Track } } - /* - if (MouseInTimeline) - { - var wheel = Input.mouseScrollDelta.y; - - if (wheel != 0) - { - var incre = 0.0f; - if (wheel > 0) - { - incre += wheel * (Zoom * 0.25f); - } - else - { - incre += wheel * (Zoom * 0.2f); - } - - var v = new Vector3[4]; - TimelineScroll.viewport.GetWorldCorners(v); - var viewportPos = Editor.instance.EditorCamera.WorldToScreenPoint(v[0]); - - var left = leftSide; - var viewportWidth = TimelineScroll.viewport.rect.width; - var localPointRec = Mathf.Lerp(left, left + (viewportWidth / Zoom), - MathUtils.Normalize(Input.mousePosition.x, viewportPos.x, viewportPos.x + viewportWidth)); - - var xPixels = (localPointRec * incre); - xPixels *= (Zoom); - - TimelineContent.anchoredPosition = new Vector2( - TimelineContent.anchoredPosition.x - xPixels, - TimelineContent.anchoredPosition.y - ); - - Zoom += incre; - Zoom = Mathf.Clamp(Zoom, 1, 1000); - } - } - */ - MousePos2Beat = relativeMousePos.x / PixelsPerBeat; MousePos2Layer = Mathf.Clamp(Mathf.FloorToInt(-(relativeMousePos.y) / LayerHeight()), 0, LayerCount - 1); Conductor cond = Conductor.instance; - // waveform.rectTransform.anchoredPosition = new Vector2( - // -(GameManager.instance.Beatmap.data.offset / (60.0f / GameManager.instance.Beatmap.bpm)), - // waveform.rectTransform.anchoredPosition.y); - - // WaveformBTN.transform.GetChild(0).GetComponent().color = (cond.musicSource.clip != null && waveform.gameObject.activeInHierarchy) ? Color.white : Color.gray; if (!cond.isPlaying && !cond.isPaused) { @@ -631,9 +586,13 @@ namespace HeavenStudio.Editor.Track { TimelinePlaybackBeat.text = $"Beat {string.Format("{0:0.000}", PlaybackBeat)}"; - if (TimelineSongPosLine != null && !Conductor.instance.WaitingForDsp) + if (TimelineSongPosLineRef != null && !Conductor.instance.WaitingForDsp) { - TimelineSongPosLine.transform.localPosition = new Vector3(Conductor.instance.songPositionInBeats * PixelsPerBeat, TimelineSongPosLine.transform.localPosition.y); + if (Conductor.instance.isPlaying && !TimelineSongPosLineRef.gameObject.activeSelf) + { + TimelineSongPosLineRef.gameObject.SetActive(true); + } + TimelineSongPosLineRef.transform.localPosition = new Vector3(Conductor.instance.songPositionInBeats * PixelsPerBeat, TimelineSongPosLineRef.transform.localPosition.y); } } @@ -677,9 +636,7 @@ namespace HeavenStudio.Editor.Track GameManager.instance.SafePlay(time, 0, false); if (!Conductor.instance.isPaused) { - TimelineSongPosLine = Instantiate(TimelineSongPosLineRef, TimelineSongPosLineRef.parent).GetComponent(); - TimelineSongPosLine.gameObject.SetActive(true); - TimelineSongPosLine.transform.localPosition = new Vector3(time * PixelsPerBeat, TimelineSongPosLine.transform.localPosition.y); + TimelineSongPosLineRef.transform.localPosition = new Vector3(time * PixelsPerBeat, TimelineSongPosLineRef.transform.localPosition.y); } SetTimeButtonColors(false, true, true); @@ -687,7 +644,6 @@ namespace HeavenStudio.Editor.Track public void Pause() { - // isPaused = true; GameManager.instance.Pause(); SetTimeButtonColors(true, false, true); @@ -695,11 +651,8 @@ namespace HeavenStudio.Editor.Track public void Stop(float time) { - // isPaused = true; - // timelineSlider.value = 0; - - if (TimelineSongPosLine != null) - Destroy(TimelineSongPosLine.gameObject); + if (TimelineSongPosLineRef != null) + TimelineSongPosLineRef.gameObject.SetActive(false); GameManager.instance.Stop(time); From d60c8b921c0a211b5d19caa565ad79d97a84d519 Mon Sep 17 00:00:00 2001 From: wookywok <62037083+wookywok@users.noreply.github.com> Date: Tue, 9 Apr 2024 08:43:56 -0500 Subject: [PATCH 4/4] Made Nail Carpenter Half-Time! (#845) * changed cues, added legacy support * Added Legacy Scroll Speed --- Assets/Resources/Games/nailCarpenter.prefab | 50 ++++++- .../Games/NailCarpenter/NailCarpenter.cs | 124 ++++++++++++++++-- 2 files changed, 161 insertions(+), 13 deletions(-) diff --git a/Assets/Resources/Games/nailCarpenter.prefab b/Assets/Resources/Games/nailCarpenter.prefab index edc40beb1..aafb5086d 100644 --- a/Assets/Resources/Games/nailCarpenter.prefab +++ b/Assets/Resources/Games/nailCarpenter.prefab @@ -635,13 +635,55 @@ MonoBehaviour: SoundSequences: [] scheduledInputs: [] puddingPattern: + - beat: 0 + type: 2 + - beat: 1 + type: 0 + - beat: 2 + type: 8 + cherryPattern: + - beat: 0 + type: 2 + - beat: 1 + type: 0 + - beat: 2 + type: 0 + - beat: 3 + type: 0 + - beat: 4 + type: 8 + cakePattern: + - beat: 0 + type: 2 + - beat: 1 + type: 0 + - beat: 2 + type: 3 + - beat: 2.5 + type: 0 + - beat: 3.5 + type: 0 + - beat: 4 + type: 8 + cakeLongPattern: + - beat: 0 + type: 2 + - beat: 1 + type: 0 + - beat: 2 + type: 9 + - beat: 3 + type: 1 + - beat: 4 + type: 8 + puddingPatternOld: - beat: 0 type: 2 - beat: 0.5 type: 0 - beat: 1 type: 8 - cherryPattern: + cherryPatternOld: - beat: 0 type: 2 - beat: 0.5 @@ -652,7 +694,7 @@ MonoBehaviour: type: 0 - beat: 2 type: 8 - cakePattern: + cakePatternOld: - beat: 0 type: 2 - beat: 0.5 @@ -665,7 +707,7 @@ MonoBehaviour: type: 0 - beat: 2 type: 8 - cakeLongPattern: + cakeLongPatternOld: - beat: 0 type: 2 - beat: 0.5 @@ -676,7 +718,7 @@ MonoBehaviour: type: 1 - beat: 2 type: 8 - scrollMetresPerBeat: -4.5 + scrollMetresPerBeat: -2.25 boardWidth: 19.2 baseNail: {fileID: 7504610799131467556} baseLongNail: {fileID: 4122843866948130824} diff --git a/Assets/Scripts/Games/NailCarpenter/NailCarpenter.cs b/Assets/Scripts/Games/NailCarpenter/NailCarpenter.cs index c895aab4f..37cbd2ce0 100644 --- a/Assets/Scripts/Games/NailCarpenter/NailCarpenter.cs +++ b/Assets/Scripts/Games/NailCarpenter/NailCarpenter.cs @@ -14,26 +14,31 @@ namespace HeavenStudio.Games.Loaders { return new Minigame("nailCarpenter", "Nail Carpenter", "fab96e", false, false, new List() { - new GameAction("puddingNail", "Pudding Nail") + + new GameAction("puddingNailNew", "Pudding Nail") { defaultLength = 8f, resizable = true }, - new GameAction("cherryNail", "Cherry Nail") + + new GameAction("cherryNailNew", "Cherry Nail") { defaultLength = 4f, resizable = true }, - new GameAction("cakeNail", "Cake Nail") + + new GameAction("cakeNailNew", "Cake Nail") { defaultLength = 4f, resizable = true }, - new GameAction("cakeLongNail", "Cake Long Nail") + new GameAction("cakeLongNailNew", "Cake Long Nail") { defaultLength = 4f, resizable = true }, + + new GameAction("slideFusuma", "Slide Shoji") { function = delegate { @@ -49,6 +54,29 @@ namespace HeavenStudio.Games.Loaders new Param("mute", false, "Mute", "Toggle if the cue should be muted.") } }, + new GameAction("puddingNail", "Pudding Nail (Legacy)") + { + defaultLength = 8f, + resizable = true, + hidden = true, + }, + + new GameAction("cherryNail", "Cherry Nail (Legacy)") + { + defaultLength = 4f, + resizable = true, + hidden = true, + }, + new GameAction("cakeNail", "Cake Nail (Legacy)") + { + defaultLength = 4f, + resizable = true, hidden = true, + }, + new GameAction("cakeLongNail", "Cake Long Nail (Legacy)") + { + defaultLength = 4f, + resizable = true, hidden = true, + }, }, new List() { "pco", "normal" }, @@ -102,6 +130,10 @@ namespace HeavenStudio.Games Cherry, Cake, CakeLong, + PuddingOld, + CherryOld, + CakeOld, + CakeLongOld, None } @@ -109,7 +141,12 @@ namespace HeavenStudio.Games [SerializeField] ObjectPatternItem[] cherryPattern; [SerializeField] ObjectPatternItem[] cakePattern; [SerializeField] ObjectPatternItem[] cakeLongPattern; + [SerializeField] ObjectPatternItem[] puddingPatternOld; + [SerializeField] ObjectPatternItem[] cherryPatternOld; + [SerializeField] ObjectPatternItem[] cakePatternOld; + [SerializeField] ObjectPatternItem[] cakeLongPatternOld; [SerializeField] float scrollMetresPerBeat = 4f; + [SerializeField] float legacyScrollMultiplier = 2; [SerializeField] float boardWidth = 19.2f; public GameObject baseNail; @@ -195,6 +232,7 @@ namespace HeavenStudio.Games double slideBeat = double.MaxValue; double slideLength; double cachedPatternLengthPudding, cachedPatternLengthCherry, cachedPatternLengthCake, cachedPatternLengthCakeLong; + double cachedPatternLengthPuddingOld, cachedPatternLengthCherryOld, cachedPatternLengthCakeOld, cachedPatternLengthCakeLongOld; Util.EasingFunction.Ease slideEase; float slideRatioLast = 0, slideRatioNext = 0; @@ -249,6 +287,11 @@ namespace HeavenStudio.Games cachedPatternLengthCherry = cherryPattern[^1].beat; cachedPatternLengthCake = cakePattern[^1].beat; cachedPatternLengthCakeLong = cakeLongPattern[^1].beat; + cachedPatternLengthPuddingOld = puddingPatternOld[^1].beat; + cachedPatternLengthCherryOld = cherryPatternOld[^1].beat; + cachedPatternLengthCakeOld = cakePatternOld[^1].beat; + cachedPatternLengthCakeLongOld = cakeLongPatternOld[^1].beat; + float legacyScrollSpeed = (scrollMetresPerBeat*legacyScrollMultiplier); double endBeat = double.MaxValue; var entities = gameManager.Beatmap.Entities; @@ -259,19 +302,27 @@ namespace HeavenStudio.Games RiqEntity firstEnd = entities.Find(c => (c.datamodel.StartsWith("gameManager/switchGame") || c.datamodel.Equals("gameManager/end")) && c.beat > gameStartBeat); endBeat = firstEnd?.beat ?? endBeat; - List events = entities.FindAll(v => (v.datamodel is "nailCarpenter/puddingNail" or "nailCarpenter/cherryNail" or "nailCarpenter/cakeNail" or "nailCarpenter/cakeLongNail") && v.beat >= gameStartBeat && v.beat < endBeat); + List events = entities.FindAll(v => (v.datamodel is "nailCarpenter/puddingNail" or "nailCarpenter/cherryNail" or "nailCarpenter/cakeNail" or "nailCarpenter/cakeLongNail" or "nailCarpenter/puddingNailNew" or "nailCarpenter/cherryNailNew" or "nailCarpenter/cakeNailNew" or "nailCarpenter/cakeLongNailNew") && v.beat >= gameStartBeat && v.beat < endBeat); + scheduledPatterns.Clear(); patternIndex = 0; + bool hasChecked = false; + + foreach (var evt in events) { if (evt.length == 0) continue; int patternDivisions = (int)Math.Ceiling(evt.length / PATTERN_SEEK_TIME); PatternType patternType = evt.datamodel switch { - "nailCarpenter/puddingNail" => PatternType.Pudding, - "nailCarpenter/cherryNail" => PatternType.Cherry, - "nailCarpenter/cakeNail" => PatternType.Cake, - "nailCarpenter/cakeLongNail" => PatternType.CakeLong, + "nailCarpenter/puddingNail" => PatternType.PuddingOld, + "nailCarpenter/cherryNail" => PatternType.CherryOld, + "nailCarpenter/cakeNail" => PatternType.CakeOld, + "nailCarpenter/cakeLongNail" => PatternType.CakeLongOld, + "nailCarpenter/puddingNailNew" => PatternType.Pudding, + "nailCarpenter/cherryNailNew" => PatternType.Cherry, + "nailCarpenter/cakeNailNew" => PatternType.Cake, + "nailCarpenter/cakeLongNailNew" => PatternType.CakeLong, _ => throw new NotImplementedException() }; for (int i = 0; i < patternDivisions; i++) @@ -284,7 +335,19 @@ namespace HeavenStudio.Games }; scheduledPatterns.Add(pattern); } + if (evt.datamodel is "nailCarpenter/puddingNail" or "nailCarpenter/cherryNail" or "nailCarpenter/cakeNail" or "nailCarpenter/cakeLongNail") + { + if (hasChecked == false) + { + scrollMetresPerBeat = legacyScrollSpeed; + hasChecked = true; + } + } + } + + + } public override void OnPlay(double beat) @@ -355,6 +418,10 @@ namespace HeavenStudio.Games PatternType.Cherry => cachedPatternLengthCherry, PatternType.Cake => cachedPatternLengthCake, PatternType.CakeLong => cachedPatternLengthCakeLong, + PatternType.PuddingOld => cachedPatternLengthPuddingOld, + PatternType.CherryOld => cachedPatternLengthCherryOld, + PatternType.CakeOld => cachedPatternLengthCakeOld, + PatternType.CakeLongOld => cachedPatternLengthCakeLongOld, _ => throw new NotImplementedException() }; patternType = pattern; @@ -367,6 +434,11 @@ namespace HeavenStudio.Games PatternType.Cherry => cherryPattern, PatternType.Cake => cakePattern, PatternType.CakeLong => cakeLongPattern, + PatternType.PuddingOld => puddingPatternOld, + PatternType.CherryOld => cherryPatternOld, + PatternType.CakeOld => cakePatternOld, + PatternType.CakeLongOld => cakeLongPatternOld, + _ => throw new NotImplementedException() }); lastPatternType = patternType; @@ -405,10 +477,18 @@ namespace HeavenStudio.Games SoundByte.PlayOneShotGame("nailCarpenter/one", itemBeat, forcePlay: true); sweetType = Sweet.sweetsType.Pudding; break; + case PatternType.PuddingOld: + SoundByte.PlayOneShotGame("nailCarpenter/one", itemBeat, forcePlay: true); + sweetType = Sweet.sweetsType.Pudding; + break; case PatternType.Cherry: SoundByte.PlayOneShotGame("nailCarpenter/three", itemBeat, forcePlay: true); sweetType = Sweet.sweetsType.CherryPudding; break; + case PatternType.CherryOld: + SoundByte.PlayOneShotGame("nailCarpenter/three", itemBeat, forcePlay: true); + sweetType = Sweet.sweetsType.CherryPudding; + break; case PatternType.Cake: SoundByte.PlayOneShotGame("nailCarpenter/alarm", itemBeat, forcePlay: true); sweetType = Sweet.sweetsType.ShortCake; @@ -420,6 +500,17 @@ namespace HeavenStudio.Games }) }); break; + case PatternType.CakeOld: + SoundByte.PlayOneShotGame("nailCarpenter/alarm", itemBeat, forcePlay: true); + sweetType = Sweet.sweetsType.ShortCake; + BeatAction.New(instance, new List() + { + new BeatAction.Action(itemBeat, delegate + { + EffectExclamRed.DoScaledAnimationAsync("exclamAppear", 0.25f); + }) + }); + break; case PatternType.CakeLong: SoundByte.PlayOneShotGame("nailCarpenter/signal1", itemBeat, forcePlay: true); sweetType = Sweet.sweetsType.LayerCake; @@ -431,6 +522,17 @@ namespace HeavenStudio.Games }), }); break; + case PatternType.CakeLongOld: + SoundByte.PlayOneShotGame("nailCarpenter/signal1", itemBeat, forcePlay: true); + sweetType = Sweet.sweetsType.LayerCake; + BeatAction.New(instance, new List() + { + new BeatAction.Action(itemBeat, delegate + { + EffectExclamBlue.DoScaledAnimationAsync("exclamAppear", 0.25f); + }), + }); + break; default: break; } @@ -438,6 +540,10 @@ namespace HeavenStudio.Games { SpawnSweet(itemBeat, startbeat, Sweet.sweetsType.Cherry); } + else if (lastPatternType == PatternType.CakeOld) + { + SpawnSweet(itemBeat, startbeat, Sweet.sweetsType.Cherry); + } else if (sweetType != Sweet.sweetsType.None) { SpawnSweet(itemBeat, startbeat, sweetType);