using UdonSharp; using UnityEngine; using VRC.SDK3.Data; using VRC.SDK3.UdonNetworkCalling; using VRC.SDKBase; using VRC.Udon.Common.Interfaces; public enum PanelType { Empty, Loot, Warrant, Crook } [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class GameManagerRound2 : GameManagerBase { [SerializeField] private CaseManager _CaseManager; [SerializeField] private LocationBoard _LocationBoard; [UdonSynced] private string[] _Landmarks; [UdonSynced] private int _StageIndex = 0; [UdonSynced] private int _CurrentPlayerCounter = 0; [UdonSynced] private string[] _Players = new string[2]; private readonly Color COLOR_STANDARD = new Color(0.78431f, 0.78431f, 0.78431f); private readonly Color COLOR_RED = new Color(0.78431f, 0.0f, 0.0f); private readonly Color COLOR_YELLOW = new Color(0.78431f, 0.78431f, 0.0f); private readonly Color COLOR_GREEN = new Color(0.0f, 0.78431f, 0.0f); public override void InitialiseGameMode() { _StageIndex = 0; _CurrentPlayerCounter = 0; InitialiseLocationBoard(); _LocationBoard.SetLootImageURL(_CaseManager.GetLootImage()); RequestSerialization(); base.InitialiseGameMode(); } private void InitialiseLocationBoard() { _LocationBoard.RandomiseLocations(); _LocationBoard.RandomiseMaterials(); LocationBoardReset(); } public override void LoadQuestionData(DataToken Data) { DataDictionary LandmarkDictionary = Data.DataDictionary; if (LandmarkDictionary.ContainsKey("Location") && LandmarkDictionary.ContainsKey("Landmarks")) { if (LandmarkDictionary["Landmarks"].TokenType == TokenType.DataList && LandmarkDictionary["Landmarks"].DataList.Count >= 15) { DataList LandmarksList = LandmarkDictionary["Landmarks"].DataList; string[] NewLandmarks = new string[LandmarksList.Count]; for (int i = 0; i < LandmarksList.Count; i++) { if (LandmarksList[i].TokenType == TokenType.DataDictionary) { DataDictionary LandmarkEntry = LandmarksList[i].DataDictionary; if (LandmarkEntry.ContainsKey("Landmark")) { NewLandmarks[i] = LandmarkEntry["Landmark"].String; } else { Debug.LogError("Malformed landmark entry. Ensure the 'Landmark' key exists."); } } else { Debug.LogError("Malformed landmark entry. Ensure each landmark is a dictionary containing a 'Landmark' key."); } } _Landmarks = NewLandmarks; _LocationBoard.SendCustomNetworkEvent(NetworkEventTarget.All, "PopulateLandmarks", NewLandmarks); LocationBoardReset(); RequestSerialization(); } else { Debug.LogError("Malformed landmark data. Ensure there is a list of at least 15 landmarks."); } } else { Debug.LogError("Malformed round data. Ensure Round 2 contains 'Location' and 'Landmark' keys."); } EnableInteraction("Start Game"); } private void DisplayBriefing() { HostCardRecoverTheLootExplainerInterface RecoverTheLootInterface = (HostCardRecoverTheLootExplainerInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLootExplainer); RecoverTheLootInterface.HeaderUI.text = RoundSegmentTypeToString(RoundSegmentType.RecoverTheLootExplainer); _AudioManager.SendCustomNetworkEvent(NetworkEventTarget.All, "PlayMusicLoop", MusicEventType.CapitalLoop); EnableInteraction("Begin Round"); } private void BeginRound() { _Players = _CaseManager.GetCurrentWinningPlayers(); if (_Players == null || _Players.Length != 2) { _Players = new string[2]; _Players[0] = Networking.GetOwner(gameObject).displayName; _Players[1] = _Players[0]; } HostCardRecoverTheLootInterface RecoverTheLootInterface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); RecoverTheLootInterface.SetComment(_Players[_CurrentPlayerCounter % _Players.Length] + ", you're up first.", COLOR_STANDARD); RecoverTheLootInterface.EnableAllPanelButtons(true); for (int i = 0; i < _Landmarks.Length; i++) { RecoverTheLootInterface.AddLandmarkName(i, _Landmarks[i]); } NetworkCalling.SendCustomNetworkEvent((IUdonEventReceiver)_AudioManager, NetworkEventTarget.All, "PlayMusicLoop", MusicEventType.RecoverTheLoot); } public void OnTheRightTrack() { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("On the right track. You get a free turn.", COLOR_GREEN); } public void AlmostThere() { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("Almost got it. Another free turn.", COLOR_YELLOW); } public void OutOfOrder(PanelType Type) { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); string PanelToken = ""; switch (Type) { case PanelType.Loot: PanelToken = _CaseManager.GetLoot(); break; case PanelType.Warrant: PanelToken = "the warrant"; break; case PanelType.Crook: PanelToken = _CaseManager.GetAccusedCrook(); break; } Interface.SetComment("Found " + PanelToken + ". Remember the order: loot, warrant, crook. Use some strategy.", COLOR_YELLOW); } // All of these next functions are the end of a turn, and should disable // all inputs to prevent messing up the game state. public void NothingThere() { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("Nothing there.", COLOR_STANDARD); Interface.EnableAllPanelButtons(false); } public void AlreadyTried() { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("Already tried that one.", COLOR_STANDARD); Interface.EnableAllPanelButtons(false); } public void NiceStrategy() { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("Nice strategy.", COLOR_GREEN); Interface.EnableAllPanelButtons(false); } // This is for when a player wins the game. This should disable all inputs, // and should also enable victory animations. public void YoureWinner() { string[] Winner = new string[1]; Winner[0] = _Players[_CurrentPlayerCounter % _Players.Length]; _CaseManager.SetCurrentWinningPlayers(Winner); HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment("Winner! Congratulations, " + Winner[0], COLOR_RED); Interface.EnableAllPanelButtons(false); NetworkCalling.SendCustomNetworkEvent((IUdonEventReceiver)_AudioManager, NetworkEventTarget.All, "StopMusic"); EnableInteraction("Go To The Map"); } private void EndRound() { HostCardBetweenRoundsInterface Interface = (HostCardBetweenRoundsInterface)GetHostCardInterface(RoundSegmentType.BetweenSegments); Interface.HeaderUI.text = "Round is over. Let's go to the map!"; _CaseManager.ContinueToRound3(); } public void LocationBoardReset(bool UpdateHostCardInterface = false) { _CurrentPlayerCounter++; NetworkCalling.SendCustomNetworkEvent( (IUdonEventReceiver)_LocationBoard, NetworkEventTarget.All, "ResetPanelBoard"); if (UpdateHostCardInterface) { HostCardRecoverTheLootInterface Interface = (HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot); Interface.SetComment(_Players[_CurrentPlayerCounter % _Players.Length] + ", your turn.", COLOR_STANDARD); Interface.EnableAllPanelButtons(true); } RequestSerialization(); } public Texture GetCrookPortrait() { return _CaseManager.GetAccusedCrookPortrait(); } public void PlayTheLoot() { _AudioManager.PlaySFX(SFXEventType.TheLoot); } public void PlayTheWarrant() { _AudioManager.PlaySFX(SFXEventType.TheWarrant); } public void PlayTheCrookTheme() { _AudioManager.PlayCrookTheme(_CaseManager.GetCrook()); } protected override HostCardInterfaceBase GetHostCardInterface(RoundSegmentType Question) { return _HostCard.EnableHostCardDisplay(RoundType.RecoverTheLoot, Question); } protected override void _HostCardUseButtonDown_Internal() { DisableInteraction(); _StageIndex++; switch(_StageIndex) { case 1: DisplayBriefing(); break; case 2: BeginRound(); break; case 3: EndRound(); break; } } public void Button_RevealPanel(int Panel) { ((HostCardRecoverTheLootInterface)GetHostCardInterface(RoundSegmentType.RecoverTheLoot)) .DisablePanelButton(Panel); NetworkCalling.SendCustomNetworkEvent( (IUdonEventReceiver)_LocationBoard, NetworkEventTarget.All, "RevealPanel", Panel); } public void Button_RevealPanel1() { Button_RevealPanel(1); } public void Button_RevealPanel2() { Button_RevealPanel(2); } public void Button_RevealPanel3() { Button_RevealPanel(3); } public void Button_RevealPanel4() { Button_RevealPanel(4); } public void Button_RevealPanel5() { Button_RevealPanel(5); } public void Button_RevealPanel6() { Button_RevealPanel(6); } public void Button_RevealPanel7() { Button_RevealPanel(7); } public void Button_RevealPanel8() { Button_RevealPanel(8); } public void Button_RevealPanel9() { Button_RevealPanel(9); } public void Button_RevealPanel10() { Button_RevealPanel(10); } public void Button_RevealPanel11() { Button_RevealPanel(11); } public void Button_RevealPanel12() { Button_RevealPanel(12); } public void Button_RevealPanel13() { Button_RevealPanel(13); } public void Button_RevealPanel14() { Button_RevealPanel(14); } public void Button_RevealPanel15() { Button_RevealPanel(15); } private string PanelTypeToString(PanelType Type) { switch(Type) { case PanelType.Empty: return "Empty"; case PanelType.Loot: return "Loot"; case PanelType.Warrant: return "Warrant"; case PanelType.Crook: return "Crook"; default: return "[[ERROR]]"; } } }