using TMPro; using UdonSharp; using UnityEngine; using VRC.SDKBase; using VRC.Udon.Common; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class LocationBoard : UdonSharpBehaviour { [SerializeField] private GameManagerRound2 _GameManager; [SerializeField] private AudioManager _AudioManager; [SerializeField] private Animator _Animator; [Space] [SerializeField] private MeshRenderer[] _LocationPanelInfoSheets; [SerializeField] private GameObject[] _LocationPanelsEmpty; [SerializeField] private GameObject[] _LocationPanelsLoot; [SerializeField] private GameObject[] _LocationPanelsWarrant; [SerializeField] private GameObject[] _LocationPanelsCrook; [SerializeField] private TextMeshProUGUI[] _LocationPanelText; [Space] [SerializeField] private Material _LootMaterial; [SerializeField] private Material[] _LocationSheetMaterialSelections; [UdonSynced] private int[] _RandomMaterialSettings = new int[NUMBER_OF_LOCATIONS]; private int[] _RandomMaterialSettings_Cache = new int[NUMBER_OF_LOCATIONS]; [UdonSynced] private string[] _Landmarks = new string[NUMBER_OF_LOCATIONS]; private string[] _Landmarks_Cache = new string[NUMBER_OF_LOCATIONS]; [UdonSynced, FieldChangeCallback(nameof(LootLocation))] private int _LootLocation = 0; [UdonSynced, FieldChangeCallback(nameof(WarrantLocation))] private int _WarrantLocation = 0; [UdonSynced, FieldChangeCallback(nameof(CrookLocation))] private int _CrookLocation = 0; [UdonSynced, FieldChangeCallback(nameof(RevealedPanel))] private int _RevealedPanel = 0; [UdonSynced] private bool[] _OrderIsCorrect = new bool[3]; [UdonSynced] private bool[] _HasBeenCheckedBefore = new bool[NUMBER_OF_LOCATIONS]; private int _ActiveSpinners = 0; private const int NUMBER_OF_LOCATIONS = 15; void Start() { _Animator = GetComponent(); foreach (GameObject LootPanel in _LocationPanelsLoot) { MeshRenderer LootMesh; if (LootMesh = LootPanel.GetComponent()) { LootMesh.material = _LootMaterial; } } } public override void OnDeserialization(DeserializationResult Result) { if (_IsRandomMaterialListDifferent()) { _ApplyRandomMaterials(); } if (_IsLandmarksListDifferent()) { _ApplyPopulatedLandmarks(); } base.OnDeserialization(Result); } public void PopulateLandmarks(string[] NewLandmarks) { if (NewLandmarks.Length == NUMBER_OF_LOCATIONS) { _Landmarks = NewLandmarks; if (_IsLandmarksListDifferent()) { _ApplyPopulatedLandmarks(); } RequestSerialization(); } else { Debug.LogError("[LocationBoard] Incorrect number of landmarks; resetting values."); _Landmarks = _Landmarks_Cache; } } private void _ApplyPopulatedLandmarks() { for (int i = 0; i < NUMBER_OF_LOCATIONS; i++) { _LocationPanelText[i].text = _Landmarks[i]; } _Landmarks_Cache = _Landmarks; } public void SetLootImage(Texture2D LootTexture) { _LootMaterial.SetTexture("_MainTex", LootTexture); } public void RevealPanel(int Panel) { RevealedPanel = Panel; RequestSerialization(); } private void _RevealPanel_Private() { if (_ActiveSpinners < 3) { _Animator.SetBool("Flip " + RevealedPanel, true); switch (_ActiveSpinners) { case 0: { _OrderIsCorrect[0] = (RevealedPanel == LootLocation); if (_OrderIsCorrect[0]) { _GameManager.OnTheRightTrack(); } else if (RevealedPanel == WarrantLocation) { _GameManager.OutOfOrder(PanelType.Warrant); } else if (RevealedPanel == CrookLocation) { _GameManager.OutOfOrder(PanelType.Crook); } else if (_HasBeenCheckedBefore[RevealedPanel - 1]) { _GameManager.AlreadyTried(); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } else { _GameManager.NothingThere(); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } } break; case 1: { _OrderIsCorrect[1] = (RevealedPanel == WarrantLocation); if (_OrderIsCorrect[1]) { if (!_OrderIsCorrect[0]) { _GameManager.OutOfOrder(PanelType.Warrant); } else { _GameManager.AlmostThere(); } } else if (RevealedPanel == LootLocation) { _GameManager.OutOfOrder(PanelType.Loot); } else if (RevealedPanel == CrookLocation) { _GameManager.OutOfOrder(PanelType.Crook); } else if (_HasBeenCheckedBefore[RevealedPanel - 1]) { if (!_OrderIsCorrect[0]) { _GameManager.NiceStrategy(); } else { _GameManager.AlreadyTried(); } SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } else { _GameManager.NothingThere(); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } } break; case 2: { _OrderIsCorrect[2] = (RevealedPanel == CrookLocation); if (_OrderIsCorrect[2]) { if (!_OrderIsCorrect[1] || !_OrderIsCorrect[0]) { _GameManager.OutOfOrder(PanelType.Crook); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 2.5f); } } else if (RevealedPanel == LootLocation) { _GameManager.OutOfOrder(PanelType.Loot); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 2.5f); } else if (RevealedPanel == WarrantLocation) { _GameManager.OutOfOrder(PanelType.Warrant); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 2.5f); } else if (_HasBeenCheckedBefore[RevealedPanel - 1]) { if (!_OrderIsCorrect[0] || !_OrderIsCorrect[1]) { _GameManager.NiceStrategy(); } else { _GameManager.AlreadyTried(); } SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } else { _GameManager.NothingThere(); SendCustomEventDelayedSeconds(nameof(InitiateBoardReset), 1.0f); } } break; } _ActiveSpinners++; if (RevealedPanel == LootLocation) { _GameManager.SendCustomEventDelayedSeconds("PlayTheLoot", 0.35f); } else if (RevealedPanel == WarrantLocation) { _GameManager.SendCustomEventDelayedSeconds("PlayTheWarrant", 0.35f); } else if (RevealedPanel == CrookLocation) { _GameManager.SendCustomEventDelayedSeconds("PlayTheCrookTheme", 0.35f); } if (_OrderIsCorrect[0] && _OrderIsCorrect[1] && _OrderIsCorrect[2]) { _GameManager.YoureWinner(); } } _HasBeenCheckedBefore[RevealedPanel - 1] = true; } public void InitiateBoardReset() { _GameManager.LocationBoardReset(true); } public void ResetPanelBoard() { RevealedPanel = 0; RequestSerialization(); } private void _ResetPanelBoard_Private() { for (int i = 1; i <= 15; i++) { _Animator.SetBool("Flip " + i, false); } _ActiveSpinners = 0; _OrderIsCorrect[0] = _OrderIsCorrect[1] = _OrderIsCorrect[2] = false; } public void RandomiseLocations() { Random.InitState(Networking.GetServerTimeInMilliseconds()); LootLocation = Random.Range(0, NUMBER_OF_LOCATIONS) + 1; int TempWarrantLocation = _LootLocation; while (TempWarrantLocation == _LootLocation) { TempWarrantLocation = Random.Range(0, NUMBER_OF_LOCATIONS) + 1; } WarrantLocation = TempWarrantLocation; int TempCrookLocation = _WarrantLocation; while (TempCrookLocation == _WarrantLocation || TempCrookLocation == _LootLocation) { TempCrookLocation = Random.Range(0, NUMBER_OF_LOCATIONS) + 1; } CrookLocation = TempCrookLocation; for (int i = 0; i < NUMBER_OF_LOCATIONS; i++) { _HasBeenCheckedBefore[i] = false; } RequestSerialization(); } public void RandomiseMaterials() { int[] MaterialsArray = new int[NUMBER_OF_LOCATIONS]; int PreviousMaterial = 0; for (int i = 0; i < NUMBER_OF_LOCATIONS; i++) { int RandomValue = PreviousMaterial; while (RandomValue == PreviousMaterial) { RandomValue = Random.Range(0, _LocationSheetMaterialSelections.Length); } PreviousMaterial = RandomValue; MaterialsArray[i] = RandomValue; } _RandomMaterialSettings = MaterialsArray; if (_IsRandomMaterialListDifferent()) { _ApplyRandomMaterials(); } RequestSerialization(); } private void _ApplyRandomMaterials() { for (int i = 0; i < NUMBER_OF_LOCATIONS; i++) { Material[] Materials = _LocationPanelInfoSheets[i].materials; Materials[1] = _LocationSheetMaterialSelections[_RandomMaterialSettings[i]]; _LocationPanelInfoSheets[i].materials = Materials; } _RandomMaterialSettings_Cache = _RandomMaterialSettings; } private void PlaceEmpty(int Panel) { if (Panel > 0) { _LocationPanelsLoot[Panel - 1].SetActive(false); _LocationPanelsWarrant[Panel - 1].SetActive(false); _LocationPanelsCrook[Panel - 1].SetActive(false); _LocationPanelsEmpty[Panel - 1].SetActive(true); } } private void PlaceLoot(int Panel) { if (Panel > 0) { _LocationPanelsEmpty[Panel - 1].SetActive(false); _LocationPanelsWarrant[Panel - 1].SetActive(false); _LocationPanelsCrook[Panel - 1].SetActive(false); _LocationPanelsLoot[Panel - 1].SetActive(true); } } private void PlaceWarrant(int Panel) { if (Panel > 0) { _LocationPanelsEmpty[Panel - 1].SetActive(false); _LocationPanelsLoot[Panel - 1].SetActive(false); _LocationPanelsCrook[Panel - 1].SetActive(false); _LocationPanelsWarrant[Panel - 1].SetActive(true); } } private void PlaceCrook(int Panel) { if (Panel > 0) { _LocationPanelsEmpty[Panel - 1].SetActive(false); _LocationPanelsLoot[Panel - 1].SetActive(false); _LocationPanelsWarrant[Panel - 1].SetActive(false); _LocationPanelsCrook[Panel - 1].SetActive(true); } MeshRenderer CrookMesh; if (CrookMesh = _LocationPanelsCrook[Panel - 1].GetComponent()) { CrookMesh.material.SetTexture("_MainTex", _GameManager.GetCrookPortrait()); } } private bool _IsRandomMaterialListDifferent() { if (_RandomMaterialSettings.Length != NUMBER_OF_LOCATIONS) { Debug.LogError("[LocationBoard] Random material list length is incorrect"); return true; } for (int i = 0; i < _RandomMaterialSettings.Length; i++) { if (_RandomMaterialSettings[i] != _RandomMaterialSettings_Cache[i]) { return true; } } return false; } private bool _IsLandmarksListDifferent() { if (_Landmarks.Length != NUMBER_OF_LOCATIONS) { Debug.LogError("[LocationBoard] Landmark list length is incorrect"); return true; } for (int i = 0; i < _Landmarks.Length; i++) { if (_Landmarks[i] != _Landmarks_Cache[i]) { return true; } } return false; } public int LootLocation { set { PlaceEmpty(_LootLocation); _LootLocation = value; PlaceLoot(value); } get => _LootLocation; } public int WarrantLocation { set { PlaceEmpty(_WarrantLocation); _WarrantLocation = value; PlaceWarrant(_WarrantLocation); } get => _WarrantLocation; } public int CrookLocation { set { PlaceEmpty(_CrookLocation); _CrookLocation = value; PlaceCrook(_CrookLocation); } get => _CrookLocation; } private int RevealedPanel { set { _RevealedPanel = value; if (_RevealedPanel > 0) { _RevealPanel_Private(); } else { _ResetPanelBoard_Private(); } } get => _RevealedPanel; } }