From 674db30b8c6d69cfb44353379e93154c4cafd4fa Mon Sep 17 00:00:00 2001 From: Zeo <67521686+ThatZeoMan@users.noreply.github.com> Date: Fri, 6 Jan 2023 21:59:54 -0600 Subject: [PATCH] Unrecognized entity support (#191) Due to some recent discoveries about a certain upcoming rhythm game, I have added support for unrecognized entities found in remix.json to be loaded and moved, and be able to save them. --- .../Scripts/BeatmapFormats/DynamicBeatmap.cs | 58 +++++++++++++++++-- Assets/Scripts/GameManager.cs | 8 ++- Assets/Scripts/LevelEditor/Editor.cs | 21 ++++--- 3 files changed, 72 insertions(+), 15 deletions(-) diff --git a/Assets/Scripts/BeatmapFormats/DynamicBeatmap.cs b/Assets/Scripts/BeatmapFormats/DynamicBeatmap.cs index 543fddef..77ef3024 100644 --- a/Assets/Scripts/BeatmapFormats/DynamicBeatmap.cs +++ b/Assets/Scripts/BeatmapFormats/DynamicBeatmap.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; +using System.Text.RegularExpressions; using UnityEngine; using Newtonsoft.Json; @@ -344,8 +345,33 @@ namespace HeavenStudio System.Type type, pType; foreach (var e in entities) { - game = EventCaller.instance.GetMinigame(e.datamodel.Split(0)); - action = EventCaller.instance.GetGameAction(game, e.datamodel.Split(1)); + var gameName = e.datamodel.Split(0); + var actionName = e.datamodel.Split(1); + game = EventCaller.instance.GetMinigame(gameName); + if (game == null) + { + Debug.LogWarning($"Unknown game {gameName} found in remix.json! Adding game..."); + game = new Minigames.Minigame(gameName, DisplayName(gameName) + " \n[inferred from remix.json]", "", false, true, new List()); + EventCaller.instance.minigames.Add(game); + Editor.Editor.instance.AddIcon(game); + } + action = EventCaller.instance.GetGameAction(game, actionName); + if (action == null) + { + Debug.LogWarning($"Unknown action {gameName}/{actionName} found in remix.json! Adding action..."); + var parameters = new List(); + foreach (var item in e.DynamicData) + { + var value = item.Value; + if (value.GetType() == typeof(long)) + value = new EntityTypes.Integer(int.MinValue, int.MaxValue, (int)value); + else if (value.GetType() == typeof(double)) + value = new EntityTypes.Float(float.NegativeInfinity, float.PositiveInfinity, (float)value); + parameters.Add(new Minigames.Param(item.Key, value, item.Key, "[inferred from remix.json]")); + } + action = new Minigames.GameAction(actionName, DisplayName(actionName), e.length, true, parameters); + game.actions.Add(action); + } Dictionary dynamicData = new Dictionary(); //check each param of the action if (action.parameters != null) @@ -361,9 +387,9 @@ namespace HeavenStudio { Debug.LogWarning($"Property {param.propertyName} does not exist in the entity's dynamic data! Adding..."); if (type == typeof(EntityTypes.Integer)) - dynamicData.Add(param.propertyName, (int)param.parameter); + dynamicData.Add(param.propertyName, ((EntityTypes.Integer)param.parameter).val); else if (type == typeof(EntityTypes.Float)) - dynamicData.Add(param.propertyName, (float)param.parameter); + dynamicData.Add(param.propertyName, ((EntityTypes.Float)param.parameter).val); else if (type.IsEnum && param.propertyName != "ease") dynamicData.Add(param.propertyName, (int)param.parameter); else @@ -408,5 +434,29 @@ namespace HeavenStudio } } } + + private string DisplayName(string name) + { + // "gameName" -> "Game Name" + // "action name" -> "Action Name" + if (!name.Contains(" ")) + name = SplitCamelCase(name); + System.Globalization.TextInfo textInfo = new System.Globalization.CultureInfo("en-US", false).TextInfo; + return textInfo.ToTitleCase(name); + } + + // https://stackoverflow.com/a/5796793 + public static string SplitCamelCase(string str) + { + return Regex.Replace( + Regex.Replace( + str, + @"(\P{Ll})(\P{Ll}\p{Ll})", + "$1 $2" + ), + @"(\p{Ll})(\P{Ll})", + "$1 $2" + ); + } } } \ No newline at end of file diff --git a/Assets/Scripts/GameManager.cs b/Assets/Scripts/GameManager.cs index 876bf42a..829e50a9 100644 --- a/Assets/Scripts/GameManager.cs +++ b/Assets/Scripts/GameManager.cs @@ -599,14 +599,18 @@ namespace HeavenStudio { if (gameInfo.fxOnly) { - name = Beatmap.entities.FindAll(c => { + var gameEntities = Beatmap.entities.FindAll(c => { var gameName = c.datamodel.Split(0); var newGameInfo = GetGameInfo(gameName); if (newGameInfo == null) return false; else return !newGameInfo.fxOnly; - }).ToList()[0].datamodel.Split(0); + }).ToList(); + if (gameEntities.Count != 0) + name = gameEntities[0].datamodel.Split(0); + else + name = "noGame"; } else { diff --git a/Assets/Scripts/LevelEditor/Editor.cs b/Assets/Scripts/LevelEditor/Editor.cs index 4e2b3617..549fafb2 100644 --- a/Assets/Scripts/LevelEditor/Editor.cs +++ b/Assets/Scripts/LevelEditor/Editor.cs @@ -100,15 +100,8 @@ namespace HeavenStudio.Editor GameManager.instance.Init(); Timeline.Init(); - for (int i = 0; i < EventCaller.instance.minigames.Count; i++) - { - GameObject GameIcon_ = Instantiate(GridGameSelector.GetChild(0).gameObject, GridGameSelector); - GameIcon_.GetComponent().sprite = GameIcon(EventCaller.instance.minigames[i].name); - GameIcon_.GetComponent().MaskTex = GameIconMask(EventCaller.instance.minigames[i].name); - GameIcon_.GetComponent().UnClickIcon(); - GameIcon_.gameObject.SetActive(true); - GameIcon_.name = EventCaller.instance.minigames[i].displayName; - } + foreach (var minigame in EventCaller.instance.minigames) + AddIcon(minigame); Tooltip.AddTooltip(NewBTN.gameObject, "New [Ctrl+N]"); Tooltip.AddTooltip(OpenBTN.gameObject, "Open [Ctrl+O]"); @@ -128,6 +121,16 @@ namespace HeavenStudio.Editor BuildDateDisplay.text = GlobalGameManager.buildTime; } + public void AddIcon(Minigames.Minigame minigame) + { + GameObject GameIcon_ = Instantiate(GridGameSelector.GetChild(0).gameObject, GridGameSelector); + GameIcon_.GetComponent().sprite = GameIcon(minigame.name); + GameIcon_.GetComponent().MaskTex = GameIconMask(minigame.name); + GameIcon_.GetComponent().UnClickIcon(); + GameIcon_.gameObject.SetActive(true); + GameIcon_.name = minigame.displayName; + } + public void LateUpdate() { #region Keyboard Shortcuts