feat: worldgeneration using decomp

This commit is contained in:
Lord_Cambion 2026-04-13 17:45:07 +02:00
parent 0606ce717d
commit b512cc8f11
54 changed files with 1265 additions and 816 deletions

View file

@ -0,0 +1,106 @@
#include "stdafx.h"
#include "AddEdgeLayer.h"
#include "net.minecraft.world.level.biome.h"
#include "IntCache.h"
AddEdgeLayer::AddEdgeLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup, int mode)
: Layer(seedMixup)
{
this->parent = parent;
this->mode = mode;
}
intArray AddEdgeLayer::getArea(int xo, int yo, int w, int h)
{
if (mode == 1) return heatIce(xo, yo, w, h);
if (mode == 2) return introduceSpecial(xo, yo, w, h);
return coolWarm(xo, yo, w, h);
}
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)
{
int north = b[(ix + 1) + (iy + 0) * stride];
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;
}
result[ix + iy * w] = center;
}
}
return result;
}
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)
{
int center = b[(ix + 1) + (iy + 1) * stride];
if (center == 4)
{
int north = b[(ix + 1) + (iy + 0) * stride];
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)
center = 3;
}
result[ix + iy * w] = center;
}
}
return result;
}
intArray AddEdgeLayer::introduceSpecial(int xo, int yo, int w, int h)
{
intArray b = parent->getArea(xo, yo, w, h);
intArray result = IntCache::allocate(w * h);
for (int iy = 0; iy < h; ++iy)
{
for (int ix = 0; ix < w; ++ix)
{
initRandom(ix + xo, iy + yo);
int val = b[ix + iy * w];
if (val != 0)
{
if (nextRandom(13) == 0)
val |= ((nextRandom(15) + 1) << 8) & 0xF00;
}
result[ix + iy * w] = val;
}
}
return result;
}

View file

@ -0,0 +1,20 @@
#pragma once
#include "Layer.h"
class AddEdgeLayer : public Layer
{
private:
int mode;
intArray coolWarm(int xo, int yo, int w, int h);
intArray heatIce(int xo, int yo, int w, int h);
intArray introduceSpecial(int xo, int yo, int w, int h);
public:
AddEdgeLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup, int mode);
virtual ~AddEdgeLayer() {}
intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "net.minecraft.world.level.biome.h"
AddIslandLayer::AddIslandLayer(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
AddIslandLayer::AddIslandLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -5,7 +5,7 @@
class AddIslandLayer : public Layer
{
public:
AddIslandLayer(int64_t seedMixup, shared_ptr<Layer>parent);
AddIslandLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -3,7 +3,7 @@
#include "net.minecraft.world.level.biome.h"
AddMushroomIslandLayer::AddMushroomIslandLayer(int64_t seedMixup, shared_ptr<Layer> parent) : Layer(seedMixup)
AddMushroomIslandLayer::AddMushroomIslandLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -4,6 +4,6 @@
class AddMushroomIslandLayer : public Layer
{
public:
AddMushroomIslandLayer(int64_t seedMixup, shared_ptr<Layer> parent);
AddMushroomIslandLayer(int64_t seed, shared_ptr<Layer> parent,int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "net.minecraft.world.level.biome.h"
AddSnowLayer::AddSnowLayer(int64_t seedMixup, shared_ptr<Layer> parent) : Layer(seedMixup)
AddSnowLayer::AddSnowLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -4,6 +4,6 @@
class AddSnowLayer : public Layer
{
public:
AddSnowLayer(int64_t seedMixup, shared_ptr<Layer> parent);
AddSnowLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -527,4 +527,29 @@ int Biome::getRandomDoublePlantType(Random *random)
if (type == 7) return 3;
if (type == 8) return 4;
return 2;
}
Biome* Biome::getBiome(uint32_t id) {
if (id < 257) {
Biome* b = Biome::biomes[id];
if (b != nullptr) {
return b;
}
}
return Biome::ocean;
}
Biome* Biome::getBiome(uint32_t id, Biome* fallback) {
if (id < 257) {
Biome* b = Biome::biomes[id];
if (b != nullptr) {
return b;
}
return fallback;
}
return Biome::ocean;
}

View file

@ -227,5 +227,6 @@ public:
virtual int getGrassColor() const;
virtual Feature *getFlowerFeature(Random *random, int x, int y, int z);
virtual int getRandomDoublePlantType(Random *random);
Biome* getBiome(uint32_t id);
Biome* getBiome(uint32_t id, Biome* fallback);
};

View file

@ -0,0 +1,67 @@
#include "stdafx.h"
#include "BiomeEdgeLayer.h"
#include "net.minecraft.world.level.biome.h"
#include "IntCache.h"
BiomeEdgeLayer::BiomeEdgeLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}
intArray BiomeEdgeLayer::getArea(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 (!checkEdge(b, result, ix, iy, stride, Biome::extremeHills->id, Biome::smallerExtremeHills->id, center) &&
!checkEdge(b, result, ix, iy, stride, Biome::mesaPlateauF->id, Biome::mesaPlateau->id, center) &&
!checkEdge(b, result, ix, iy, stride, Biome::mesaPlateau->id, Biome::mesaPlateau->id, center) &&
!checkEdge(b, result, ix, iy, stride, Biome::megaTaiga->id, Biome::megaTaiga->id, center))
{
if (center == Biome::desert->id) {
int n = b[(ix + 1) + (iy + 0) * stride];
int e = b[(ix + 2) + (iy + 1) * stride];
int w1 = b[(ix + 0) + (iy + 1) * stride];
int s = b[(ix + 1) + (iy + 2) * stride];
if (n == Biome::iceFlats->id || e == Biome::iceFlats->id || w1 == Biome::iceFlats->id || s == Biome::iceFlats->id) {
center = Biome::extremeHills->id;
}
}
result[ix + iy * w] = center;
}
}
}
return result;
}
bool BiomeEdgeLayer::checkEdge(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int center)
{
if (center != biome) return false;
int n = b[(x + 1) + (y + 0) * w];
int e = b[(x + 2) + (y + 1) * w];
int w1 = b[(x + 0) + (y + 1) * w];
int s = b[(x + 1) + (y + 2) * w];
if (n != biome || e != biome || w1 != biome || s != biome)
{
result[x + y * (w-2)] = target;
return true;
}
return false;
}
bool BiomeEdgeLayer::isValidTemperatureEdge(int a1biome, int a2biome)
{
if (a1biome == a2biome) return true;
return true;
}

View file

@ -0,0 +1,15 @@
#pragma once
#include "Layer.h"
class BiomeEdgeLayer : public Layer
{
public:
BiomeEdgeLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual ~BiomeEdgeLayer() {}
virtual intArray getArea(int xo, int yo, int w, int h) override;
private:
static bool isValidTemperatureEdge(int a1biome, int a2biome);
bool checkEdge(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int replacement);
bool checkEdgeStrict(intArray& b, intArray& result, int x, int y, int w, int biome, int target, int replacement);
};

View file

