diff --git a/Minecraft.Client/ServerLevel.cpp b/Minecraft.Client/ServerLevel.cpp index 507bfbc7..864f9ce4 100644 --- a/Minecraft.Client/ServerLevel.cpp +++ b/Minecraft.Client/ServerLevel.cpp @@ -917,58 +917,54 @@ void ServerLevel::initializeLevel(LevelSettings *settings) */ void ServerLevel::setInitialSpawn(LevelSettings *levelSettings) { - if (!dimension->mayRespawn()) - { - levelData->setSpawn(0, dimension->getSpawnYPosition(), 0); - return; - } + if (!dimension->mayRespawn()) + { + levelData->setSpawn(0, dimension->getSpawnYPosition(), 0); + return; + } - isFindingSpawn = true; + isFindingSpawn = true; - BiomeSource *biomeSource = dimension->biomeSource; - vector playerSpawnBiomes = biomeSource->getPlayerSpawnBiomes(); - Random random(getSeed()); + BiomeSource *biomeSource = dimension->biomeSource; + vector playerSpawnBiomes = biomeSource->getPlayerSpawnBiomes(); + Random random(getSeed()); - TilePos *findBiome = biomeSource->findBiome(0, 0, 16 * 16, playerSpawnBiomes, &random); + TilePos *spawnPos = biomeSource->findBiome(0, 0, 256, playerSpawnBiomes, &random); - int xSpawn = 0; // (Level.MAX_LEVEL_SIZE - 100) * 0; - int ySpawn = dimension->getSpawnYPosition(); - int zSpawn = 0; // (Level.MAX_LEVEL_SIZE - 100) * 0; - int minXZ = - (dimension->getXZSize() * 16 ) / 2; - int maxXZ = (dimension->getXZSize() * 16 ) / 2 - 1; + int xSpawn = 0; + int ySpawn = dimension->getSpawnYPosition(); + int zSpawn = 0; + int minXZ = -(dimension->getXZSize() * 16) / 2; + int maxXZ = (dimension->getXZSize() * 16) / 2 - 1; - if (findBiome != nullptr) - { - xSpawn = findBiome->x; - zSpawn = findBiome->z; - delete findBiome; - } - else - { - app.DebugPrintf("Level::setInitialSpawn - Unable to find spawn biome\n"); - } + if (spawnPos != nullptr) + { + xSpawn = spawnPos->x; + zSpawn = spawnPos->z; + delete spawnPos; + } + else + { + app.DebugPrintf("Level::setInitialSpawn - Unable to find spawn biome\n"); + } - int tries = 0; + int tries = 0; + while (!dimension->isValidSpawn(xSpawn, zSpawn)) + { + xSpawn += random.nextInt(64) - random.nextInt(64); + if (xSpawn > maxXZ) xSpawn = 0; + if (xSpawn < minXZ) xSpawn = 0; + zSpawn += random.nextInt(64) - random.nextInt(64); + if (zSpawn > maxXZ) zSpawn = 0; + if (zSpawn < minXZ) zSpawn = 0; + if (++tries == 1000) break; + } - while (!dimension->isValidSpawn(xSpawn, zSpawn)) - { - // 4J-PB changed to stay within our level limits - xSpawn += random.nextInt(64) - random.nextInt(64); - if(xSpawn>maxXZ) xSpawn=0; - if(xSpawnmaxXZ) zSpawn=0; - if(zSpawnsetSpawn(xSpawn, ySpawn, zSpawn); + if (levelSettings->hasStartingBonusItems()) + generateBonusItemsNearSpawn(); - if (++tries == 1000) break; - } - - levelData->setSpawn(xSpawn, ySpawn, zSpawn); - if (levelSettings->hasStartingBonusItems()) - { - generateBonusItemsNearSpawn(); - } - isFindingSpawn = false; + isFindingSpawn = false; } // 4J - brought forward from 1.3.2 diff --git a/Minecraft.World/AddEdgeLayer.cpp b/Minecraft.World/AddEdgeLayer.cpp index 6547f0b6..d6233f87 100644 --- a/Minecraft.World/AddEdgeLayer.cpp +++ b/Minecraft.World/AddEdgeLayer.cpp @@ -23,13 +23,10 @@ intArray AddEdgeLayer::coolWarm(int xo, int yo, int w, int h) intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2); intArray result = IntCache::allocate(w * h); int stride = w + 2; - for (int iy = 0; iy < h; ++iy) { for (int ix = 0; ix < w; ++ix) { - initRandom(ix + xo, iy + yo); - int center = b[(ix + 1) + (iy + 1) * stride]; if (center == 1) { @@ -37,10 +34,8 @@ intArray AddEdgeLayer::coolWarm(int xo, int yo, int w, int h) int east = b[(ix + 2) + (iy + 1) * stride]; int west = b[(ix + 0) + (iy + 1) * stride]; int south = b[(ix + 1) + (iy + 2) * stride]; - bool hasCold = (north == 3 || east == 3 || west == 3 || south == 3); bool hasIcy = (north == 4 || east == 4 || west == 4 || south == 4); - if (hasCold || hasIcy) center = 2; } @@ -56,11 +51,11 @@ intArray AddEdgeLayer::heatIce(int xo, int yo, int w, int h) intArray b = parent->getArea(xo - 1, yo - 1, w + 2, h + 2); intArray result = IntCache::allocate(w * h); int stride = w + 2; - for (int iy = 0; iy < h; ++iy) { for (int ix = 0; ix < w; ++ix) { + initRandom(ix + xo, iy + yo); int center = b[(ix + 1) + (iy + 1) * stride]; if (center == 4) { @@ -68,11 +63,9 @@ intArray AddEdgeLayer::heatIce(int xo, int yo, int w, int h) int east = b[(ix + 2) + (iy + 1) * stride]; int west = b[(ix + 0) + (iy + 1) * stride]; int south = b[(ix + 1) + (iy + 2) * stride]; - bool nearWarm = (north == 2 || east == 2 || west == 2 || south == 2); bool nearHot = (north == 1 || east == 1 || west == 1 || south == 1); - - if (nearHot || nearWarm || nearWarm) + if (nearHot || nearWarm) center = 3; } result[ix + iy * w] = center; diff --git a/Minecraft.World/Biome.cpp b/Minecraft.World/Biome.cpp index 91dbf3c0..499afecf 100644 --- a/Minecraft.World/Biome.cpp +++ b/Minecraft.World/Biome.cpp @@ -109,7 +109,7 @@ void Biome::staticCtor() Biome::smallerExtremeHills = (new ExtremeHillsBiome(20))->setColor(0x72789a)->setName(L"Extreme Hills Edge")->setDepthAndScale(0.2f, 0.8f)->setTemperatureAndDownfall(0.2f, 0.3f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHillsEdge, eMinecraftColour_Foliage_ExtremeHillsEdge, eMinecraftColour_Water_ExtremeHillsEdge,eMinecraftColour_Sky_ExtremeHillsEdge); Biome::jungle = (new JungleBiome(21, false))->setColor(0x537b09)->setName(L"Jungle")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(0.2f, 0.4f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); Biome::jungleHills = (new JungleBiome(22, false))->setColor(0x2c4205)->setName(L"Jungle Hills")->setLeafColor(0x537b09)->setTemperatureAndDownfall(1.2f, 0.9f)->setDepthAndScale(1.8f, 0.5f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_JungleHills, eMinecraftColour_Foliage_JungleHills, eMinecraftColour_Water_JungleHills,eMinecraftColour_Sky_JungleHills); - Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F); + Biome::jungleEdge = (new JungleBiome(23, true))->setColor(0x6458135)->setName(L"Jungle Edge")->setLeafColor(0x5470985)->setTemperatureAndDownfall(0.95F, 0.8F)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Jungle, eMinecraftColour_Foliage_Jungle, eMinecraftColour_Water_Jungle,eMinecraftColour_Sky_Jungle); Biome::deepOcean= (new OceanBiome(24))->setName(L"Deep Ocean")->setDepthAndScale(-1.8,0.1f)->setColor(0x000070)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_Ocean, eMinecraftColour_Foliage_Ocean, eMinecraftColour_Water_Ocean,eMinecraftColour_Sky_Ocean);; Biome::stoneBeach = (new StoneBeachBiome(25))->setColor(0xa2a284)->setName(L"Stone Beach")->setTemperatureAndDownfall(0.2f, 0.3f)->setDepthAndScale(-1.0f, 0.1f)->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_ExtremeHills,eMinecraftColour_Foliage_ExtremeHills,eMinecraftColour_Water_ExtremeHills,eMinecraftColour_Sky_ExtremeHills); Biome::coldBeach = (new BeachBiome(26))->setColor(0xFAF0C0)->setName(L"Cold Beach")->setTemperatureAndDownfall(0.05F, 0.3F)->setDepthAndScale(0.0F, 0.025F)->setSnowCovered()->setLeafFoliageWaterSkyColor(eMinecraftColour_Grass_IcePlains, eMinecraftColour_Foliage_IcePlains, eMinecraftColour_Water_IcePlains, eMinecraftColour_Sky_IcePlains); diff --git a/Minecraft.World/BiomeSource.cpp b/Minecraft.World/BiomeSource.cpp index 864a098e..e8b29d67 100644 --- a/Minecraft.World/BiomeSource.cpp +++ b/Minecraft.World/BiomeSource.cpp @@ -15,11 +15,11 @@ void BiomeSource::_init() generatorOptions = L""; cache = new BiomeCache(this); - playerSpawnBiomes.push_back(Biome::plains); playerSpawnBiomes.push_back(Biome::forest); + playerSpawnBiomes.push_back(Biome::plains); playerSpawnBiomes.push_back(Biome::taiga); - playerSpawnBiomes.push_back(Biome::forestHills); playerSpawnBiomes.push_back(Biome::taigaHills); + playerSpawnBiomes.push_back(Biome::forestHills); playerSpawnBiomes.push_back(Biome::jungle); playerSpawnBiomes.push_back(Biome::jungleHills); } diff --git a/Minecraft.World/GrowMushroomIslandLayer.cpp b/Minecraft.World/GrowMushroomIslandLayer.cpp index b95abd23..c0f5e19c 100644 --- a/Minecraft.World/GrowMushroomIslandLayer.cpp +++ b/Minecraft.World/GrowMushroomIslandLayer.cpp @@ -16,29 +16,25 @@ intArray GrowMushroomIslandLayer::getArea(int xo, int yo, int w, int h) int ph = h + 2; intArray p = parent->getArea(px, py, pw, ph); intArray result = IntCache::allocate(w * h); - int mushroomId = Biome::mushroomIsland->id; for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { - int ul = p[(x + 0) + (y + 0) * pw]; int ur = p[(x + 2) + (y + 0) * pw]; int dl = p[(x + 0) + (y + 2) * pw]; int dr = p[(x + 2) + (y + 2) * pw]; int c = p[(x + 1) + (y + 1) * pw]; - int north = p[(x + 1) + (y + 0) * pw]; - int south = p[(x + 1) + (y + 2) * pw]; - int west = p[(x + 0) + (y + 1) * pw]; int east = p[(x + 2) + (y + 1) * pw]; - - if (ul == mushroomId || ur == mushroomId || - dl == mushroomId || dr == mushroomId || - north == mushroomId || south == mushroomId || - west == mushroomId || east == mushroomId) + int south = p[(x + 1) + (y + 2) * pw]; + if (ul == 14 || ur == 14 || dl == 14 || dr == 14) { - result[x + y * w] = mushroomId; + result[x + y * w] = 14; + } + else if (north == 14 || east == 14 || south == 14) + { + result[x + y * w] = 14; } else { diff --git a/Minecraft.World/Layer.cpp b/Minecraft.World/Layer.cpp index 256b1d9d..35149330 100644 --- a/Minecraft.World/Layer.cpp +++ b/Minecraft.World/Layer.cpp @@ -18,7 +18,6 @@ libdivide::divider fast_d6(6); libdivide::divider fast_d7(7); libdivide::divider fast_d10(10); #endif - LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig) { int32_t seed32 = (int32_t)seed; @@ -65,9 +64,37 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup riverLayerFinal = make_shared(seed32, riverLayerFinal, 0x3E8); shared_ptr biomeLayer = make_shared(seed32, baseLayer, 0xC8, levelType, superflatConfig); - + + { + auto testBiome = make_shared(seed32, baseLayer, 0xC8, levelType, superflatConfig); + testBiome->init((uint32_t)seed); + IntCache::releaseAll(); + intArray testArea = testBiome->getArea(0, 0, 20, 20); + app.DebugPrintf("BiomeInitLayer only seed=%d:\n", seed32); + for (int z = 0; z < 20; z++) { + for (int x = 0; x < 20; x++) + app.DebugPrintf("%3d ", testArea[x + z*20]); + app.DebugPrintf("\n"); + } + IntCache::releaseAll(); +} + biomeLayer = make_shared(seed32, biomeLayer, 0x3E8); biomeLayer = make_shared(seed32, biomeLayer, hillsNoise, 0x3E8); + { + auto testLayer = biomeLayer; + testLayer->init((uint32_t)seed); + IntCache::releaseAll(); + intArray testArea = testLayer->getArea(0, 0, 20, 20); + app.DebugPrintf("After RegionHillsLayer seed=%d:\n", seed32); + for (int z = 0; z < 20; z++) { + for (int x = 0; x < 20; x++) + app.DebugPrintf("%3d ", testArea[x + z*20]); + app.DebugPrintf("\n"); + } + IntCache::releaseAll(); +} + biomeLayer = make_shared(seed32, biomeLayer, 0x3E9); for (int i = 0; i < zoomLevel; ++i) @@ -86,19 +113,44 @@ LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* sup } biomeLayer = make_shared(seed32, biomeLayer, 0x3E8); + { + auto testLayer = biomeLayer; + testLayer->init((uint32_t)seed); + IntCache::releaseAll(); + intArray testArea = testLayer->getArea(60, 240, 20, 20); + app.DebugPrintf("After zoom loop seed=%d:\n", seed32); + for (int z = 0; z < 20; z++) { + for (int x = 0; x < 20; x++) + app.DebugPrintf("%3d ", testArea[x + z*20]); + app.DebugPrintf("\n"); + } + IntCache::releaseAll(); +} shared_ptr mixed = make_shared(seed32, biomeLayer, riverLayerFinal, 0x64); shared_ptr voronoi = make_shared(seed32, mixed, 0xA); mixed->init((uint32_t)seed); voronoi->init((uint32_t)seed); +IntCache::releaseAll(); +mixed->init((uint32_t)seed); +intArray testArea = mixed->getArea(0, 200, 60, 60); +app.DebugPrintf("Biomes 0-60, 200-260 seed=%d:\n", seed32); +for (int z = 0; z < 60; z++) { + for (int x = 0; x < 60; x++) + app.DebugPrintf("%3d ", testArea[x + z*60]); + app.DebugPrintf("\n"); +} +IntCache::releaseAll(); + LayerArray result(3, false); result[0] = mixed; result[1] = voronoi; result[2] = mixed; + + return result; } - Layer::Layer(int64_t s) { int64_t sm = (int64_t)(int32_t)s; @@ -132,41 +184,40 @@ void Layer::initRandom(int64_t x, int64_t y) int Layer::nextRandom(int max) { - int32_t hi = (int32_t)(rval >> 32); - int result = (hi >> 24) % max; + int64_t rval_full = this->rval; + uint32_t rval_lo = (uint32_t)rval_full; + uint32_t rval_hi = (uint32_t)(rval_full >> 32); + uint32_t seed_lo = (uint32_t)this->seed; + + int result = (int)((int64_t)(rval_full >> 24) % (int64_t)max); if (result < 0) result += max; - int64_t v = rval; - int64_t lo = (int64_t)(int32_t)( - (int32_t)v * (1284865837 * (int32_t)v - 144211633) - + (int32_t)seed); - int64_t hi64 = v * (0x5851F42D4C957F2DLL * v + 0x14057B7EF767814FLL) + seed; - rval = (hi64 & 0xFFFFFFFF00000000LL) | (uint32_t)lo; + uint32_t new_lo = rval_lo * (1284865837u * rval_lo - 144211633u) + seed_lo; + + uint64_t paired = ((uint64_t)rval_lo << 32) | (uint64_t)rval_lo; + uint64_t big = (uint64_t)(int64_t)rval_full * (0x5851F42D4C957F2DULL * paired + 0x14057B7EF767814FULL); + uint32_t carry = (uint32_t)(((uint64_t)(rval_lo * (1284865837u * rval_lo - 144211633u)) + seed_lo) >> 32); + uint32_t new_hi = seed_lo + carry + (uint32_t)(big >> 32); + + this->rval = ((int64_t)new_hi << 32) | (int64_t)new_lo; return result; } -void Layer::init(int64_t seed) +void Layer::init(int64_t worldSeed) { if (parent != nullptr) - parent->init(seed); - - uint32_t lo = (uint32_t)seed; - uint32_t m = (uint32_t)seedMixup; - - uint32_t v12 = lo * (1284865837u * lo - 144211633u); - uint32_t sum = v12 + m; - uint32_t step1 = sum * (1284865837u * sum - 144211633u); - uint32_t sum2 = step1 + m; - - int64_t step2 = (int64_t)(int32_t)sum2 - * (0x5851F42D4C957F2DLL * (int64_t)(int32_t)sum2 - + 0x14057B7EF767814FLL) - + (int64_t)(int32_t)m; - static bool first = true; - + parent->init(worldSeed); - this->seed = step2; + uint32_t ws = (uint32_t)worldSeed; + int64_t m = this->seedMixup; + + uint32_t v12 = ws * (1284865837u * ws - 144211633u); + int64_t sum1 = (int64_t)(int32_t)v12 + m; + uint32_t v14_lo = (uint32_t)sum1 * (1284865837u * (uint32_t)sum1 - 144211633u); + int64_t sum2 = (int64_t)(int32_t)v14_lo + m; + + this->seed = sum2 * (0x5851F42D4C957F2DLL * sum2 + 0x14057B7EF767814FLL) + m; } bool Layer::isOcean(int biomeId) diff --git a/Minecraft.World/RegionHillsLayer.cpp b/Minecraft.World/RegionHillsLayer.cpp index 81b3a49e..c90ebb20 100644 --- a/Minecraft.World/RegionHillsLayer.cpp +++ b/Minecraft.World/RegionHillsLayer.cpp @@ -120,7 +120,7 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) } else if (k == Biome::ocean->id) { - // java: ocean → deepOcean + i1 = Biome::deepOcean->id; } else if (k == Biome::extremeHills->id) @@ -129,14 +129,19 @@ intArray RegionHillsLayer::getArea(int xo, int yo, int w, int h) } else if (k == Biome::savanna->id) { - // Java: savanna → savannaPlateau + i1 = Biome::savannaPlateau->id; } - else if (k == Biome::deepOcean->id && nextRandom(3) == 0) + else if (k == Biome::deepOcean->id) { - - i1 = (nextRandom(2) == 0) ? Biome::plains->id : Biome::forest->id; + if (nextRandom(3) == 0) + { + if (nextRandom(2) == 0) + i1 = Biome::plains->id; + else + i1 = Biome::forest->id; + } } diff --git a/Minecraft.World/RiverInitLayer.cpp b/Minecraft.World/RiverInitLayer.cpp index 64f3d665..2a4a964f 100644 --- a/Minecraft.World/RiverInitLayer.cpp +++ b/Minecraft.World/RiverInitLayer.cpp @@ -9,17 +9,15 @@ RiverInitLayer::RiverInitLayer(int64_t seed, std::shared_ptr parent, int6 intArray RiverInitLayer::getArea(int xo, int yo, int w, int h) { - intArray b = parent->getArea(xo, yo, w, h); - - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - initRandom(x + xo, y + yo); - result[x + y * w] = b[x + y * w] > 0 ? nextRandom(2) + 2 : 0; - } - } - - return result; + intArray b = parent->getArea(xo, yo, w, h); + intArray result = IntCache::allocate(w * h); + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + initRandom(x + xo, y + yo); + result[x + y * w] = b[x + y * w] > 0 ? nextRandom(299999) + 2 : 0; + } + } + return result; } \ No newline at end of file diff --git a/Minecraft.World/RiverLayer.cpp b/Minecraft.World/RiverLayer.cpp index 07207c22..7ffd3433 100644 --- a/Minecraft.World/RiverLayer.cpp +++ b/Minecraft.World/RiverLayer.cpp @@ -9,32 +9,33 @@ RiverLayer::RiverLayer(int64_t seed, shared_ptr parent, int64_t seedMixup intArray RiverLayer::getArea(int xo, int yo, int w, int h) { - int px = xo - 1; - int py = yo - 1; - int pw = w + 2; - int ph = h + 2; - intArray p = parent->getArea(px, py, pw, ph); + int px = xo - 1; + int py = yo - 1; + int pw = w + 2; + int ph = h + 2; + intArray p = parent->getArea(px, py, pw, ph); + intArray result = IntCache::allocate(w * h); + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int c = p[(x + 1) + (y + 1) * pw]; + int n = p[(x + 1) + (y + 0) * pw]; + int e = p[(x + 2) + (y + 1) * pw]; + int s = p[(x + 1) + (y + 2) * pw]; + int w1 = p[(x + 0) + (y + 1) * pw]; - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - int l = p[(x + 0) + (y + 1) * pw]; - int r = p[(x + 2) + (y + 1) * pw]; - int u = p[(x + 1) + (y + 0) * pw]; - int d = p[(x + 1) + (y + 2) * pw]; - int c = p[(x + 1) + (y + 1) * pw]; - if (c == 0 || (l == 0 || r == 0 || u == 0 || d == 0) || c != l || c != u || c != r || c != d) - { - result[x + y * w] = Biome::river->id; - } - else - { - result[x + y * w] = -1; - } - } - } + int cc = c >= 2 ? (c & 1) + 2 : c; + int nc = n >= 2 ? (n & 1) + 2 : n; + int ec = e >= 2 ? (e & 1) + 2 : e; + int sc = s >= 2 ? (s & 1) + 2 : s; + int wc = w1 >= 2 ? (w1 & 1) + 2 : w1; - return result; + if (cc == nc && cc == ec && cc == sc && cc == wc) + result[x + y * w] = -1; + else + result[x + y * w] = Biome::river->id; + } + } + return result; } \ No newline at end of file diff --git a/Minecraft.World/SmoothLayer.cpp b/Minecraft.World/SmoothLayer.cpp index 9549fb1f..24c5edee 100644 --- a/Minecraft.World/SmoothLayer.cpp +++ b/Minecraft.World/SmoothLayer.cpp @@ -8,38 +8,40 @@ SmoothLayer::SmoothLayer(int64_t seed, shared_ptr parent, int64_t seedMix intArray SmoothLayer::getArea(int xo, int yo, int w, int h) { - int px = xo - 1; - int py = yo - 1; - int pw = w + 2; - int ph = h + 2; - intArray p = parent->getArea(px, py, pw, ph); + int px = xo - 1; + int py = yo - 1; + int pw = w + 2; + int ph = h + 2; + intArray p = parent->getArea(px, py, pw, ph); + intArray result = IntCache::allocate(w * h); + for (int y = 0; y < h; y++) + { + for (int x = 0; x < w; x++) + { + int l = p[(x + 0) + (y + 1) * pw]; + int r = p[(x + 2) + (y + 1) * pw]; + int u = p[(x + 1) + (y + 0) * pw]; + int d = p[(x + 1) + (y + 2) * pw]; + int c = p[(x + 1) + (y + 1) * pw]; - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - for (int x = 0; x < w; x++) - { - int l = p[(x + 0) + (y + 1) * pw]; - int r = p[(x + 2) + (y + 1) * pw]; - int u = p[(x + 1) + (y + 0) * pw]; - int d = p[(x + 1) + (y + 2) * pw]; - int c = p[(x + 1) + (y + 1) * pw]; - if (l == r && u == d) - { - initRandom((x + xo), (y + yo)); - if (nextRandom(2) == 0) c = l; - else c = u; + if (l == r && u == d) + { + initRandom(x + xo, y + yo); + if (nextRandom(2) == 0) c = l; + else c = u; + } + else if (l == r) + { + initRandom(x + xo, y + yo); + if (nextRandom(2) == 0) c = l; + } + else if (u == d) + { + c = u; + } - } - else - { - if (l == r) c = l; - if (u == d) c = u; - } - result[x + y * w] = c; - - } - } - - return result; + result[x + y * w] = c; + } + } + return result; } \ No newline at end of file diff --git a/Minecraft.World/VoronoiZoom.cpp b/Minecraft.World/VoronoiZoom.cpp index 63d0afab..46da5c71 100644 --- a/Minecraft.World/VoronoiZoom.cpp +++ b/Minecraft.World/VoronoiZoom.cpp @@ -2,88 +2,72 @@ #include "net.minecraft.world.level.newbiome.layer.h" #include "System.h" -VoronoiZoom::VoronoiZoom(int64_t seed, shared_ptr parent, int64_t seedMixup) : Layer(seedMixup) +VoronoiZoom::VoronoiZoom(int64_t seed, shared_ptr parent, int64_t seedMixup) : Layer(seed) { - this->parent = parent; + this->parent = parent; } intArray VoronoiZoom::getArea(int xo, int yo, int w, int h) { - xo -= 2; - yo -= 2; - int bits = 2; - int ss = 1 << bits; - int px = xo >> bits; - int py = yo >> bits; - int pw = (w >> bits) + 3; - int ph = (h >> bits) + 3; - intArray p = parent->getArea(px, py, pw, ph); + xo -= 2; + yo -= 2; + int px = xo >> 2; + int py = yo >> 2; + int pw = (w >> 2) + 2; + int ph = (h >> 2) + 2; + intArray p = parent->getArea(px, py, pw, ph); + int ww = pw << 2; + intArray tmp = IntCache::allocate(ww * (ph << 2)); - int ww = pw << bits; - int hh = ph << bits; - intArray tmp = IntCache::allocate(ww * hh); - for (int y = 0; y < ph - 1; y++) - { - int ul = p[(0 + 0) + (y + 0) * pw]; - int dl = p[(0 + 0) + (y + 1) * pw]; - for (int x = 0; x < pw - 1; x++) - { - double s = ss * 0.9; - initRandom((x + px) << bits, (y + py) << bits); - double x0 = (nextRandom(1024) / 1024.0 - 0.5) * s; - double y0 = (nextRandom(1024) / 1024.0 - 0.5) * s; - initRandom((x + px + 1) << bits, (y + py) << bits); - double x1 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; - double y1 = (nextRandom(1024) / 1024.0 - 0.5) * s; - initRandom((x + px) << bits, (y + py + 1) << bits); - double x2 = (nextRandom(1024) / 1024.0 - 0.5) * s; - double y2 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; - initRandom((x + px + 1) << bits, (y + py + 1) << bits); - double x3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; - double y3 = (nextRandom(1024) / 1024.0 - 0.5) * s + ss; + for (int y = 0; y < ph - 1; y++) + { + int ul = p[0 + y * pw]; + int dl = p[0 + (y + 1) * pw]; + for (int x = 0; x < pw - 1; x++) + { + initRandom((x + px) << 2, (y + py) << 2); + double x0 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6; + double y0 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6; + initRandom((x + px + 1) << 2, (y + py) << 2); + double x1 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0; + double y1 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6; + initRandom((x + px) << 2, (y + py + 1) << 2); + double x2 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6; + double y2 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0; + initRandom((x + px + 1) << 2, (y + py + 1) << 2); + double x3 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0; + double y3 = (nextRandom(1024) / 1024.0 - 0.5) * 3.6 + 4.0; + int ur = p[(x + 1) + y * pw]; + int dr = p[(x + 1) + (y + 1) * pw]; - int ur = p[(x + 1) + (y + 0) * pw]; - int dr = p[(x + 1) + (y + 1) * pw]; + for (int yy = 0; yy < 4; yy++) + { + int pp = ((y << 2) + yy) * ww + (x << 2); + for (int xx = 0; xx < 4; xx++) + { + double d0 = (xx - x0) * (xx - x0) + (yy - y0) * (yy - y0); + double d1 = (xx - x1) * (xx - x1) + (yy - y1) * (yy - y1); + double d2 = (xx - x2) * (xx - x2) + (yy - y2) * (yy - y2); + double d3 = (xx - x3) * (xx - x3) + (yy - y3) * (yy - y3); + if (d0 < d1 && d0 < d2 && d0 < d3) + tmp[pp++] = ul; + else if (d1 < d0 && d1 < d2 && d1 < d3) + tmp[pp++] = ur; + else if (d2 < d0 && d2 < d1 && d2 < d3) + tmp[pp++] = dl; + else + tmp[pp++] = dr; + } + } + ul = ur; + dl = dr; + } + } - for (int yy = 0; yy < ss; yy++) - { - int pp = ((y << bits) + yy) * ww + ((x << bits)); - for (int xx = 0; xx < ss; xx++) - { - double d0 = ((yy - y0) * (yy - y0) + (xx - x0) * (xx - x0)); - double d1 = ((yy - y1) * (yy - y1) + (xx - x1) * (xx - x1)); - double d2 = ((yy - y2) * (yy - y2) + (xx - x2) * (xx - x2)); - double d3 = ((yy - y3) * (yy - y3) + (xx - x3) * (xx - x3)); - - if (d0 < d1 && d0 < d2 && d0 < d3) - { - tmp[pp++] = ul; - } - else if (d1 < d0 && d1 < d2 && d1 < d3) - { - tmp[pp++] = ur; - } - else if (d2 < d0 && d2 < d1 && d2 < d3) - { - tmp[pp++] = dl; - } - else - { - tmp[pp++] = dr; - } - } - } - - ul = ur; - dl = dr; - } - } - intArray result = IntCache::allocate(w * h); - for (int y = 0; y < h; y++) - { - System::arraycopy(tmp, (y + (yo & (ss - 1))) * (pw << bits) + (xo & (ss - 1)), &result, y * w, w); - } - return result; + intArray result = IntCache::allocate(w * h); + for (int y = 0; y < h; y++) + System::arraycopy(tmp, (y + (yo & 3)) * ww + (xo & 3), &result, y * w, w); + return result; } int VoronoiZoom::random(int a, int b)