aboutsummaryrefslogtreecommitdiff
path: root/Minecraft.World/CanyonFeature.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Minecraft.World/CanyonFeature.cpp')
-rw-r--r--Minecraft.World/CanyonFeature.cpp185
1 files changed, 185 insertions, 0 deletions
diff --git a/Minecraft.World/CanyonFeature.cpp b/Minecraft.World/CanyonFeature.cpp
new file mode 100644
index 00000000..b96c97e0
--- /dev/null
+++ b/Minecraft.World/CanyonFeature.cpp
@@ -0,0 +1,185 @@
+#include "stdafx.h"
+#include "net.minecraft.world.level.h"
+#include "CanyonFeature.h"
+#include "net.minecraft.world.level.tile.h"
+#include "net.minecraft.world.level.biome.h"
+
+void CanyonFeature::addTunnel(__int64 seed, int xOffs, int zOffs, byteArray blocks, double xCave, double yCave, double zCave, float thickness, float yRot, float xRot, int step, int dist, double yScale)
+{
+ MemSect(49);
+ Random *random = new Random(seed);
+ MemSect(0);
+ double xMid = xOffs * 16 + 8;
+ double zMid = zOffs * 16 + 8;
+
+ float yRota = 0;
+ float xRota = 0;
+ // int dist = CAVE_RADIUS * 16 - 16;
+ // if (step>0) dist = step*2;
+
+ if (dist <= 0)
+ {
+ int max = radius * 16 - 16;
+ dist = max - random->nextInt(max / 4);
+ }
+ bool singleStep = false;
+
+ if (step == -1)
+ {
+ step = dist / 2;
+ singleStep = true;
+ }
+
+ float f = 1;
+ for (int i = 0; i < Level::genDepth; i++)
+ {
+ if (i == 0 || random->nextInt(3) == 0)
+ {
+ f = 1 + (random->nextFloat() * random->nextFloat()) * 1.0f;
+ }
+ rs[i] = f * f;
+ }
+
+ for (; step < dist; step++)
+ {
+ double rad = 1.5 + (Mth::sin(step * PI / dist) * thickness) * 1;
+ double yRad = rad * yScale;
+
+ rad *= (random->nextFloat() * 0.25 + 0.75);
+ yRad *= (random->nextFloat() * 0.25 + 0.75);
+
+ float xc = Mth::cos(xRot);
+ float xs = Mth::sin(xRot);
+ xCave += Mth::cos(yRot) * xc;
+ yCave += xs;
+ zCave += Mth::sin(yRot) * xc;
+
+ xRot *= 0.7f;
+
+ xRot += xRota * 0.05f;
+ yRot += yRota * 0.05f;
+
+ xRota *= 0.80f;
+ yRota *= 0.50f;
+ xRota += (random->nextFloat() - random->nextFloat()) * random->nextFloat() * 2;
+ yRota += (random->nextFloat() - random->nextFloat()) * random->nextFloat() * 4;
+
+ if (!singleStep && random->nextInt(4) == 0) continue;
+
+ {
+ double xd = xCave - xMid;
+ double zd = zCave - zMid;
+ double remaining = dist - step;
+ double rr = (thickness + 2) + 16;
+ if (xd * xd + zd * zd - (remaining * remaining) > rr * rr)
+ {
+ delete random;
+ return;
+ }
+ }
+
+ if (xCave < xMid - 16 - rad * 2 || zCave < zMid - 16 - rad * 2 || xCave > xMid + 16 + rad * 2 || zCave > zMid + 16 + rad * 2) continue;
+
+ int x0 = Mth::floor(xCave - rad) - xOffs * 16 - 1;
+ int x1 = Mth::floor(xCave + rad) - xOffs * 16 + 1;
+
+ int y0 = Mth::floor(yCave - yRad) - 1;
+ int y1 = Mth::floor(yCave + yRad) + 1;
+
+ int z0 = Mth::floor(zCave - rad) - zOffs * 16 - 1;
+ int z1 = Mth::floor(zCave + rad) - zOffs * 16 + 1;
+
+ if (x0 < 0) x0 = 0;
+ if (x1 > 16) x1 = 16;
+
+ if (y0 < 1) y0 = 1;
+ if (y1 > Level::genDepth - 8) y1 = Level::genDepth - 8;
+
+ if (z0 < 0) z0 = 0;
+ if (z1 > 16) z1 = 16;
+
+ bool detectedWater = false;
+ for (int xx = x0; !detectedWater && xx < x1; xx++)
+ {
+ for (int zz = z0; !detectedWater && zz < z1; zz++)
+ {
+ for (int yy = y1 + 1; !detectedWater && yy >= y0 - 1; yy--)
+ {
+ int p = (xx * 16 + zz) * Level::genDepth + yy;
+ if (yy < 0 || yy >= Level::genDepth) continue;
+ if (blocks[p] == Tile::water_Id || blocks[p] == Tile::calmWater_Id)
+ {
+ detectedWater = true;
+ }
+ if (yy != y0 - 1 && xx != x0 && xx != x1 - 1 && zz != z0 && zz != z1 - 1)
+ {
+ yy = y0;
+ }
+ }
+ }
+ }
+ if (detectedWater) continue;
+
+ for (int xx = x0; xx < x1; xx++)
+ {
+ double xd = ((xx + xOffs * 16 + 0.5) - xCave) / rad;
+ for (int zz = z0; zz < z1; zz++)
+ {
+ double zd = ((zz + zOffs * 16 + 0.5) - zCave) / rad;
+ int p = (xx * 16 + zz) * Level::genDepth + y1;
+ bool hasGrass = false;
+ if (xd * xd + zd * zd < 1)
+ {
+ for (int yy = y1 - 1; yy >= y0; yy--)
+ {
+ double yd = (yy + 0.5 - yCave) / yRad;
+ if ((xd * xd + zd * zd) * rs[yy] + (yd * yd / 6) < 1)
+ {
+ int block = blocks[p];
+ if (block == Tile::grass_Id) hasGrass = true;
+ if (block == Tile::rock_Id || block == Tile::dirt_Id || block == Tile::grass_Id)
+ {
+ if (yy < 10)
+ {
+ blocks[p] = (byte) Tile::lava_Id;
+ }
+ else
+ {
+ blocks[p] = (byte) 0;
+ if (hasGrass && blocks[p - 1] == Tile::dirt_Id) blocks[p - 1] = (byte) level->getBiome(xx + xOffs * 16, zz + zOffs * 16)->topMaterial;
+ }
+ }
+ }
+ p--;
+ }
+ }
+ }
+ }
+ if (singleStep) break;
+ }
+ delete random;
+}
+
+void CanyonFeature::addFeature(Level *level, int x, int z, int xOffs, int zOffs, byteArray blocks)
+{
+ if (random->nextInt(50) != 0) return;
+
+ double xCave = x * 16 + random->nextInt(16);
+ double yCave = random->nextInt(random->nextInt(40) + 8) + 20;
+ double zCave = z * 16 + random->nextInt(16);
+
+ int tunnels = 1;
+
+ for (int i = 0; i < tunnels; i++)
+ {
+ float yRot = random->nextFloat() * PI * 2;
+ float xRot = ((random->nextFloat() - 0.5f) * 2) / 8;
+ float thickness = (random->nextFloat() * 2 + random->nextFloat()) * 2;
+
+ addTunnel(random->nextLong(), xOffs, zOffs, blocks, xCave, yCave, zCave, thickness, yRot, xRot, 0, 0, 3.0);
+
+ // 4J Add to feature list
+ app.AddTerrainFeaturePosition(eTerrainFeature_Ravine,(int)(xCave/16.0),(int)(yCave/16.0));
+ }
+
+} \ No newline at end of file