Beispiel #1
0
        public override IEnumerator Recalculating()
        {
            byte  sandTileId = _tileset.Sand.Id;
            byte  soilId     = _tileset.Soil.Id;
            float seaLevel   = GameContext.SeaLevel;

            int layer = (int)TilemapLayer.Soil;

            foreach (Position position in Values.AllCellMiddles())
            {
                if (_waterMapValues.Get(position) != WaterIngredientGenerator.Ground)
                {
                    Values.Set(position, None);
                    continue;
                }

                float height = _heightMapValues.Get(position);

                float aboveSeaLevel = height - seaLevel;
                if (aboveSeaLevel < _config.HeightAboveSeaForNormalSoil)
                {
                    Values.Set(position, Sand);
                    _tileMatricesByte[layer].Set(position, sandTileId);
                }
                else
                {
                    Values.Set(position, Soil);
                    _tileMatricesByte[layer].Set(position, soilId);
                }
            }

            yield return(new WaitForSeconds(0.1f));
        }
Beispiel #2
0
        public override IEnumerator Recalculating()
        {
            _seaLevel = GameContext.SeaLevel;
            var matrixByteForWaterLayer = GameContext.TileMatricesByLayer[(int)TilemapLayer.Water];
            var matrixByteForDirtLayer  = GameContext.TileMatricesByLayer[(int)TilemapLayer.Dirt];

            byte saltyWaterId = _tileset.SaltyWater.Id;
            byte dirtId       = _tileset.DryDirt.Id;

            foreach (Position cellMiddle in Values.AllCellMiddles())
            {
                matrixByteForWaterLayer.Set(cellMiddle, saltyWaterId);

                if (_heightMapValues.Get(cellMiddle) < _seaLevel)
                {
                    Values.Set(cellMiddle, Sea);
                }
                else
                {
                    matrixByteForDirtLayer.Set(cellMiddle, dirtId);
                    Values.Set(cellMiddle, Ground);
                }
            }

            float mapHectars = Values.XSize * Values.YSize / 10000f;
            int   lakeCount  = (int)(mapHectars * _config.SoleLakesCountPerHectar);

            for (int i = 0; i < lakeCount; i++)
            {
                int lakePositions = (int)_config.RandomToSoleLakeArea.Evaluate(_rng.NextFloat());
                yield return(new WaitForSeconds(0.1f));
            }

            yield return(new WaitForSeconds(0.1f));
        }
Beispiel #3
0
        private void SimulateOneGeneration(bool allowSpreading)
        {
            for (var x = 0; x < Values.XSize; x++)
            {
                for (var y = 0; y < Values.YSize; y++)
                {
                    Plant plant = _plants[x, y];
                    if (plant != null)
                    {
                        float scoreFromSoil       = ScoreFromSoil(plant, _soilMap.Get(new Position(x, y)));
                        float scoreFromNeighbours = GetScoreFromNeighbours(plant, x, y);
                        float randomFactorScore   = _rng.NextFloat() - 0.5f;

                        float totalScore = scoreFromSoil + scoreFromNeighbours + randomFactorScore;

                        if (totalScore < plant.ScoreToDie)
                        {
                            KillPlant(x, y, plant);
                        }
                        else
                        {
                            bool shouldSpread = allowSpreading && totalScore > plant.ScoreToSpreadSeeds;
                            if (shouldSpread)
                            {
                                for (var i = 0; i < plant.SeedsAmount; i++)
                                {
                                    int newSeedX = x + _rng.Next(1, plant.SeedsSpread) * _rng.Sign();
                                    int newSeedY = y + _rng.Next(1, plant.SeedsSpread) * _rng.Sign();
                                    if (newSeedX < 0 || newSeedY < 0 || newSeedX >= Values.XSize ||
                                        newSeedY >= Values.YSize)
                                    {
                                        continue;
                                    }
                                    if (_plants[newSeedX, newSeedY] == null)
                                    {
                                        SetPlant(newSeedX, newSeedY, plant);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #4
0
        private float GetScoreFromNeighbours(Plant plant, int plantX, int plantY)
        {
            int   plantRootsRange               = plant.RootsRange;
            int   totalNutritionAvailable       = (plantRootsRange + 1) * (plantRootsRange + 1);
            float nutritionTakenByNeighbours    = 0;
            float scoreFromSympathyToNeighbours = 0;

            for (int x = plantX - plantRootsRange; x <= plantX + plantRootsRange; x++)
            {
                for (int y = plantY - plantRootsRange; y <= plantY + plantRootsRange; y++)
                {
                    if (x < 0 || y < 0 || x >= Values.XSize || y >= Values.YSize ||
                        x == plantX && y == plantY)
                    {
                        continue;
                    }
                    Plant neighbourPlant = _plants[x, y];
                    if (neighbourPlant != null)
                    {
                        nutritionTakenByNeighbours += neighbourPlant.NutritionTaken;
                        float likelinessGain = 0.1f / (plantRootsRange + 1);
                        foreach (Plant likedNeighbour in plant.LikedNeighbours.Where(n => n == neighbourPlant))
                        {
                            scoreFromSympathyToNeighbours += likelinessGain;
                        }

                        foreach (Plant dislikedNeighbour in plant.DislikedNeighbours.Where(n => n == neighbourPlant))
                        {
                            scoreFromSympathyToNeighbours -= likelinessGain;
                        }
                    }
                }
            }

            float score = plant.AvailableNutritionRatioToScore.Evaluate(nutritionTakenByNeighbours / totalNutritionAvailable);

            float height = _heightMap.Get(plantX, plantY);

            score += plant.HeightToScore.Evaluate(height);

            score += scoreFromSympathyToNeighbours;
            return(score);
        }
Beispiel #5
0
        public override IEnumerator Recalculating()
        {
            MatrixFloat walkabilityMap = _context.Walkability;

            foreach (Position cellMiddle in _waterMap.AllCellMiddles())
            {
                if (Math.Abs(_waterMap.Get(cellMiddle) - WaterIngredientGenerator.Ground) < 0.01f)
                {
                    Values.Set(cellMiddle, 1f);
                    walkabilityMap.Set(cellMiddle, 1f);
                }
                else
                {
                    Values.Set(cellMiddle, 0f);
                    walkabilityMap.Set(cellMiddle, 0f);
                }
            }

            yield return(new WaitForSeconds(0.1f));
        }
Beispiel #6
0
        public override IEnumerator Recalculating()
        {
            OsnowaBaseTile dirtBaseTile   = _worldGeneratorConfig.Tileset.DryDirt;
            MatrixByte     dirtMatrixByte = GameContext.TileMatricesByLayer[(int)dirtBaseTile.Layer];
            float          seaLevel       = GameContext.SeaLevel;

            foreach (Position position in Values.AllCellMiddles())
            {
                float value  = _initialShapeValues.Get(position);
                bool  isLand = value > seaLevel;
                value = isLand ? float.MaxValue : float.MinValue;
                Values.Set(position, value);
                if (isLand)
                {
                    dirtMatrixByte.Set(position, dirtBaseTile.Id);
                }
            }

            yield return(new WaitForSeconds(0.1f));
        }