/// <summary> /// Automatically generates territories based on the different colors included in the texture. /// </summary> /// <param name="neutral">This color won't generate any texture.</param> public void CreateTerritories(Texture2D texture, Color neutral) { if (texture == null || cells == null) { return; } List <Color> dsColors = new List <Color> (); int cellCount = cells.Count; Color[] colors = null; try { colors = texture.GetPixels(); } catch { Debug.Log("Texture used to create territories is not readable. Check import settings."); return; } for (int k = 0; k < cellCount; k++) { if (!cells [k].visible) { continue; } Vector2 uv = cells [k].center; uv.x += 0.5f; uv.y += 0.5f; int x = (int)(uv.x * texture.width); int y = (int)(uv.y * texture.height); int pos = y * texture.width + x; if (pos < 0 || pos > colors.Length) { continue; } Color pixelColor = colors [pos]; int territoryIndex = dsColors.IndexOf(pixelColor); if (territoryIndex < 0) { dsColors.Add(pixelColor); territoryIndex = dsColors.Count - 1; } CellSetTerritory(k, territoryIndex); if (territoryIndex >= MAX_TERRITORIES - 1) { break; } } if (dsColors.Count > 0) { _numTerritories = dsColors.Count; _showTerritories = true; if (territories == null) { territories = new List <Territory> (_numTerritories); } else { territories.Clear(); } for (int c = 0; c < _numTerritories; c++) { Territory territory = new Territory(c.ToString()); Color territoryColor = dsColors [c]; if (territoryColor.r != neutral.r || territoryColor.g != neutral.g || territoryColor.b != neutral.b) { territory.fillColor = territoryColor; } else { territory.fillColor = new Color(0, 0, 0, 0); territory.visible = false; } territories.Add(territory); } isDirty = true; issueRedraw = RedrawType.Full; Redraw(); } }
void CreateTerritories() { _numTerritories = Mathf.Clamp(_numTerritories, 1, MAX_CELLS); if (!_colorizeTerritories && !_showTerritories && _highlightMode != HIGHLIGHT_MODE.Territories) { if (territories!=null) territories.Clear(); if (territoryLayer!=null) DestroyImmediate(territoryLayer); return; } // Freedom for the cells!... CheckCells(); for (int k=0;k<cells.Count;k++) { cells[k].territoryIndex = -1; } UnityEngine.Random.seed = seed; // ... em, not. Start creating countries and assigning one cell if (territories==null) { territories = new List<Territory>(_numTerritories); } else { territories.Clear(); } for (int c=0;c<_numTerritories;c++) { Territory territory = new Territory(c.ToString()); territory.fillColor = factoryColors[c]; int territoryIndex = territories.Count; int p = UnityEngine.Random.Range (0, cells.Count); int z=0; while (cells[p].territoryIndex!=-1 && z++<=cells.Count) { p++; if (p>=cells.Count) p=0; } if (z>cells.Count) break; // no more territories can be found - this should not happen Cell prov = cells[p]; prov.territoryIndex = territoryIndex; territory.capitalCenter = prov.center; territory.cells.Add (prov); // territory.polygon = prov.polygon.Clone(); territories.Add (territory); } // Continue conquering cells // PolygonClipper[] pc = new PolygonClipper[_numTerritories]; int[] territoryCellIndex = new int[territories.Count]; // Iterate one cell per country (this is not efficient but ensures balanced distribution) bool remainingCells = true; while (remainingCells) { remainingCells = false; for (int k=0; k<territories.Count; k++) { Territory territory = territories [k]; for (int p=territoryCellIndex[k]; p<territory.cells.Count; p++) { Region cellRegion = territory.cells[p].region; for (int n=0; n<cellRegion.neighbours.Count; n++) { Region otherRegion = cellRegion.neighbours [n]; Cell otherProv = (Cell)otherRegion.entity; if (otherProv.territoryIndex == -1) { otherProv.territoryIndex = k; territory.cells.Add (otherProv); remainingCells = true; p = territory.cells.Count; break; } } if (p<territory.cells.Count) // no free neighbours left for this cell territoryCellIndex[k]++; } } } FindTerritoryFrontiers(); UpdateTerritoryBoundaries(); }
void HideTerritoryRegionHighlight() { HideCellRegionHighlight (); if (_territoryHighlighted == null) return; if (highlightedObj != null) { if (_territoryHighlighted != null && _territoryHighlighted.region.customMaterial != null) { ApplyMaterialToSurface (highlightedObj, _territoryHighlighted.region.customMaterial); if (!_colorizeTerritories) highlightedObj.SetActive (false); } else { highlightedObj.SetActive (false); } highlightedObj = null; } _territoryHighlighted = null; _territoryHighlightedIndex = -1; }
/// <summary> /// Highlights the territory 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 territory 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 HighlightTerritoryRegion(int territoryIndex, bool refreshGeometry) { if (highlightedObj!=null) HideTerritoryRegionHighlight(); if (territoryIndex<0 || territoryIndex>=territories.Count) return null; int cacheIndex = GetCacheIndexForTerritoryRegion (territoryIndex); bool existsInCache = surfaces.ContainsKey (cacheIndex); if (refreshGeometry && existsInCache) { GameObject obj = surfaces [cacheIndex]; surfaces.Remove(cacheIndex); DestroyImmediate(obj); existsInCache = false; } if (existsInCache) { highlightedObj = surfaces [cacheIndex]; if (highlightedObj==null) { surfaces.Remove(cacheIndex); } else { if (!highlightedObj.activeSelf) highlightedObj.SetActive (true); Renderer rr = highlightedObj.GetComponent<Renderer> (); if (rr.sharedMaterial!=hudMatTerritory) rr.sharedMaterial = hudMatTerritory; } } else { highlightedObj = GenerateTerritoryRegionSurface (territoryIndex, hudMatTerritory, Vector2.one, Vector2.zero, 0); } _territoryHighlightedIndex = territoryIndex; _territoryHighlighted = territories[territoryIndex]; return highlightedObj; }
/// <summary> /// Automatically generates territories based on the different colors included in the texture. /// </summary> /// <param name="neutral">This color won't generate any texture.</param> public void CreateTerritories(Texture2D texture, Color neutral, bool hideNeutralCells = false) { if (texture == null || cells == null) return; List<Color> dsColors = new List<Color>(); Dictionary<Color, int> dsColorDict = new Dictionary<Color, int>(); int cellCount = cells.Count; Color[] colors = null; try { colors = texture.GetPixels(); } catch { Debug.Log("Texture used to create territories is not readable. Check import settings."); return; } for (int k = 0; k < cellCount; k++) { if (!cells[k].visible) continue; Vector2 uv = cells[k].center; uv.x += 0.5f; uv.y += 0.5f; int x = (int)(uv.x * texture.width); int y = (int)(uv.y * texture.height); int pos = y * texture.width + x; if (pos < 0 || pos >= colors.Length) continue; Color pixelColor = colors[pos]; int territoryIndex; if (!dsColorDict.TryGetValue(pixelColor, out territoryIndex)) { dsColors.Add(pixelColor); territoryIndex = dsColors.Count - 1; dsColorDict[pixelColor] = territoryIndex; } cells[k].territoryIndex = territoryIndex; if (territoryIndex >= MAX_TERRITORIES - 1) break; } needUpdateTerritories = true; if (dsColors.Count > 0) { _numTerritories = dsColors.Count; _showTerritories = true; if (territories == null) { territories = new List<Territory>(_numTerritories); } else { territories.Clear(); } for (int c = 0; c < _numTerritories; c++) { Territory territory = new Territory(c.ToString()); Color territoryColor = dsColors[c]; if (territoryColor.r != neutral.r || territoryColor.g != neutral.g || territoryColor.b != neutral.b) { territory.fillColor = territoryColor; } else { territory.fillColor = new Color(0, 0, 0, 0); territory.visible = false; } // Add cells to territories for (int k = 0; k < cellCount; k++) { Cell cell = cells[k]; if (cell.territoryIndex == c) { territory.cells.Add(cell); territory.center += cell.center; } } if (territory.cells.Count > 0) { territory.center /= territory.cells.Count; // Ensure center belongs to territory Cell cellAtCenter = CellGetAtPosition(territory.center); if (cellAtCenter.territoryIndex != c) { territory.center = territory.cells[0].center; } } territories.Add(territory); } isDirty = true; issueRedraw = RedrawType.Full; Redraw(); } }