コード例 #1
0
    private void ColourContries()
    {
        Debug.Log("Color Countries ___________________________________________________________________________________________________________________");

        foreach (assemblyCsharp.Province prov in State.getProvinces().Values)
        {
            int provIndex = prov.getIndex();
            WorldMapStrategyKit.Province mapProv = map.provinces[provIndex];
            int countryIndex = mapProv.countryIndex;
            int nationIndex  = prov.getOwnerIndex();
            if (countryIndex != nationIndex)
            {
                Debug.Log("Reassign Nation");
                mapProv.countryIndex = nationIndex;
                Region  provRegion      = mapProv.mainRegion;
                Country newOwnerCountry = map.countries[nationIndex];
                map.CountryTransferProvinceRegion(countryIndex, provRegion, true);
            }
        }
        for (int k = 0; k < map.countries.Length; k++)
        {
            Color color = new Color(UnityEngine.Random.Range(0.0f, 0.65f),
                                    UnityEngine.Random.Range(0.0f, 0.65f), UnityEngine.Random.Range(0.0f, 0.65f));
            Nation nation = State.getNations()[k];
            // Debug.Log(nation.getName());
            nation.setColor(color);
            map.ToggleCountrySurface(k, true, color);
        }
    }
コード例 #2
0
ファイル: PlaceArmy.cs プロジェクト: alabecki/Imperial-Times
    public void placeArmyOnMap(int provIndex, Nation nation, int id)
    {
        map = WMSK.instance;
        GameObject armyPrefabInstance = Instantiate(Resources.Load <GameObject>
                                                        ("ToonyTinyPeople/TT_ww1/EarlyEraArmy"));

        WorldMapStrategyKit.Province prov = map.GetProvince(provIndex);
        if (nation.getType() == MyEnum.NationType.major || nation.getType() == MyEnum.NationType.minor)
        {
            if (State.GerEra() == MyEnum.Era.Early)
            {
                armyPrefabInstance = Instantiate(Resources.Load <GameObject>
                                                 // ("ToonyTinyPeople/TT_ww1/EarlyEraArmy"));
                                                     ("ToonyTinyPeople/TT_ww1/EarlyEraArmy"));
            }
        }
        else
        {
            {
                armyPrefabInstance = Instantiate(Resources.Load <GameObject>
                                                     ("Model_Warrior/barbOne"));
            }
        }

        Vector2            position = prov.center;
        GameObjectAnimator army     = armyPrefabInstance.WMSK_MoveTo(position);

        army.gameObject.AddComponent <GenericSoldierController>();
        army.name = id.ToString();



        SkinnedMeshRenderer[] smrs = armyPrefabInstance.GetComponentsInChildren <SkinnedMeshRenderer>();
        foreach (SkinnedMeshRenderer smr in smrs)
        {
            if (smr.name.StartsWith("flagcl"))
            {
                Debug.Log("Army of " + nation.getNationName());
                smr.material = Resources.Load("Flags/Materials/" + nation.getNationName(), typeof(Material)) as Material;
            }
        }
        if (nation.getType() == MyEnum.NationType.major || nation.getType() == MyEnum.NationType.minor)
        {
            army.transform.localScale = new Vector3(0.5f, 0.5f, 0.5f);
        }
        else
        {
            army.transform.localScale = new Vector3(0.2f, 0.2f, 0.2f);
        }
        army.preserveOriginalRotation = true;
        army.terrainCapability        = TERRAIN_CAPABILITY.OnlyGround;
        army.autoScale = true;
        army.group     = 1;
        army.transform.localRotation = Quaternion.Euler(-30f, 180f, 0f);
        army.BlocksRayCast           = true;

        army.attrib["owner"] = nation.getIndex();
        army.attrib["id"]    = id;
    }
コード例 #3
0
ファイル: RailPlacer.cs プロジェクト: alabecki/Imperial-Times
    public void drawRailroadOnMap(assemblyCsharp.Province prov, Nation player)
    {
        WorldMapStrategyKit.Province mapProvince = map.provinces[prov.getIndex()];
        Vector2 provCenter = mapProvince.center;

        for (int i = 0; i < prov.Neighbours.Count; i++)
        {
            if (PlayerCalculator.getAllProvinces(player).Contains(prov.Neighbours[i]))
            {
                // draw rail segment from prv to neighbourProv
                assemblyCsharp.Province neighbourProvince = State.getProvinces()[prov.Neighbours[i]];
                if (neighbourProvince.railroad && !neighbourProvince.Linked.Contains(prov.getIndex()) &&
                    !prov.Linked.Contains(neighbourProvince.getIndex()))
                {
                    WorldMapStrategyKit.Province mapNeighbourProvince = map.provinces[prov.Neighbours[i]];
                    Vector2    neighbourCenter = mapNeighbourProvince.center;
                    Cell       startCell       = map.GetCell(provCenter);
                    Cell       endCell         = map.GetCell(neighbourCenter);
                    List <int> cellIndices     = map.FindRoute(startCell, endCell, TERRAIN_CAPABILITY.OnlyGround);
                    if (cellIndices == null)
                    {
                        return;
                    }
                    int positionsCount = cellIndices.Count;
                    Debug.Log("Number of positions: " + positionsCount);

                    Vector2[] positions = new Vector2[positionsCount];
                    for (int k = 0; k < positionsCount; k++)
                    {
                        positions[k] = map.cells[cellIndices[k]].center;
                    }

                    // Build a railroad along the map coordinates
                    LineMarkerAnimator lma         = map.AddLine(positions, Color.white, 0.0f, 0.15f);
                    Texture2D          railwayMatt = Resources.Load("Sprites/GUI/railRoad", typeof(Texture2D)) as Texture2D;

                    lma.lineMaterial.mainTexture      = railwayMatt;
                    lma.lineMaterial.mainTextureScale = new Vector2(16f, 2f);
                    neighbourProvince.Linked.Add(prov.getIndex());
                    prov.Linked.Add(neighbourProvince.getIndex());
                }
            }
        }
    }
コード例 #4
0
    public void ApplyScenarioDataToMap()
    {
        string nationsPath = Application.dataPath +
                             "/StreamingAssets/Scenarios/" + scenario + "/Nations";
        string provincesPath = Application.dataPath +
                               "/StreamingAssets/Scenarios/" + scenario + "/Provinces";

        string[] provFiles = Directory.GetFiles(provincesPath, "*.json");
        foreach (string file in provFiles)
        {
            string dataAsJson  = File.ReadAllText(file);
            var    newProvince = Newtonsoft.Json.JsonConvert.DeserializeObject <assemblyCsharp.Province>
                                     (dataAsJson);
            //  Debug.Log("Prov quality size" + newProvince.quality[0]);
            provinces.Add(newProvince.getIndex(), newProvince);
            map.GetProvince(newProvince.getIndex()).name        = newProvince.getProvName();
            map.GetProvince(newProvince.getIndex()).customLabel = newProvince.getProvName();
        }

        string[] nationFiles = Directory.GetFiles(nationsPath, "*.json");
        foreach (string file in nationFiles)
        {
            string dataAsJson = File.ReadAllText(file);
            var    newNation  = Newtonsoft.Json.JsonConvert.DeserializeObject <assemblyCsharp.Nation>(dataAsJson);

            nations.Add(newNation.getIndex(), newNation);
            Debug.Log("Nation Name: " + newNation.getNationName());
            Debug.Log("Nation's Capital " + newNation.capital);

            // Debug.Log("Nation Name: " + newNation.getNationName());
            //   Debug.Log("Number of Provinces " + newNation.getAllProvinceIndexes().Count);
            map.GetCountry(newNation.getIndex()).name        = newNation.getNationName();
            map.GetCountry(newNation.getIndex()).customLabel = newNation.getNationName();
            map.CountryRename("Country" + newNation.getIndex(), newNation.getNationName());
            for (int i = 0; i < newNation.getProvinces().Count; i++)
            {
                int provIndex = newNation.getProvinces()[i];
                WorldMapStrategyKit.Province prov = map.GetProvince(provIndex);
                prov.countryIndex = newNation.getIndex();
            }
        }
    }
