Пример #1
0
    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);
    }
Пример #2
0
    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);
    }
Пример #3
0
        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();
        }
Пример #4
0
    /// <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;
    }
Пример #5
0
    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;
                        }
    }