public void GenMountainPositionsForGridCell(List <MountainData> locs, Vector2i mountainPos, Vector2i chunkPos, int seed)
        {
            Vector2i mtChunk     = new Vector2i((int)(mountainPos.X * MountainGridSize), (int)(mountainPos.Y * MountainGridSize));
            Location chunkCenter = chunkPos.ToLocation() * Constants.CHUNK_WIDTH;
            MTRandom random      = new MTRandom(39, (ulong)(mountainPos.X * 39 + mountainPos.Y + seed));
            int      count       = random.Next(1, 3);

            for (int i = 0; i < count; i++)
            {
                int rangeSize;
                if (random.Next(10) > 5)
                {
                    rangeSize = random.Next(5, 13);
                }
                else
                {
                    rangeSize = random.Next(3, 8);
                }
                double       ca       = random.NextDouble();
                double       cb       = random.NextDouble();
                Vector2i     centerMt = new Vector2i(mtChunk.X * Constants.CHUNK_WIDTH + (int)(ca * MountainGridSize * Constants.CHUNK_WIDTH), mtChunk.Y * Constants.CHUNK_WIDTH + (int)(cb * MountainGridSize * Constants.CHUNK_WIDTH));
                double       ch       = random.NextDouble() * 512 + 512;
                double       cradius  = random.NextDouble() * ch * 0.25 + ch * 0.75;
                MountainData cmt      = new MountainData()
                {
                    Center = centerMt, Height = ch, Radius = cradius
                };
                if (centerMt.ToLocation().DistanceSquared(chunkCenter) < (MountainMaxSizeBlocks * MountainMaxSizeBlocks))
                {
                    locs.Add(cmt);
                }
                double ph = ch;
                for (int r = 1; r < rangeSize; r++)
                {
                    double ra = random.NextDouble() * 2.0 - 1.0;
                    double rb = random.NextDouble() * 2.0 - 1.0;
                    ra = ra > 0 ? Math.Max(r / (double)rangeSize, ra) : Math.Min(-r / (double)rangeSize, ra);
                    rb = rb > 0 ? Math.Max(r / (double)rangeSize, rb) : Math.Min(-r / (double)rangeSize, rb);
                    Vector2i     rngMt   = new Vector2i(centerMt.X + (int)(ra * MountainRangeRadius), centerMt.Y + (int)(rb * MountainRangeRadius));
                    double       rh      = random.NextDouble() * (ph * 0.5) + (ph * 0.5);
                    double       rradius = random.NextDouble() * rh * 0.25 + rh * 0.75;
                    MountainData rmt     = new MountainData()
                    {
                        Center = rngMt, Height = rh, Radius = rradius
                    };
                    if (rngMt.ToLocation().DistanceSquared(chunkCenter) < (MountainMaxSizeBlocks * MountainMaxSizeBlocks))
                    {
                        locs.Add(rmt);
                    }
                }
            }
        }