コード例 #5
0
        void ProvinceSubstractProvinceEnclaves(int provinceIndex, Region region, Poly2Tri.Polygon poly)
        {
            List <Region> negativeRegions = new List <Region>();

            for (int oc = 0; oc < _countries.Length; oc++)
            {
                Country ocCountry = _countries[oc];
                if (ocCountry.hidden || ocCountry.provinces == null)
                {
                    continue;
                }
                Region mainCountryRegion = ocCountry.regions[ocCountry.mainRegionIndex];
                if (!mainCountryRegion.rect2D.Overlaps(region.rect2D))
                {
                    continue;
                }
                for (int op = 0; op < ocCountry.provinces.Length; op++)
                {
                    Province opProvince = ocCountry.provinces[op];
                    if (opProvince == provinces[provinceIndex])
                    {
                        continue;
                    }
                    if (opProvince.regions == null)
                    {
                        ReadProvincePackedString(opProvince);
                    }
                    if (opProvince.regions == null)
                    {
                        continue;
                    }
                    if (opProvince.regionsRect2D.Overlaps(region.rect2D, true))
                    {
                        Region oProvRegion = opProvince.regions[opProvince.mainRegionIndex];
                        if (region.Contains(oProvRegion))   // just check main region of province for speed purposes
                        {
                            negativeRegions.Add(oProvRegion.Clone());
                        }
                    }
                }
            }
            // Collapse negative regions in big holes
            for (int nr = 0; nr < negativeRegions.Count - 1; nr++)
            {
                for (int nr2 = nr + 1; nr2 < negativeRegions.Count; nr2++)
                {
                    if (negativeRegions[nr].Intersects(negativeRegions[nr2]))
                    {
                        Clipper clipper = new Clipper();
                        int     control = negativeRegions[nr].points.Length;
                        clipper.AddPath(negativeRegions[nr], PolyType.ptSubject);
                        clipper.AddPath(negativeRegions[nr2], PolyType.ptClip);
                        clipper.Execute(ClipType.ctUnion);
                        negativeRegions.RemoveAt(nr2);
                        nr = -1;
                        break;
                    }
                }
            }

            // Substract holes
            int negativeRegionsCount = negativeRegions.Count;

            for (int r = 0; r < negativeRegionsCount; r++)
            {
                int       pointCount = negativeRegions[r].points.Length;
                Vector2[] pp         = new Vector2[pointCount];
                for (int p = 0; p < pointCount; p++)
                {
                    Vector2 point    = negativeRegions[r].points[p];
                    Vector2 midPoint = negativeRegions[r].center;
                    pp[p] = point + (midPoint - point) * 0.0001f; // prevents Poly2Tri issues when enclave boarders are to near from region borders
                }
                Poly2Tri.Polygon polyHole = new Poly2Tri.Polygon(pp);
                poly.AddHole(polyHole);
            }
        }
コード例 #6
0
        /// <summary>
        /// Highlights the province region specified. Returns the generated highlight surface gameObject.
        /// Internally used by the Map UI and the Editor component, but you can use it as well to temporarily mark a country region.
        /// </summary>
        /// <param name="refreshGeometry">Pass true only if you're sure you want to force refresh the geometry of the highlight (for instance, if the frontiers data has changed). If you're unsure, pass false.</param>
        public GameObject HighlightProvinceRegion(int provinceIndex, int regionIndex, bool refreshGeometry)
        {
            if (!refreshGeometry && _provinceHighlightedIndex == provinceIndex && _provinceRegionHighlightedIndex == regionIndex)
            {
                return(provinceRegionHighlightedObj);
            }
            if (provinceRegionHighlightedObj != null)
            {
                HideProvinceRegionHighlight();
            }
            if (provinceIndex < 0 || provinceIndex >= provinces.Length || provinces[provinceIndex].regions == null || regionIndex < 0 || regionIndex >= provinces[provinceIndex].regions.Count)
            {
                return(null);
            }

            if (OnProvinceHighlight != null)
            {
                bool allowHighlight = true;
                OnProvinceHighlight(provinceIndex, regionIndex, ref allowHighlight);
                if (!allowHighlight)
                {
                    return(null);
                }
            }

            int        cacheIndex = GetCacheIndexForProvinceRegion(provinceIndex, regionIndex);
            GameObject obj;
            bool       existsInCache = surfaces.TryGetValue(cacheIndex, out obj);

            if (refreshGeometry && existsInCache)
            {
                surfaces.Remove(cacheIndex);
                DestroyImmediate(obj);
                existsInCache = false;
            }

            bool doHighlight = true;

            if (_highlightMaxScreenAreaSize < 1f)
            {
                // Check screen area size
                Region region = provinces[provinceIndex].regions[regionIndex];
                doHighlight = CheckScreenAreaSizeOfRegion(region);
            }
            if (doHighlight)
            {
                if (_enableProvinceHighlight && _provinces[provinceIndex].allowHighlight && _countries[_provinces[provinceIndex].countryIndex].allowProvincesHighlight)
                {
                    if (existsInCache)
                    {
                        provinceRegionHighlightedObj = surfaces[cacheIndex];
                        if (provinceRegionHighlightedObj == null)
                        {
                            surfaces.Remove(cacheIndex);
                        }
                        else
                        {
                            if (!provinceRegionHighlightedObj.activeSelf)
                            {
                                provinceRegionHighlightedObj.SetActive(true);
                            }
                            Renderer[] rr = provinceRegionHighlightedObj.GetComponentsInChildren <Renderer>(true);
                            for (int k = 0; k < rr.Length; k++)
                            {
                                if (rr[k].sharedMaterial != hudMatProvince && rr[k].sharedMaterial != outlineMatSimple)
                                {
                                    rr[k].enabled        = true;
                                    rr[k].sharedMaterial = hudMatProvince;
                                }
                            }
                        }
                    }
                    else
                    {
                        provinceRegionHighlightedObj = GenerateProvinceRegionSurface(provinceIndex, regionIndex, hudMatProvince);
                        // Add rest of regions?
                        if (_highlightAllProvinceRegions)
                        {
                            Province province = provinces[provinceIndex];
                            for (int r = 0; r < province.regions.Count; r++)
                            {
                                if (r != regionIndex)
                                {
                                    Region otherRegion = province.regions[r];
                                    // Triangulate to get the polygon vertex indices
                                    Poly2Tri.Polygon poly = new Poly2Tri.Polygon(otherRegion.points);
                                    P2T.Triangulate(poly);
                                    GameObject otherSurf = Drawing.CreateSurface(provinceRegionHighlightedObj.name, poly, hudMatProvince, otherRegion.rect2D, Misc.Vector2zero, Misc.Vector2zero, 0, disposalManager);

                                    otherSurf.transform.SetParent(provinceRegionHighlightedObj.transform, false);
                                    otherSurf.transform.localPosition = Misc.Vector3zero;
                                    otherSurf.transform.localRotation = Quaternion.Euler(Misc.Vector3zero);
                                    otherSurf.layer = gameObject.layer;
                                }
                            }
                        }
                    }
                }
                else
                {
                    provinceRegionHighlightedObj = null;
                }
            }

            _provinceHighlighted            = provinces[provinceIndex];
            _provinceHighlightedIndex       = provinceIndex;
            _provinceRegionHighlighted      = _provinceHighlighted.regions[regionIndex];
            _provinceRegionHighlightedIndex = regionIndex;
            return(provinceRegionHighlightedObj);
        }
