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, FieldChangeCallback(nameof(Activate))] private bool _Activate; [UdonSynced, FieldChangeCallback(nameof(RandomisedCountriesAndCities))] private int[] _RandomisedCountriesAndCities; private string[] _ChosenCountries = new string[MAX_SELECTED_COUNTRIES]; private string[] _ChosenRegions = new string[MAX_SELECTED_COUNTRIES]; private string[] _ChosenCities = new string[MAX_SELECTED_COUNTRIES]; public const int MAX_SELECTED_COUNTRIES = 13; private const float DEACTIVATE_HEIGHT = -1000.0f; private void ActivateMap() { transform.localPosition = new Vector3(transform.localPosition.x, Activate ? 0.0f : DEACTIVATE_HEIGHT, transform.localPosition.z); } public void RandomiseCountries() { 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 regions, then all cities. int[] RandomCountriesAndCities = new int[MAX_SELECTED_COUNTRIES * 3]; 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(); 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; _ChosenRegions[i] = Location.Region; _ChosenCities[i] = Location.City; } _RandomisedCountriesAndCities = NewCountrySelections; } public string GetCountry(int CountryIndex) { return CountryIndex < _ChosenCountries.Length ? _ChosenCountries[CountryIndex] : ""; } public string GetRegion(int RegionIndex) { return RegionIndex < _ChosenRegions.Length ? _ChosenRegions[RegionIndex] : ""; } public string GetCity(int CityIndex) { return CityIndex < _ChosenCities.Length ? _ChosenCities[CityIndex] : ""; } 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; } }