@ -4,7 +4,7 @@
#include "net.minecraft.world.level.h"
#include "BiomeInitLayer.h"
BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, LevelType *levelType) : Layer(seed)
BiomeInitLayer::BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig) : Layer(seedMixup)
{
this->parent = parent;
bLegacy1_1 = (levelType == LevelType::lvl_normal_1_1);

View file

@ -1,25 +1,25 @@
#pragma once
#include "Layer.h"
class LevelType;
class BiomeInitLayer : public Layer
{
private:
BiomeArray startBiomes;
// matching Java GenLayerBiome
BiomeArray desertBiomes;
BiomeArray warmBiomes;
BiomeArray coolBiomes;
BiomeArray icyBiomes;
bool bLegacy1_1;
public:
BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, LevelType *levelType);
virtual ~BiomeInitLayer();
intArray getArea(int xo, int yo, int w, int h);
};
#pragma once
#include "Layer.h"
class LevelType;
class BiomeInitLayer : public Layer
{
private:
BiomeArray startBiomes;
// matching Java GenLayerBiome
BiomeArray desertBiomes;
BiomeArray warmBiomes;
BiomeArray coolBiomes;
BiomeArray icyBiomes;
bool bLegacy1_1;
public:
BiomeInitLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup, LevelType *levelType, void* superflatConfig);
virtual ~BiomeInitLayer();
intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -8,643 +8,460 @@
#include "../Minecraft.Client/Minecraft.h"
#include "../Minecraft.Client/ProgressRenderer.h"
// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3
void BiomeSource::_init()
{
layer = nullptr;
zoomedLayer = nullptr;
cache = new BiomeCache(this);
playerSpawnBiomes.push_back(Biome::forest);
playerSpawnBiomes.push_back(Biome::taiga);
// 4J-PB - Moving forward plains as a spawnable biome (mainly for the Superflat world)
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::taigaHills);
playerSpawnBiomes.push_back(Biome::forestHills);
playerSpawnBiomes.push_back(Biome::jungle);
playerSpawnBiomes.push_back(Biome::jungleHills);
playerSpawnBiomes.push_back(Biome::savanna);
playerSpawnBiomes.push_back(Biome::roofedForest);
playerSpawnBiomes.push_back(Biome::flowerForest);
playerSpawnBiomes.push_back(Biome::sunflowersPlains);
playerSpawnBiomes.push_back(Biome::iceSpikes);
layer = nullptr;
zoomedLayer = nullptr;
generatorOptions = L"";
cache = new BiomeCache(this);
playerSpawnBiomes.push_back(Biome::forest);
playerSpawnBiomes.push_back(Biome::taiga);
playerSpawnBiomes.push_back(Biome::plains);
playerSpawnBiomes.push_back(Biome::taigaHills);
playerSpawnBiomes.push_back(Biome::forestHills);
playerSpawnBiomes.push_back(Biome::jungle);
playerSpawnBiomes.push_back(Biome::jungleHills);
}
void BiomeSource::_init(int64_t seed, LevelType *generator, int xzSize)
{
_init();
LayerArray layers = Layer::getDefaultLayers(seed, generator);
layer = layers[0];
zoomedLayer = layers[1];
delete [] layers.data;
_init();
LayerArray layers = Layer::getDefaultLayers(seed, generator);
if (layers.length >= 2)
{
this->layer = layers.data[0];
this->zoomedLayer = layers.data[1];
layers.data = nullptr;
layers.length = 0;
}
}
BiomeSource::BiomeSource()
{
_init();
_init();
}
// 4J added
BiomeSource::BiomeSource(int64_t seed, LevelType *generator, int xzSize)
{
_init(seed, generator, xzSize);
_init(seed, generator, xzSize);
}
// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3
BiomeSource::BiomeSource(Level *level)
{
_init(level->getSeed(), level->getLevelData()->getGenerator(), level->getLevelData()->getXZSize());
_init(level->getSeed(), level->getLevelData()->getGenerator(), level->getLevelData()->getXZSize());
}
BiomeSource::~BiomeSource()
{
delete cache;
if (cache) {
delete cache;
cache = nullptr;
}
if (layer) { layer = nullptr; }
if (zoomedLayer) { zoomedLayer = nullptr; }
}
Biome *BiomeSource::getBiome(ChunkPos *cp)
{
return getBiome(cp->x << 4, cp->z << 4);
return getBiome(cp->x << 4, cp->z << 4);
}
Biome *BiomeSource::getBiome(int x, int z)
{
return cache->getBiome(x, z);
return cache->getBiome(x, z);
}
float BiomeSource::getDownfall(int x, int z) const
{
return cache->getDownfall(x, z);
return cache->getDownfall(x, z);
}
// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only.
floatArray BiomeSource::getDownfallBlock(int x, int z, int w, int h) const
{
floatArray downfalls;
getDownfallBlock(downfalls, x, z, w, h);
return downfalls;
floatArray downfalls;
getDownfallBlock(downfalls, x, z, w, h);
return downfalls;
}
// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only.
// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3
void BiomeSource::getDownfallBlock(floatArray &downfalls, int x, int z, int w, int h) const
{
IntCache::releaseAll();
//if (downfalls == nullptr || downfalls->length < w * h)
if (downfalls.data == nullptr || downfalls.length < w * h)
{
if(downfalls.data != nullptr) delete [] downfalls.data;
downfalls = floatArray(w * h);
}
IntCache::releaseAll();
if (downfalls.data == nullptr || downfalls.length < w * h)
{
if(downfalls.data != nullptr) delete [] downfalls.data;
downfalls = floatArray(w * h);
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
float d = static_cast<float>(Biome::biomes[result[i]]->getDownfallInt()) / 65536.0f;
if (d > 1) d = 1;
downfalls[i] = d;
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
float d = static_cast<float>(Biome::biomes[result[i]]->getDownfallInt()) / 65536.0f;
if (d > 1) d = 1;
downfalls[i] = d;
}
}
BiomeCache::Block *BiomeSource::getBlockAt(int x, int y)
{
return cache->getBlockAt(x, y);
return cache->getBlockAt(x, y);
}
float BiomeSource::getTemperature(int x, int y, int z) const
{
return scaleTemp(cache->getTemperature(x, z), y);
return scaleTemp(cache->getTemperature(x, z), y);
}
// 4J - brought forward from 1.2.3
float BiomeSource::scaleTemp(float temp, int y ) const
{
return temp;
return temp;
}
floatArray BiomeSource::getTemperatureBlock(int x, int z, int w, int h) const
{
floatArray temperatures;
getTemperatureBlock(temperatures, x, z, w, h);
return temperatures;
floatArray temperatures;
getTemperatureBlock(temperatures, x, z, w, h);
return temperatures;
}
// 4J - note that caller is responsible for deleting returned array. temperatures array is for output only.
// 4J - removal of separate temperature & downfall layers brought forward from 1.2.3
void BiomeSource::getTemperatureBlock(floatArray& temperatures, int x, int z, int w, int h) const
{
IntCache::releaseAll();
//if (temperatures == null || temperatures.length < w * h) {
if (temperatures.data == nullptr || temperatures.length < w * h)
{
if( temperatures.data != nullptr ) delete [] temperatures.data;
temperatures = floatArray(w * h);
}
IntCache::releaseAll();
if (temperatures.data == nullptr || temperatures.length < w * h)
{
if( temperatures.data != nullptr ) delete [] temperatures.data;
temperatures = floatArray(w * h);
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
float t = static_cast<float>(Biome::biomes[result[i]]->getTemperatureInt()) / 65536.0f;
if (t > 1) t = 1;
temperatures[i] = t;
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
float t = static_cast<float>(Biome::biomes[result[i]]->getTemperatureInt()) / 65536.0f;
if (t > 1) t = 1;
temperatures[i] = t;
}
}
BiomeArray BiomeSource::getRawBiomeBlock(int x, int z, int w, int h) const
{
BiomeArray biomes;
getRawBiomeBlock(biomes, x, z, w, h);
return biomes;
BiomeArray biomes;
getRawBiomeBlock(biomes, x, z, w, h);
return biomes;
}
// 4J added
void BiomeSource::getRawBiomeIndices(intArray &biomes, int x, int z, int w, int h) const
{
IntCache::releaseAll();
intArray result = layer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = result[i];
}
IntCache::releaseAll();
intArray result = layer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = result[i];
}
}
void BiomeSource::getRawBiomeBlock(BiomeArray &biomes, int x, int z, int w, int h) const
{
IntCache::releaseAll();
//if (biomes == null || biomes.length < w * h)
if (biomes.data == nullptr || biomes.length < w * h)
{
if(biomes.data != nullptr) delete [] biomes.data;
biomes = BiomeArray(w * h);
}
IntCache::releaseAll();
if (biomes.data == nullptr || biomes.length < w * h)
{
if(biomes.data != nullptr) delete [] biomes.data;
biomes = BiomeArray(w * h);
}
intArray result = layer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = Biome::biomes[result[i]];
intArray result = layer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = Biome::biomes[result[i]];
#ifndef _CONTENT_PACKAGE
if(biomes[i] == nullptr)
{
app.DebugPrintf("Tried to assign null biome %d\n", result[i]);
__debugbreak();
}
if(biomes[i] == nullptr)
{
app.DebugPrintf("Tried to assign null biome %d\n", result[i]);
__debugbreak();
}
#endif
}
}
}
BiomeArray BiomeSource::getBiomeBlock(int x, int z, int w, int h) const
{
if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
return cache->getBiomeBlockAt(x, z);
}
BiomeArray biomes;
getBiomeBlock(biomes, x, z, w, h, true);
return biomes;
if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
return cache->getBiomeBlockAt(x, z);
}
BiomeArray biomes;
getBiomeBlock(biomes, x, z, w, h, true);
return biomes;
}
// 4J - caller is responsible for deleting biomes array
void BiomeSource::getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, bool useCache) const
{
IntCache::releaseAll();
//if (biomes == null || biomes.length < w * h)
if (biomes.data == nullptr || biomes.length < w * h)
{
if(biomes.data != nullptr) delete [] biomes.data;
biomes = BiomeArray(w * h);
}
IntCache::releaseAll();
if (biomes.data == nullptr || biomes.length < w * h)
{
if(biomes.data != nullptr) delete [] biomes.data;
biomes = BiomeArray(w * h);
}
if (useCache && w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
BiomeArray tmp = cache->getBiomeBlockAt(x, z);
System::arraycopy(tmp, 0, &biomes, 0, w * h);
delete tmp.data; // MGH - added, the caching creates this array from the indices now.
//return biomes;
}
if (useCache && w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
BiomeArray tmp = cache->getBiomeBlockAt(x, z);
System::arraycopy(tmp, 0, &biomes, 0, w * h);
delete tmp.data;
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = Biome::biomes[result[i]];
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomes[i] = Biome::biomes[result[i]];
}
}
byteArray BiomeSource::getBiomeIndexBlock(int x, int z, int w, int h) const
{
if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
return cache->getBiomeIndexBlockAt(x, z);
}
byteArray biomeIndices;
getBiomeIndexBlock(biomeIndices, x, z, w, h, true);
return biomeIndices;
if (w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
return cache->getBiomeIndexBlockAt(x, z);
}
byteArray biomeIndices;
getBiomeIndexBlock(biomeIndices, x, z, w, h, true);
return biomeIndices;
}
// 4J - caller is responsible for deleting biomes array
void BiomeSource::getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const
{
IntCache::releaseAll();
//if (biomes == null || biomes.length < w * h)
if (biomeIndices.data == nullptr || biomeIndices.length < w * h)
{
if(biomeIndices.data != nullptr) delete [] biomeIndices.data;
biomeIndices = byteArray(w * h);
}
IntCache::releaseAll();
if (biomeIndices.data == nullptr || biomeIndices.length < w * h)
{
if(biomeIndices.data != nullptr) delete [] biomeIndices.data;
biomeIndices = byteArray(w * h);
}
if (useCache && w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
byteArray tmp = cache->getBiomeIndexBlockAt(x, z);
System::arraycopy(tmp, 0, &biomeIndices, 0, w * h);
//return biomes;
}
if (useCache && w == 16 && h == 16 && (x & 0xf) == 0 && (z & 0xf) == 0)
{
byteArray tmp = cache->getBiomeIndexBlockAt(x, z);
System::arraycopy(tmp, 0, &biomeIndices, 0, w * h);
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomeIndices[i] = static_cast<byte>(result[i]);
}
intArray result = zoomedLayer->getArea(x, z, w, h);
for (int i = 0; i < w * h; i++)
{
biomeIndices[i] = static_cast<byte>(result[i]);
}
}
/**
* Checks if an area around a block contains only the specified biomes.
* Useful for placing elements like towns.
*
* This is a bit of a rough check, to make it as fast as possible. To ensure
* NO other biomes, add a margin of at least four blocks to the radius
*/
bool BiomeSource::containsOnly(int x, int z, int r, vector<Biome *> allowed)
{
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
intArray biomes = layer->getArea(x0, z0, w, h);
for (int i = 0; i < w * h; i++)
{
Biome *b = Biome::biomes[biomes[i]];
if (find(allowed.begin(), allowed.end(), b) == allowed.end()) return false;
}
intArray biomes = layer->getArea(x0, z0, w, h);
for (int i = 0; i < w * h; i++)
{
Biome *b = Biome::biomes[biomes[i]];
if (find(allowed.begin(), allowed.end(), b) == allowed.end()) return false;
}
return true;
return true;
}
/**
* Checks if an area around a block contains only the specified biome.
* Useful for placing elements like towns.
*
* This is a bit of a rough check, to make it as fast as possible. To ensure
* NO other biomes, add a margin of at least four blocks to the radius
*/
bool BiomeSource::containsOnly(int x, int z, int r, Biome *allowed)
{
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
int w = x1 - x0;
int h = z1 - z0;
int biomesCount = w*h;
intArray biomes = layer->getArea(x0, z0, w, h);
for (unsigned int i = 0; i < biomesCount; i++)
{
Biome *b = Biome::biomes[biomes[i]];
if (allowed != b) return false;
}
int w = x1 - x0;
int h = z1 - z0;
int biomesCount = w*h;
intArray biomes = layer->getArea(x0, z0, w, h);
for (unsigned int i = 0; i < biomesCount; i++)
{
Biome *b = Biome::biomes[biomes[i]];
if (allowed != b) return false;
}
return true;
return true;
}
/**
* Finds the specified biome within the radius. This will return a random
* position if several are found. This test is fairly rough.
*
* Returns null if the biome wasn't found
*/
TilePos *BiomeSource::findBiome(int x, int z, int r, Biome *toFind, Random *random)
{
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
intArray biomes = layer->getArea(x0, z0, w, h);
TilePos *res = nullptr;
int found = 0;
int biomesCount = w*h;
for (unsigned int i = 0; i < biomesCount; i++)
{
int xx = x0 + i % w;
int zz = z0 + i / w;
Biome *b = Biome::biomes[biomes[i]];
if (b == toFind)
{
if (res == nullptr || random->nextInt(found + 1) == 0)
{
res = new TilePos(xx, 0, zz);
found++;
}
}
}
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
intArray biomes = layer->getArea(x0, z0, w, h);
TilePos *res = nullptr;
int found = 0;
int biomesCount = w*h;
for (unsigned int i = 0; i < biomesCount; i++)
{
int xx = x0 + i % w;
int zz = z0 + i / w;
Biome *b = Biome::biomes[biomes[i]];
if (b == toFind)
{
if (res == nullptr || random->nextInt(found + 1) == 0)
{
res = new TilePos(xx, 0, zz);
found++;
}
}
}
return res;
return res;
}
/**
* Finds one of the specified biomes within the radius. This will return a
* random position if several are found. This test is fairly rough.
*
* Returns null if the biome wasn't found
*/
TilePos *BiomeSource::findBiome(int x, int z, int r, vector<Biome *> allowed, Random *random)
{
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
IntCache::releaseAll();
int x0 = ((x - r) >> 2);
int z0 = ((z - r) >> 2);
int x1 = ((x + r) >> 2);
int z1 = ((z + r) >> 2);
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
MemSect(50);
intArray biomes = layer->getArea(x0, z0, w, h);
TilePos *res = nullptr;
int found = 0;
for (unsigned int i = 0; i < w * h; i++)
{
int xx = (x0 + i % w) << 2;
int zz = (z0 + i / w) << 2;
Biome *b = Biome::biomes[biomes[i]];
if (find(allowed.begin(), allowed.end(), b) != allowed.end())
{
if (res == nullptr || random->nextInt(found + 1) == 0)
{
delete res;
res = new TilePos(xx, 0, zz);
found++;
}
}
}
MemSect(0);
int w = x1 - x0 + 1;
int h = z1 - z0 + 1;
MemSect(50);
intArray biomes = layer->getArea(x0, z0, w, h);
TilePos *res = nullptr;
int found = 0;
for (unsigned int i = 0; i < w * h; i++)
{
int xx = (x0 + i % w) << 2;
int zz = (z0 + i / w) << 2;
Biome *b = Biome::biomes[biomes[i]];
if (find(allowed.begin(), allowed.end(), b) != allowed.end())
{
if (res == nullptr || random->nextInt(found + 1) == 0)
{
delete res;
res = new TilePos(xx, 0, zz);
found++;
}
}
}
MemSect(0);
return res;
return res;
}
void BiomeSource::update()
{
cache->update();
cache->update();
}
//#define DEBUG_SEEDS 50
// 4J added - find a seed for this biomesource that matches certain criteria
#ifdef __PSVITA__
int64_t BiomeSource::findSeed(LevelType *generator, bool* pServerRunning) // MGH - added pRunning, so we can early out of this on Vita as it can take up to 60 secs
int64_t BiomeSource::findSeed(LevelType *generator, bool* pServerRunning)
#else
int64_t BiomeSource::findSeed(LevelType *generator)
#endif
{
Random pr;
int64_t seed;
float fracs[256];
float groupFracs[8];
bool matchFound = false;
int tryCount = 0;
int64_t bestSeed = 0;
if (generator != nullptr && generator->m_generatorName != L"default")
{
return pr.nextLong();
}
ProgressRenderer *mcprogress = Minecraft::GetInstance()->progressRenderer;
mcprogress->progressStage(IDS_PROGRESS_NEW_WORLD_SEED);
do {
seed = pr.nextLong();
BiomeSource bs(seed, generator);
intArray indices = bs.layer->getArea(-100, -100, 200, 200);
if (indices.data != nullptr && indices.length > 0)
{
bs.getFracs(indices, fracs, groupFracs);
matchFound = bs.getIsMatch(fracs, groupFracs);
}
#ifndef _CONTENT_PACKAGE
if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_EnableBiomeOverride))
{
// Do nothing
}
else
#endif
{
#ifdef DEBUG_SEEDS
for( int k = 0; k < DEBUG_SEEDS; k++ )
#endif
{
// Try and genuinely random this search up
Random *pr = new Random(System::nanoTime());
tryCount++;
// Raw biome data has one result per 4x4 group of tiles.
// Removing a border of 8 from each side since we'll be doing special things at the edge to turn our world into an island, and so don't want to count things
// in the edge region in case they later get removed
static const int biomeWidth = ( 54 * 4 ) - 16; // Should be even so we can offset evenly
static const int biomeOffset = -( biomeWidth / 2 );
if (tryCount >= 100)
{
matchFound = true;
}
// Storage for our biome indices
intArray indices = intArray( biomeWidth * biomeWidth );
IntCache::releaseAll();
// Storage for the fractional amounts of each biome that will be calculated
float toCompare[Biome::BIOME_COUNT];
bool matchFound = false;
int tryCount = 0;
// Just keeping trying to generate seeds until we find one that matches our criteria
do
{
int64_t seed = pr->nextLong();
BiomeSource *biomeSource = new BiomeSource(seed,generator);
biomeSource->getRawBiomeIndices(indices, biomeOffset, biomeOffset, biomeWidth, biomeWidth);
getFracs(indices, toCompare);
matchFound = getIsMatch( toCompare );
if( matchFound ) bestSeed = seed;
delete biomeSource;
tryCount++;
mcprogress->progressStagePercentage( tryCount % 100 );
#ifdef __PSVITA__
} while (!matchFound && *pServerRunning);
} while (!matchFound && (*pServerRunning));
#else
} while (!matchFound);
} while (!matchFound);
#endif
// Clean up
delete pr;
delete indices.data;
#ifdef DEBUG_SEEDS
app.DebugPrintf("%d: %d tries taken, seed used is %lld\n", k, tryCount, bestSeed);
BiomeSource *biomeSource = new BiomeSource(bestSeed);
BiomeArray biomes = biomeSource->getBiomeBlock(-27 * 16, -27 * 16, 54 * 16, 54 * 16);
unsigned int *pixels = new unsigned int[54 * 16 * 54 * 16];
for(int i = 0; i < 54 * 16 * 54 * 16; i++ )
{
int id = biomes[i]->id;
// Create following colours:
// 0 ocean 0000 black
// 1 plains 0001 pastel cyan
// 2 desert 0010 green
// 3 extreme hills 0011 yellow
// 4 forest 0100 blue
// 5 taiga 0101 magenta
// 6 swamps 0110 cyan
// 7 river 0111 white
// 8 hell 1000 grey
// 9 end biome 1001 white
// 10 frozen ocean 1010 pastel green
// 11 frozen river 1011 pastel yellow
// 12 ice flats 1100 pastel blue
// 13 ice mountains 1101 pastel magenta
// 14 mushroom island 1110 red
// 15 mushroom shore 1111 pastel red
if( id == 1 ) id = 14;
else if ( id == 14 ) id = 1;
else if( id == 9 ) id = 15;
else if( id == 15 ) id = 9;
pixels[i] = 0xff000000;
if( id & 1 ) pixels[i] |= 0x00ff0000;
if( id & 2 ) pixels[i] |= 0x0000ff00;
if( id & 4 ) pixels[i] |= 0x000000ff;
if( id & 8 ) pixels[i] |= 0x00808080;
}
D3DXIMAGE_INFO srcInfo;
srcInfo.Format = D3DFMT_LIN_A8R8G8B8;
srcInfo.ImageFileFormat = D3DXIFF_BMP;
srcInfo.Width = 54 * 16;
srcInfo.Height = 54 * 16;
char buf[256];
sprintf(buf,"GAME:\\BiomeTest%d.bmp",k);
RenderManager.SaveTextureData(buf, &srcInfo, (int *)pixels);
delete [] pixels;
delete biomes.data;
delete biomeSource;
#endif
}
}
return bestSeed;
return seed;
}
// 4J added - get the fractional amounts of each biome type in the given indices
void BiomeSource::getFracs(intArray indices, float *fracs)
int BiomeSource::getBiomeGroup(int id)
{
for( int i = 0; i < Biome::BIOME_COUNT; i++ )
{
fracs[i] = 0.0f;
}
for( int i = 0; i < indices.length; i++ )
{
fracs[indices[i]] += 1.0f;
}
for( int i = 0; i < Biome::BIOME_COUNT; i++ )
{
fracs[i] /= static_cast<float>(indices.length);
}
return 0;
}
// 4J added - determine if this particular set of fractional amounts of biome types matches are requirements
bool BiomeSource::getIsMatch(float *frac)
void BiomeSource::getFracs(intArray indices, float *fracs, float *groupFracs)
{
// A true for a particular biome type here marks it as one that *has* to be present
static const bool critical[Biome::BIOME_COUNT] = {
true, // ocean
true, // plains
true, // desert
false, // extreme hills
true, // forest
true, // taiga
true, // swamps
false, // river
false, // hell
false, // end biome
false, // frozen ocean
false, // frozen river
false, // ice flats
false, // ice mountains
true, // mushroom island / shore
false, // mushroom shore (combined with above)
false, // beach
false, // desert hills (combined with desert)
false, // forest hills (combined with forest)
false, // taiga hills (combined with taga)
false, // small extreme hills
true, // jungle
false, // jungle hills (combined with jungle)
};
for (int i = 0; i < 256; i++) fracs[i] = 0.0f;
for (int i = 0; i < 8; i++) groupFracs[i] = 0.0f;
for (int i = 0; i < indices.length; i++)
{
int id = indices[i];
if (id >= 0 && id < 256)
{
fracs[id] += 1.0f;
int group = getBiomeGroup(id);
if (group >= 0 && group < 8)
{
groupFracs[group] += 1.0f;
}
}
}
// Don't want more than 15% ocean (normal + deep)
if (frac[0] + frac[24] > 0.15f)
{
return false;
}
float invLen = 1.0f / (float)indices.length;
for (int i = 0; i < 256; i++) fracs[i] *= invLen;
for (int i = 0; i < 8; i++) groupFracs[i] *= invLen;
}
// But we need some ocean to be present (critical[0])
frac[0] += frac[24];
bool BiomeSource::getIsMatch(float *fracs, float *groupFracs)
{
if (fracs[0] + fracs[24] > 0.15f) return false;
int varietyCount = 0;
for (int i = 0; i < 8; i++)
{
if (groupFracs[i] > 0.0f)
{
varietyCount++;
}
}
// Consider mushroom shore & islands as the same by finding max
frac[14] = ( ( frac[15] > frac[14] ) ? frac[15] : frac[14] );
// Merge desert and desert hills
frac[2] = ( ( frac[17] > frac[2] ) ? frac[17] : frac[2] );
// Merge forest and forest hills
frac[4] = ( ( frac[18] > frac[4] ) ? frac[18] : frac[4] );
// Merge taiga and taiga hills
frac[5] = ( ( frac[19] > frac[5] ) ? frac[19] : frac[5] );
// Merge jungle and jungle hills
frac[21] = ( ( frac[22] > frac[21] ) ? frac[22] : frac[21] );
// Loop through all biome types, and:
// (1) count them
// (2) give up if one of the critical ones is missing
int typeCount = 0;
for( int i = 0; i < Biome::BIOME_COUNT; i++ )
{
// We want to skip some where we have merged with another type
if(i == 15 || i == 17 || i == 18 || i == 19 || i == 22) continue;
// Consider 0.1% as being "present" - this equates an area of about 3 chunks
if( frac[i] > 0.001f )
{
typeCount++;
}
else
{
// If a critical biome is missing, just give up
if( critical[i] )
{
return false;
}
}
}
// Consider as suitable if we've got all the critical ones, and in total 9 or more - currently there's 8 critical so this just forces at least 1 more others
return ( typeCount >= 9 );
return varietyCount >= 5;
}