コード例 #7
0
        bool DrawProvinces(List <Country> targetCountries, bool justComputeBorders)
        {
            // optimize required lines
            if (frontiersCacheHit == null)
            {
                frontiersCacheHit = new Dictionary <double, Region>(500000);
            }
            else
            {
                frontiersCacheHit.Clear();
            }
            int tcCount = targetCountries.Count;

            if (justComputeBorders)
            {
                provinceNeighboursComputed = true;
                // Compute borders but ignore mesh building
                for (int c = 0; c < tcCount; c++)
                {
                    Country targetCountry = targetCountries[c];
                    if (targetCountry.provinces == null || targetCountry.hidden || !targetCountry.showProvinces)
                    {
                        continue;
                    }
                    for (int p = 0; p < targetCountry.provinces.Length; p++)
                    {
                        Province province = targetCountry.provinces[p];
                        if (province.regions == null)   // read province data the first time we need it
                        {
                            ReadProvincePackedString(province);
                        }
                        int prCount = province.regions.Count;
                        for (int r = 0; r < prCount; r++)
                        {
                            Region region = province.regions[r];
                            region.entity      = province;
                            region.regionIndex = r;
                            region.neighbours.Clear();
                            int numPoints = region.points.Length - 1;
                            for (int i = 0; i < numPoints; i++)
                            {
                                Vector2 p0 = region.points[i];
                                Vector2 p1 = region.points[i + 1];
                                double  v  = (p0.x + p1.x) + MAP_PRECISION * (p0.y + p1.y);
                                Region  neighbour;
                                if (frontiersCacheHit.TryGetValue(v, out neighbour))
                                {
                                    if (neighbour != region)
                                    {
                                        if (!region.neighbours.Contains(neighbour))
                                        {
                                            region.neighbours.Add(neighbour);
                                            neighbour.neighbours.Add(region);
                                        }
                                    }
                                }
                                else
                                {
                                    frontiersCacheHit[v] = region;
                                }
                            }
                        }
                    }
                }
                return(true); // ignore mesh building
            }

            if (_showTiles && _currentZoomLevel > _tileLinesMaxZoomLevel)
            {
                return(false);
            }

            if (frontiersPoints == null)
            {
                frontiersPoints = new List <Vector2>(1000000);
            }
            else
            {
                frontiersPoints.Clear();
            }

            TestNeighbourSegment testFunction;

            if (_provincesCoastlines)
            {
                testFunction = TestProvinceNeighbourSegmentAny;
            }
            else
            {
                testFunction = TestProvinceNeighbourSegmentInland;
            }

            for (int c = 0; c < tcCount; c++)
            {
                Country targetCountry = targetCountries[c];
                if (targetCountry.provinces == null || targetCountry.hidden || !targetCountry.showProvinces)
                {
                    continue;
                }
                for (int p = 0; p < targetCountry.provinces.Length; p++)
                {
                    Province province = targetCountry.provinces[p];
                    if (province.regions == null)   // read province data the first time we need it
                    {
                        ReadProvincePackedString(province);
                    }
                    int prCount = province.regions.Count;
                    for (int r = 0; r < prCount; r++)
                    {
                        Region region = province.regions[r];
                        region.entity      = province;
                        region.regionIndex = r;
                        region.neighbours.Clear();
                        int numPoints = region.points.Length - 1;
                        for (int i = 0; i < numPoints; i++)
                        {
                            testFunction(region, i, i + 1);
                        }
                        // Close the polygon
                        testFunction(region, numPoints, 0);
                    }
                }
            }

            int meshGroups = (frontiersPoints.Count / 65000) + 1;
            int meshIndex  = -1;

            int[][]     provincesIndices = new int[meshGroups][];
            Vector3[][] provincesBorders = new Vector3[meshGroups][];
            int         fpCount          = frontiersPoints.Count;

            for (int k = 0; k < fpCount; k += 65000)
            {
                int max = Mathf.Min(fpCount - k, 65000);
                provincesBorders[++meshIndex] = new Vector3[max];
                provincesIndices[meshIndex]   = new int[max];
                for (int j = k; j < k + max; j++)
                {
                    provincesBorders[meshIndex][j - k].x = frontiersPoints[j].x;
                    provincesBorders[meshIndex][j - k].y = frontiersPoints[j].y;
                    provincesIndices[meshIndex][j - k]   = j - k;
                }
            }

            // Create province layer if needed
            if (provincesObj != null)
            {
                DestroyRecursive(provincesObj);
            }

            if (provincesBorders.Length > 0)
            {
                provincesObj = new GameObject("Provinces");
                if (disposalManager != null)
                {
                    disposalManager.MarkForDisposal(provincesObj); //provincesObj.hideFlags = HideFlags.DontSave;
                }
                provincesObj.transform.SetParent(transform, false);
                provincesObj.transform.localPosition = Misc.Vector3back * 0.002f;
                provincesObj.layer = gameObject.layer;

                for (int k = 0; k < provincesBorders.Length; k++)
                {
                    GameObject flayer = new GameObject("flayer");
                    if (disposalManager != null)
                    {
                        disposalManager.MarkForDisposal(flayer); // flayer.hideFlags = HideFlags.DontSave;
                    }
                    flayer.hideFlags |= HideFlags.HideInHierarchy;
                    flayer.transform.SetParent(provincesObj.transform, false);
                    flayer.transform.localPosition = Misc.Vector3zero;
                    flayer.transform.localRotation = Quaternion.Euler(Misc.Vector3zero);
                    flayer.layer = provincesObj.layer;

                    Mesh mesh = new Mesh();
                    mesh.vertices = provincesBorders[k];
                    mesh.SetIndices(provincesIndices[k], MeshTopology.Lines, 0);
                    mesh.RecalculateBounds();
                    if (disposalManager != null)
                    {
                        disposalManager.MarkForDisposal(mesh); // mesh.hideFlags = HideFlags.DontSave;
                    }
                    MeshFilter mf = flayer.AddComponent <MeshFilter>();
                    mf.sharedMesh = mesh;

                    MeshRenderer mr = flayer.AddComponent <MeshRenderer>();
                    mr.receiveShadows       = false;
                    mr.reflectionProbeUsage = UnityEngine.Rendering.ReflectionProbeUsage.Off;
                    mr.shadowCastingMode    = UnityEngine.Rendering.ShadowCastingMode.Off;
                    mr.sharedMaterial       = provincesMat;
                }
            }
            return(true);
        }
