using TMPro; using UdonSharp; using UnityEngine; using VRC.SDK3.Image; using VRC.SDK3.UdonNetworkCalling; using VRC.SDKBase; using VRC.Udon.Common.Interfaces; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class LocationBoard : UdonSharpBehaviour { [SerializeField] private GameManagerRound2 _GameManager; [SerializeField] private AudioManager _AudioManager; [SerializeField] private MeshRenderer[] _LocationPanelInfoSheets; [SerializeField] private GameObject[] _LocationPanelsEmpty; [SerializeField] private GameObject[] _LocationPanelsLoot; [SerializeField] private GameObject[] _LocationPanelsWarrant; [SerializeField] private GameObject[] _LocationPanelsCrook; [SerializeField] private TextMeshProUGUI[] _LocationPanelText; [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(LootImageURL))] private VRCUrl _LootImageURL; [UdonSynced, FieldChangeCallback(nameof(Landmarks))] private string[] _Landmarks; [UdonSynced, FieldChangeCallback(nameof(RandomMaterialSettings))] private int[] _RandomMaterialSettings; [UdonSynced, FieldChangeCallback(nameof(RevealedPanel))] private int _RevealedPanel = 0; [UdonSynced] private bool[] _OrderIsCorrect = new bool[3]; [UdonSynced] private bool[] _HasBeenCheckedBefore; [SerializeField] private Material _LootMaterial; [SerializeField] private Material[] _LocationSheetMaterialSelections; private Animator _Animator; private VRCImageDownloader _LootImageDownloader; private int _ActiveSpinners = 0; void Start() { _Animator = GetComponent(); _LootImageDownloader = new VRCImageDownloader(); _HasBeenCheckedBefore = new bool[_LocationPanelsEmpty.Length]; MeshRenderer LootMesh; if (LootMesh = _LocationPanelsLoot[0].GetComponent()) { LootMesh.sharedMaterial = _LootMaterial; } } void OnDestroy() { _LootImageDownloader.Dispose(); } [NetworkCallable] public void PopulateLandmarks(string[] NewLandmarks) { for (int i = 0; i < NewLandmarks.Length; i++) { _LocationPanelText[i].text = NewLandmarks[i]; } _Landmarks = NewLandmarks; } public void SetLootImageURL(VRCUrl URL) { LootImageURL = URL; RequestSerialization(); } private void DownloadLootImage() { TextureInfo AdditionalTextureInfo = new TextureInfo(); AdditionalTextureInfo.WrapModeU = TextureWrapMode.Clamp; AdditionalTextureInfo.WrapModeV = TextureWrapMode.Clamp; AdditionalTextureInfo.GenerateMipMaps = true; _LootImageDownloader.DownloadImage( LootImageURL, _LootMaterial, null, AdditionalTextureInfo); } public void RevealPanel(int Panel) { RevealedPanel = Panel; RequestSerialization(); } private void _RevealPanel_Private() { Debug.Log("[LocationBoard] Revealing panel " + RevealedPanel); if (_ActiveSpinners < 3) { Debug.Log("[LocationBoard] Active spinners is currently less than three"); _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, _LocationPanelsLoot.Length) + 1; int TempWarrantLocation = _LootLocation; while (TempWarrantLocation == _LootLocation) { TempWarrantLocation = Random.Range(0, _LocationPanelsWarrant.Length) + 1; } WarrantLocation = TempWarrantLocation; int TempCrookLocation = _WarrantLocation; while (TempCrookLocation == _WarrantLocation || TempCrookLocation == _LootLocation) { TempCrookLocation = Random.Range(0, _LocationPanelsCrook.Length) + 1; } CrookLocation = TempCrookLocation; for (int i = 0; i < _LocationPanelsEmpty.Length; i++) { _HasBeenCheckedBefore[i] = false; } RequestSerialization(); } public void RandomiseMaterials() { int[] MaterialsArray = new int[_LocationPanelInfoSheets.Length]; int PreviousMaterial = 0; for (int i = 0; i < MaterialsArray.Length; i++) { int RandomValue = PreviousMaterial; while (RandomValue == PreviousMaterial) { RandomValue = Random.Range(0, _LocationSheetMaterialSelections.Length); } PreviousMaterial = RandomValue; MaterialsArray[i] = RandomValue; } SendCustomNetworkEvent(NetworkEventTarget.All, nameof(ApplyRandomMaterials), MaterialsArray); RequestSerialization(); } [NetworkCallable] public void ApplyRandomMaterials(int[] NewMaterials) { for (int i = 0; i < NewMaterials.Length; i++) { Material[] Materials = _LocationPanelInfoSheets[i].materials; Materials[1] = _LocationSheetMaterialSelections[NewMaterials[i]]; _LocationPanelInfoSheets[i].materials = Materials; } _RandomMaterialSettings = NewMaterials; } 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[CrookLocation - 1].GetComponent()) { CrookMesh.sharedMaterial.SetTexture("_MainTex", _GameManager.GetCrookPortrait()); } } 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; } public VRCUrl LootImageURL { set { _LootImageURL = value; DownloadLootImage(); } get => _LootImageURL; } public string[] Landmarks { set { _Landmarks = value; PopulateLandmarks(value); } get => _Landmarks; } public int[] RandomMaterialSettings { set { _RandomMaterialSettings = value; ApplyRandomMaterials(value); } get => _RandomMaterialSettings; } private int RevealedPanel { set { _RevealedPanel = value; if (_RevealedPanel > 0) { _RevealPanel_Private(); } else { _ResetPanelBoard_Private(); } } get => _RevealedPanel; } }