public void Generate(ValueStore keyStore)
        {
            Reset ();

            if (park == null) return;

            var seed = 0;
            // Generate a random seed.
            foreach (char c in keyStore.Seed) {
                seed += (int)c;
            }

            _waterRandom = new SRandom(seed);
            _treeRandom = new SRandom(seed);

            for (var z = 0; z <= park.zSize; z++)
            {
                for (var x = 0; x <= park.xSize; x++)
                {
                    // Calculate height of terrain patch based on perlin noise.
                    var y = (Mathf.PerlinNoise(x/(park.xSize* keyStore.PlainScale) + seed, z/(park.zSize*keyStore.PlainScale) + seed)*
                        (1 + keyStore.DitchRatio)) -
                        (float)keyStore.DitchRatio;
                    if (y < 0 && keyStore.DitchRatio != 0)
                        y /= keyStore.DitchRatio;

                    y = y*(y < 0 ? keyStore.MaxDepth : (float)keyStore.MaxHeight);
                    y = y > 0 ? Mathf.FloorToInt(y) : Mathf.CeilToInt(y);

                    // Generate terrain type for the terrain patch based on perlin noise.
                    if (keyStore.GenerateTerrainType)
                    {
                        var patch = park.getTerrain(x, z);
                        if (patch != null)
                        {
                            var types = ScriptableSingleton<AssetManager>.Instance.terrainTypes.Length;
                            var terrainTypeIndex = Mathf.PerlinNoise(x/(park.xSize*keyStore.TerrainScale ) + seed,
                                z/(park.xSize*keyStore.TerrainScale) + seed);

                            patch.TerrainType = Mathf.FloorToInt(Mathf.Abs(terrainTypeIndex - 0.5f)*types);
                        }
                    }

                    // Limit heights near road.
                    var roadWidth = Mathf.Max(MIN_ROAD_WIDTH, keyStore.EntranceClearance);
                    if (x < roadWidth)
                        continue;

                    y = Mathf.Clamp(y, roadWidth - x, x - roadWidth);

                    // Limit heights near entrance.
                    var distanceToEntrance = Vector3.Distance(park.parkEntrances.First().transform.position,
                        new Vector3(x, GROUND_HEIGHT, z));

                    if (distanceToEntrance < roadWidth)
                        continue;

                    // If this location should be raised, change the hight of the patch and the ones around.
                    if (y != 0)
                        for (var cornerIndex = 0; cornerIndex < 4; cornerIndex++)
                        {
                            var ox = cornerIndex == 1 || cornerIndex == 2 ? 1 : 0;
                            var oz = cornerIndex == 2 || cornerIndex == 3 ? 1 : 0;

                            var patch = park.getTerrain(x - ox, z - oz);

                            if (patch != null)
                            {
                                var current = patch.h[cornerIndex] - DEF_HEIGHT;
                                patch.smoothChangeHeight(park, cornerIndex, y - current);
                            }
                        }
                }
            }

            // Randomly flood the map.
            for (var i = 0; i < keyStore.FloodRounds; i++)
            {
                var x = Mathf.RoundToInt(_waterRandom.NextFloat(keyStore.EntranceClearance, park.xSize));
                var z = Mathf.RoundToInt(_waterRandom.NextFloat(0, park.zSize));

                var patch = park.getTerrain(x, z);
                if (patch == null || patch.hasWater() || patch.getLowestHeight() >= GROUND_HEIGHT) continue;

                WaterFlooding.flood(new Vector3(x,   GROUND_HEIGHT -  WATTER_OFFSET, z));
            }

            // Randomly spawn a forrest.
            for (var i = 0; i < keyStore.TreeCount; i++)
            {
                var x = Mathf.RoundToInt(_treeRandom.NextFloat(keyStore.EntranceClearance, park.xSize -PARK_FENCE_OFFSET));
                var z = Mathf.RoundToInt(_treeRandom.NextFloat(PARK_FENCE_OFFSET, park.zSize - PARK_FENCE_OFFSET));

                var patch = park.getTerrain(x, z);
                if (patch == null || patch.hasWater()) continue;

                var y = patch.getHeighestHeight();
                if (y != patch.getLowestHeight()) continue;

                TreeEntity fir = null;
                foreach (var o in ScriptableSingleton<AssetManager>.Instance.getDecoObjects())
                    if (o.getName().StartsWith("Fir") && o is TreeEntity) fir = o as TreeEntity;

                if (fir != null)
                {
                    var tree = ConfigWindow.Instantiate(fir);
                    tree.transform.position = new Vector3(x, y, z);
                    tree.transform.forward = Vector3.forward;
                    tree.Initialize();
                    tree.startAnimateSpawn(Vector3.zero);
                }
            }
        }
Esempio n. 2
0
        public void Generate(ValueStore keyStore)
        {
            Reset();

            if (park == null)
            {
                return;
            }

            var seed = 0;

            // Generate a random seed.
            foreach (char c in keyStore.Seed)
            {
                seed += (int)c;
            }

            _waterRandom = new SRandom(seed);
            _treeRandom  = new SRandom(seed);


            for (var z = 0; z <= park.zSize; z++)
            {
                for (var x = 0; x <= park.xSize; x++)
                {
                    // Calculate height of terrain patch based on perlin noise.
                    var y = (Mathf.PerlinNoise(x / (park.xSize * keyStore.PlainScale) + seed, z / (park.zSize * keyStore.PlainScale) + seed) *
                             (1 + keyStore.DitchRatio)) -
                            (float)keyStore.DitchRatio;
                    if (y < 0 && keyStore.DitchRatio != 0)
                    {
                        y /= keyStore.DitchRatio;
                    }


                    y = y * (y < 0 ? keyStore.MaxDepth : (float)keyStore.MaxHeight);
                    y = y > 0 ? Mathf.FloorToInt(y) : Mathf.CeilToInt(y);

                    // Generate terrain type for the terrain patch based on perlin noise.
                    if (keyStore.GenerateTerrainType)
                    {
                        var patch = park.getTerrain(x, z);
                        if (patch != null)
                        {
                            var types            = ScriptableSingleton <AssetManager> .Instance.terrainTypes.Length;
                            var terrainTypeIndex = Mathf.PerlinNoise(x / (park.xSize * keyStore.TerrainScale) + seed,
                                                                     z / (park.xSize * keyStore.TerrainScale) + seed);

                            patch.TerrainType = Mathf.FloorToInt(Mathf.Abs(terrainTypeIndex - 0.5f) * types);
                        }
                    }

                    // Limit heights near road.
                    var roadWidth = Mathf.Max(MIN_ROAD_WIDTH, keyStore.EntranceClearance);
                    if (x < roadWidth)
                    {
                        continue;
                    }

                    y = Mathf.Clamp(y, roadWidth - x, x - roadWidth);

                    // Limit heights near entrance.
                    var distanceToEntrance = Vector3.Distance(park.parkEntrances.First().transform.position,
                                                              new Vector3(x, GROUND_HEIGHT, z));

                    if (distanceToEntrance < roadWidth)
                    {
                        continue;
                    }

                    // If this location should be raised, change the hight of the patch and the ones around.
                    if (y != 0)
                    {
                        for (var cornerIndex = 0; cornerIndex < 4; cornerIndex++)
                        {
                            var ox = cornerIndex == 1 || cornerIndex == 2 ? 1 : 0;
                            var oz = cornerIndex == 2 || cornerIndex == 3 ? 1 : 0;

                            var patch = park.getTerrain(x - ox, z - oz);

                            if (patch != null)
                            {
                                var current = patch.h[cornerIndex] - DEF_HEIGHT;
                                patch.smoothChangeHeight(park, cornerIndex, y - current);
                            }
                        }
                    }
                }
            }

            // Randomly flood the map.
            for (var i = 0; i < keyStore.FloodRounds; i++)
            {
                var x = Mathf.RoundToInt(_waterRandom.NextFloat(keyStore.EntranceClearance, park.xSize));
                var z = Mathf.RoundToInt(_waterRandom.NextFloat(0, park.zSize));

                var patch = park.getTerrain(x, z);
                if (patch == null || patch.hasWater() || patch.getLowestHeight() >= GROUND_HEIGHT)
                {
                    continue;
                }

                WaterFlooding.flood(new Vector3(x, GROUND_HEIGHT - WATTER_OFFSET, z));
            }

            // Randomly spawn a forrest.
            for (var i = 0; i < keyStore.TreeCount; i++)
            {
                var x = Mathf.RoundToInt(_treeRandom.NextFloat(keyStore.EntranceClearance, park.xSize - PARK_FENCE_OFFSET));
                var z = Mathf.RoundToInt(_treeRandom.NextFloat(PARK_FENCE_OFFSET, park.zSize - PARK_FENCE_OFFSET));

                var patch = park.getTerrain(x, z);
                if (patch == null || patch.hasWater())
                {
                    continue;
                }

                var y = patch.getHighestHeight();
                if (y != patch.getLowestHeight())
                {
                    continue;
                }

                TreeEntity fir = null;
                foreach (var o in ScriptableSingleton <AssetManager> .Instance.getDecoObjects())
                {
                    if (o.getName().StartsWith("Fir") && o is TreeEntity)
                    {
                        fir = o as TreeEntity;
                    }
                }

                if (fir != null)
                {
                    var tree = ConfigWindow.Instantiate(fir);
                    tree.transform.position = new Vector3(x, y, z);
                    tree.transform.forward  = Vector3.forward;
                    tree.Initialize();
                    tree.startAnimateSpawn(Vector3.zero);
                }
            }
        }