View file

@ -13,94 +13,68 @@ class LevelType;
class BiomeSource
{
private:
shared_ptr<Layer> layer;
shared_ptr<Layer> zoomedLayer;
shared_ptr<Layer> layer;
shared_ptr<Layer> zoomedLayer;
public:
static const int CACHE_DIAMETER = 256;
static const int CACHE_DIAMETER = 256;
private:
BiomeCache *cache;
vector<Biome *> playerSpawnBiomes;
BiomeCache *cache;
vector<Biome *> playerSpawnBiomes;
std::wstring generatorOptions;
protected:
void _init();
void _init(int64_t seed, LevelType *generator, int xzSize = 864);
void _init();
void _init(int64_t seed, LevelType *generator, int xzSize = 864);
BiomeSource();
public:
BiomeSource(int64_t seed, LevelType *generator, int xzSize = 864);
BiomeSource(int64_t seed, LevelType *generator, int xzSize = 864);
BiomeSource(Level *level);
private:
static bool getIsMatch(float *frac); // 4J added
static void getFracs(intArray indices, float *fracs); // 4J added
public:
#ifdef __PSVITA__
static int64_t findSeed(LevelType *generator, bool* pServerRunning); // MGH - added pRunning, so we can early out of this on Vita as it can take up to 60 secs // 4J added
#else
static int64_t findSeed(LevelType *generator); // 4J added
#endif
~BiomeSource();
public:
vector<Biome *> getPlayerSpawnBiomes() { return playerSpawnBiomes; }
~BiomeSource();
#ifdef __PSVITA__
static int64_t findSeed(LevelType *generator, bool* pServerRunning);
#else
static int64_t findSeed(LevelType *generator);
#endif
vector<Biome *> getPlayerSpawnBiomes() { return playerSpawnBiomes; }
virtual Biome *getBiome(ChunkPos *cp);
virtual Biome *getBiome(int x, int z);
// 4J - changed the interface for these methods, mainly for thread safety
virtual float getDownfall(int x, int z) const;
virtual float getDownfall(int x, int z) const;
virtual floatArray getDownfallBlock(int x, int z, int w, int h) const;
virtual void getDownfallBlock(floatArray &downfalls, int x, int z, int w, int h) const;
// 4J - changed the interface for these methods, mainly for thread safety
virtual BiomeCache::Block *getBlockAt(int x, int y);
virtual float getTemperature(int x, int y, int z) const;
float scaleTemp(float temp, int y ) const; // 4J - brought forward from 1.2.3
virtual floatArray getTemperatureBlock(int x, int z, int w, int h) const;
virtual BiomeCache::Block *getBlockAt(int x, int y);
virtual float getTemperature(int x, int y, int z) const;
float scaleTemp(float temp, int y) const;
virtual floatArray getTemperatureBlock(int x, int z, int w, int h) const;
virtual void getTemperatureBlock(floatArray& temperatures, int x, int z, int w, int h) const;
virtual BiomeArray getRawBiomeBlock(int x, int z, int w, int h) const;
virtual void getRawBiomeBlock(BiomeArray &biomes, int x, int z, int w, int h) const;
virtual void getRawBiomeIndices(intArray &biomes, int x, int z, int w, int h) const; // 4J added
virtual BiomeArray getBiomeBlock(int x, int z, int w, int h) const;
virtual BiomeArray getRawBiomeBlock(int x, int z, int w, int h) const;
virtual void getRawBiomeBlock(BiomeArray &biomes, int x, int z, int w, int h) const;
virtual void getRawBiomeIndices(intArray &biomes, int x, int z, int w, int h) const;
virtual BiomeArray getBiomeBlock(int x, int z, int w, int h) const;
virtual void getBiomeBlock(BiomeArray& biomes, int x, int z, int w, int h, bool useCache) const;
virtual byteArray getBiomeIndexBlock(int x, int z, int w, int h) const;
virtual void getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const;
virtual byteArray getBiomeIndexBlock(int x, int z, int w, int h) const;
virtual void getBiomeIndexBlock(byteArray& biomeIndices, int x, int z, int w, int h, bool useCache) const;
/**
* Checks if an area around a block contains only the specified biomes.
* Useful for placing elements like towns.
*
* This is a bit of a rough check, to make it as fast as possible. To ensure
* NO other biomes, add a margin of at least four blocks to the radius
*/
virtual bool containsOnly(int x, int z, int r, vector<Biome *> allowed);
virtual bool containsOnly(int x, int z, int r, vector<Biome *> allowed);
virtual bool containsOnly(int x, int z, int r, Biome *allowed);
/**
* Checks if an area around a block contains only the specified biome.
* Useful for placing elements like towns.
*
* This is a bit of a rough check, to make it as fast as possible. To ensure
* NO other biomes, add a margin of at least four blocks to the radius
*/
virtual bool containsOnly(int x, int z, int r, Biome *allowed);
virtual TilePos *findBiome(int x, int z, int r, Biome *toFind, Random *random);
virtual TilePos *findBiome(int x, int z, int r, vector<Biome *> allowed, Random *random);
/**
* Finds the specified biome within the radius. This will return a random
* position if several are found. This test is fairly rough.
*
* Returns null if the biome wasn't found
*/
virtual TilePos *findBiome(int x, int z, int r, Biome *toFind, Random *random);
void update();
/**
* Finds one of the specified biomes within the radius. This will return a
* random position if several are found. This test is fairly rough.
*
* Returns null if the biome wasn't found
*/
virtual TilePos *findBiome(int x, int z, int r, vector<Biome *> allowed, Random *random);
int getBiomeGroup(int id);
void getFracs(intArray indices, float* fracs, float* groupFracs);
void update();
};
private:
static bool getIsMatch(float* fracs, float* groupFracs);
};

