From ce3e6f2d912d2e5c71091bf518de0954175c547b Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sun, 11 Jun 2023 12:13:01 -0400 Subject: [PATCH] update from Release 1 (#464) * Integration of Jukebox Library (#451) * add Jukebox library todo: - saving / loading of new format - inferrence of unknown data like past versions - move the temporary float casts to proper use of double - make sound related functions take double for timing - inform people that the Jukebox sound player was renamed to SoundByte lol * make sound, input scheduling, and super curve use double precision * successfully load charts * editor works again v1 riqs can be saved and loaded * first tempo and volume markers are unmovable fix loading of charts' easing values * use gsync / freesync * update Jukebox refs to SoundByte * game events use double part 1 Air Rally - Glee Club converted * don't load song if chart load fails * finish conversion of all minigames * remove editor waveform toggle * timeline now respects added song offset length clear cache files on app close prepped notes for dsp sync * update timeline length when offset changed * update to latest Jukebox * make error panel object in global game manager * improve conductor music scheduling * added error message box fix first game events sometimes not playing * editor fixes (#459) * ditch loading dialog doesn't show up when it's supposed to * format song offset in editor * remove VorbisPlugin * Update Editor.cs * make base datamodels for special entity reading (#463) * make base datamodels for special entity reading * fix crop stomp breaking when no game switch or remix end is set * fix save shortcut fix loading charts with no music --- Assets/Scripts/GameManager.cs | 5 ++ Assets/Scripts/Games/CropStomp/CropStomp.cs | 23 ++++-- Assets/Scripts/LevelEditor/Editor.cs | 7 +- Assets/Scripts/Minigames.cs | 84 ++++++++++++++++----- 4 files changed, 91 insertions(+), 28 deletions(-) diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 135e8fb8..03ea53f4 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -188,6 +188,11 @@ namespace HeavenStudio } current = load.Current; } + catch (System.IO.FileNotFoundException f) + { + Debug.LogWarning("chart has no music: " + f.Message); + Conductor.instance.musicSource.clip = null; + } catch (Exception e) { Debug.LogError($"Failed to load music: {e.Message}"); diff --git a/Assets/Scripts/Games/CropStomp/CropStomp.cs b/Assets/Scripts/Games/CropStomp/CropStomp.cs index 4f77a0ce..1653ea7c 100644 --- a/Assets/Scripts/Games/CropStomp/CropStomp.cs +++ b/Assets/Scripts/Games/CropStomp/CropStomp.cs @@ -160,16 +160,23 @@ namespace HeavenStudio.Games // find out when the next game switch (or remix end) happens var allEnds = EventCaller.GetAllInGameManagerList("gameManager", new string[] { "switchGame", "end" }); - allEnds.Sort((x, y) => x.beat.CompareTo(y.beat)); - - //get the beat of the closest end event - foreach (var end in allEnds) + if (allEnds.Count == 0) { - if (end.datamodel.Split(2) == "cropStomp") continue; - if (end.beat > startBeat) + endBeat = double.MaxValue; + } + else + { + allEnds.Sort((x, y) => x.beat.CompareTo(y.beat)); + + //get the beat of the closest end event + foreach (var end in allEnds) { - endBeat = end.beat; - break; + if (end.datamodel.Split(2) == "cropStomp") continue; + if (end.beat > startBeat) + { + endBeat = end.beat; + break; + } } } diff --git a/Assets/Scripts/LevelEditor/Editor.cs b/Assets/Scripts/LevelEditor/Editor.cs index 1d57164a..072f9a78 100644 --- a/Assets/Scripts/LevelEditor/Editor.cs +++ b/Assets/Scripts/LevelEditor/Editor.cs @@ -315,7 +315,7 @@ namespace HeavenStudio.Editor } else { - if (currentRemixPath == string.Empty) + if (currentRemixPath == string.Empty || currentRemixPath == null) { SaveRemixFilePanel(); } @@ -370,15 +370,16 @@ namespace HeavenStudio.Editor public void LoadRemix(bool create = false) { if (create) + { GameManager.instance.NewRemix(); + currentRemixPath = string.Empty; + } else { GameManager.instance.LoadRemix(true); } Timeline.instance.LoadRemix(); Timeline.FitToSong(); - - currentRemixPath = string.Empty; } public void OpenRemix() diff --git a/Assets/Scripts/Minigames.cs b/Assets/Scripts/Minigames.cs index 1281038e..103d0326 100644 --- a/Assets/Scripts/Minigames.cs +++ b/Assets/Scripts/Minigames.cs @@ -73,6 +73,70 @@ namespace HeavenStudio {"resultrepeat_ng", "Next time, follow the example better."}, // "Try Again" message for call-and-response games (two-liner) }; + static Dictionary tempoChangeModel = new() + { + {"tempo", 120f}, + {"swing", 0f}, + {"timeSignature", new Vector2(4, 4)}, + }; + + static Dictionary volumeChangeModel = new() + { + {"volume", 1f}, + {"fade", Util.EasingFunction.Ease.Instant}, + }; + + static Dictionary sectionMarkModel = new() + { + {"sectionName", ""}, + {"isCheckpoint", false}, + {"startPerfect", false}, + {"breakSection", false}, + {"extendsPrevious", false}, + {"sectionWeight", 1f}, + }; + + static void PreProcessSpecialEntity(RiqEntity e, Dictionary model) + { + foreach (var t in model) + { + string propertyName = t.Key; + Type type = t.Value.GetType(); + if (!e.dynamicData.ContainsKey(propertyName)) + { + e.CreateProperty(propertyName, t.Value); + } + Type pType = e[propertyName].GetType(); + if (pType != type) + { + try + { + if (type == typeof(Util.EasingFunction.Ease) && (pType == typeof(string) || pType == typeof(int) || pType == typeof(long))) + { + if (pType == typeof(int) || pType == typeof(long) || pType == typeof(Jukebox.EasingFunction.Ease)) + { + e[propertyName] = (Util.EasingFunction.Ease)e[propertyName]; + } + else + e[propertyName] = Enum.Parse(typeof(Util.EasingFunction.Ease), (string)e[propertyName]); + } + else if (type.IsEnum) + e[propertyName] = (int)e[propertyName]; + else if (pType == typeof(Newtonsoft.Json.Linq.JObject)) + e[propertyName] = e[propertyName].ToObject(type); + else + e[propertyName] = Convert.ChangeType(e[propertyName], type); + } + catch + { + Debug.LogWarning($"Could not convert {propertyName} to {type}! Using default value..."); + // use default value + e.CreateProperty(propertyName, t.Value); + } + } + } + } + /// /// processes an riq beatmap after it is loaded /// @@ -179,31 +243,17 @@ namespace HeavenStudio foreach (var tempo in data.tempoChanges) { - tempo["tempo"] = (float)tempo["tempo"]; - tempo["swing"] = (float)tempo["swing"]; - if (tempo.dynamicData.ContainsKey("timeSignature")) - tempo["timeSignature"] = (Vector2)tempo["timeSignature"]; - else - tempo.dynamicData.Add("timeSignature", new Vector2(4, 4)); + PreProcessSpecialEntity(tempo, tempoChangeModel); } foreach (var vol in data.volumeChanges) { - vol["volume"] = (float)vol["volume"]; - if (vol["fade"].GetType() == typeof(string)) - vol["fade"] = Enum.Parse(typeof(Util.EasingFunction.Ease), (string)vol["fade"]); - else - vol["fade"] = (Util.EasingFunction.Ease)vol["fade"]; + PreProcessSpecialEntity(vol, volumeChangeModel); } foreach (var section in data.beatmapSections) { - section["sectionName"] = (string)section["sectionName"]; - section["isCheckpoint"] = (bool)section["isCheckpoint"]; - section["startPerfect"] = (bool)section["startPerfect"]; - section["breakSection"] = (bool)section["breakSection"]; - section["extendsPrevious"] = (bool)section["extendsPrevious"]; - section["sectionWeight"] = (float)section["sectionWeight"]; + PreProcessSpecialEntity(section, sectionMarkModel); } //go thru each property of the model beatmap and add any missing keyvalue pair