private static TerrainType[,] CreateNewBlankTerrain(Config_Map config) { if (config.BlankTerrain == null) { #if UNITY_EDITOR Debug.LogError($"At least 1 Blank Terrain Type needs to be added to any Map Config. Please add a Blank Terrain to {config.MapName}"); #endif return(null); } TerrainType[,] types = new TerrainType[config.GridSize, config.GridSize]; for (int i = 0; i < types.GetLength(0); i++) { for (int j = 0; j < types.GetLength(1); j++) { types[i, j] = new TerrainType(config.BlankTerrain); } } return(types); }
public static TerrainType[,] DeserializeTerrainTypes() { MapSave save = MAP_DATA.MAPSAVE; if (save.gpuData.Length == 0) { return(null); } var mapConfig = save.mapConfig; var terrainTypes = new TerrainType[mapConfig.GridSize, mapConfig.GridSize]; int count = 0; for (int i = 0; i < terrainTypes.GetLength(0); i++) { for (int j = 0; j < terrainTypes.GetLength(1); j++) { TerrainType type = new TerrainType(mapConfig.GetTerrainConfigByID((int)save.gpuData[count].x)); terrainTypes[j, i] = type; count++; } } return(terrainTypes); }
protected override void _GenerateStep(bool clearPrevious) { TerrainType[,] terrainTypes = new TerrainType[mapManager.mapConfiguration.mapRadius * 2 + 1, mapManager.mapConfiguration.mapRadius * 2 + 1]; for (int x = -mapManager.mapConfiguration.mapRadius; x <= mapManager.mapConfiguration.mapRadius; x++) { for (int y = -mapManager.mapConfiguration.mapRadius; y <= mapManager.mapConfiguration.mapRadius; y++) { Vector2Int arrayCoords = new Vector2Int(x + mapManager.mapConfiguration.mapRadius, y + mapManager.mapConfiguration.mapRadius); if (terrainTypes[arrayCoords.x, arrayCoords.y] != TerrainType.none) { continue; } if (!mapManager.IsLocationUnderWater(new Vector2(x, y))) { terrainTypes[arrayCoords.x, arrayCoords.y] = TerrainType.land; } else { if (arrayCoords.x == 0 || arrayCoords.y == 0 || arrayCoords.x == terrainTypes.GetLength(0) - 1 || arrayCoords.y == terrainTypes.GetLength(1) - 1) { terrainTypes[arrayCoords.x, arrayCoords.y] = TerrainType.sea; } } } } terrainTypes = PropagateSea(terrainTypes); // Only interior water sopts should be left for (int x = -mapManager.mapConfiguration.mapRadius; x <= mapManager.mapConfiguration.mapRadius; x++) { for (int y = -mapManager.mapConfiguration.mapRadius; y <= mapManager.mapConfiguration.mapRadius; y++) { Vector2Int arrayCoords = new Vector2Int(x + mapManager.mapConfiguration.mapRadius, y + mapManager.mapConfiguration.mapRadius); if (terrainTypes[arrayCoords.x, arrayCoords.y] != TerrainType.none) { continue; } terrainTypes[arrayCoords.x, arrayCoords.y] = TerrainType.interior; } } //Replace interior with shorelineInterior int avoidedEdge = 1; for (int x = -mapManager.mapConfiguration.mapRadius + avoidedEdge; x <= mapManager.mapConfiguration.mapRadius - avoidedEdge; x++) { for (int y = -mapManager.mapConfiguration.mapRadius + avoidedEdge; y <= mapManager.mapConfiguration.mapRadius - avoidedEdge; y++) { Vector2Int arrayCoords = new Vector2Int(x + mapManager.mapConfiguration.mapRadius, y + mapManager.mapConfiguration.mapRadius); if (terrainTypes[arrayCoords.x, arrayCoords.y] != TerrainType.interior) { continue; } try { TerrainType bottom = terrainTypes[arrayCoords.x - 1, arrayCoords.y]; TerrainType top = terrainTypes[arrayCoords.x + 1, arrayCoords.y]; TerrainType left = terrainTypes[arrayCoords.x, arrayCoords.y - 1]; TerrainType right = terrainTypes[arrayCoords.x, arrayCoords.y + 1]; bool isAnyNeighbourInterior = bottom == TerrainType.interior || top == TerrainType.interior || left == TerrainType.interior || right == TerrainType.interior; bool isAnyNeighbourLand = bottom == TerrainType.land || top == TerrainType.land || left == TerrainType.land || right == TerrainType.land; //bool isOnlyOneNeighbourLand = ((topLeftTerrainType == TerrainType.land ^ topRightTerrainType == TerrainType.land) ^ (bottomLeftTerrainType == TerrainType.land ^ bottomRightTerrainType == TerrainType.land)); if (isAnyNeighbourLand && isAnyNeighbourInterior) { terrainTypes[arrayCoords.x, arrayCoords.y] = TerrainType.interiorShoreline; } } catch (Exception e) { Debug.LogError($"Array coords: {arrayCoords}. Array Length: [{terrainTypes.GetLength(0)},{terrainTypes.GetLength(1)}]. World coords: ({x},{y}).\nERROR: {e.Message}"); } } } // Do whatever with each type (spawn water sources, ...) for (int x = -mapManager.mapConfiguration.mapRadius; x <= mapManager.mapConfiguration.mapRadius; x++) { for (int y = -mapManager.mapConfiguration.mapRadius; y <= mapManager.mapConfiguration.mapRadius; y++) { Vector2Int arrayCoords = new Vector2Int(x + mapManager.mapConfiguration.mapRadius, y + mapManager.mapConfiguration.mapRadius); float rayDuration = 1f; float rayLength = 0.3f; switch (terrainTypes[arrayCoords.x, arrayCoords.y]) { case TerrainType.none: Debug.DrawRay(new Vector3(x, mapManager.mapConfiguration.seaHeightAbsolute, y), Vector3.up * rayLength, Color.black, rayDuration); break; case TerrainType.sea: Debug.DrawRay(new Vector3(x, mapManager.mapConfiguration.seaHeightAbsolute, y), Vector3.up * rayLength, Color.white, rayDuration); break; case TerrainType.interior: Debug.DrawRay(new Vector3(x, mapManager.mapConfiguration.seaHeightAbsolute, y), Vector3.up * rayLength, Color.yellow, rayDuration); break; case TerrainType.interiorShoreline: Debug.DrawRay(new Vector3(x, mapManager.mapConfiguration.seaHeightAbsolute, y), Vector3.up * rayLength, Color.magenta, rayDuration); MapElement spawned = mapManager.mapGenerator.SpawnMapElement(waterSourcePrefab, new Vector3(x, mapManager.mapConfiguration.seaHeightAbsolute, y), Quaternion.identity, this.transform); //Debug.Log("SPAWN", spawned.gameObject); break; case TerrainType.land: Debug.DrawRay(new Vector3(x, mapManager.GetHeightAt(new Vector2(x, y)), y), Vector3.up * rayLength, Color.green, rayDuration); break; default: throw new ArgumentOutOfRangeException(); } } } InvokeOnFinishStepGeneration(); }
/// <summary> /// Подсчитывает сколько рядом "рек". /// </summary> /// <returns>Число хексов вокруг, занятых рекой.</returns> /// <param name="y"> y координата.</param> /// <param name="x"> x координата.</param> /// <param name="matrix">Карта рек.</param> /// Функция подсчитывает количство соседних клеток, помеченных как "Река" или находящихся в "стеке реки" /// TODO Проверить работу стека реки static byte RiverNeighbours(U16Vec2 pos, TerrainType[,] terrainMatrix) { ushort height = (ushort)terrainMatrix.GetLength(0); ushort width = (ushort)terrainMatrix.GetLength(1); byte k = (byte)(pos.X & 1); //TODO Провести рефакторинг. byte riversCount = 0; if (pos.Y > 0 && pos.X > 0 && ((terrainMatrix[pos.Y - (k ^ 1), pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y - (k ^ 1)))))) riversCount++; if (pos.X > 0 && pos.Y < height - 1 && ((terrainMatrix[pos.Y + k, pos.X - 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X - 1), (ushort)(pos.Y + k))))) riversCount++; if (pos.Y > 0 && ((terrainMatrix[pos.Y - 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2(pos.X, (ushort)(pos.Y - 1))))) riversCount++; if (pos.Y < height - 1 && ((terrainMatrix[pos.Y + 1, pos.X] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2(pos.X, (ushort)(pos.Y + 1))))) riversCount++; if (pos.Y > 0 && pos.X < width - 1 && ((terrainMatrix[pos.Y - (k ^ 1), pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y - (k ^ 1)))))) riversCount++; if (pos.X < width - 1 && pos.Y < height - 1 && ((terrainMatrix[pos.Y + k, pos.X + 1] & TerrainType.RIVER) != TerrainType.NONE || RiverStack.Contains(new U16Vec2((ushort)(pos.X + 1), (ushort)(pos.Y + k))))) riversCount++; return riversCount; }
public static void CreateTerrainmap(ref TerrainType[,] terrainmap, float[,] matrix, GlobalTerrainSettings terrainParam) { ushort height = (ushort)terrainmap.GetLength(0); ushort width = (ushort)terrainmap.GetLength(1); for (ushort y = 0; y < height; ++y) for (ushort x = 0; x < width; ++x) if (matrix[y, x] < terrainParam.Terrains[0].StartingHeight) terrainmap[y, x] |= terrainParam.BottommostTerrain; else if (matrix[y, x] >= terrainParam.Terrains[terrainParam.Terrains.Length - 1].StartingHeight) terrainmap[y, x] |= terrainParam.Terrains[terrainParam.Terrains.Length - 1].TerrainType; else for (byte i = 1; i < terrainParam.Terrains.Length; ++i) if (matrix[y, x] < terrainParam.Terrains[i].StartingHeight) { terrainmap[y, x] |= terrainParam.Terrains[i - 1].TerrainType; break; } }