コード例 #8
0
        /// <summary>
        /// Unpacks province geodata information. Used by Map Editor.
        /// </summary>
        /// <param name="province">Province.</param>
        public void ReadProvincePackedString(IAdminEntity entity)
        {
            Province province = (Province)entity;

            if (province == null || province.packedRegions == null)
            {
                return;
            }
            string[] regions     = province.packedRegions.Split(SPLIT_SEP_ASTERISK, StringSplitOptions.RemoveEmptyEntries);
            int      regionCount = regions.Length;

            province.regions = new List <Region>(regionCount);
            float   maxVol      = float.MinValue;
            Vector2 minProvince = Misc.Vector2one * 10;
            Vector2 maxProvince = -minProvince;

            for (int r = 0; r < regionCount; r++)
            {
                string[] coordinates    = regions[r].Split(SPLIT_SEP_SEMICOLON, StringSplitOptions.RemoveEmptyEntries);
                int      coorCount      = coordinates.Length;
                Vector2  min            = Misc.Vector2one * 10;
                Vector2  max            = -min;
                Region   provinceRegion = new Region(province, province.regions.Count);
                provinceRegion.points = new Vector2[coorCount];
                for (int c = 0; c < coorCount; c++)
                {
                    float x, y;
                    GetPointFromPackedString(ref coordinates[c], out x, out y);
                    if (x < min.x)
                    {
                        min.x = x;
                    }
                    if (x > max.x)
                    {
                        max.x = x;
                    }
                    if (y < min.y)
                    {
                        min.y = y;
                    }
                    if (y > max.y)
                    {
                        max.y = y;
                    }
                    provinceRegion.points[c].x = x;
                    provinceRegion.points[c].y = y;
                }
                FastVector.Average(ref min, ref max, ref provinceRegion.center);
                provinceRegion.sanitized = true;
                province.regions.Add(provinceRegion);

                // Calculate province bounding rect
                if (min.x < minProvince.x)
                {
                    minProvince.x = min.x;
                }
                if (min.y < minProvince.y)
                {
                    minProvince.y = min.y;
                }
                if (max.x > maxProvince.x)
                {
                    maxProvince.x = max.x;
                }
                if (max.y > maxProvince.y)
                {
                    maxProvince.y = max.y;
                }
                provinceRegion.rect2D     = new Rect(min.x, min.y, max.x - min.x, max.y - min.y);
                provinceRegion.rect2DArea = provinceRegion.rect2D.width * provinceRegion.rect2D.height;
                float vol = FastVector.SqrDistance(ref min, ref max); // (max - min).sqrMagnitude;
                if (vol > maxVol)
                {
                    maxVol = vol;
                    province.mainRegionIndex = r;
                    province.center          = provinceRegion.center;
                }
            }
            province.regionsRect2D = new Rect(minProvince.x, minProvince.y, Math.Abs(maxProvince.x - minProvince.x), Mathf.Abs(maxProvince.y - minProvince.y));
        }
コード例 #9
0
        /// <summary>
        /// Removes a province
        /// </summary>
        /// <param name="provinceIndex">Province index.</param>
        public bool ProvinceDelete(int provinceIndex)
        {
            if (provinceIndex < 0 || provinceIndex >= provinces.Length)
            {
                return(false);
            }

            // Clears references from mount points
            if (mountPoints != null)
            {
                int mountPointsCount = mountPoints.Count;
                for (int k = 0; k < mountPointsCount; k++)
                {
                    if (mountPoints[k].provinceIndex == provinceIndex)
                    {
                        mountPoints[k].provinceIndex = -1;
                    }
                }
            }

            List <Province> newProvinces = new List <Province>(_provinces.Length);
            // Clears references from cities
            int countryIndex = _provinces[provinceIndex].countryIndex;

            if (countryIndex >= 0 && countryIndex < _countries.Length)
            {
                string provinceName = _provinces[provinceIndex].name;
                if (cities != null)
                {
                    int citiesCount = _cities.Length;
                    for (int k = 0; k < citiesCount; k++)
                    {
                        if (_cities[k].countryIndex == countryIndex && _cities[k].province.Equals(provinceName))
                        {
                            _cities[k].province = "";
                        }
                    }
                }

                // Remove it from the country array
                Country country = _countries[countryIndex];
                if (country.provinces != null)
                {
                    for (int k = 0; k < country.provinces.Length; k++)
                    {
                        Province prov = country.provinces[k];
                        if (prov.regions.Count > 0 && !prov.name.Equals(provinceName))
                        {
                            newProvinces.Add(country.provinces[k]);
                        }
                    }
                    newProvinces.Sort(ProvinceSizeComparer);
                    country.provinces = newProvinces.ToArray();
                }
            }

            // Remove from the global array
            newProvinces.Clear();
            for (int k = 0; k < _provinces.Length; k++)
            {
                if (k != provinceIndex)
                {
                    newProvinces.Add(_provinces[k]);
                }
            }
            provinces = newProvinces.ToArray();

            return(true);
        }
コード例 #10
0
        /// <summary>
        /// Generate and replace provinces, city and country data
        /// </summary>
        public void GenerateMap()
        {
            try {
                UnityEngine.Random.InitState(seed);
                GenerateHeightMap();
                CreateMapProvinces();
                AssignHeightMapToProvinces(true);
                CreateMapCountries();
                CreateMapCities();

                UnityEngine.Random.InitState(seedNames);
                // Replace countries
                int            mapCountriesCount = mapCountries.Count;
                List <Country> newCountries      = new List <Country> (mapCountriesCount);
                for (int k = 0; k < mapCountriesCount; k++)
                {
                    MapCountry c      = mapCountries [k];
                    Vector2[]  points = c.region.points;
                    if (points == null || points.Length < 3)
                    {
                        continue;
                    }
                    string  name       = GetUniqueRandomName(0, 4, usedNames);
                    Country newCountry = new Country(name, "World", k);
                    Region  region     = new Region(newCountry, newCountry.regions.Count);
                    newCountry.regions.Add(region);
                    region.UpdatePointsAndRect(points);
                    map.RefreshCountryGeometry(newCountry);
                    newCountries.Add(newCountry);
                }
                map.countries  = newCountries.ToArray();
                countryChanges = true;

                // Replace provinces
                usedNames.Clear();
                int             mapProvincesCount = mapProvinces.Count;
                List <Province> newProvinces      = new List <Province> (mapProvincesCount);
                Province[]      provinces         = _map.provinces;
                if (provinces == null)
                {
                    provinces = new Province[0];
                }
                for (int k = 0; k < mapProvincesCount; k++)
                {
                    MapProvince c = mapProvinces [k];
                    if (!c.visible)
                    {
                        continue;
                    }
                    Vector2[] points = c.region.points;
                    if (points == null || points.Length < 3)
                    {
                        continue;
                    }
                    int countryIndex = map.GetCountryIndex(c.center);
                    if (countryIndex < 0)
                    {
                        continue;
                    }

                    string   name        = GetUniqueRandomName(0, 4, usedNames);
                    Province newProvince = new Province(name, countryIndex, k);
                    newProvince.regions = new List <Region> ();
                    Region region = new Region(newProvince, newProvince.regions.Count);
                    newProvince.attrib ["mapColor"] = c.color;
                    newProvince.regions.Add(region);
                    region.UpdatePointsAndRect(points);
                    map.RefreshProvinceGeometry(newProvince);
                    newProvinces.Add(newProvince);

                    Country         country          = map.countries [countryIndex];
                    List <Province> countryProvinces = country.provinces != null ? new List <Province> (country.provinces) : new List <Province> ();
                    countryProvinces.Add(newProvince);
                    country.provinces = countryProvinces.ToArray();
                }
                map.provinces   = newProvinces.ToArray();
                provinceChanges = true;

                // Replace cities
                usedNames.Clear();
                int         mapCitiesCount = mapCities.Count;
                List <City> newCities      = new List <City> (mapCitiesCount);
                string      provinceName   = "";
                for (int k = 0; k < mapCitiesCount; k++)
                {
                    MapCity  c = mapCities [k];
                    City     newCity;
                    Province prov = map.GetProvince(c.unity2DLocation);
                    if (prov == null)
                    {
                        continue;
                    }
                    provinceName = prov != null ? prov.name : "";
                    string name = GetUniqueRandomName(0, 4, usedNames);
                    newCity = new City(name, provinceName, prov.countryIndex, c.population, c.unity2DLocation, c.cityClass, k);
                    newCities.Add(newCity);
                }
                map.cities  = newCities;
                cityChanges = true;

                // Generate textures
                GenerateWorldTexture();

                // Apply some complementary style
                if (changeStyle && heightGradientPreset != HeightMapGradientPreset.Custom)
                {
                    map.frontiersColor           = Color.black;
                    map.frontiersColorOuter      = Color.black;
                    map.provincesColor           = Color.gray;
                    map.countryLabelsColor       = Color.white;
                    map.countryLabelsShadowColor = new Color(0.1f, 0.1f, 0.1f, 0.25f);
                }
                if (_map.earthStyle.isScenicPlus())
                {
                    _map.earthStyle = EARTH_STYLE.Natural;
                }

                // Save map data
                SaveGeneratedMapData();

                map.showFrontiers    = true;
                map.showCountryNames = true;
                map.waterLevel       = seaLevel;
                map.Redraw(true);
            } catch (Exception ex) {
                                #if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    Debug.LogError("Error generating map: " + ex.ToString());
                    EditorUtility.DisplayDialog("Error Generating Map", "An error occured while generating map. Try choosing another 'Seed' value, reducing 'Border Curvature' amount or number of provinces.", "Ok");
                }
                                #endif
            }
        }
