- 5,018
- 47
- 783
В общем, сидел я такой гудел, пытался сделать мир. В итоге вроде что то получилось, но вот беда - почему то ни в какую не хочет мой WorldProvider подгружать мой биом. При заходе в мой мир биом\биомы остается\остаются теми же, которые были в ванилле на тот момент когда я покидал мир. Я перепробовал уже все, поудалял все-все что только можно, но выяснить в чем ошибка, даже теперь не могу. Спустя двое суток еб... беготни, я решил все таки написать на форум с этой проблемой.
Я прилагаю полный код всего что наделал, если кто шарит в мирах, взгляните пожалуйста, может быть вы скажете, что не так.
Ну и биомпровайдер еще есть, но не считая того что ванильные биомы там заменены на один мой пока, он ничем от ванильного не отличается.
Я прилагаю полный код всего что наделал, если кто шарит в мирах, взгляните пожалуйста, может быть вы скажете, что не так.
Java:
public class RealismChunkGenerator implements IChunkGenerator
{
protected static final IBlockState STONE = BlocksList.MAGMATIC_STONE.getDefaultState();
private final Random rand;
private NoiseGeneratorOctaves minLimitPerlinNoise;
private NoiseGeneratorOctaves maxLimitPerlinNoise;
private NoiseGeneratorOctaves mainPerlinNoise;
private NoiseGeneratorPerlin surfaceNoise;
public NoiseGeneratorOctaves scaleNoise;
public NoiseGeneratorOctaves depthNoise;
public NoiseGeneratorOctaves forestNoise;
private final World world;
private final boolean mapFeaturesEnabled;
private final WorldType terrainType;
private final double[] heightMap;
private final float[] biomeWeights;
private ChunkGeneratorSettings settings;
private IBlockState oceanBlock = Blocks.WATER.getDefaultState();
private double[] depthBuffer = new double[256];
private Biome[] biomesForGeneration;
double[] mainNoiseRegion;
double[] minLimitRegion;
double[] maxLimitRegion;
double[] depthRegion;
public RealismChunkGenerator(World worldIn, long seed, boolean mapFeaturesEnabledIn, String generatorOptions)
{
this.world = worldIn;
this.mapFeaturesEnabled = mapFeaturesEnabledIn;
this.terrainType = worldIn.getWorldInfo().getTerrainType();
this.rand = new Random(seed);
this.minLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.maxLimitPerlinNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.mainPerlinNoise = new NoiseGeneratorOctaves(this.rand, 8);
this.surfaceNoise = new NoiseGeneratorPerlin(this.rand, 4);
this.scaleNoise = new NoiseGeneratorOctaves(this.rand, 10);
this.depthNoise = new NoiseGeneratorOctaves(this.rand, 16);
this.forestNoise = new NoiseGeneratorOctaves(this.rand, 8);
this.heightMap = new double[825];
this.biomeWeights = new float[25];
for (int i = -2; i <= 2; ++i)
{
for (int j = -2; j <= 2; ++j)
{
float f = 10.0F / MathHelper.sqrt((float)(i * i + j * j) + 0.2F);
this.biomeWeights[i + 2 + (j + 2) * 5] = f;
}
}
if (generatorOptions != null)
{
this.settings = ChunkGeneratorSettings.Factory.jsonToFactory(generatorOptions).build();
this.oceanBlock = this.settings.useLavaOceans ? Blocks.LAVA.getDefaultState() : Blocks.WATER.getDefaultState();
worldIn.setSeaLevel(this.settings.seaLevel);
}
net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld ctx =
new net.minecraftforge.event.terraingen.InitNoiseGensEvent.ContextOverworld(minLimitPerlinNoise, maxLimitPerlinNoise, mainPerlinNoise, surfaceNoise, scaleNoise, depthNoise, forestNoise);
ctx = net.minecraftforge.event.terraingen.TerrainGen.getModdedNoiseGenerators(worldIn, this.rand, ctx);
this.minLimitPerlinNoise = ctx.getLPerlin1();
this.maxLimitPerlinNoise = ctx.getLPerlin2();
this.mainPerlinNoise = ctx.getPerlin();
this.surfaceNoise = ctx.getHeight();
this.scaleNoise = ctx.getScale();
this.depthNoise = ctx.getDepth();
this.forestNoise = ctx.getForest();
}
public void setBlocksInChunk(int x, int z, ChunkPrimer primer)
{
this.biomesForGeneration = this.world.getBiomeProvider().getBiomesForGeneration(this.biomesForGeneration, x * 4 - 2, z * 4 - 2, 10, 10);
this.generateHeightmap(x * 4, 0, z * 4);
for (int i = 0; i < 4; ++i)
{
int j = i * 5;
int k = (i + 1) * 5;
for (int l = 0; l < 4; ++l)
{
int i1 = (j + l) * 33;
int j1 = (j + l + 1) * 33;
int k1 = (k + l) * 33;
int l1 = (k + l + 1) * 33;
for (int i2 = 0; i2 < 32; ++i2)
{
double d0 = 0.125D;
double d1 = this.heightMap[i1 + i2];
double d2 = this.heightMap[j1 + i2];
double d3 = this.heightMap[k1 + i2];
double d4 = this.heightMap[l1 + i2];
double d5 = (this.heightMap[i1 + i2 + 1] - d1) * 0.125D;
double d6 = (this.heightMap[j1 + i2 + 1] - d2) * 0.125D;
double d7 = (this.heightMap[k1 + i2 + 1] - d3) * 0.125D;
double d8 = (this.heightMap[l1 + i2 + 1] - d4) * 0.125D;
for (int j2 = 0; j2 < 8; ++j2)
{
double d9 = 0.25D;
double d10 = d1;
double d11 = d2;
double d12 = (d3 - d1) * 0.25D;
double d13 = (d4 - d2) * 0.25D;
for (int k2 = 0; k2 < 4; ++k2)
{
double d14 = 0.25D;
double d16 = (d11 - d10) * 0.25D;
double lvt_45_1_ = d10 - d16;
for (int l2 = 0; l2 < 4; ++l2)
{
if ((lvt_45_1_ += d16) > 0.0D)
{
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, STONE);
}
else if (i2 * 8 + j2 < this.settings.seaLevel)
{
primer.setBlockState(i * 4 + k2, i2 * 8 + j2, l * 4 + l2, this.oceanBlock);
}
}
d10 += d12;
d11 += d13;
}
d1 += d5;
d2 += d6;
d3 += d7;
d4 += d8;
}
}
}
}
}
public void replaceBiomeBlocks(int x, int z, ChunkPrimer primer, Biome[] biomesIn)
{
if (!net.minecraftforge.event.ForgeEventFactory.onReplaceBiomeBlocks(this, x, z, primer, this.world)) return;
double d0 = 0.03125D;
this.depthBuffer = this.surfaceNoise.getRegion(this.depthBuffer, (double)(x * 16), (double)(z * 16), 16, 16, 0.0625D, 0.0625D, 1.0D);
for (int i = 0; i < 16; ++i)
{
for (int j = 0; j < 16; ++j)
{
Biome biome = biomesIn[j + i * 16];
biome.genTerrainBlocks(this.world, this.rand, primer, x * 16 + i, z * 16 + j, this.depthBuffer[j + i * 16]);
}
}
}
public Chunk generateChunk(int x, int z)
{
this.rand.setSeed((long)x * 341873128712L + (long)z * 132897987541L);
ChunkPrimer chunkprimer = new ChunkPrimer();
this.setBlocksInChunk(x, z, chunkprimer);
this.biomesForGeneration = this.world.getBiomeProvider().getBiomes(this.biomesForGeneration, x * 16, z * 16, 16, 16);
this.replaceBiomeBlocks(x, z, chunkprimer, this.biomesForGeneration);
Chunk chunk = new Chunk(this.world, chunkprimer, x, z);
byte[] abyte = chunk.getBiomeArray();
for (int i = 0; i < abyte.length; ++i)
{
abyte[i] = (byte)Biome.getIdForBiome(this.biomesForGeneration[i]);
}
chunk.generateSkylightMap();
return chunk;
}
private void generateHeightmap(int p_185978_1_, int p_185978_2_, int p_185978_3_)
{
this.depthRegion = this.depthNoise.generateNoiseOctaves(this.depthRegion, p_185978_1_, p_185978_3_, 5, 5, (double)this.settings.depthNoiseScaleX, (double)this.settings.depthNoiseScaleZ, (double)this.settings.depthNoiseScaleExponent);
float f = this.settings.coordinateScale;
float f1 = this.settings.heightScale;
this.mainNoiseRegion = this.mainPerlinNoise.generateNoiseOctaves(this.mainNoiseRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)(f / this.settings.mainNoiseScaleX), (double)(f1 / this.settings.mainNoiseScaleY), (double)(f / this.settings.mainNoiseScaleZ));
this.minLimitRegion = this.minLimitPerlinNoise.generateNoiseOctaves(this.minLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
this.maxLimitRegion = this.maxLimitPerlinNoise.generateNoiseOctaves(this.maxLimitRegion, p_185978_1_, p_185978_2_, p_185978_3_, 5, 33, 5, (double)f, (double)f1, (double)f);
int i = 0;
int j = 0;
for (int k = 0; k < 5; ++k)
{
for (int l = 0; l < 5; ++l)
{
float f2 = 0.0F;
float f3 = 0.0F;
float f4 = 0.0F;
int i1 = 2;
Biome biome = this.biomesForGeneration[k + 2 + (l + 2) * 10];
for (int j1 = -2; j1 <= 2; ++j1)
{
for (int k1 = -2; k1 <= 2; ++k1)
{
Biome biome1 = this.biomesForGeneration[k + j1 + 2 + (l + k1 + 2) * 10];
float f5 = this.settings.biomeDepthOffSet + biome1.getBaseHeight() * this.settings.biomeDepthWeight;
float f6 = this.settings.biomeScaleOffset + biome1.getHeightVariation() * this.settings.biomeScaleWeight;
if (this.terrainType == WorldType.AMPLIFIED && f5 > 0.0F)
{
f5 = 1.0F + f5 * 2.0F;
f6 = 1.0F + f6 * 4.0F;
}
float f7 = this.biomeWeights[j1 + 2 + (k1 + 2) * 5] / (f5 + 2.0F);
if (biome1.getBaseHeight() > biome.getBaseHeight())
{
f7 /= 2.0F;
}
f2 += f6 * f7;
f3 += f5 * f7;
f4 += f7;
}
}
f2 = f2 / f4;
f3 = f3 / f4;
f2 = f2 * 0.9F + 0.1F;
f3 = (f3 * 4.0F - 1.0F) / 8.0F;
double d7 = this.depthRegion[j] / 8000.0D;
if (d7 < 0.0D)
{
d7 = -d7 * 0.3D;
}
d7 = d7 * 3.0D - 2.0D;
if (d7 < 0.0D)
{
d7 = d7 / 2.0D;
if (d7 < -1.0D)
{
d7 = -1.0D;
}
d7 = d7 / 1.4D;
d7 = d7 / 2.0D;
}
else
{
if (d7 > 1.0D)
{
d7 = 1.0D;
}
d7 = d7 / 8.0D;
}
++j;
double d8 = (double)f3;
double d9 = (double)f2;
d8 = d8 + d7 * 0.2D;
d8 = d8 * (double)this.settings.baseSize / 8.0D;
double d0 = (double)this.settings.baseSize + d8 * 4.0D;
for (int l1 = 0; l1 < 33; ++l1)
{
double d1 = ((double)l1 - d0) * (double)this.settings.stretchY * 128.0D / 256.0D / d9;
if (d1 < 0.0D)
{
d1 *= 4.0D;
}
double d2 = this.minLimitRegion[i] / (double)this.settings.lowerLimitScale;
double d3 = this.maxLimitRegion[i] / (double)this.settings.upperLimitScale;
double d4 = (this.mainNoiseRegion[i] / 10.0D + 1.0D) / 2.0D;
double d5 = MathHelper.clampedLerp(d2, d3, d4) - d1;
if (l1 > 29)
{
double d6 = (double)((float)(l1 - 29) / 3.0F);
d5 = d5 * (1.0D - d6) + -10.0D * d6;
}
this.heightMap[i] = d5;
++i;
}
}
}
}
@Override
public void populate(int x, int z) {
// TODO Auto-generated method stub
}
@Override
public boolean generateStructures(Chunk chunkIn, int x, int z) {
return false;
}
@Override
public List<SpawnListEntry> getPossibleCreatures(EnumCreatureType creatureType, BlockPos pos) {
// TODO Auto-generated method stub
return null;
}
@Override
public BlockPos getNearestStructurePos(World worldIn, String structureName, BlockPos position,
boolean findUnexplored) {
// TODO Auto-generated method stub
return null;
}
@Override
public void recreateStructures(Chunk chunkIn, int x, int z) {
// TODO Auto-generated method stub
}
@Override
public boolean isInsideStructure(World worldIn, String structureName, BlockPos pos) {
// TODO Auto-generated method stub
return false;
}
}
Java:
public class RegBiomes {
public static final Biome MAGMATIC_BIOME = new MagmaticBiome();
// public static final Biome SEDIMENTARY_BIOME = new SedimentaryBiome();
// public static final Biome METAMORPHIC_BIOME = new MetamorhicBiome();
public static void registerBiomes() {
register(MAGMATIC_BIOME, "magmatic_biome", BiomeType.WARM, Type.HILLS);
}
public static Biome register(Biome b, String name, BiomeType bt, Type... types) {
b.setRegistryName(name);
ForgeRegistries.BIOMES.register(b);
BiomeDictionary.addTypes(b, types);
BiomeManager.addBiome(bt, new BiomeEntry(b, 10));
BiomeManager.addSpawnBiome(b);
return b;
}
}
public class RealismWorld extends WorldProviderSurface {
public RealismWorld() {
super();
this.biomeProvider = new RealismBiomeProvider();
}
@Override
public DimensionType getDimensionType() {
return RegWorlds.REALISM_WORLD;
}
@Override
public IChunkGenerator createChunkGenerator() {
return new RealismChunkGenerator(world, world.rand.nextLong(), false, "magmatic_biome");
}
@Override
public boolean canRespawnHere() {
return true;
}
@Override
public boolean isSurfaceWorld() {
return true;
}
}
public RealismWorld() {
super();
this.biomeProvider = new RealismBiomeProvider();
}
@Override
public DimensionType getDimensionType() {
return RegWorlds.REALISM_WORLD;
}
@Override
public IChunkGenerator createChunkGenerator() {
return new RealismChunkGenerator(world, world.rand.nextLong(), false, "magmatic_biome");
}
@Override
public boolean canRespawnHere() {
return true;
}
@Override
public boolean isSurfaceWorld() {
return true;
}
}
Java:
public class RealismBiomeProvider extends BiomeProvider
{
private ChunkGeneratorSettings settings;
private GenLayer genBiomes;
/** A GenLayer containing the indices into BiomeGenBase.biomeList[] */
private GenLayer biomeIndexLayer;
/** The biome list. */
private final BiomeCache biomeCache;
/** A list of biomes that the player can spawn in. */
private final List<Biome> biomesToSpawnIn;
public static List<Biome> allowedBiomes = Lists.newArrayList(RegBiomes.MAGMATIC_BIOME);
public RealismBiomeProvider()
{
this.biomeCache = new BiomeCache(this);
this.biomesToSpawnIn = Lists.newArrayList(allowedBiomes);
}
private RealismBiomeProvider(long seed, WorldType worldType, ChunkGeneratorSettings options) {
this();
GenLayer[] agenlayer = GenLayer.initializeAllBiomeGenerators(seed, worldType, options);
//agenlayer = getModdedBiomeGenerators(worldTypeIn, seed, agenlayer);
this.genBiomes = agenlayer[0];
this.biomeIndexLayer = agenlayer[1];
}
public RealismBiomeProvider(WorldInfo info)
{
this();
}
/**
* Gets the list of valid biomes for the player to spawn in.
*/
public List<Biome> getBiomesToSpawnIn()
{
return this.biomesToSpawnIn;
}
/**
* Returns the biome generator
*/
public Biome getBiome(BlockPos pos)
{
return this.getBiome(pos, (Biome)null);
}
public Biome getBiome(BlockPos pos, Biome defaultBiome)
{
return this.biomeCache.getBiome(pos.getX(), pos.getZ(), defaultBiome);
}
/**
* Return an adjusted version of a given temperature based on the y height
*/
public float getTemperatureAtHeight(float p_76939_1_, int p_76939_2_)
{
return p_76939_1_;
}
/**
* Returns an array of biomes for the location input.
*/
public Biome[] getBiomesForGeneration(Biome[] biomes, int x, int z, int width, int height)
{
IntCache.resetIntCache();
if (biomes == null || biomes.length < width * height)
{
biomes = new Biome[width * height];
}
int[] aint = this.genBiomes.getInts(x, z, width, height);
try
{
for (int i = 0; i < width * height; ++i)
{
biomes[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
}
return biomes;
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
CrashReportCategory crashreportcategory = crashreport.makeCategory("RawBiomeBlock");
crashreportcategory.addCrashSection("biomes[] size", Integer.valueOf(biomes.length));
crashreportcategory.addCrashSection("x", Integer.valueOf(x));
crashreportcategory.addCrashSection("z", Integer.valueOf(z));
crashreportcategory.addCrashSection("w", Integer.valueOf(width));
crashreportcategory.addCrashSection("h", Integer.valueOf(height));
throw new ReportedException(crashreport);
}
}
/**
* Gets biomes to use for the blocks and loads the other data like temperature and humidity onto the
* WorldChunkManager.
*/
public Biome[] getBiomes(@Nullable Biome[] oldBiomeList, int x, int z, int width, int depth)
{
return this.getBiomes(oldBiomeList, x, z, width, depth, true);
}
/**
* Gets a list of biomes for the specified blocks.
*/
public Biome[] getBiomes(@Nullable Biome[] listToReuse, int x, int z, int width, int length, boolean cacheFlag)
{
IntCache.resetIntCache();
if (listToReuse == null || listToReuse.length < width * length)
{
listToReuse = new Biome[width * length];
}
if (cacheFlag && width == 16 && length == 16 && (x & 15) == 0 && (z & 15) == 0)
{
Biome[] abiome = this.biomeCache.getCachedBiomes(x, z);
System.arraycopy(abiome, 0, listToReuse, 0, width * length);
return listToReuse;
}
else
{
int[] aint = this.biomeIndexLayer.getInts(x, z, width, length);
for (int i = 0; i < width * length; ++i)
{
listToReuse[i] = Biome.getBiome(aint[i], Biomes.DEFAULT);
}
return listToReuse;
}
}
/**
* checks given Chunk's Biomes against List of allowed ones
*/
public boolean areBiomesViable(int x, int z, int radius, List<Biome> allowed)
{
IntCache.resetIntCache();
int i = x - radius >> 2;
int j = z - radius >> 2;
int k = x + radius >> 2;
int l = z + radius >> 2;
int i1 = k - i + 1;
int j1 = l - j + 1;
int[] aint = this.genBiomes.getInts(i, j, i1, j1);
try
{
for (int k1 = 0; k1 < i1 * j1; ++k1)
{
Biome biome = Biome.getBiome(aint[k1]);
if (!allowed.contains(biome))
{
return false;
}
}
return true;
}
catch (Throwable throwable)
{
CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Invalid Biome id");
CrashReportCategory crashreportcategory = crashreport.makeCategory("Layer");
crashreportcategory.addCrashSection("Layer", this.genBiomes.toString());
crashreportcategory.addCrashSection("x", Integer.valueOf(x));
crashreportcategory.addCrashSection("z", Integer.valueOf(z));
crashreportcategory.addCrashSection("radius", Integer.valueOf(radius));
crashreportcategory.addCrashSection("allowed", allowed);
throw new ReportedException(crashreport);
}
}
@Nullable
public BlockPos findBiomePosition(int x, int z, int range, List<Biome> biomes, Random random)
{
IntCache.resetIntCache();
int i = x - range >> 2;
int j = z - range >> 2;
int k = x + range >> 2;
int l = z + range >> 2;
int i1 = k - i + 1;
int j1 = l - j + 1;
int[] aint = this.genBiomes.getInts(i, j, i1, j1);
BlockPos blockpos = null;
int k1 = 0;
for (int l1 = 0; l1 < i1 * j1; ++l1)
{
int i2 = i + l1 % i1 << 2;
int j2 = j + l1 / i1 << 2;
Biome biome = Biome.getBiome(aint[l1]);
if (biomes.contains(biome) && (blockpos == null || random.nextInt(k1 + 1) == 0))
{
blockpos = new BlockPos(i2, 0, j2);
++k1;
}
}
return blockpos;
}
/**
* Calls the WorldChunkManager's biomeCache.cleanupCache()
*/
public void cleanupCache()
{
this.biomeCache.cleanupCache();
}
public GenLayer[] getModdedBiomeGenerators(WorldType worldType, long seed, GenLayer[] original)
{
net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens event = new net.minecraftforge.event.terraingen.WorldTypeEvent.InitBiomeGens(worldType, seed, original);
net.minecraftforge.common.MinecraftForge.TERRAIN_GEN_BUS.post(event);
return event.getNewBiomeGens();
}
public boolean isFixedBiome()
{
return this.settings != null && this.settings.fixedBiome >= 0;
}
public Biome getFixedBiome()
{
return this.settings != null && this.settings.fixedBiome >= 0 ? Biome.getBiomeForId(this.settings.fixedBiome) : null;
}
}
Последнее редактирование: