
org.bukkit.craftbukkit.generator.CustomChunkGenerator Maven / Gradle / Ivy
package org.bukkit.craftbukkit.generator;
import net.minecraft.server.*;
import org.bukkit.block.Biome;
import org.bukkit.craftbukkit.block.CraftBlock;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
import java.util.List;
import java.util.Random;
public class CustomChunkGenerator extends InternalChunkGenerator {
private final ChunkGenerator generator;
private final WorldServer world;
private final Random random;
private final WorldGenStronghold strongholdGen = new WorldGenStronghold();
public CustomChunkGenerator(World world, long seed, ChunkGenerator generator) {
this.world = (WorldServer) world;
this.generator = generator;
this.random = new Random(seed);
}
public boolean isChunkLoaded(int x, int z) {
return true;
}
public Chunk getOrCreateChunk(int x, int z) {
random.setSeed((long) x * 341873128712L + (long) z * 132897987541L);
Chunk chunk;
// Get default biome data for chunk
CustomBiomeGrid biomegrid = new CustomBiomeGrid();
biomegrid.biome = new BiomeBase[256];
world.getWorldChunkManager().getBiomeBlock(biomegrid.biome, x << 4, z << 4, 16, 16);
// Try ChunkData method (1.8+)
CraftChunkData data = (CraftChunkData) generator.generateChunkData(this.world.getWorld(), random, x, z, biomegrid);
if (data != null) {
char[][] sections = data.getRawChunkData();
chunk = new Chunk(this.world, x, z);
ChunkSection[] csect = chunk.getSections();
int scnt = Math.min(csect.length, sections.length);
// Loop through returned sections
for (int sec = 0; sec < scnt; sec++) {
if (sections[sec] == null) {
continue;
}
char[] section = sections[sec];
char emptyTest = 0;
for (int i = 0; i < 4096; i++) {
// Filter invalid block id & data values.
if (Block.d.a(section[i]) == null) {
section[i] = 0;
}
emptyTest |= section[i];
}
// Build chunk section
if (emptyTest != 0) {
csect[sec] = new ChunkSection(sec << 4, true, section);
}
}
} else {
// Try extended block method (1.2+)
short[][] xbtypes = generator.generateExtBlockSections(this.world.getWorld(), this.random, x, z, biomegrid);
if (xbtypes != null) {
chunk = new Chunk(this.world, x, z);
ChunkSection[] csect = chunk.getSections();
int scnt = Math.min(csect.length, xbtypes.length);
// Loop through returned sections
for (int sec = 0; sec < scnt; sec++) {
if (xbtypes[sec] == null) {
continue;
}
char[] secBlkID = new char[4096]; // Allocate blk ID bytes
short[] bdata = xbtypes[sec];
for (int i = 0; i < bdata.length; i++) {
Block b = Block.getById(bdata[i]);
secBlkID[i] = (char) Block.d.b(b.getBlockData());
}
// Build chunk section
csect[sec] = new ChunkSection(sec << 4, true, secBlkID);
}
} else { // Else check for byte-per-block section data
byte[][] btypes = generator.generateBlockSections(this.world.getWorld(), this.random, x, z, biomegrid);
if (btypes != null) {
chunk = new Chunk(this.world, x, z);
ChunkSection[] csect = chunk.getSections();
int scnt = Math.min(csect.length, btypes.length);
for (int sec = 0; sec < scnt; sec++) {
if (btypes[sec] == null) {
continue;
}
char[] secBlkID = new char[4096]; // Allocate block ID bytes
for (int i = 0; i < secBlkID.length; i++) {
Block b = Block.getById(btypes[sec][i] & 0xFF);
secBlkID[i] = (char) Block.d.b(b.getBlockData());
}
csect[sec] = new ChunkSection(sec << 4, true, secBlkID);
}
} else { // Else, fall back to pre 1.2 method
@SuppressWarnings("deprecation")
byte[] types = generator.generate(this.world.getWorld(), this.random, x, z);
int ydim = types.length / 256;
int scnt = ydim / 16;
chunk = new Chunk(this.world, x, z); // Create empty chunk
ChunkSection[] csect = chunk.getSections();
scnt = Math.min(scnt, csect.length);
// Loop through sections
for (int sec = 0; sec < scnt; sec++) {
ChunkSection cs = null; // Add sections when needed
char[] csbytes = null;
for (int cy = 0; cy < 16; cy++) {
int cyoff = cy | (sec << 4);
for (int cx = 0; cx < 16; cx++) {
int cxyoff = (cx * ydim * 16) + cyoff;
for (int cz = 0; cz < 16; cz++) {
byte blk = types[cxyoff + (cz * ydim)];
if (blk != 0) { // If non-empty
if (cs == null) { // If no section yet, get one
cs = csect[sec] = new ChunkSection(sec << 4, true);
csbytes = cs.getIdArray();
}
Block b = Block.getById(blk & 0xFF);
csbytes[(cy << 8) | (cz << 4) | cx] = (char) Block.d.b(b.getBlockData());
}
}
}
}
// If section built, finish prepping its state
if (cs != null) {
cs.recalcBlockCounts();
}
}
}
}
}
// Set biome grid
byte[] biomeIndex = chunk.getBiomeIndex();
for (int i = 0; i < biomeIndex.length; i++) {
biomeIndex[i] = (byte) (biomegrid.biome[i].id & 0xFF);
}
// Initialize lighting
chunk.initLighting();
return chunk;
}
@Override
public Chunk getChunkAt(BlockPosition blockPosition) {
return getChunkAt(blockPosition.getX() >> 4, blockPosition.getZ() >> 4);
}
public void getChunkAt(IChunkProvider icp, int i, int i1) {
// Nothing!
}
@Override
public boolean a(IChunkProvider iChunkProvider, Chunk chunk, int i, int i1) {
return false;
}
public boolean saveChunks(boolean bln, IProgressUpdate ipu) {
return true;
}
public boolean unloadChunks() {
return false;
}
public boolean canSave() {
return true;
}
@SuppressWarnings("deprecation")
public byte[] generate(org.bukkit.World world, Random random, int x, int z) {
return generator.generate(world, random, x, z);
}
public byte[][] generateBlockSections(org.bukkit.World world, Random random, int x, int z, BiomeGrid biomes) {
return generator.generateBlockSections(world, random, x, z, biomes);
}
public short[][] generateExtBlockSections(org.bukkit.World world, Random random, int x, int z, BiomeGrid biomes) {
return generator.generateExtBlockSections(world, random, x, z, biomes);
}
public Chunk getChunkAt(int x, int z) {
return getOrCreateChunk(x, z);
}
@Override
public boolean canSpawn(org.bukkit.World world, int x, int z) {
return generator.canSpawn(world, x, z);
}
@Override
public List getDefaultPopulators(org.bukkit.World world) {
return generator.getDefaultPopulators(world);
}
@Override
public List getMobsFor(EnumCreatureType type, BlockPosition position) {
BiomeBase biomebase = world.getBiome(position);
return biomebase == null ? null : biomebase.getMobs(type);
}
@Override
public BlockPosition findNearestMapFeature(World world, String type, BlockPosition position) {
return "Stronghold".equals(type) && this.strongholdGen != null ? this.strongholdGen.getNearestGeneratedFeature(world, position) : null;
}
public void recreateStructures(int i, int j) {
}
public int getLoadedChunks() {
return 0;
}
@Override
public void recreateStructures(Chunk chunk, int i, int i1) {
}
public String getName() {
return "CustomChunkGenerator";
}
public void c() {
}
private static class CustomBiomeGrid implements BiomeGrid {
BiomeBase[] biome;
public Biome getBiome(int x, int z) {
return CraftBlock.biomeBaseToBiome(biome[(z << 4) | x]);
}
public void setBiome(int x, int z, Biome bio) {
biome[(z << 4) | x] = CraftBlock.biomeToBiomeBase(bio);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy