mirror of
https://github.com/PaperMC/Paper.git
synced 2024-12-02 21:17:00 +01:00
SPIGOT-5422: Add support for 3-dimensional biomes
This commit is contained in:
parent
4633e6c5c7
commit
db0dafb17c
5 changed files with 83 additions and 81 deletions
|
@ -5,8 +5,10 @@ import java.lang.ref.WeakReference;
|
|||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import net.minecraft.server.BiomeBase;
|
||||
import net.minecraft.server.BiomeStorage;
|
||||
import net.minecraft.server.BlockPosition;
|
||||
import net.minecraft.server.Blocks;
|
||||
import net.minecraft.server.ChunkCoordIntPair;
|
||||
import net.minecraft.server.ChunkSection;
|
||||
import net.minecraft.server.DataPaletteBlock;
|
||||
import net.minecraft.server.EnumSkyBlock;
|
||||
|
@ -282,55 +284,22 @@ public class CraftChunk implements Chunk {
|
|||
hmap.a(chunk.heightMap.get(HeightMap.Type.MOTION_BLOCKING).a());
|
||||
}
|
||||
|
||||
BiomeBase[] biome = null;
|
||||
double[] biomeTemp = null;
|
||||
BiomeStorage biome = null;
|
||||
|
||||
if (includeBiome || includeBiomeTempRain) {
|
||||
WorldChunkManager wcm = worldServer.getChunkProvider().getChunkGenerator().getWorldChunkManager();
|
||||
|
||||
if (includeBiome) {
|
||||
biome = new BiomeBase[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biome[i] = chunk.getBiomeIndex().getBiome(i & 0xF, 0, i >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
if (includeBiomeTempRain) {
|
||||
biomeTemp = new double[256];
|
||||
float[] dat = getTemperatures(wcm, getX() << 4, getZ() << 4);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeTemp[i] = dat[i];
|
||||
}
|
||||
}
|
||||
if (includeBiome|| includeBiomeTempRain) {
|
||||
biome = chunk.getBiomeIndex().b();
|
||||
}
|
||||
|
||||
World world = getWorld();
|
||||
return new CraftChunkSnapshot(getX(), getZ(), world.getName(), world.getFullTime(), sectionBlockIDs, sectionSkyLights, sectionEmitLights, sectionEmpty, hmap, biome, biomeTemp);
|
||||
return new CraftChunkSnapshot(getX(), getZ(), world.getName(), world.getFullTime(), sectionBlockIDs, sectionSkyLights, sectionEmitLights, sectionEmpty, hmap, biome);
|
||||
}
|
||||
|
||||
public static ChunkSnapshot getEmptyChunkSnapshot(int x, int z, CraftWorld world, boolean includeBiome, boolean includeBiomeTempRain) {
|
||||
BiomeBase[] biome = null;
|
||||
double[] biomeTemp = null;
|
||||
BiomeStorage biome = null;
|
||||
|
||||
if (includeBiome || includeBiomeTempRain) {
|
||||
WorldChunkManager wcm = world.getHandle().getChunkProvider().getChunkGenerator().getWorldChunkManager();
|
||||
|
||||
if (includeBiome) {
|
||||
biome = new BiomeBase[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biome[i] = world.getHandle().getBiome(new BlockPosition((x << 4) + (i & 0xF), 0, (z << 4) + (i >> 4)));
|
||||
}
|
||||
}
|
||||
|
||||
if (includeBiomeTempRain) {
|
||||
biomeTemp = new double[256];
|
||||
float[] dat = getTemperatures(wcm, x << 4, z << 4);
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
biomeTemp[i] = dat[i];
|
||||
}
|
||||
}
|
||||
biome = new BiomeStorage(new ChunkCoordIntPair(x, z), wcm);
|
||||
}
|
||||
|
||||
/* Fill with empty data */
|
||||
|
@ -347,23 +316,7 @@ public class CraftChunk implements Chunk {
|
|||
empty[i] = true;
|
||||
}
|
||||
|
||||
return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, skyLight, emitLight, empty, new HeightMap(null, HeightMap.Type.MOTION_BLOCKING), biome, biomeTemp);
|
||||
}
|
||||
|
||||
private static float[] getTemperatures(WorldChunkManager chunkmanager, int chunkX, int chunkZ) {
|
||||
float[] temps = new float[256];
|
||||
|
||||
for (int i = 0; i < 256; i++) {
|
||||
float temp = chunkmanager.getBiome((chunkX << 4) + (i & 0xF), 0, (chunkZ << 4) + (i >> 4)).getTemperature(); // Vanilla of olde: ((int) biomes[i].temperature * 65536.0F) / 65536.0F
|
||||
|
||||
if (temp > 1F) {
|
||||
temp = 1F;
|
||||
}
|
||||
|
||||
temps[i] = temp;
|
||||
}
|
||||
|
||||
return temps;
|
||||
return new CraftChunkSnapshot(x, z, world.getName(), world.getFullTime(), blockIDs, skyLight, emitLight, empty, new HeightMap(null, HeightMap.Type.MOTION_BLOCKING), biome);
|
||||
}
|
||||
|
||||
static void validateChunkCoordinates(int x, int y, int z) {
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
package org.bukkit.craftbukkit;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
import net.minecraft.server.BiomeBase;
|
||||
import net.minecraft.server.BiomeStorage;
|
||||
import net.minecraft.server.BlockPosition;
|
||||
import net.minecraft.server.DataPaletteBlock;
|
||||
import net.minecraft.server.HeightMap;
|
||||
import net.minecraft.server.IBlockData;
|
||||
|
@ -26,10 +27,9 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
|||
private final boolean[] empty;
|
||||
private final HeightMap hmap; // Height map
|
||||
private final long captureFulltime;
|
||||
private final BiomeBase[] biome;
|
||||
private final double[] biomeTemp;
|
||||
private final BiomeStorage biome;
|
||||
|
||||
CraftChunkSnapshot(int x, int z, String wname, long wtime, DataPaletteBlock<IBlockData>[] sectionBlockIDs, byte[][] sectionSkyLights, byte[][] sectionEmitLights, boolean[] sectionEmpty, HeightMap hmap, BiomeBase[] biome, double[] biomeTemp) {
|
||||
CraftChunkSnapshot(int x, int z, String wname, long wtime, DataPaletteBlock<IBlockData>[] sectionBlockIDs, byte[][] sectionSkyLights, byte[][] sectionEmitLights, boolean[] sectionEmpty, HeightMap hmap, BiomeStorage biome) {
|
||||
this.x = x;
|
||||
this.z = z;
|
||||
this.worldname = wname;
|
||||
|
@ -40,7 +40,6 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
|||
this.empty = sectionEmpty;
|
||||
this.hmap = hmap;
|
||||
this.biome = biome;
|
||||
this.biomeTemp = biomeTemp;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -119,18 +118,28 @@ public class CraftChunkSnapshot implements ChunkSnapshot {
|
|||
|
||||
@Override
|
||||
public final Biome getBiome(int x, int z) {
|
||||
Preconditions.checkState(biome != null, "ChunkSnapshot created without biome. Please call getSnapshot with includeBiome=true");
|
||||
CraftChunk.validateChunkCoordinates(x, 0, z);
|
||||
return getBiome(x, 0, z);
|
||||
}
|
||||
|
||||
return CraftBlock.biomeBaseToBiome(biome[z << 4 | x]);
|
||||
@Override
|
||||
public final Biome getBiome(int x, int y, int z) {
|
||||
Preconditions.checkState(biome != null, "ChunkSnapshot created without biome. Please call getSnapshot with includeBiome=true");
|
||||
CraftChunk.validateChunkCoordinates(x, y, z);
|
||||
|
||||
return CraftBlock.biomeBaseToBiome(biome.getBiome(x, y, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public final double getRawBiomeTemperature(int x, int z) {
|
||||
Preconditions.checkState(biomeTemp != null, "ChunkSnapshot created without biome temperatures. Please call getSnapshot with includeBiomeTempRain=true");
|
||||
CraftChunk.validateChunkCoordinates(x, 0, z);
|
||||
return getRawBiomeTemperature(x, 0, z);
|
||||
}
|
||||
|
||||
return biomeTemp[z << 4 | x];
|
||||
@Override
|
||||
public final double getRawBiomeTemperature(int x, int y, int z) {
|
||||
Preconditions.checkState(biome != null, "ChunkSnapshot created without biome. Please call getSnapshot with includeBiome=true");
|
||||
CraftChunk.validateChunkCoordinates(x, y, z);
|
||||
|
||||
return biome.getBiome(x, y, z).getAdjustedTemperature(new BlockPosition((this.x << 4) | x, y, (this.z << 4) | z));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -894,17 +894,30 @@ public class CraftWorld implements World {
|
|||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
return CraftBlock.biomeBaseToBiome(this.world.getBiome(new BlockPosition(x, 0, z)));
|
||||
return getBiome(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z) {
|
||||
return CraftBlock.biomeBaseToBiome(this.world.getBiome(new BlockPosition(x, y, z)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, Biome bio) {
|
||||
for (int y = 0; y < getMaxHeight(); y++) {
|
||||
setBiome(x, y, z, bio);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int y, int z, Biome bio) {
|
||||
BiomeBase bb = CraftBlock.biomeToBiomeBase(bio);
|
||||
if (this.world.isLoaded(new BlockPosition(x, 0, z))) {
|
||||
net.minecraft.server.Chunk chunk = this.world.getChunkAtWorldCoords(new BlockPosition(x, 0, z));
|
||||
BlockPosition pos = new BlockPosition(x, 0, z);
|
||||
if (this.world.isLoaded(pos)) {
|
||||
net.minecraft.server.Chunk chunk = this.world.getChunkAtWorldCoords(pos);
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.getBiomeIndex().setBiome(x, 0, z, bb);
|
||||
chunk.getBiomeIndex().setBiome(x, y, z, bb);
|
||||
|
||||
chunk.markDirty(); // SPIGOT-2890
|
||||
}
|
||||
|
@ -913,12 +926,23 @@ public class CraftWorld implements World {
|
|||
|
||||
@Override
|
||||
public double getTemperature(int x, int z) {
|
||||
return this.world.getBiome(new BlockPosition(x, 0, z)).getTemperature();
|
||||
return getTemperature(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getTemperature(int x, int y, int z) {
|
||||
BlockPosition pos = new BlockPosition(x, y, z);
|
||||
return this.world.getBiome(pos).getAdjustedTemperature(pos);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHumidity(int x, int z) {
|
||||
return this.world.getBiome(new BlockPosition(x, 0, z)).getHumidity();
|
||||
return getHumidity(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public double getHumidity(int x, int y, int z) {
|
||||
return this.world.getBiome(new BlockPosition(x, y, z)).getHumidity();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -473,12 +473,12 @@ public class CraftBlock implements Block {
|
|||
|
||||
@Override
|
||||
public Biome getBiome() {
|
||||
return getWorld().getBiome(getX(), getZ());
|
||||
return getWorld().getBiome(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(Biome bio) {
|
||||
getWorld().setBiome(getX(), getZ(), bio);
|
||||
getWorld().setBiome(getX(), getY(), getZ(), bio);
|
||||
}
|
||||
|
||||
public static Biome biomeBaseToBiome(BiomeBase base) {
|
||||
|
@ -504,7 +504,7 @@ public class CraftBlock implements Block {
|
|||
|
||||
@Override
|
||||
public double getHumidity() {
|
||||
return getWorld().getHumidity(getX(), getZ());
|
||||
return getWorld().getHumidity(getX(), getY(), getZ());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -45,16 +45,33 @@ public class CustomChunkGenerator extends InternalChunkGenerator<GeneratorSettin
|
|||
private final MobSpawnerCat mobSpawnerCat = new MobSpawnerCat();
|
||||
private final VillageSiege villageSiege = new VillageSiege();
|
||||
|
||||
private static class CustomBiomeGrid implements BiomeGrid {
|
||||
BiomeStorage biome;
|
||||
private class CustomBiomeGrid implements BiomeGrid {
|
||||
|
||||
private final BiomeStorage biome;
|
||||
|
||||
public CustomBiomeGrid(BiomeStorage biome) {
|
||||
this.biome = biome;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int z) {
|
||||
return CraftBlock.biomeBaseToBiome(biome.getBiome(x, 0, z));
|
||||
return getBiome(x, 0, z);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int z, Biome bio) {
|
||||
for (int y = 0; y < world.getWorld().getMaxHeight(); y++) {
|
||||
setBiome(x, y, z, bio);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Biome getBiome(int x, int y, int z) {
|
||||
return CraftBlock.biomeBaseToBiome(biome.getBiome(x, 0, z));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBiome(int x, int y, int z, Biome bio) {
|
||||
biome.setBiome(x, 0, z, CraftBlock.biomeToBiomeBase(bio));
|
||||
}
|
||||
}
|
||||
|
@ -75,8 +92,7 @@ public class CustomChunkGenerator extends InternalChunkGenerator<GeneratorSettin
|
|||
random.setSeed((long) x * 341873128712L + (long) z * 132897987541L);
|
||||
|
||||
// Get default biome data for chunk
|
||||
CustomBiomeGrid biomegrid = new CustomBiomeGrid();
|
||||
biomegrid.biome = new BiomeStorage(ichunkaccess.getPos(), this.getWorldChunkManager());
|
||||
CustomBiomeGrid biomegrid = new CustomBiomeGrid(new BiomeStorage(ichunkaccess.getPos(), this.getWorldChunkManager()));
|
||||
|
||||
ChunkData data;
|
||||
if (generator.isParallelCapable()) {
|
||||
|
|
Loading…
Reference in a new issue