View file

@ -0,0 +1,136 @@
#include "stdafx.h"
#include "CustomizableSourceSettings.h"
CustomizableSourceSettings::Builder::Builder()
{
setDefaults(this);
}
CustomizableSourceSettings::Builder* CustomizableSourceSettings::Builder::setDefaults(Builder* b)
{
b->coordinateScale = 684.412f;
b->heightScale = 684.412f;
b->upperLimitScale = 512.0f;
b->lowerLimitScale = 512.0f;
b->mainNoiseScaleX = 80.0f;
b->mainNoiseScaleY = 160.0f;
b->mainNoiseScaleZ = 80.0f;
b->depthNoiseScaleX = 200.0f;
b->depthNoiseScaleZ = 200.0f;
b->depthNoiseExponent = 0.5f;
b->biomeDepthWeight = 1.0f;
b->biomeDepthOffset = 0.0f;
b->biomeScaleWeight = 1.0f;
b->biomeScaleOffset = 0.0f;
b->baseSize = 8.5f;
b->stretchY = 12.0f;
b->seaLevel = 63;
b->useCaves = true;
b->useStrongholds = true;
b->biomeOverride = -1;
b->useDungeons = true;
b->dungeonChance = 8;
b->useTemples = true;
b->useMineShafts = true;
b->useVillages = true;
b->useRavines = true;
b->useWaterLakes = true;
b->waterLakeChance = 4;
b->useLavaLakes = true;
b->lavaLakeChance = 80;
b->useNether = false;
b->dirtSize = 33;
b->dirtCount = 10;
b->gravelSize = 33;
b->gravelCount = 8;
b->graniteSize = 33;
b->graniteCount = 10;
b->dioriteSize = 33;
b->dioriteCount = 10;
b->andesiteSize = 33;
b->andesiteCount = 10;
b->coalOreSize = 17;
b->coalOreCount = 20;
b->ironOreSize = 9;
b->ironOreCount = 20;
b->goldOreSize = 9;
b->goldOreCount = 2;
b->redstoneOreSize = 8;
b->redstoneOreCount = 8;
b->diamondOreSize = 8;
b->diamondOreCount = 1;
b->lapisOreSize = 7;
b->lapisOreCount = 1;
b->lapisOreHeight = 16;
b->lapisOreSpread = 16;
return b;
}
CustomizableSourceSettings::Builder* CustomizableSourceSettings::Builder::fromString(void* superflatConfig)
{
Builder* b = new Builder();
setDefaults(b);
// Logic to parse superflatConfig should go here if needed.
return b;
}
CustomizableSourceSettings* CustomizableSourceSettings::Builder::build(Builder* b)
{
CustomizableSourceSettings* s = new CustomizableSourceSettings();
s->coordinateScale = b->coordinateScale;
s->heightScale = b->heightScale;
s->upperLimitScale = b->upperLimitScale;
s->lowerLimitScale = b->lowerLimitScale;
s->mainNoiseScaleX = b->mainNoiseScaleX;
s->mainNoiseScaleY = b->mainNoiseScaleY;
s->mainNoiseScaleZ = b->mainNoiseScaleZ;
s->depthNoiseScaleX = b->depthNoiseScaleX;
s->depthNoiseScaleZ = b->depthNoiseScaleZ;
s->depthNoiseExponent = b->depthNoiseExponent;
s->biomeDepthWeight = b->biomeDepthWeight;
s->biomeDepthOffset = b->biomeDepthOffset;
s->biomeScaleWeight = b->biomeScaleWeight;
s->biomeScaleOffset = b->biomeScaleOffset;
s->baseSize = b->baseSize;
s->stretchY = b->stretchY;
s->seaLevel = b->seaLevel;
s->useCaves = b->useCaves;
s->useStrongholds = b->useStrongholds;
s->biomeOverride = b->biomeOverride;
s->useDungeons = b->useDungeons;
s->dungeonChance = b->dungeonChance;
s->useTemples = b->useTemples;
s->useMineShafts = b->useMineShafts;
s->useVillages = b->useVillages;
s->useRavines = b->useRavines;
s->useWaterLakes = b->useWaterLakes;
s->waterLakeChance = b->waterLakeChance;
s->useLavaLakes = b->useLavaLakes;
s->lavaLakeChance = b->lavaLakeChance;
s->useNether = b->useNether;
s->dirtSize = b->dirtSize;
s->dirtCount = b->dirtCount;
s->gravelSize = b->gravelSize;
s->gravelCount = b->gravelCount;
s->graniteSize = b->graniteSize;
s->graniteCount = b->graniteCount;
s->dioriteSize = b->dioriteSize;
s->dioriteCount = b->dioriteCount;
s->andesiteSize = b->andesiteSize;
s->andesiteCount = b->andesiteCount;
s->coalOreSize = b->coalOreSize;
s->coalOreCount = b->coalOreCount;
s->ironOreSize = b->ironOreSize;
s->ironOreCount = b->ironOreCount;
s->goldOreSize = b->goldOreSize;
s->goldOreCount = b->goldOreCount;
s->redstoneOreSize = b->redstoneOreSize;
s->redstoneOreCount = b->redstoneOreCount;
s->diamondOreSize = b->diamondOreSize;
s->diamondOreCount = b->diamondOreCount;
s->lapisOreSize = b->lapisOreSize;
s->lapisOreCount = b->lapisOreCount;
s->lapisOreHeight = b->lapisOreHeight;
s->lapisOreSpread = b->lapisOreSpread;
return s;
}

View file

@ -0,0 +1,174 @@

#pragma once
#include "FlatGeneratorInfo.h"
class CustomizableSourceSettings
{
public:
float mainNoiseScaleX;
float mainNoiseScaleY;
float mainNoiseScaleZ;
float depthNoiseScaleX;
float depthNoiseScaleZ;
float depthNoiseExponent;
float coordinateScale;
float heightScale;
float upperLimitScale;
float lowerLimitScale;
float biomeDepthWeight;
float biomeDepthOffset;
float biomeScaleWeight;
float biomeScaleOffset;
float baseSize;
float stretchY;
int seaLevel;
bool useCaves;
bool useStrongholds;
int biomeOverride;
bool useDungeons;
bool useTemples;
bool useMineShafts;
bool useVillages;
bool useRavines;
bool useWaterLakes;
bool useLavaLakes;
int dungeonChance;
int waterLakeChance;
int lavaLakeChance;
bool useNether;
int dirtSize;
int dirtCount;
int gravelSize;
int gravelCount;
int graniteSize;
int graniteCount;
int dioriteSize;
int dioriteCount;
int andesiteSize;
int andesiteCount;
int coalOreSize;
int coalOreCount;
int ironOreSize;
int ironOreCount;
int goldOreSize;
int goldOreCount;
int redstoneOreSize;
int redstoneOreCount;
int diamondOreSize;
int diamondOreCount;
int lapisOreSize;
int lapisOreCount;
int lapisOreHeight;
int lapisOreSpread;
int goldOreExtraSize;
int goldOreExtraCount;
int goldOreExtraHeight;
int emeraldOreSize;
int emeraldOreCount;
int silverfishSize;
int silverfishCount;
int silverfishHeight;
int quartzOreSize;
int quartzOreCount;
int quartzOreHeight;
int magmaSize;
int magmaCount;
int netherGoldSize;
int netherGoldCount;
int netherQuartzSize;
int netherQuartzCount;
int netherQuartzHeight;
int netherBrickSize;
int netherBrickCount;
int soulSandSize;
int soulSandCount;
int glowstoneSize;
int getBiomeOverride() const
{
if (biomeOverride == 8)
return -1;
return biomeOverride;
}
int getBiomeSize() { return *reinterpret_cast<int*>(reinterpret_cast<char*>(this) + 0x68); }
int getRiverSize() { return *reinterpret_cast<int*>(reinterpret_cast<char*>(this) + 0x6C); }
class Builder
{
public:
float mainNoiseScaleX;
float mainNoiseScaleY;
float mainNoiseScaleZ;
float depthNoiseScaleX;
float depthNoiseScaleZ;
float depthNoiseExponent;
float coordinateScale;
float heightScale;
float upperLimitScale;
float lowerLimitScale;
float biomeDepthWeight;
float biomeDepthOffset;
float biomeScaleWeight;
float biomeScaleOffset;
float baseSize;
float stretchY;
int seaLevel;
bool useCaves;
bool useStrongholds;
int biomeOverride;
bool useDungeons;
bool useTemples;
bool useMineShafts;
bool useVillages;
bool useRavines;
bool useWaterLakes;
bool useLavaLakes;
bool useNether;
int dungeonChance;
int waterLakeChance;
int lavaLakeChance;
int dirtSize, dirtCount;
int gravelSize, gravelCount;
int graniteSize, graniteCount;
int dioriteSize, dioriteCount;
int andesiteSize, andesiteCount;
int coalOreSize, coalOreCount;
int ironOreSize, ironOreCount;
int goldOreSize, goldOreCount;
int redstoneOreSize, redstoneOreCount;
int diamondOreSize, diamondOreCount;
int lapisOreSize, lapisOreCount;
int lapisOreHeight, lapisOreSpread;
int goldOreExtraSize, goldOreExtraCount, goldOreExtraHeight;
int emeraldOreSize, emeraldOreCount;
int silverfishSize, silverfishCount, silverfishHeight;
int quartzOreSize, quartzOreCount, quartzOreHeight;
int magmaSize, magmaCount;
int netherGoldSize, netherGoldCount;
int netherQuartzSize, netherQuartzCount, netherQuartzHeight;
int netherBrickSize, netherBrickCount;
int soulSandSize, soulSandCount;
int glowstoneSize;
Builder();
static Builder* setDefaults(Builder* b);
static Builder* fromString(void* superflatConfig);
static CustomizableSourceSettings* build(Builder* b);
};
};

View file