コード例 #11
0
        /// <summary>
        /// Creates a new province with the given region
        /// </summary>
        public void ProvinceCreate(Region region)
        {
            if (region == null)
            {
                return;
            }

            // Remove region from source entity
            IAdminEntity entity = region.entity;

            if (entity != null)
            {
                entity.regions.Remove(region);
                Country country;
                // Refresh entity definition
                if (region.entity is Country)
                {
                    int countryIndex = _map.GetCountryIndex((Country)region.entity);
                    country = _map.countries [countryIndex];
                    _map.RefreshCountryGeometry(country);
                }
                else
                {
                    int provinceIndex = map.GetProvinceIndex((Province)region.entity);
                    country = _map.countries [_map.provinces [provinceIndex].countryIndex];
                    _map.RefreshProvinceGeometry(provinceIndex);
                }
            }

            provinceIndex       = map.provinces.Length;
            provinceRegionIndex = 0;
            string   newProvinceName = GetProvinceUniqueName("New Province");
            Province newProvince     = new Province(newProvinceName, countryIndex, map.GetUniqueId(new List <IExtendableAttribute> (map.provinces)));
            Region   newRegion       = new Region(newProvince, 0);

            newRegion.UpdatePointsAndRect(region.points);
            newProvince.regions = new List <Region> ();
            newProvince.regions.Add(newRegion);
            map.ProvinceAdd(newProvince);
            map.RefreshProvinceDefinition(provinceIndex, false);

            // Update cities
            List <City> cities      = _map.GetCities(region);
            int         citiesCount = cities.Count;

            if (citiesCount > 0)
            {
                for (int k = 0; k < citiesCount; k++)
                {
                    if (cities [k].province != newProvinceName)
                    {
                        cities [k].province = newProvinceName;
                        cityChanges         = true;
                    }
                }
            }

            lastProvinceCount = -1;
            GUIProvinceName   = newProvince.name;
            SyncGUIProvinceSelection();
            ProvinceRegionSelect();
            provinceChanges = true;
        }
