using UnityEngine;
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
namespace WPM {
public partial class WorldMapEditor : MonoBehaviour {
public int GUICityIndex;
public string GUICityName = "";
public string GUICityNewName = "";
public string GUICityPopulation = "";
public string GUICityProvince = "";
public Vector2 GUICityLatLon;
public CITY_CLASS GUICityClass = CITY_CLASS.CITY;
public int cityIndex = -1;
public bool cityChanges;
// if there's any pending change to be saved
public bool cityAttribChanges;
// private fields
int lastCityCount = -1;
string[] _cityNames;
public string[] cityNames {
get {
if (map.cities != null && lastCityCount != map.cities.Count) {
cityIndex = -1;
ReloadCityNames();
}
return _cityNames;
}
}
#region Editor functionality
public void ClearCitySelection() {
map.HideCityHighlights();
cityIndex = -1;
GUICityName = "";
GUICityIndex = -1;
GUICityNewName = "";
}
///
/// Adds a new city to current country.
///
public void CityCreate(Vector3 newPoint) {
if (countryIndex < 0)
return;
GUICityName = "New City " + (map.cities.Count + 1);
newPoint = newPoint.normalized * 0.5f;
City newCity = new City(GUICityName, GUIProvinceName, countryIndex, 100, newPoint, GUICityClass);
map.cities.Add(newCity);
map.DrawCities();
lastCityCount = -1;
ReloadCityNames();
cityChanges = true;
}
public bool CityUpdate() {
if (cityIndex < 0)
return false;
bool changes = false;
City city = map.cities[cityIndex];
if (city.cityClass != GUICityClass) {
city.cityClass = GUICityClass;
changes = true;
}
int newPopulation;
if (int.TryParse(GUICityPopulation, out newPopulation) && city.population != newPopulation) {
city.population = newPopulation;
changes = true;
}
if (city.latlon != GUICityLatLon) {
city.latlon = GUICityLatLon;
changes = true;
}
string prevName = city.name;
GUICityNewName = GUICityNewName.Trim();
if (!prevName.Equals(GUICityNewName)) {
city.name = GUICityNewName;
GUICityName = GUICityNewName;
lastCityCount = -1;
ReloadCityNames();
changes = true;
}
if (changes) {
map.DrawCities();
cityChanges = true;
}
return true;
}
public void CityMove(Vector3 destination) {
if (cityIndex < 0)
return;
map.cities[cityIndex].localPosition = destination.normalized * 0.5f;
UpdateCityVisualPosition();
cityChanges = true;
}
void UpdateCityVisualPosition() {
GameObject cityObj = map.cities[cityIndex].gameObject;
if (cityObj != null) {
cityObj.transform.localPosition = map.cities[cityIndex].localPosition * 1.001f;
}
}
public void CitySelectByCombo(int selection) {
GUICityName = "";
GUICityIndex = selection;
if (GetCityIndexByGUISelection()) {
if (Application.isPlaying) {
map.BlinkCity(cityIndex, Color.black, Color.green, 1.2f, 0.2f);
}
}
CitySelect();
}
bool GetCityIndexByGUISelection() {
if (GUICityIndex < 0 || GUICityIndex >= cityNames.Length)
return false;
string[] s = cityNames[GUICityIndex].Split(new char[] {
'(',
')'
}, System.StringSplitOptions.RemoveEmptyEntries);
if (s.Length >= 2) {
GUICityName = s[0].Trim();
if (int.TryParse(s[1], out cityIndex)) {
return true;
}
}
return false;
}
public void CitySelect() {
if (cityIndex < 0 || cityIndex > map.cities.Count)
return;
// If no country is selected (the city could be at sea) select it
City city = map.cities[cityIndex];
int cityCountryIndex = city.countryIndex;
if (cityCountryIndex < 0) {
SetInfoMsg("Country not found in this country file.");
}
if (countryIndex != cityCountryIndex && cityCountryIndex >= 0) {
ClearSelection();
countryIndex = cityCountryIndex;
countryRegionIndex = map.countries[countryIndex].mainRegionIndex;
CountryRegionSelect();
}
// Just in case makes GUICountryIndex selects appropiate value in the combobox
GUICityName = city.name;
GUICityPopulation = city.population.ToString();
GUICityClass = city.cityClass;
GUICityProvince = city.province;
GUICityLatLon = city.latlon;
SyncGUICitySelection();
if (cityIndex >= 0) {
GUICityNewName = city.name;
CityHighlightSelection();
}
}
public bool CitySelectByScreenClick(Ray ray, int countryIndex = -1) {
int targetCityIndex;
if (map.GetCityIndex(ray, out targetCityIndex, countryIndex)) {
cityIndex = targetCityIndex;
CitySelect();
return true;
}
return false;
}
void CityHighlightSelection() {
if (cityIndex < 0 || cityIndex >= map.cities.Count)
return;
// Colorize city
map.HideCityHighlights();
map.ToggleCityHighlight(cityIndex, Color.blue, true);
}
public void ReloadCityNames() {
if (map == null || map.cities == null) {
lastCityCount = -1;
return;
}
lastCityCount = map.cities.Count; // check this size, and not result from GetCityNames because it could return additional rows (separators and so)
_cityNames = map.GetCityNames(countryIndex, true);
SyncGUICitySelection();
CitySelect(); // refresh selection
}
void SyncGUICitySelection() {
// recover GUI city index selection
if (GUICityName.Length > 0) {
for (int k = 0; k < cityNames.Length; k++) {
if (_cityNames[k].TrimStart().StartsWith(GUICityName)) {
GUICityIndex = k;
if (provinceIndex >= 0) {
cityIndex = map.GetCityIndexInProvince(provinceIndex, GUICityName);
}
if (cityIndex < 0) {
cityIndex = map.GetCityIndexInCountry(countryIndex, GUICityName);
}
return;
}
}
if (map.GetCityIndex(GUICityName) < 0) {
SetInfoMsg("City " + GUICityName + " not found in database.");
}
}
GUICityIndex = -1;
GUICityName = "";
}
///
/// Deletes current city
///
public void DeleteCity() {
if (cityIndex < 0 || cityIndex >= map.cities.Count)
return;
map.HideCityHighlights();
map.cities.RemoveAt(cityIndex);
cityIndex = -1;
GUICityName = "";
SyncGUICitySelection();
map.DrawCities();
cityChanges = true;
}
///
/// Deletes all cities of current selected country
///
public void DeleteCountryCities() {
if (countryIndex < 0)
return;
map.HideCityHighlights();
int k = -1;
while (++k < map.cities.Count) {
if (map.cities[k].countryIndex == countryIndex) {
map.cities.RemoveAt(k);
k--;
}
}
cityIndex = -1;
GUICityName = "";
SyncGUICitySelection();
map.DrawCities();
cityChanges = true;
}
///
/// Deletes all cities of current selected country's continent
///
public void DeleteCitiesSameContinent() {
if (countryIndex < 0)
return;
map.HideCityHighlights();
int k = -1;
string continent = map.countries[countryIndex].continent;
while (++k < map.cities.Count) {
int cindex = map.cities[k].countryIndex;
if (cindex >= 0) {
string cityContinent = map.countries[cindex].continent;
if (cityContinent.Equals(continent)) {
map.cities.RemoveAt(k);
k--;
}
}
}
cityIndex = -1;
GUICityName = "";
SyncGUICitySelection();
map.DrawCities();
cityChanges = true;
}
///
/// Calculates correct province for cities
///
public void FixOrphanCities() {
if (_map.provinces == null)
return;
int countryAssigned = 0;
int provinceAssigned = 0;
int cityCount = _map.cities.Count;
for (int c = 0; c < cityCount; c++) {
City city = _map.cities[c];
if (city.countryIndex == -1) {
for (int k = 0; k < _map.countries.Length; k++) {
Country co = _map.countries[k];
if (co.regions == null)
continue;
int regCount = co.regions.Count;
for (int kr = 0; kr < regCount; kr++) {
if (co.regions[kr].Contains(city.latlon)) {
city.countryIndex = k;
countryAssigned++;
cityChanges = true;
k = 100000;
break;
}
}
}
}
if (city.countryIndex == -1) {
float minDist = float.MaxValue;
for (int k = 0; k < _map.countries.Length; k++) {
Country co = _map.countries[k];
if (co.regions == null)
continue;
int regCount = co.regions.Count;
for (int kr = 0; kr < regCount; kr++) {
float dist = (co.regions[kr].latlonCenter - city.latlon).sqrMagnitude;
if (dist < minDist) {
minDist = dist;
city.countryIndex = k;
cityChanges = true;
countryAssigned++;
}
}
}
}
if (city.province.Length == 0) {
Country country = _map.countries[city.countryIndex];
if (country.provinces == null)
continue;
for (int p = 0; p < country.provinces.Length; p++) {
Province province = country.provinces[p];
if (province.regions == null)
_map.ReadProvincePackedString(province);
if (province.regions == null)
continue;
int regCount = province.regions.Count;
for (int pr = 0; pr < regCount; pr++) {
Region reg = province.regions[pr];
if (reg.Contains(city.latlon)) {
city.province = province.name;
cityChanges = true;
p = 100000;
break;
}
}
}
}
}
for (int c = 0; c < cityCount; c++) {
City city = _map.cities[c];
if (city.province.Length == 0) {
float minDist = float.MaxValue;
int pg = -1;
for (int p = 0; p < _map.provinces.Length; p++) {
Province province = _map.provinces[p];
if (province.regions == null)
_map.ReadProvincePackedString(province);
if (province.regions == null)
continue;
int regCount = province.regions.Count;
for (int pr = 0; pr < regCount; pr++) {
Region pregion = province.regions[pr];
for (int prp = 0; prp < pregion.latlon.Length; prp++) {
float dist = (city.latlon - pregion.latlon[prp]).sqrMagnitude;
if (dist < minDist) {
minDist = dist;
pg = p;
}
}
}
}
if (pg >= 0) {
city.province = _map.provinces[pg].name;
provinceAssigned++;
cityChanges = true;
}
} else { // check for differences in capitals
#if !UNITY_WSA
if (!city.name.Equals(city.province) && String.Compare(city.name, city.province, System.Globalization.CultureInfo.CurrentCulture, System.Globalization.CompareOptions.IgnoreNonSpace) == 0) {
city.name = city.province;
cityChanges = true;
}
#endif
}
}
Debug.Log(countryAssigned + " cities were assigned a new country.");
Debug.Log(provinceAssigned + " cities were assigned a new province.");
if (countryAssigned > 0 || provinceAssigned > 0) {
cityChanges = true;
}
}
#endregion
}
}