@ -3,7 +3,7 @@
#include "IntCache.h"
#include "DeepOceanLayer.h"
DeepOceanLayer::DeepOceanLayer(int64_t seed, shared_ptr<Layer> parent) : Layer(seed)
DeepOceanLayer::DeepOceanLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -5,7 +5,7 @@
class DeepOceanLayer : public Layer
{
public:
DeepOceanLayer(int64_t seed, shared_ptr<Layer> parent);
DeepOceanLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual ~DeepOceanLayer() {}
virtual intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -2,7 +2,7 @@
#include "System.h"
#include "net.minecraft.world.level.newbiome.layer.h"
FuzzyZoomLayer::FuzzyZoomLayer(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
FuzzyZoomLayer::FuzzyZoomLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}
@ -66,7 +66,7 @@ shared_ptr<Layer>FuzzyZoomLayer::zoom(int64_t seed, shared_ptr<Layer>sup, int co
shared_ptr<Layer> result = sup;
for (int i = 0; i < count; i++)
{
result = std::make_shared<FuzzyZoomLayer>(seed + i, result);
result = std::make_shared<FuzzyZoomLayer>(seed, result, 0x7D0 + i);
}
return result;
}

View file

@ -5,7 +5,7 @@
class FuzzyZoomLayer : public Layer
{
public:
FuzzyZoomLayer(int64_t seedMixup, shared_ptr<Layer>parent);
FuzzyZoomLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
intArray getArea(int xo, int yo, int w, int h);
protected:

View file

@ -3,7 +3,7 @@
#include "net.minecraft.world.level.biome.h"
GrowMushroomIslandLayer::GrowMushroomIslandLayer(int64_t seedMixup, shared_ptr<Layer> parent) : Layer(seedMixup)
GrowMushroomIslandLayer::GrowMushroomIslandLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -4,6 +4,6 @@
class GrowMushroomIslandLayer : public Layer
{
public:
GrowMushroomIslandLayer(int64_t seedMixup, shared_ptr<Layer> parent);
GrowMushroomIslandLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -0,0 +1,68 @@
#include "stdafx.h"
#include "ImposeContinentsLayer.h"
#include "IntCache.h"
bool dword_10073FD8[100] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
ImposeContinentsLayer::ImposeContinentsLayer(int64_t seed, shared_ptr<Layer> parent) : Layer(seed)
{
this->parent = parent;
}
ImposeContinentsLayer::~ImposeContinentsLayer()
{
}
intArray ImposeContinentsLayer::getArea(int xo, int yo, int w, int h)
{
intArray parentArea = parent->getArea(xo - 1, yo - 1, w + 2, h + 2);
intArray resultArea = IntCache::allocate(w * h);
int seedOffset = static_cast<int>(this->seedMixup);
for (int i = 0; i < h; ++i)
{
for (int j = 0; j < w; ++j)
{
int absX = xo + j;
int absY = yo + i;
int val = parentArea[(j + 1) + (i + 1) * (w + 2)];
if (absX != 0 || absY != 0)
{
int modX = (absX + seedOffset) % 10;
int modY = (absY + seedOffset) % 10;
if (modX < 0)
{
modX += 10;
}
if (modY < 0)
{
modY += 10;
}
if (!dword_10073FD8[modY * 10 + modX])
{
val = 0;
}
}
resultArea[j + i * w] = val;
}
}
return resultArea;
}

View file

@ -0,0 +1,12 @@
#pragma once
#include "Layer.h"
class ImposeContinentsLayer : public Layer
{
public:
ImposeContinentsLayer(int64_t seed, shared_ptr<Layer> parent);
virtual ~ImposeContinentsLayer();
virtual intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
IslandLayer::IslandLayer(int64_t seedMixup) : Layer(seedMixup)
IslandLayer::IslandLayer(int64_t seed, int64_t seedMixup) : Layer(seedMixup)
{
}

View file

@ -5,7 +5,7 @@
class IslandLayer : public Layer
{
public:
IslandLayer(int64_t seedMixup);
IslandLayer(int64_t seed, int64_t seedMixup);
intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -1,214 +1,201 @@
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
#include "net.minecraft.world.level.h"
#include "BiomeOverrideLayer.h"
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
#include "RiverInitLayer.h"
#include "RareBiomeSpotLayer.h"
#include "net.minecraft.world.level.h"
#include "BiomeOverrideLayer.h"
#include "CustomizableSourceSettings.h"
#ifdef __PSVITA__
// AP - this is used to perform fast 64bit divides of known values
#include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h"
#ifdef __PSVITA__
// AP - this is used to perform fast 64bit divides of known values
#include "../Minecraft.Client/PSVita/PSVitaExtras/libdivide.h"
#include <ImposeContinentsLayer.h>
libdivide::divider<long long> fast_d2(2);
libdivide::divider<long long> fast_d3(3);
libdivide::divider<long long> fast_d4(4);
libdivide::divider<long long> fast_d5(5);
libdivide::divider<long long> fast_d6(6);
libdivide::divider<long long> fast_d7(7);
libdivide::divider<long long> fast_d10(10);
#endif
LayerArray Layer::getDefaultLayers(int64_t seed, LevelType *levelType)
{
// 4J - Some changes moved here from 1.2.3. Temperature & downfall layers are no longer created & returned, and a debug layer is isn't.
// For reference with regard to future merging, things NOT brought forward from the 1.2.3 version are new layer types that we
// don't have yet (shores, swamprivers, region hills etc.)
shared_ptr<Layer>islandLayer = std::make_shared<IslandLayer>(1);
islandLayer = std::make_shared<FuzzyZoomLayer>(2000, islandLayer);
islandLayer = std::make_shared<AddIslandLayer>(1, islandLayer);
islandLayer = std::make_shared<ZoomLayer>(2001, islandLayer);
islandLayer = std::make_shared<AddIslandLayer>(2, islandLayer);
islandLayer = std::make_shared<RemoveTooMuchOceanLayer>(2, islandLayer);
islandLayer = std::make_shared<AddSnowLayer>(2, islandLayer);
islandLayer = std::make_shared<ZoomLayer>(2002, islandLayer);
islandLayer = std::make_shared<AddIslandLayer>(3, islandLayer);
islandLayer = std::make_shared<ZoomLayer>(2003, islandLayer);
islandLayer = std::make_shared<AddIslandLayer>(4, islandLayer);
libdivide::divider<long long> fast_d2(2);
libdivide::divider<long long> fast_d3(3);
libdivide::divider<long long> fast_d4(4);
libdivide::divider<long long> fast_d5(5);
libdivide::divider<long long> fast_d6(6);
libdivide::divider<long long> fast_d7(7);
libdivide::divider<long long> fast_d10(10);
#endif
// islandLayer = shared_ptr<Layer>(new AddMushroomIslandLayer(5, islandLayer)); // 4J - old position of mushroom island layer
LayerArray Layer::getDefaultLayers(int64_t seed, LevelType* levelType, void* superflatConfig) {
shared_ptr<Layer> islandLayer = std::make_shared<IslandLayer>(seed, 1);
islandLayer = std::make_shared<FuzzyZoomLayer>(seed, islandLayer, 0x7D0);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 1);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D1);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x32);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 0x46);
islandLayer = std::make_shared<RemoveTooMuchOceanLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddSnowLayer>(seed, islandLayer, 2);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 3);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 0);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 2, 1);
islandLayer = std::make_shared<AddEdgeLayer>(seed, islandLayer, 3, 2);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D2);
islandLayer = std::make_shared<ZoomLayer>(seed, islandLayer, 0x7D3);
islandLayer = std::make_shared<AddIslandLayer>(seed, islandLayer, 4);
islandLayer = std::make_shared<AddMushroomIslandLayer>(seed, islandLayer, 5);
islandLayer = std::make_shared<DeepOceanLayer>(seed, islandLayer, 4);
int zoomLevel = 4;
if (levelType == LevelType::lvl_largeBiomes)
shared_ptr<Layer> baseLayer = ZoomLayer::zoom(seed, islandLayer, 0x3E8, 0);
int zoomLevel = 4;
int riverZoomCount = 4;
if (levelType == LevelType::lvl_customized && superflatConfig != nullptr) {
auto settings = CustomizableSourceSettings::Builder::build(
CustomizableSourceSettings::Builder::fromString(superflatConfig));
zoomLevel = settings->getBiomeSize();
riverZoomCount = settings->getRiverSize();
}
if (levelType == LevelType::lvl_largeBiomes) {
zoomLevel = 6;
}
shared_ptr<Layer> riverInit = make_shared<RiverInitLayer>(seed, baseLayer, 0x64);
shared_ptr<Layer> hillsNoise = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2);
shared_ptr<Layer> riverLayerFinal = ZoomLayer::zoom(seed, riverInit, 0x3E8, 2);
riverLayerFinal = ZoomLayer::zoom(seed, riverLayerFinal, 0x3E8, riverZoomCount);
riverLayerFinal = make_shared<RiverLayer>(seed, riverLayerFinal, 1);
riverLayerFinal = make_shared<SmoothLayer>(seed, riverLayerFinal, 0x3E8);
shared_ptr<Layer> biomeLayer = make_shared<BiomeInitLayer>(seed, baseLayer, 0xC8, levelType, superflatConfig);
biomeLayer = ZoomLayer::zoom(seed, biomeLayer, 0x3E8, 2);
biomeLayer = make_shared<BiomeEdgeLayer>(seed, biomeLayer, 0x3E8);
biomeLayer = make_shared<RegionHillsLayer>(seed, biomeLayer, hillsNoise, 0x3E8);
biomeLayer = make_shared<RareBiomeSpotLayer>(seed, biomeLayer, 0x3E9);
for (int i = 0; i < zoomLevel; ++i) {
biomeLayer = make_shared<ZoomLayer>(seed, biomeLayer, 0x3E8 + i);
if (i == 0) {
biomeLayer = make_shared<AddIslandLayer>(seed, biomeLayer, 3);
}
if (i == 1 || zoomLevel == 1) {
biomeLayer = make_shared<ShoreLayer>(seed, biomeLayer, 0x3E8);
}
}
biomeLayer = make_shared<SmoothLayer>(seed, biomeLayer, 0x3E8);
shared_ptr<Layer> mixed = make_shared<RiverMixerLayer>(seed, biomeLayer, riverLayerFinal, 0x64);
shared_ptr<Layer> voronoi = make_shared<VoronoiZoom>(seed, mixed, 0xA);
mixed->init(seed);
voronoi->init(seed);
LayerArray result(3, false);
result[0] = mixed;
result[1] = voronoi;
result[2] = mixed;
return result;
}
Layer::Layer(int64_t seedMixup)
{
zoomLevel = 6;
parent = nullptr;
this->seedMixup = seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
}
shared_ptr<Layer> riverLayer = islandLayer;
riverLayer = ZoomLayer::zoom(1000, riverLayer, 0);
riverLayer = std::make_shared<RiverInitLayer>(100, riverLayer);
riverLayer = ZoomLayer::zoom(1000, riverLayer, zoomLevel + 2);
riverLayer = std::make_shared<RiverLayer>(1, riverLayer);
riverLayer = std::make_shared<SmoothLayer>(1000, riverLayer);
shared_ptr<Layer> biomeLayer = islandLayer;
biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 0);
biomeLayer = std::make_shared<BiomeInitLayer>(200, biomeLayer, levelType);
biomeLayer = ZoomLayer::zoom(1000, biomeLayer, 2);
shared_ptr<Layer> hillsNoise = islandLayer;
hillsNoise = ZoomLayer::zoom(1000, hillsNoise, 0);
hillsNoise = std::make_shared<RiverInitLayer>(100, hillsNoise);
hillsNoise = ZoomLayer::zoom(1000, hillsNoise, 2);
biomeLayer = std::make_shared<RegionHillsLayer>(1000, biomeLayer, hillsNoise);
biomeLayer = std::make_shared<RareBiomeLayer>(1001, biomeLayer);
for (int i = 0; i < zoomLevel; i++)
void Layer::initRandom(int64_t x, int64_t y)
{
biomeLayer = std::make_shared<ZoomLayer>(1000 + i, biomeLayer);
rval = seed;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
}
if (i == 0) biomeLayer = std::make_shared<AddIslandLayer>(3, biomeLayer);
if (i == 0)
int Layer::nextRandom(int max)
{
#ifdef __PSVITA__
// AP - 64bit mods are very slow on Vita. Replaced with a divide/mult for general case and a fast divide library for specific numbers
// todo - this can sometimes yield a different number to the original. There's a strange bug sometimes with Vita where if the line
// "result = (int) ((rval >> 24) % max);" is done twice in a row 'result' will not be the same. Need to speak to Sony about that
// Also need to compare level against a different platform using the same seed
int result;
long long temp = rval;
temp >>= 24;
if( max == 2 )
{
// 4J - moved mushroom islands to here. This skips 3 zooms that the old location of the add was, making them about 1/8 of the original size. Adding
// them at this scale actually lets us place them near enough other land, if we add them at the same scale as java then they have to be too far out to see for
// the scale of our maps
biomeLayer = std::make_shared<AddMushroomIslandLayer>(5, biomeLayer);
//Adding Deep Ocean here as well, now that we are at a suitable scale for LCE maps.
biomeLayer = std::make_shared<DeepOceanLayer>(4, biomeLayer);
result = temp-(temp/fast_d2)*2;
}
if (i == 1 )
else if( max == 3 )
{
// 4J - now expand mushroom islands up again. This does a simple region grow to add a new mushroom island element when any of the neighbours are also mushroom islands.
// This helps make the islands into nice compact shapes of the type that are actually likely to be able to make an island out of the sea in a small space. Also
// helps the shore layer from doing too much damage in shrinking the islands we are making
biomeLayer = std::make_shared<GrowMushroomIslandLayer>(5, biomeLayer);
// Note - this reduces the size of mushroom islands by turning their edges into shores. We are doing this at i == 1 rather than i == 0 as the original does
biomeLayer = std::make_shared<ShoreLayer>(1000, biomeLayer);
biomeLayer = std::make_shared<SwampRiversLayer>(1000, biomeLayer);
result = temp-(temp/fast_d3)*3;
}
else if( max == 4 )
{
result = temp-(temp/fast_d4)*4;
}
else if( max == 5 )
{
result = temp-(temp/fast_d5)*5;
}
else if( max == 6 )
{
result = temp-(temp/fast_d6)*6;
}
else if( max == 7 )
{
result = temp-(temp/fast_d7)*7;
}
else if( max == 10 )
{
result = temp-(temp/fast_d10)*10;
}
else
{
result = temp-(temp/max)*max;
}
#else
int result = static_cast<int>((rval >> 24) % max);
#endif
if (result < 0) result += max;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += seed;
return result;
}
biomeLayer = std::make_shared<SmoothLayer>(1000, biomeLayer);
biomeLayer = std::make_shared<RiverMixerLayer>(100, biomeLayer, riverLayer);
#ifndef _CONTENT_PACKAGE
#ifdef _BIOME_OVERRIDE
if(app.DebugSettingsOn() && app.GetGameSettingsDebugMask(ProfileManager.GetPrimaryPad())&(1L<<eDebugSetting_EnableBiomeOverride))
{
biomeLayer = std::make_shared<BiomeOverrideLayer>(1);
}
#endif
#endif
shared_ptr<Layer> debugLayer = biomeLayer;
shared_ptr<Layer>zoomedLayer = std::make_shared<VoronoiZoom>(10, biomeLayer);
biomeLayer->init(seed);
zoomedLayer->init(seed);
LayerArray result(3);
result[0] = biomeLayer;
result[1] = zoomedLayer;
result[2] = debugLayer;
return result;
}
Layer::Layer(int64_t seedMixup)
void Layer::init(int64_t seed)
{
parent = nullptr;
this->seedMixup = seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
this->seedMixup *= this->seedMixup * 6364136223846793005l + 1442695040888963407l;
this->seedMixup += seedMixup;
}
void Layer::init(int64_t seed)
{
this->seed = seed;
if (parent != nullptr) parent->init(seed);
this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005l + 1442695040888963407l;
this->seed += seedMixup;
}
void Layer::initRandom(int64_t x, int64_t y)
{
rval = seed;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += x;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += y;
}
int Layer::nextRandom(int max)
{
#ifdef __PSVITA__
// AP - 64bit mods are very slow on Vita. Replaced with a divide/mult for general case and a fast divide library for specific numbers
// todo - this can sometimes yield a different number to the original. There's a strange bug sometimes with Vita where if the line
// "result = (int) ((rval >> 24) % max);" is done twice in a row 'result' will not be the same. Need to speak to Sony about that
// Also need to compare level against a different platform using the same seed
int result;
long long temp = rval;
temp >>= 24;
if( max == 2 )
{
result = temp-(temp/fast_d2)*2;
}
else if( max == 3 )
{
result = temp-(temp/fast_d3)*3;
}
else if( max == 4 )
{
result = temp-(temp/fast_d4)*4;
}
else if( max == 5 )
{
result = temp-(temp/fast_d5)*5;
}
else if( max == 6 )
{
result = temp-(temp/fast_d6)*6;
}
else if( max == 7 )
{
result = temp-(temp/fast_d7)*7;
}
else if( max == 10 )
{
result = temp-(temp/fast_d10)*10;
}
else
{
result = temp-(temp/max)*max;
}
#else
int result = static_cast<int>((rval >> 24) % max);
#endif
if (result < 0) result += max;
rval *= rval * 6364136223846793005l + 1442695040888963407l;
rval += seed;
return result;
}
this->seed = seed;
if (parent != nullptr) parent->init(seed);
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed += seedMixup;
this->seed *= this->seed * 6364136223846793005LL + 1442695040888963407LL;
this->seed += seedMixup;
}

