From db0dafb17c107b2325fd95d592ed378498e834ba Mon Sep 17 00:00:00 2001 From: md_5 Date: Wed, 11 Dec 2019 15:28:37 +1100 Subject: [PATCH] SPIGOT-5422: Add support for 3-dimensional biomes --- .../org/bukkit/craftbukkit/CraftChunk.java | 65 +++---------------- .../craftbukkit/CraftChunkSnapshot.java | 31 +++++---- .../org/bukkit/craftbukkit/CraftWorld.java | 36 ++++++++-- .../bukkit/craftbukkit/block/CraftBlock.java | 6 +- .../generator/CustomChunkGenerator.java | 26 ++++++-- 5 files changed, 83 insertions(+), 81 deletions(-) diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java index e423bc8e7f..fe95c7bdeb 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunk.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunk.java @@ -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) { diff --git a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java index 2e5d457f8c..01322d8752 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java @@ -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[] sectionBlockIDs, byte[][] sectionSkyLights, byte[][] sectionEmitLights, boolean[] sectionEmpty, HeightMap hmap, BiomeBase[] biome, double[] biomeTemp) { + CraftChunkSnapshot(int x, int z, String wname, long wtime, DataPaletteBlock[] 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 diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 0602970d95..662343a182 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -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 diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java index 3d632543b8..2267ff2284 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java @@ -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 diff --git a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java index 0986eca086..32a5ee4e3e 100644 --- a/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java +++ b/src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java @@ -45,16 +45,33 @@ public class CustomChunkGenerator extends InternalChunkGenerator