using UnityEngine; using UdonSharp; using VRC.SDKBase; using VRC.SDK3.UdonNetworkCalling; using VRC.Udon.Common.Interfaces; [UdonBehaviourSyncMode(BehaviourSyncMode.Manual)] public class FloorMap : UdonSharpBehaviour { public FloorMapCountry[] Countries; [UdonSynced] private int _CurrentCountry = 0; [UdonSynced, FieldChangeCallback(nameof(Activate))] private bool _Activate; [UdonSynced, FieldChangeCallback(nameof(RandomisedCountriesAndCities))] private int[] _RandomisedCountriesAndCities; private string[] _ChosenCountries = new string[MAX_SELECTED_COUNTRIES]; private string[] _ChosenCities = new string[MAX_SELECTED_COUNTRIES]; private const int MAX_SELECTED_COUNTRIES = 13; private const float DEACTIVATE_HEIGHT = -1000.0f; private void ActivateMap() { transform.localPosition = Activate ? Vector3.zero : new Vector3(0.0f, DEACTIVATE_HEIGHT, 0.0f); } public void RandomiseCountries() { Debug.Log("[FloorMap] Randomising countries..."); for (int i = 0; i < Countries.Length; i++) { Countries[i].gameObject.SetActive(false); } Random.InitState(Networking.GetServerTimeInMilliseconds()); int[] NewRandomCountries = new int[MAX_SELECTED_COUNTRIES]; int[] NewRandomCities = new int[MAX_SELECTED_COUNTRIES]; // Fill the countries array with a value too big to be valid. int NumberOfCountries = Countries.Length; for (int i = 0; i < MAX_SELECTED_COUNTRIES; i++) { NewRandomCountries[i] = NumberOfCountries; } for (int i = 0; i < MAX_SELECTED_COUNTRIES; i++) { int NewPulledIndex = NumberOfCountries; while (CountryIsAlreadyInArray(NewRandomCountries, NewPulledIndex) || Countries[NewPulledIndex].HardModeSelection) { NewPulledIndex = Random.Range(0, NumberOfCountries); } NewRandomCountries[i] = NewPulledIndex; NewRandomCities[i] = Random.Range(0, Countries[NewPulledIndex].Locations.Length); } // We're syncing the countries and cities as one array to keep // things simple to sync all at once. // Array format is all countries first, then all cities. int[] RandomCountriesAndCities = new int[MAX_SELECTED_COUNTRIES * 2]; NewRandomCountries.CopyTo(RandomCountriesAndCities, 0); NewRandomCities.CopyTo(RandomCountriesAndCities, MAX_SELECTED_COUNTRIES); SendCustomNetworkEvent(NetworkEventTarget.All, nameof(AssignRandomCountriesAndCities), RandomCountriesAndCities); RequestSerialization(); } private bool CountryIsAlreadyInArray(int[] Countries, int IndexToCheck) { for (int i = 0; i < MAX_SELECTED_COUNTRIES; i++) { if (Countries[i] == IndexToCheck) { return true; } } return false; } [NetworkCallable] public void AssignRandomCountriesAndCities(int[] NewCountrySelections) { DisableAllLocations(); _CurrentCountry = 0; for (int i = 0; i < MAX_SELECTED_COUNTRIES; i++) { FloorMapCountry Country = Countries[NewCountrySelections[i]]; Country.gameObject.SetActive(true); FloorMapLocation Location = Country.Locations[NewCountrySelections[MAX_SELECTED_COUNTRIES + i]]; Location.gameObject.SetActive(true); _ChosenCountries[i] = Location.Country; _ChosenCities[i] = Location.City; } _RandomisedCountriesAndCities = NewCountrySelections; } public int NextCountry() { _CurrentCountry++; if (_CurrentCountry >= MAX_SELECTED_COUNTRIES) { // We ran out of countries. Just end the game here. return -1; } RequestSerialization(); return _CurrentCountry; } public int GetCurrentCountryIndex() { return _CurrentCountry; } public string GetCurrentCountry() { return _ChosenCountries[_CurrentCountry]; } public string GetCurrentCity() { return _ChosenCities[_CurrentCountry]; } private void DisableAllLocations() { for (int i = 0; i < Countries.Length; i++) { FloorMapCountry Country = Countries[i]; for (int j = 0; j < Country.Locations.Length; j++) { Country.Locations[j].gameObject.SetActive(false); } Country.gameObject.SetActive(false); } } public bool Activate { set { _Activate = value; ActivateMap(); } get => _Activate; } public int[] RandomisedCountriesAndCities { set { _RandomisedCountriesAndCities = value; AssignRandomCountriesAndCities(value); } get => _RandomisedCountriesAndCities; } }