View file

@ -16,12 +16,12 @@ private:
protected:
shared_ptr<Layer>parent;
private:
protected:
int64_t rval;
int64_t seedMixup;
public:
static LayerArray getDefaultLayers(int64_t seed, LevelType *levelType);
static LayerArray getDefaultLayers(int64_t seed, LevelType *levelType, void* superflatConfig = nullptr);
Layer(int64_t seedMixup);

View file

@ -18,6 +18,7 @@ LevelType *LevelType::lvl_normal=nullptr;// = new LevelType(0, "default", 1).set
LevelType *LevelType::lvl_flat=nullptr;// = new LevelType(1, "flat");
LevelType *LevelType::lvl_largeBiomes = nullptr;// = new LevelType(2, "largeBiomes");
LevelType *LevelType::lvl_normal_1_1=nullptr;// = new LevelType(8, "default_1_1", 0).setSelectableByUser(false);
LevelType *LevelType::lvl_customized = nullptr;
void LevelType::staticCtor()
{
@ -28,6 +29,7 @@ void LevelType::staticCtor()
lvl_largeBiomes = new LevelType(2, L"largeBiomes");
lvl_normal_1_1 = new LevelType(8, L"default_1_1", 0);
lvl_normal_1_1->setSelectableByUser(false);
lvl_customized = new LevelType(4, L"customized");
}
LevelType::LevelType(int id, wstring generatorName)

View file

@ -9,13 +9,14 @@ public:
static LevelType *lvl_normal;// = new LevelType(0, "default", 1).setHasReplacement();
static LevelType *lvl_flat;// = new LevelType(1, "flat");
static LevelType *lvl_largeBiomes;// = new LevelType(2, "largeBiomes");
static LevelType *lvl_customized;
static LevelType *lvl_normal_1_1;// = new LevelType(8, "default_1_1", 0).setSelectableByUser(false);
static void staticCtor();
wstring m_generatorName;
private:
int id;
wstring m_generatorName;
int m_version;
bool m_selectable;
bool m_replacement;

