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); } } } }
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)); } } }