コード例 #12
0
        /// <summary>
        /// Draws the province labels for a given country. Note that it will update cached textmesh objects if labels are already drawn. Used internally.
        /// </summary>
        void DrawProvinceLabelsInt(Country country)
        {
            if (!Application.isPlaying || !_showProvinceNames || !gameObject.activeInHierarchy || country == null || country.hidden || provinces == null || country.provinces == null)
            {
                return;
            }

            countryProvincesLabelsShown = country;

            // Set colors
            provLabelsFont.material.color  = _provinceLabelsColor;
            provLabelsShadowMaterial.color = _provinceLabelsShadowColor;

            // Create texts
            GameObject overlay = GetOverlayLayer(true);
            Transform  t       = overlay.transform.Find(OVERLAY_TEXT_PROVINCE_ROOT);

            if (t == null)
            {
                textProvinceRoot = new GameObject(OVERLAY_TEXT_PROVINCE_ROOT);
                if (disposalManager != null)
                {
                    disposalManager.MarkForDisposal(textProvinceRoot);                                        // textProvinceRoot.hideFlags = HideFlags.DontSave;
                }
                textProvinceRoot.layer = overlay.layer;
            }
            else
            {
                textProvinceRoot = t.gameObject;
            }

            if (meshRects == null)
            {
                meshRects = new List <MeshRect> (country.provinces.Length);
            }
            else
            {
                meshRects.Clear();
            }
            float mw = mapWidth;
            float mh = mapHeight;

            for (int p = 0; p < country.provinces.Length; p++)
            {
                Province province = country.provinces[p];
                if (province.regions == null)
                {
                    ReadProvincePackedString(province);
                }
                if (province == null || province.hidden || !province.labelVisible || province.regions == null || province.mainRegionIndex < 0 || province.mainRegionIndex >= province.regions.Count)
                {
                    continue;
                }

                if (_provinceLabelsVisibility == PROVINCE_LABELS_VISIBILITY.Automatic && !_showAllCountryProvinceNames && province != _provinceHighlighted)
                {
                    continue;
                }

                Vector2 center = new Vector2(province.center.x * mapWidth, province.center.y * mh) + province.labelOffset;
                Region  region = province.regions[province.mainRegionIndex];

                // Adjusts province name length
                string provinceName             = province.customLabel != null ? province.customLabel : province.name.ToUpper();
                bool   introducedCarriageReturn = false;
                if (provinceName.Length > 15)
                {
                    int spaceIndex = provinceName.IndexOf(' ', provinceName.Length / 2);
                    if (spaceIndex >= 0)
                    {
                        provinceName             = provinceName.Substring(0, spaceIndex) + "\n" + provinceName.Substring(spaceIndex + 1);
                        introducedCarriageReturn = true;
                    }
                }

                // add caption
                GameObject textObj;
                TextMesh   tm;
                Renderer   tmRenderer;
                TextMesh   tmShadow = null;
                if (province.labelTextMeshGO == null)
                {
                    Color    labelColor = province.labelColorOverride ? province.labelColor : _provinceLabelsColor;
                    Font     customFont = province.labelFontOverride ?? provLabelsFont;
                    Material customLabelShadowMaterial = province.labelFontShadowMaterial ?? provLabelsShadowMaterial;
                    tm      = Drawing.CreateText(provinceName, null, center, customFont, labelColor, _showProvinceLabelsShadow, customLabelShadowMaterial, _provinceLabelsShadowColor, out tmShadow);
                    textObj = tm.gameObject;
                    province.labelTextMesh   = tm;
                    province.labelTextMeshGO = tm.gameObject;
                    tmRenderer = textObj.GetComponent <Renderer>();
                    Bounds bounds = tmRenderer.bounds;
                    province.labelMeshWidth  = bounds.size.x;
                    province.labelMeshHeight = bounds.size.y;
                    province.labelMeshCenter = center;
                    textObj.transform.SetParent(textProvinceRoot.transform, false);
                    textObj.transform.localPosition = center;
                    textObj.layer = textProvinceRoot.gameObject.layer;
                    if (_showProvinceLabelsShadow)
                    {
                        province.labelShadowTextMesh = tmShadow;
                        province.labelShadowTextMesh.gameObject.layer = textObj.layer;
                    }
                }
                else
                {
                    tm      = province.labelTextMesh;
                    textObj = tm.gameObject;
                    textObj.transform.localPosition = center;
                    tmRenderer = textObj.GetComponent <Renderer>();
                }

                float meshWidth  = province.labelMeshWidth;
                float meshHeight = province.labelMeshHeight;

                // adjusts caption
                Rect  rect = new Rect(region.rect2D.xMin * mw, region.rect2D.yMin * mh, region.rect2D.width * mw, region.rect2D.height * mh);
                float absoluteHeight;
                if (province.labelRotation > 0)
                {
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, province.labelRotation);
                    absoluteHeight = Mathf.Min(rect.height * _provinceLabelsSize, rect.width);
                }
                else if (rect.height > rect.width * 1.45f)
                {
                    float angle;
                    if (rect.height > rect.width * 1.5f)
                    {
                        angle = 90;
                    }
                    else
                    {
                        angle = Mathf.Atan2(rect.height, rect.width) * Mathf.Rad2Deg;
                    }
                    textObj.transform.localRotation = Quaternion.Euler(0, 0, angle);
                    absoluteHeight = Mathf.Min(rect.width * _provinceLabelsSize, rect.height);
                }
                else
                {
                    absoluteHeight = Mathf.Min(rect.height * _provinceLabelsSize, rect.width);
                }

                // adjusts scale to fit width in rect
                float adjustedMeshHeight = introducedCarriageReturn ? meshHeight * 0.5f : meshHeight;
                float scale = absoluteHeight / adjustedMeshHeight;
                if (province.labelFontSizeOverride)
                {
                    scale = province.labelFontSize;
                }
                else
                {
                    float desiredWidth = meshWidth * scale;
                    if (desiredWidth > rect.width)
                    {
                        scale = rect.width / meshWidth;
                    }
                    if (adjustedMeshHeight * scale < _provinceLabelsAbsoluteMinimumSize)
                    {
                        scale = _provinceLabelsAbsoluteMinimumSize / adjustedMeshHeight;
                    }
                }

                // stretchs out the caption
                float  displayedMeshWidth  = meshWidth * scale;
                float  displayedMeshHeight = meshHeight * scale;
                string wideName;
                int    times = Mathf.FloorToInt(rect.width * 0.45f / (meshWidth * scale));
                if (times > 10)
                {
                    times = 10;
                }
                if (times > 0)
                {
                    StringBuilder sb     = new StringBuilder();
                    string        spaces = new string(' ', times * 2);
                    for (int c = 0; c < provinceName.Length; c++)
                    {
                        sb.Append(provinceName[c]);
                        if (c < provinceName.Length - 1)
                        {
                            sb.Append(spaces);
                        }
                    }
                    wideName = sb.ToString();
                }
                else
                {
                    wideName = provinceName;
                }

                if (tm.text.Length != wideName.Length)
                {
                    tm.text             = wideName;
                    displayedMeshWidth  = tmRenderer.bounds.size.x * scale;
                    displayedMeshHeight = tmRenderer.bounds.size.y * scale;
                    if (_showProvinceLabelsShadow)
                    {
                        tmShadow.text = wideName;
                    }
                }

                // apply scale
                textObj.transform.localScale = new Vector3(scale, scale, 1);

                // Save mesh rect for overlapping checking
                if (province.labelOffset == Misc.Vector2zero)
                {
                    int      provinceIndex = GetProvinceIndex(province);
                    float    xMin          = center.x - displayedMeshWidth * 0.5f;
                    float    yMin          = center.y - displayedMeshHeight * 0.5f;
                    float    xMax          = xMin + displayedMeshWidth;
                    float    yMax          = yMin + displayedMeshHeight;
                    MeshRect mr            = new MeshRect(provinceIndex, new Vector4(xMin, yMin, xMax, yMax));
//					MeshRect mr = new MeshRect(provinceIndex, new Rect(center.x - displayedMeshWidth * 0.5f, center.y - displayedMeshHeight * 0.5f, displayedMeshWidth, displayedMeshHeight));
                    meshRects.Add(mr);
                }
            }

            // Simple-fast overlapping checking
            int  cont        = 0;
            bool needsResort = true;

            int meshRectsCount = meshRects.Count;

            while (needsResort && ++cont < 10)
            {
                meshRects.Sort(overlapComparer);

                for (int c = 1; c < meshRectsCount; c++)
                {
                    Vector4 r1 = meshRects[c].rect;
                    for (int prevc = c - 1; prevc >= 0; prevc--)
                    {
                        Vector4 r2       = meshRects[prevc].rect;
                        bool    overlaps = !(r2.x > r1.z || r2.z <r1.x || r2.y> r1.w || r2.w < r1.y);
                        if (overlaps)
                        {
                            needsResort = true;
                            int        thisProvinceIndex = meshRects[c].entityIndex;
                            Province   province          = _provinces[thisProvinceIndex];
                            GameObject thisLabel         = province.labelTextMeshGO;

                            // displaces this label
                            float offsety = r1.w - r2.y;
                            offsety = Mathf.Min(province.regions[province.mainRegionIndex].rect2D.height * mh * 0.35f, offsety);
                            thisLabel.transform.localPosition = new Vector3(province.labelMeshCenter.x, province.labelMeshCenter.y - offsety, thisLabel.transform.localPosition.z);
//							r1 = new Rect(thisLabel.transform.localPosition.x - r1.width * 0.5f,
//								thisLabel.transform.localPosition.y - r1.height * 0.5f,
//								r1.width, r1.height);
//							meshRects[c].rect = r1;
                            float width  = r1.z - r1.x;
                            float height = r1.w - r1.y;
                            float xMin   = thisLabel.transform.localPosition.x - width * 0.5f;
                            float yMin   = thisLabel.transform.localPosition.y - height * 0.5f;
                            float xMax   = xMin + width;
                            float yMax   = yMin + height;
                            r1 = new Vector4(xMin, yMin, xMax, yMax);
                            meshRects [c].rect = r1;
                        }
                    }
                }
            }

            // Adjusts parent
            textProvinceRoot.transform.SetParent(overlay.transform, false);
            textProvinceRoot.transform.localPosition = new Vector3(0, 0, -0.001f);
            textProvinceRoot.transform.localRotation = Misc.QuaternionZero;
            textProvinceRoot.transform.localScale    = new Vector3(1.0f / mw, 1.0f / mh, 1);

            // Adjusts alpha based on distance to camera
            if (Application.isPlaying)
            {
                FadeProvinceLabels();
            }
        }
コード例 #13
0
        void FadeProvinceLabels()
        {
            if (countryProvincesLabelsShown == null || countryProvincesLabelsShown.provinces == null)
            {
                return;
            }

            // Automatically fades in/out province labels based on their screen size

            float y0 = _currentCamera.WorldToViewportPoint(transform.TransformPoint(0, 0, 0)).y;
            float y1 = _currentCamera.WorldToViewportPoint(transform.TransformPoint(0, 1.0f, 0)).y;
            float th = y1 - y0;

            float maxAlpha            = _provinceLabelsColor.a;
            float maxAlphaShadow      = _provinceLabelsShadowColor.a;
            float labelFadeMinSize    = 0.018f;
            float labelFadeMaxSize    = 0.2f;
            float labelFadeMinFallOff = 0.005f;
            float labelFadeMaxFallOff = 0.5f;

            float mh = mapHeight;

            for (int k = 0; k < countryProvincesLabelsShown.provinces.Length; k++)
            {
                Province province = countryProvincesLabelsShown.provinces[k];
                TextMesh tm       = province.labelTextMesh;
                if (tm != null)
                {
                    // Fade label
                    float labelSize    = (province.labelMeshHeight + province.labelMeshWidth) * 0.5f;
                    float screenHeight = labelSize * tm.transform.localScale.y * th / mh;
                    float ad;
                    if (screenHeight < labelFadeMinSize)
                    {
                        ad = Mathf.Lerp(1.0f, 0, (labelFadeMinSize - screenHeight) / labelFadeMinFallOff);
                    }
                    else if (screenHeight > labelFadeMaxSize)
                    {
                        ad = Mathf.Lerp(1.0f, 0, (screenHeight - labelFadeMaxSize) / labelFadeMaxFallOff);
                    }
                    else
                    {
                        ad = 1.0f;
                    }
                    float newAlpha = ad * maxAlpha;
                    if (tm.color.a != newAlpha)
                    {
                        tm.color = new Color(tm.color.r, tm.color.g, tm.color.b, newAlpha);
                    }
                    // Fade label shadow
                    TextMesh tmShadow = province.labelShadowTextMesh;
                    if (tmShadow != null)
                    {
                        newAlpha = ad * maxAlphaShadow;
                        if (tmShadow.color.a != newAlpha)
                        {
                            tmShadow.color = new Color(tmShadow.color.r, tmShadow.color.g, tmShadow.color.b, maxAlphaShadow * ad);
                        }
                    }
                }
            }
        }