View file

@ -0,0 +1,14 @@
#include "stdafx.h"
#include "RareBiomeSpotLayer.h"
#include "IntCache.h"
RareBiomeSpotLayer::RareBiomeSpotLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}
intArray RareBiomeSpotLayer::getArea(int xo, int yo, int w, int h)
{
return parent->getArea(xo, yo, w, h);
}

View file

@ -0,0 +1,10 @@
#pragma once
#include "Layer.h"
#include <memory>
class RareBiomeSpotLayer : public Layer
{
public:
RareBiomeSpotLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -11,7 +11,7 @@ RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent) : Lay
this->riverNoise = nullptr;
}
RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent, shared_ptr<Layer> riverNoise) : Layer(seed)
RegionHillsLayer::RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent, shared_ptr<Layer> riverNoise, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
this->riverNoise = riverNoise;

View file

@ -9,7 +9,7 @@ private:
public:
RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent);
RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent, shared_ptr<Layer> riverNoise);
RegionHillsLayer(int64_t seed, shared_ptr<Layer> parent, shared_ptr<Layer> riverNoise, int64_t seedMixup);
virtual void init(int64_t seed) override;
virtual intArray getArea(int xo, int yo, int w, int h) override;

View file

@ -3,7 +3,7 @@
#include "IntCache.h"
#include "RemoveTooMuchOceanLayer.h"
RemoveTooMuchOceanLayer::RemoveTooMuchOceanLayer(int64_t seed, shared_ptr<Layer> parent) : Layer(seed)
RemoveTooMuchOceanLayer::RemoveTooMuchOceanLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}
@ -26,15 +26,19 @@ intArray RemoveTooMuchOceanLayer::getArea(int xo, int yo, int w, int h)
int i2 = aint[j1 + 1 - 1 + (i1 + 1) * (w + 2)];
int j2 = aint[j1 + 1 + (i1 + 1 + 1) * (w + 2)];
int k2 = aint[j1 + 1 + (i1 + 1) * k];
aint1[j1 + i1 * w] = k2;
this->initRandom((int64_t)(j1 + xo), (int64_t)(i1 + yo));
if (k2 == 0 && k1 == 0 && l1 == 0 && i2 == 0 && j2 == 0)
{
aint1[j1 + i1 * w] = 1;
if (this->nextRandom(2) == 0)
{
aint1[j1 + i1 * w] = 1;
}
}
}
}
return aint1;
}
}

View file

@ -5,7 +5,7 @@
class RemoveTooMuchOceanLayer : public Layer
{
public:
RemoveTooMuchOceanLayer(int64_t seed, shared_ptr<Layer> parent);
RemoveTooMuchOceanLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual ~RemoveTooMuchOceanLayer() {}
virtual intArray getArea(int xo, int yo, int w, int h) override;
};

View file

@ -1,7 +1,8 @@
#include "stdafx.h"
#include "RiverInitLayer.h"
#include "net.minecraft.world.level.newbiome.layer.h"
RiverInitLayer::RiverInitLayer(int64_t seed, shared_ptr<Layer>parent) : Layer(seed)
RiverInitLayer::RiverInitLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -1,11 +1,11 @@
#pragma once
#include "Layer.h"
#include <memory>
class RiverInitLayer : public Layer
{
public:
RiverInitLayer(int64_t seed, shared_ptr<Layer>parent);
RiverInitLayer(int64_t seed, std::shared_ptr<Layer> parent, int64_t seedMixup);
intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.biome.h"
#include "net.minecraft.world.level.newbiome.layer.h"
RiverLayer::RiverLayer(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
RiverLayer::RiverLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -5,6 +5,6 @@
class RiverLayer : public Layer
{
public:
RiverLayer(int64_t seedMixup, shared_ptr<Layer>parent);
RiverLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.biome.h"
#include "net.minecraft.world.level.newbiome.layer.h"
RiverMixerLayer::RiverMixerLayer(int64_t seed, shared_ptr<Layer>biomes, shared_ptr<Layer>rivers) : Layer(seed)
RiverMixerLayer::RiverMixerLayer(int64_t seed, shared_ptr<Layer> biomes, shared_ptr<Layer> rivers, int64_t seedMixup) : Layer(seedMixup)
{
this->biomes = biomes;
this->rivers = rivers;

View file

@ -9,7 +9,7 @@ private:
shared_ptr<Layer>rivers;
public:
RiverMixerLayer(int64_t seed, shared_ptr<Layer>biomes, shared_ptr<Layer>rivers);
RiverMixerLayer(int64_t seed, shared_ptr<Layer> biomes, shared_ptr<Layer> rivers, int64_t seedMixup);
virtual void init(int64_t seed);
virtual intArray getArea(int xo, int yo, int w, int h);

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "net.minecraft.world.level.biome.h"
ShoreLayer::ShoreLayer(int64_t seed, shared_ptr<Layer> parent) : Layer(seed)
ShoreLayer::ShoreLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -4,6 +4,6 @@
class ShoreLayer : public Layer
{
public:
ShoreLayer(int64_t seed, shared_ptr<Layer> parent);
ShoreLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -1,7 +1,7 @@
#include "stdafx.h"
#include "net.minecraft.world.level.newbiome.layer.h"
SmoothLayer::SmoothLayer(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
SmoothLayer::SmoothLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -5,7 +5,7 @@
class SmoothLayer : public Layer
{
public:
SmoothLayer(int64_t seedMixup, shared_ptr<Layer>parent);
SmoothLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
};

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "System.h"
VoronoiZoom::VoronoiZoom(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
VoronoiZoom::VoronoiZoom(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}

View file

@ -5,7 +5,7 @@
class VoronoiZoom : public Layer
{
public:
VoronoiZoom(int64_t seedMixup, shared_ptr<Layer>parent);
VoronoiZoom(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);

View file

@ -2,7 +2,7 @@
#include "net.minecraft.world.level.newbiome.layer.h"
#include "System.h"
ZoomLayer::ZoomLayer(int64_t seedMixup, shared_ptr<Layer>parent) : Layer(seedMixup)
ZoomLayer::ZoomLayer(int64_t seed, shared_ptr<Layer> parent, int64_t seedMixup) : Layer(seedMixup)
{
this->parent = parent;
}
@ -81,12 +81,12 @@ int ZoomLayer::random(int a, int b, int c, int d)
return d;
}
shared_ptr<Layer>ZoomLayer::zoom(int64_t seed, shared_ptr<Layer> sup, int count)
shared_ptr<Layer>ZoomLayer::zoom(int64_t seed, shared_ptr<Layer> sup, int64_t seedMixup, int count)
{
shared_ptr<Layer>result = sup;
for (int i = 0; i < count; i++)
{
result = std::make_shared<ZoomLayer>(seed + i, result);
result = std::make_shared<ZoomLayer>(seed, result, seedMixup + i);
}
return result;
}

View file

@ -5,7 +5,7 @@
class ZoomLayer : public Layer
{
public:
ZoomLayer(int64_t seedMixup, shared_ptr<Layer> parent);
ZoomLayer(int64_t seed, shared_ptr<Layer> parent,int64_t seedMixup);
virtual intArray getArea(int xo, int yo, int w, int h);
@ -14,5 +14,5 @@ protected:
int random(int a, int b, int c, int d);
public:
static shared_ptr<Layer> zoom(int64_t seed, shared_ptr<Layer>sup, int count);
static shared_ptr<Layer> zoom(int64_t seed, shared_ptr<Layer> sup, int64_t seedMixup, int count);
};

View file

@ -1629,6 +1629,8 @@ source_group("net/minecraft/world/level/material" FILES ${_MINECRAFT_WORLD_COMMO
set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER
"${CMAKE_CURRENT_SOURCE_DIR}/AddIslandLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/AddIslandLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/AddEdgeLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/AddEdgeLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/AddMushroomIslandLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/AddMushroomIslandLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/AddSnowLayer.cpp"
@ -1637,6 +1639,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER
"${CMAKE_CURRENT_SOURCE_DIR}/BiomeInitLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/BiomeOverrideLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/BiomeOverrideLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/BiomeEdgeLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/BiomeEdgeLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/DownfallLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/DownfallLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/DownfallMixerLayer.cpp"
@ -1653,8 +1657,12 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER
"${CMAKE_CURRENT_SOURCE_DIR}/IslandLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/Layer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/Layer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ImposeContinentsLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/ImposeContinentsLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RegionHillsLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RegionHillsLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeSpotLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeSpotLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/RiverInitLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RiverInitLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/RiverLayer.cpp"
@ -1683,6 +1691,8 @@ set(_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER
"${CMAKE_CURRENT_SOURCE_DIR}/RemoveTooMuchOceanLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeLayer.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/RareBiomeLayer.h"
"${CMAKE_CURRENT_SOURCE_DIR}/CustomizableSourceSettings.cpp"
"${CMAKE_CURRENT_SOURCE_DIR}/CustomizableSourceSettings.h"
"${CMAKE_CURRENT_SOURCE_DIR}/net.minecraft.world.level.newbiome.layer.h"
)
source_group("net/minecraft/world/level/newbiome/layer" FILES ${_MINECRAFT_WORLD_COMMON_NET_MINECRAFT_WORLD_LEVEL_NEWBIOME_LAYER})

View file

@ -1,6 +1,7 @@
#pragma once
#include "AddIslandLayer.h"
#include "AddEdgeLayer.h"
#include "AddMushroomIslandLayer.h"
#include "AddSnowLayer.h"
#include "BiomeInitLayer.h"
@ -28,4 +29,8 @@
// 1.1.
#include "RegionHillsLayer.h"
#include "SwampRiversLayer.h"
#include "SwampRiversLayer.h"
#include "RareBiomeSpotLayer.h"
#include "BiomeEdgeLayer.h"
#include "ImposeContinentsLayer.h"