371 lines
9.6 KiB
C#

using UdonSharp;
using UnityEngine;
using UnityEngine.UI;
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
{
[Header("Global Case Assets")]
[SerializeField] private Texture[] CrookPortraits;
[Space, Header("Managers")]
[SerializeField] private PermissionsPanel _PermissionsPanel;
[SerializeField] private GameManagerRound1 _Round1Manager;
[SerializeField] private GameManagerRound2 _Round2Manager;
[SerializeField] private GameManagerRound3 _Round3Manager;
[Space]
[SerializeField] private HostCardManager _HostCard;
[Space]
[SerializeField] private CaseManagerListView _CaseManagerList;
[SerializeField] private Button _HostTeleportButton;
[UdonSynced] private VRCUrl _CaseFileCluesURL;
[UdonSynced] private VRCUrl _CaseFileLootImage;
[UdonSynced] private VRCUrl[] _CaseFileMaps = new VRCUrl[0];
[UdonSynced] private VRCUrl[] _CaseFileVideos = new VRCUrl[0];
[UdonSynced] private VRCUrl[] _CaseFileVideosFallback = new VRCUrl[0];
[UdonSynced] private VRCUrl[] _CaseFileClueImages = new VRCUrl[0];
[UdonSynced] private string _CaseTitle = "";
[UdonSynced] private string _CaseDescription = "";
[UdonSynced] private int _CaseIntroVideo = -1;
[UdonSynced] private string _CaseIntroVideoTranscript = "";
[UdonSynced] private string _StolenLoot = "";
[UdonSynced] private AccusedCrook _AccusedCrook = AccusedCrook.INDEX_MAX;
[UdonSynced] private ContinentMap _FinalRoundContinent = ContinentMap.INDEX_MAX;
[UdonSynced] private string[] _CurrentWinningPlayers = new string[3];
private DataDictionary _CaseFileDictionary;
public override void OnPlayerJoined(VRCPlayerApi Player)
{
if (Player.isLocal)
{
_CaseManagerList.gameObject.SetActive(Player.isInstanceOwner || Player.isMaster || _PermissionsPanel.IsPlayerHost(Player));
}
base.OnPlayerJoined(Player);
}
public override void OnOwnershipTransferred(VRCPlayerApi Player)
{
_Round1Manager.SetOwnershipOfObjects(Player);
_Round2Manager.SetOwnershipOfObjects(Player);
_Round3Manager.SetOwnershipOfObjects(Player);
base.OnOwnershipTransferred(Player);
}
public VRCPlayerApi GetHostOwner()
{
return Networking.GetOwner(gameObject);
}
public void HostEnabled()
{
_CaseManagerList.gameObject.SetActive(true);
_HostCard.EnablePickup(true);
}
public void HostDisabled()
{
_CaseManagerList.gameObject.SetActive(false);
_HostCard.EnablePickup(false);
}
public void LoadCaseFile(CaseManagerListEntry CaseFile)
{
Networking.SetOwner(Networking.LocalPlayer, gameObject);
Networking.SetOwner(Networking.LocalPlayer, _Round1Manager.gameObject);
Networking.SetOwner(Networking.LocalPlayer, _Round2Manager.gameObject);
Networking.SetOwner(Networking.LocalPlayer, _Round3Manager.gameObject);
Networking.SetOwner(Networking.LocalPlayer, _HostCard.gameObject);
_CaseFileCluesURL = CaseFile.CaseFileURL;
_CaseFileLootImage = CaseFile.LootImage;
_CaseFileMaps = CaseFile.MapFiles;
_CaseFileVideos = CaseFile.VideoFiles;
_CaseFileVideosFallback = CaseFile.FallbackVideoFiles;
_CaseFileClueImages = CaseFile.ClueImages;
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("Case Title") && _CaseFileDictionary.ContainsKey("Case Description") &&
_CaseFileDictionary.ContainsKey("Stolen Loot") && _CaseFileDictionary.ContainsKey("Accused Crook"))
{
_CaseTitle = _CaseFileDictionary["Case Title"].String;
_CaseDescription = _CaseFileDictionary["Case Description"].String;
_StolenLoot = _CaseFileDictionary["Stolen Loot"].String;
_AccusedCrook = (AccusedCrook)(int)_CaseFileDictionary["Accused Crook"].Number;
if (_CaseFileDictionary.ContainsKey("Intro Video"))
{
_CaseIntroVideo = (int)_CaseFileDictionary["Intro Video"].Number;
}
if (_CaseFileDictionary.ContainsKey("Intro Video Transcript"))
{
_CaseIntroVideoTranscript = _CaseFileDictionary["Intro Video Transcript"].String;
}
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"]);
// Get the final round continent so we can reference it in Round 2
_FinalRoundContinent = (ContinentMap)(int)_CaseFileDictionary["Round 3"].DataDictionary["Continent"].Number;
}
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 = "All case files must include a case title and description, plus the stolen loot and accused crook.";
}
}
else
{
ErrorString = "Ensure the first element is a dictionary";
}
}
else
{
ErrorString = "JSON failed to parse.";
}
if (ErrorString != "")
{
Debug.LogError("[CaseManager] Malformed case file. " + ErrorString);
}
RequestSerialization();
}
public string ContinueToRound1()
{
_Round3Manager.DeinitialiseGameMode();
_HostCard.SetGameManager(_Round1Manager);
_Round1Manager.InitialiseGameMode();
return "";
}
public string ContinueToRound2()
{
_Round1Manager.DeinitialiseGameMode();
_HostCard.SetGameManager(_Round2Manager);
_Round2Manager.InitialiseGameMode();
return "";
}
public string ContinueToRound3()
{
_Round2Manager.DeinitialiseGameMode();
_HostCard.SetGameManager(_Round3Manager);
_Round3Manager.InitialiseGameMode();
return "";
}
public string GetCaseTitle()
{
return _CaseTitle;
}
public string GetCaseDescription()
{
return _CaseDescription;
}
public string GetIntroVideoTranscript()
{
return _CaseIntroVideoTranscript;
}
public string GetLoot()
{
return _StolenLoot;
}
public AccusedCrook GetCrook()
{
return _AccusedCrook;
}
public string GetCrookName()
{
return CrookToString(_AccusedCrook);
}
public VRCUrl[] GetMaps()
{
return _CaseFileMaps;
}
public VRCUrl GetMap(int MapIndex)
{
return _CaseFileMaps[MapIndex];
}
public int GetMapCount()
{
return _CaseFileMaps.Length;
}
public VRCUrl GetLootImage()
{
return _CaseFileLootImage;
}
public VRCUrl[] GetVideos()
{
return _CaseFileVideos;
}
public int GetIntroVideo()
{
return _CaseIntroVideo;
}
public VRCUrl GetVideo(int VideoIndex, bool Fallback = false)
{
return (Fallback && _CaseFileVideosFallback.Length >= VideoIndex) ? _CaseFileVideosFallback[VideoIndex] : _CaseFileVideos[VideoIndex];
}
public int GetVideoCount()
{
return _CaseFileVideos.Length;
}
public VRCUrl GetClueImage(int ImageIndex)
{
return _CaseFileClueImages[ImageIndex];
}
public ContinentMap GetFinalRoundContinent()
{
return _FinalRoundContinent;
}
public void SetCurrentWinningPlayers(string[] NewWinners)
{
_CurrentWinningPlayers = NewWinners;
RequestSerialization();
}
public string[] GetCurrentWinningPlayers()
{
return _CurrentWinningPlayers;
}
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 ContinentToString(ContinentMap Continent)
{
switch (Continent)
{
case ContinentMap.Africa: return "Africa";
case ContinentMap.Asia: return "Asia";
case ContinentMap.Europe: return "Europe";
case ContinentMap.NorthAmerica: return "North America";
case ContinentMap.Oceania: return "Oceania";
case ContinentMap.SouthAmerica: return "South America";
}
return "[[ERROR]]";
}
public string GetAccusedCrook()
{
return CrookToString(_AccusedCrook);
}
public Texture GetAccusedCrookPortrait()
{
return CrookPortraits[(int)_AccusedCrook];
}
}