コード例 #14
0
        /// <summary>
        /// Creates a new country based on a given region. Existing region is removed from its source entity.
        /// </summary>
        /// <param name="region">Region.</param>
        public void CountryCreate(Region region)
        {
            // Remove region from source entity
            IAdminEntity entity = region.entity;

            entity.regions.Remove(region);
            Country country;

            // Refresh entity definition
            if (region.entity is Country)
            {
                int countryIndex = _map.GetCountryIndex((Country)region.entity);
                country = _map.countries[countryIndex];
                _map.RefreshCountryGeometry(country);
            }
            else
            {
                int provinceIndex = map.GetProvinceIndex((Province)region.entity);
                country = _map.countries[_map.provinces[provinceIndex].countryIndex];
                _map.RefreshProvinceGeometry(provinceIndex);
            }

            // Create the new country
            string  uniqueName = GetCountryUniqueName(country.name);
            Country newCountry = new Country(uniqueName, country.continent, map.GetUniqueId(new List <IExtendableAttribute>(map.countries)));

            if (entity is Country)
            {
                newCountry.regions.Add(region);
            }
            else
            {
                Region newRegion = new Region(newCountry, 0);
                newRegion.UpdatePointsAndRect(region.points);
                newCountry.regions.Add(newRegion);
            }
            countryIndex       = map.CountryAdd(newCountry);
            countryRegionIndex = 0;
            lastCountryCount   = -1;
            GUICountryName     = "";
            ReloadCountryNames();
            countryChanges = true;

            // Update cities
            List <City> cities = _map.GetCities(region);

            if (cities.Count > 0)
            {
                for (int k = 0; k < cities.Count; k++)
                {
                    if (cities [k].countryIndex != countryIndex)
                    {
                        cities [k].countryIndex = countryIndex;
                        cityChanges             = true;
                    }
                }
            }

            // Update mount points
            List <MountPoint> mp = _map.GetMountPoints(region);

            if (mp.Count > 0)
            {
                for (int k = 0; k < mp.Count; k++)
                {
                    if (mp [k].countryIndex != countryIndex)
                    {
                        mp [k].countryIndex = countryIndex;
                        mountPointChanges   = true;
                    }
                }
            }

            // Transfer any contained province
            if (entity is Country)
            {
                List <Province> provinces = _map.GetProvinces(region);
                for (int k = 0; k < provinces.Count; k++)
                {
                    Province prov = provinces[k];
                    if (prov.regions == null)
                    {
                        _map.ReadProvincePackedString(prov);
                    }
                    if (prov.regions == null)
                    {
                        continue;
                    }
                    if (_map.CountryTransferProvinceRegion(countryIndex, prov.mainRegion, false))
                    {
                        provinceChanges = true;
                    }
                }
            }

            map.Redraw();
            CountryRegionSelect();
        }
コード例 #15
0
        /// <summary>
        /// Exports the geographic data in packed string format with reduced quality.
        /// </summary>
        public string GetCountryGeoDataLowQuality()
        {
            // step 1: duplicate data
            IAdminEntity[] entities;
            if (editingMode == EDITING_MODE.COUNTRIES)
            {
                entities = map.countries;
            }
            else
            {
                entities = map.provinces;
            }
            List <IAdminEntity> entities1 = new List <IAdminEntity>(entities);

            for (int k = 0; k < entities1.Count; k++)
            {
                entities1[k].regions = new List <Region>(entities1[k].regions);
                for (int r = 0; r < entities[k].regions.Count; r++)
                {
                    entities1[k].regions[r].points = new List <Vector2>(entities1[k].regions[r].points).ToArray();
                }
            }
            // step 2: ensure near points between neighbours
            float MAX_DIST = 0.00000001f;

            //			int join = 0;
            for (int k = 0; k < entities1.Count; k++)
            {
                for (int r = 0; r < entities1[k].regions.Count; r++)
                {
                    Region region1 = entities1[k].regions[r];
                    for (int p = 0; p < entities1[k].regions[r].points.Length; p++)
                    {
                        // Search near points
                        for (int k2 = 0; k2 < region1.neighbours.Count; k2++)
                        {
                            for (int r2 = 0; r2 < entities1[k2].regions.Count; r2++)
                            {
                                Region region2 = entities1[k2].regions[r2];
                                for (int p2 = 0; p2 < entities1[k2].regions[r2].points.Length; p2++)
                                {
                                    float dist = (region1.points[p].x - region2.points[p2].x) * (region1.points[p].x - region2.points[p2].x) +
                                                 (region1.points[p].y - region2.points[p2].y) * (region1.points[p].y - region2.points[p2].y);
                                    if (dist < MAX_DIST)
                                    {
                                        region2.points[p2] = region1.points[p];
                                        //										join++;
                                    }
                                }
                            }
                        }
                    }
                }
            }

            // step 2: simplify
            Dictionary <Vector2, bool> frontiersHit = new Dictionary <Vector2, bool>();
            List <IAdminEntity>        entities2 = new List <IAdminEntity>(entities1.Count);
            int   savings = 0, totalPoints = 0;
            float FACTOR = 1000f;

            for (int k = 0; k < entities1.Count; k++)
            {
                IAdminEntity refEntity = entities1[k];
                IAdminEntity newEntity;
                if (refEntity is Country)
                {
                    newEntity = new Country(refEntity.name, ((Country)refEntity).continent, map.GetUniqueId(new List <IExtendableAttribute>(map.countries)));
                }
                else
                {
                    newEntity = new Province(refEntity.name, ((Province)refEntity).countryIndex, map.GetUniqueId(new List <IExtendableAttribute>(map.provinces)));
                }
                for (int r = 0; r < refEntity.regions.Count; r++)
                {
                    Region region    = refEntity.regions[r];
                    int    numPoints = region.points.Length;
                    totalPoints += numPoints;
                    List <Vector2> points = new List <Vector2>(numPoints);
                    frontiersHit.Clear();

                    Vector3[] blockyPoints = new Vector3[numPoints];
                    for (int p = 0; p < numPoints; p++)
                    {
                        blockyPoints[p] = new Vector2(Mathf.RoundToInt(region.points[p].x * FACTOR) / FACTOR, Mathf.RoundToInt(region.points[p].y * FACTOR) / FACTOR);
                    }

                    points.Add(region.points[0] * WMSK.MAP_PRECISION);
                    for (int p = 1; p < numPoints - 1; p++)
                    {
                        if (blockyPoints[p - 1].y == blockyPoints[p].y && blockyPoints[p].y == blockyPoints[p + 1].y ||
                            blockyPoints[p - 1].x == blockyPoints[p].x && blockyPoints[p].x == blockyPoints[p + 1].x)
                        {
                            savings++;
                            continue;
                        }
                        if (!frontiersHit.ContainsKey(blockyPoints[p]))                           // add neighbour references
                        {
                            frontiersHit.Add(blockyPoints[p], true);
                            points.Add(region.points[p] * WMSK.MAP_PRECISION);
                        }
                        else
                        {
                            savings++;
                        }
                    }
                    points.Add(region.points[numPoints - 1] * WMSK.MAP_PRECISION);
                    if (points.Count >= 5)
                    {
                        Region newRegion = new Region(newEntity, newEntity.regions.Count);
                        newRegion.points = points.ToArray();
                        newEntity.regions.Add(newRegion);
                    }
                }
                if (newEntity.regions.Count > 0)
                {
                    entities2.Add(newEntity);
                }
            }

            Debug.Log(savings + " points removed of " + totalPoints + " (" + (((float)savings / totalPoints) * 100.0f).ToString("F1") + "%)");

            StringBuilder sb = new StringBuilder();

            for (int k = 0; k < entities2.Count; k++)
            {
                IAdminEntity entity = entities2[k];
                if (k > 0)
                {
                    sb.Append("|");
                }
                sb.Append(entity.name + "$");
                if (entity is Country)
                {
                    sb.Append(((Country)entity).continent + "$");
                }
                else
                {
                    sb.Append(map.countries[((Province)entity).countryIndex].name + "$");
                }
                for (int r = 0; r < entity.regions.Count; r++)
                {
                    if (r > 0)
                    {
                        sb.Append("*");
                    }
                    Region region = entity.regions[r];
                    for (int p = 0; p < region.points.Length; p++)
                    {
                        if (p > 0)
                        {
                            sb.Append(";");
                        }
                        Vector2 point = region.points[p];
                        sb.Append(point.x.ToString() + ",");
                        sb.Append(point.y.ToString());
                    }
                }
            }
            return(sb.ToString());
        }