Exemple #2
0
        void MakeBranch(Vector2i Origin, int Size, int Movement, double Roughness, int Depth, double heightstart)
        {
            Increment increment        = GetIncrement(Center.X - Origin.X, Center.Y - Origin.Y);
            Increment inc1             = increment;
            double    OriginDistance   = Math.Max(Math.Sqrt(increment.X * increment.X + increment.Y * increment.Y), 1);
            double    DistanceModifier = Size / Movement * (Depth + 1);

            increment = GetIncrement((increment.X / OriginDistance + (random.NextDouble() - 0.5) * AngleRandomer) * DistanceModifier,
                                     (increment.Y / OriginDistance + (random.NextDouble() - 0.5) * AngleRandomer) * DistanceModifier);
            if (Depth == 0)
            {
                double ang = Math.Atan2(increment.Y, increment.X);
                for (int i = 0; i < UsedAngles.Count; i++)
                {
                    if (Math.Abs(UsedAngles[i] - ang) < (Math.PI * 1.5 / Movement))
                    {
                        if (bounces++ < 15)
                        {
                            MakeBranch(Origin, Size, Movement, Roughness, Depth, heightstart);
                            return;
                        }
                    }
                }
                UsedAngles.Add(ang);
            }

            Vector2i Destination = FixBounds(new Vector2i((int)Math.Round(Center.X + increment.X),
                                                          (int)Math.Round(Center.Y + increment.Y)), Size);

            List <Vector2i> Points    = MakeLine(Origin, Destination, Size, Roughness);
            int             PointSize = Points.Count;

            if (PointSize == 0)
            {
                return;
            }

            Destination = Points[PointSize - 1];
            double distX = Center.X - Destination.X;
            double distY = Center.Y - Destination.Y;
            double DestinationDistance = Math.Max(Math.Sqrt(distX * distX + distY * distY), 1);

            double HeightStart = heightstart;
            double HeightDecay = (HeightStart - Height * ((MaxDistance - DestinationDistance) / MaxDistance)) / PointSize;

            int Branching = 0;

            Vector2i Previous = new Vector2i((int)(Origin.X / DetailScaler / SHRINKER + ADDER), (int)(Origin.Y / DetailScaler / SHRINKER / SHRINKER + ADDER));
            Vector2i prev2    = Previous;
            Vector2i Next;

            for (int i = 0; i < PointSize; i++)
            {
                double HeightValue = HeightStart - HeightDecay * (i + 1);

                Vector2i point = Points[i];

                Vector2i ScaledPoint = new Vector2i((int)(point.X / DetailScaler / SHRINKER + ADDER), (int)(point.Y / DetailScaler / SHRINKER + ADDER));

                if (prev2.X == ScaledPoint.X && prev2.Y == ScaledPoint.Y)
                {
                    prev2 = new Vector2i(ScaledPoint.X - Math.Sign(inc1.X), ScaledPoint.Y - Math.Sign(inc1.Y));
                    if (prev2.X == ScaledPoint.X && prev2.Y == ScaledPoint.Y)
                    {
                        prev2 = new Vector2i(ScaledPoint.X - 1, ScaledPoint.Y - 1);
                    }
                }


                Next = ScaledPoint;
                int n = 1;
                while (i + n < PointSize)
                {
                    Next = new Vector2i((int)(Points[i + n].X / DetailScaler / SHRINKER + ADDER), (int)(Points[i + n].Y / DetailScaler / SHRINKER + ADDER));
                    if (Next.X != ScaledPoint.X || Next.Y != ScaledPoint.Y)
                    {
                        break;
                    }
                    n++;
                }
                if (i + n >= PointSize)
                {
                    Next = new Vector2i((int)(Destination.X / DetailScaler / SHRINKER + ADDER), (int)(Destination.Y / DetailScaler / SHRINKER + ADDER));
                    if (Next.X == ScaledPoint.X && Next.Y == ScaledPoint.Y)
                    {
                        Next = new Vector2i(ScaledPoint.X + Math.Sign(increment.X), ScaledPoint.Y + Math.Sign(increment.Y));
                    }
                }
                NodePoint ScaledNodePoint = GetNodePoint(prev2, ScaledPoint, Next, HeightValue);

                if (!Nodes.ContainsKey(ScaledPoint))
                {
                    Nodes.Add(ScaledPoint, ScaledNodePoint);
                    prev2    = Previous;
                    Previous = ScaledPoint;
                }
                ToHandle.Add(new KeyValuePair <Vector2i, double>(new Vector2i((int)(point.X / SHRINKER + ADDER * DetailScaler), (int)(point.Y / SHRINKER + ADDER * DetailScaler)), HeightValue));

                if (random.NextDouble() < 0.2 && Depth < Movement && Branching < 5)
                {
                    Branching++;
                    MakeBranch(Destination, Size, Movement, Roughness, Depth + 1, HeightStart - HeightDecay * (PointSize + 1));
                }
            }
        }