using UdonSharp; using UnityEngine; using VRC.SDK3.Data; using VRC.SDK3.StringLoading; using VRC.SDKBase; using VRC.Udon.Common.Interfaces; public enum AccusedCrook { Contessa, DoubleTrouble, EarthaBrute, Kneemoi, PattyLarceny, Robocrook, SarahNade, TopGrunge, VicTheSlick, WonderRat, INDEX_MAX } [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class CaseManager : UdonSharpBehaviour { [SerializeField] protected VRCUrl _QuestionURL; [SerializeField] private GameManagerRound1 _Round1Manager; [SerializeField] private GameManagerRound2 _Round2Manager; [SerializeField] private GameManagerRound3 _Round3Manager; [SerializeField] private HostCardManager _HostCard; [SerializeField] private Texture[] CrookPortraits; private VRCUrl _CaseFileCluesURL; private VRCUrl _CaseFileLootImage; private VRCUrl[] _CaseFileMaps; private VRCUrl[] _CaseFileVideos; private DataDictionary _CaseFileDictionary; public void LoadCaseFile(CaseManagerListEntry CaseFile) { _CaseFileCluesURL = CaseFile.CaseFileURL; _CaseFileLootImage = CaseFile.LootImage; _CaseFileMaps = CaseFile.MapFiles; _CaseFileVideos = CaseFile.VideoFiles; VRCStringDownloader.LoadUrl(_CaseFileCluesURL, (IUdonEventReceiver)this); } public override void OnStringLoadSuccess(IVRCStringDownload DownloadedString) { string ErrorString = ""; string JSONString = DownloadedString.Result; if (VRCJson.TryDeserializeFromJson(JSONString, out DataToken JSONResult)) { if (JSONResult.TokenType == TokenType.DataDictionary) { _CaseFileDictionary = JSONResult.DataDictionary; if (_CaseFileDictionary.ContainsKey("Round 1") && _CaseFileDictionary.ContainsKey("Round 2") && _CaseFileDictionary.ContainsKey("Round 3")) { // Attempt to load Round 1 data if (_CaseFileDictionary["Round 1"].TokenType == TokenType.DataList) { _Round1Manager.LoadQuestionData(_CaseFileDictionary["Round 1"]); } else { ErrorString = "Ensure the 'Round 1' entry is an array of dictionaries."; } // Attempt to load Round 2 data if (_CaseFileDictionary["Round 2"].TokenType == TokenType.DataDictionary) { _Round2Manager.LoadQuestionData(_CaseFileDictionary["Round 2"]); } else { ErrorString = "Ensure the 'Round 2' entry is a dictionary with a location name and a list of landmarks."; } // Attempt to load Round 3 data if (_CaseFileDictionary["Round 3"].TokenType == TokenType.DataDictionary) { _Round3Manager.LoadQuestionData(_CaseFileDictionary["Round 3"].DataDictionary); } else { ErrorString = "Ensure the 'Round 3' dictionary entry is a dictionary with a key called 'Continent' and an integer value."; } ContinueToRound1(); } else { ErrorString = "Could not find all the necessary keys for game rounds."; } } else { ErrorString = "Ensure the first element is a dictionary"; } } if (ErrorString != "") { Debug.LogError("Malformed case file. " + ErrorString); } } public string ContinueToRound1() { _HostCard.SetGameManager(_Round1Manager); _Round1Manager.InitialiseGameMode(); return ""; } public string ContinueToRound2() { _HostCard.SetGameManager(_Round2Manager); _Round2Manager.InitialiseGameMode(); return ""; } public string ContinueToRound3() { _HostCard.SetGameManager(_Round3Manager); _Round3Manager.InitialiseGameMode(); return ""; } public string GetCaseTitle() { return _CaseFileDictionary["Case Title"].ToString(); } public string GetCaseDescription() { return _CaseFileDictionary["Case Description"].ToString(); } public string GetLoot() { return _CaseFileDictionary["Stolen Loot"].ToString(); } public AccusedCrook GetCrook() { return (AccusedCrook)_CaseFileDictionary["Accused Crook"].Number; } public VRCUrl GetMap(int MapIndex) { return _CaseFileMaps[MapIndex]; } public VRCUrl GetLootImage() { return _CaseFileLootImage; } public VRCUrl GetIntroVideo() { return _CaseFileVideos[0]; } public VRCUrl GetVideo(int VideoIndex) { return _CaseFileVideos[VideoIndex]; } public int GetVideoCount() { return _CaseFileVideos.Length; } public string CrookToString(AccusedCrook Crook) { switch (Crook) { case AccusedCrook.Contessa: return "Contessa"; case AccusedCrook.DoubleTrouble: return "Double Trouble"; case AccusedCrook.EarthaBrute: return "Eartha Brute"; case AccusedCrook.Kneemoi: return "Kneemoi"; case AccusedCrook.PattyLarceny: return "Patty Larceny"; case AccusedCrook.Robocrook: return "Robocrook"; case AccusedCrook.SarahNade: return "Sarah Nade"; case AccusedCrook.TopGrunge: return "Top Grunge"; case AccusedCrook.VicTheSlick: return "Vic The Slick"; case AccusedCrook.WonderRat: return "Wonder Rat"; } return "[[ERROR]]"; } public string GetAccusedCrook() { return CrookToString((AccusedCrook)(int)_CaseFileDictionary["Accused Crook"].Number); } public Texture GetAccusedCrookPortrait() { return CrookPortraits[(int)_CaseFileDictionary["Accused Crook"].Number]; } }