コード例 #16
0
        /// <summary>
        /// Merges all provinces in each country so their number fits a given range
        /// </summary>
        /// <param name="min">Minimum number of provinces.</param>
        /// <param name="max">Maximum number of provinces.</param>
        public void ProvincesEqualize(int min, int max, int countryIndex)
        {
            if (min < 1 || countryIndex < 0 || countryIndex >= map.countries.Length)
            {
                return;
            }
            if (max < min)
            {
                max = min;
            }

            map.showProvinces    = true;
            map.drawAllProvinces = true;

            Country country = map.countries [countryIndex];

            if (country == null || country.provinces == null)
            {
                return;
            }
            int   targetProvCount = UnityEngine.Random.Range(min, max);
            int   provCount       = country.provinces.Length;
            float provStartSize   = 0;

            while (provCount > targetProvCount)
            {
                // Take the smaller province and merges with a neighbour
                float minAreaSize   = float.MaxValue;
                int   provinceIndex = -1;
                for (int p = 0; p < provCount; p++)
                {
                    Province prov = country.provinces [p];
                    if (prov == null)
                    {
                        continue;
                    }
                    if (prov.regions == null)
                    {
                        map.ReadProvincePackedString(prov);
                    }
                    if (prov.regions == null || prov.regions.Count == 0 || prov.mainRegion.neighbours == null || prov.mainRegion.neighbours.Count == 0)
                    {
                        continue;
                    }
                    if (prov.regionsRect2DArea < minAreaSize && prov.regionsRect2DArea > provStartSize)
                    {
                        minAreaSize   = prov.regionsRect2DArea;
                        provinceIndex = map.GetProvinceIndex(prov);
                    }
                }

                if (provinceIndex < 0)
                {
                    break;
                }

                provStartSize = minAreaSize;

                // Get the smaller neighbour
                int      neighbourIndex = -1;
                Province province       = map.provinces [provinceIndex];
                int      neighbourCount = province.mainRegion.neighbours.Count;
                minAreaSize = float.MaxValue;
                for (int n = 0; n < neighbourCount; n++)
                {
                    Region   neighbour         = province.mainRegion.neighbours [n];
                    Province neighbourProvince = (Province)neighbour.entity;
                    if (neighbourProvince != null && neighbourProvince != province && neighbourProvince.countryIndex == countryIndex && neighbour.rect2DArea < minAreaSize)
                    {
                        int neighbourProvIndex = map.GetProvinceIndex(neighbourProvince);
                        if (neighbourProvIndex >= 0)
                        {
                            minAreaSize    = neighbour.rect2DArea;
                            neighbourIndex = neighbourProvIndex;
                        }
                    }
                }
                if (neighbourIndex < 0)
                {
                    continue;
                }

                // Merges province into neighbour
                string provinceSource = map.provinces [provinceIndex].name;
                string provinceTarget = map.provinces [neighbourIndex].name;
                int    prevProvCount  = country.provinces.Length;
                if (!map.ProvinceTransferProvinceRegion(neighbourIndex, map.provinces [provinceIndex].mainRegion, false))
                {
                    Debug.LogWarning("Country: " + map.countries [countryIndex].name + " => " + provinceSource + " failed merge into " + provinceTarget + ".");
                    break;
                }
                provCount = country.provinces.Length;
                if (provCount == prevProvCount)
                {
                    break;                     // can't merge more provinces
                }
            }

            provinceChanges   = true;
            cityChanges       = true;
            mountPointChanges = true;
        }
コード例 #17
0
        void GenerateWorldTexture()
        {
            // Create background texture
            int backgroundTextureWidth  = mapGenerationQuality == MapGenerationQuality.Draft ? 256 : this.backgroundTextureWidth;
            int backgroundTextureHeight = mapGenerationQuality == MapGenerationQuality.Draft ? 128 : this.backgroundTextureHeight;

            if (backgroundTexture == null || backgroundTexture.width != backgroundTextureWidth || backgroundTexture.height != backgroundTextureHeight)
            {
                backgroundTexture = new Texture2D(backgroundTextureWidth, backgroundTextureHeight, TextureFormat.RGBA32, true);
            }
            int bufferLen = backgroundTextureWidth * backgroundTextureHeight;

            if (backgroundColors == null || backgroundColors.Length != bufferLen)
            {
                backgroundColors = new Color[bufferLen];
            }
            Color backColor = seaColor;

            backColor.a = 0;
            backgroundColors.Fill <Color> (backColor);

            int provincesCount = _map.provinces.Length;

            for (int k = 0; k < provincesCount; k++)
            {
                Province prov = _map.provinces [k];
                if (prov.regions == null)
                {
                    _map.ReadProvincePackedString(prov);
                    if (prov.regions == null)
                    {
                        continue;
                    }
                }
                Region region = prov.regions [0];
                if (gradientPerPixel)
                {
                    _map.RegionPaintHeights(backgroundColors, backgroundTextureWidth, backgroundTextureHeight, region, heights, seaLevel, currentHeightmapWidth, currentHeightmapHeight, heightGradient);
                }
                else
                {
                    Color provColor = prov.attrib ["mapColor"];
                    provColor.a = 1;
                    _map.RegionPaint(backgroundColors, backgroundTextureWidth, backgroundTextureHeight, region, provColor);
                }
            }

            backgroundTexture.SetPixels(backgroundColors);
            backgroundTexture.Apply();

            // Set height to 0 out of land areas
            if (heightMapTexture != null)
            {
                if (currentHeightmapWidth == backgroundTextureWidth && currentHeightmapHeight == backgroundTextureHeight)
                {
                    for (int k = 0; k < backgroundColors.Length; k++)
                    {
                        if (backgroundColors [k].a == 0)
                        {
                            heights [k]      = 0;
                            heightColors [k] = Misc.ColorClear;
                        }
                        else
                        {
                            heightColors [k].r = heightColors [k].g = heightColors [k].b = heightColors [k].a = heights [k];
                        }
                    }
                }
                else
                {
                    for (int k = 0, y = 0; y < currentHeightmapHeight; y++)
                    {
                        int backy  = y * backgroundTextureHeight / currentHeightmapHeight;
                        int backyy = backy * backgroundTextureWidth;
                        for (int x = 0; x < currentHeightmapWidth; x++, k++)
                        {
                            int backx = x * backgroundTextureWidth / currentHeightmapWidth;
                            if (backgroundColors [backyy + backx].a == 0)
                            {
                                heights [k]      = 0;
                                heightColors [k] = Misc.ColorClear;
                            }
                            else
                            {
                                heightColors [k].r = heightColors [k].g = heightColors [k].b = heightColors [k].a = heights [k];
                            }
                        }
                    }
                }
                heightMapTexture.SetPixels(heightColors);
                heightMapTexture.Apply();
            }
        }