Esempio n. 1
0
        public TreeGenForClimate GetRandomGenForClimate(TreeVariant[] gens, int climate, int forest, int y)
        {
            int   rain      = TerraGenConfig.GetRainFall((climate >> 8) & 0xff, y);
            int   temp      = TerraGenConfig.GetScaledAdjustedTemperature((climate >> 16) & 0xff, y - TerraGenConfig.seaLevel);
            float heightRel = ((float)y - TerraGenConfig.seaLevel) / ((float)api.WorldManager.MapSizeY - TerraGenConfig.seaLevel);
            int   fertility = TerraGenConfig.GetFertility(rain, temp, heightRel);

            float total = 0;
            float fertDist, rainDist, tempDist, forestDist, heightDist;

            distances.Clear();

            for (int i = 0; i < gens.Length; i++)
            {
                TreeVariant variant = gens[i];

                fertDist   = Math.Abs(fertility - variant.FertMid) / variant.FertRange;
                rainDist   = Math.Abs(rain - variant.RainMid) / variant.RainRange;
                tempDist   = Math.Abs(temp - variant.TempMid) / variant.TempRange;
                forestDist = Math.Abs(forest - variant.ForestMid) / variant.ForestRange;
                heightDist = Math.Abs((y / worldheight) - variant.HeightMid) / variant.HeightRange;


                double distSq =
                    Math.Max(0, fertDist * fertDist - 1) +
                    Math.Max(0, rainDist * rainDist - 1) +
                    Math.Max(0, tempDist * tempDist - 1) +
                    Math.Max(0, forestDist * forestDist - 1) +
                    Math.Max(0, heightDist * heightDist - 1)
                ;

                if (random.NextDouble() < distSq)
                {
                    continue;
                }

                float distance = (fertDist + rainDist + tempDist + forestDist + heightDist) * variant.Weight / 100f;

                distances.Add(variant, distance);

                total += distance;
            }

            distances = distances.Shuffle(random);

            double rnd = random.NextDouble();

            foreach (var val in distances)
            {
                rnd -= val.Value / total;
                if (rnd <= 0.001)
                {
                    float suitabilityBonus = GameMath.Clamp(0.7f - val.Value, 0f, 0.7f) * 1 / 0.7f * val.Key.SuitabilitySizeBonus;

                    float size = val.Key.MinSize + (float)random.NextDouble() * (val.Key.MaxSize - val.Key.MinSize) + suitabilityBonus;

                    float rainVal = Math.Max(0, (rain / 255f - treeGenProps.vinesMinRain) / (1 - treeGenProps.vinesMinRain));
                    float tempVal = Math.Max(0, (TerraGenConfig.DescaleTemperature(temp) / 255f - treeGenProps.descVineMinTempRel) / (1 - treeGenProps.descVineMinTempRel));

                    float vinesGrowthChance = 2f * rainVal * tempVal;

                    ITreeGenerator treegen = treeGenerators.GetGenerator(val.Key.Generator);

                    if (treegen == null)
                    {
                        api.World.Logger.Error("treengenproperties.json references tree generator {0}, but no such generator exists!", val.Key.Generator);
                        return(null);
                    }


                    return(new TreeGenForClimate(treegen, size, vinesGrowthChance));
                }
            }

            return(null);
        }