Skip to content

Commit

Permalink
Rewrote world generation to use new API
Browse files Browse the repository at this point in the history
  • Loading branch information
tastybento committed Jan 15, 2024
1 parent 4cf1b76 commit ae61a9b
Show file tree
Hide file tree
Showing 6 changed files with 184 additions and 65 deletions.
7 changes: 6 additions & 1 deletion src/main/java/world/bentobox/skygrid/SkyGrid.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public void createWorlds() {
}
BiomeProvider bp = new SkyGridBiomeProvider();
// Create the world if it does not exist
islandWorld = WorldCreator.name(worldName).environment(World.Environment.NORMAL).generator(gen)
islandWorld = WorldCreator.name(worldName).environment(World.Environment.NORMAL).generator(gen).seed(123456L)
.biomeProvider(bp).createWorld();

// Make the nether if it does not exist
Expand Down Expand Up @@ -134,4 +134,9 @@ public void saveWorldSettings() {
}

}

@Override
public boolean isUsesNewChunkGeneration() {
return true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.ConcurrentHashMap;

import org.bukkit.World;
import org.bukkit.World.Environment;
import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.WorldInfo;
Expand All @@ -18,13 +20,19 @@
*/
public class SkyGridBiomeProvider extends BiomeProvider {

private static final Random RAND = new Random();
private final Map<World.Environment, PerlinOctaveGenerator> temperatureGenMap = new ConcurrentHashMap<>();
private final Map<World.Environment, PerlinOctaveGenerator> rainfallGenMap = new ConcurrentHashMap<>();


@Override
public Biome getBiome(WorldInfo worldInfo, int realX, int y, int realZ) {

// Handle caves
if (worldInfo.getEnvironment() == Environment.NORMAL && y < 0) {
return caveBiome(y);
}

// Make and cache the PerlinOctaveGenerator for the environment
PerlinOctaveGenerator temperatureGen = temperatureGenMap.computeIfAbsent(worldInfo.getEnvironment(), wf -> {
PerlinOctaveGenerator tg = new PerlinOctaveGenerator(worldInfo.getSeed(), 16);
Expand Down Expand Up @@ -54,6 +62,13 @@ public Biome getBiome(WorldInfo worldInfo, int realX, int y, int realZ) {
return Objects.requireNonNull(maxBiome).biome;
}

private Biome caveBiome(int y) {
if (y < -52) {
return Biome.DEEP_DARK;
}
return RAND.nextBoolean() ? Biome.LUSH_CAVES : Biome.DRIPSTONE_CAVES;
}

@Override
public List<Biome> getBiomes(WorldInfo worldInfo) {
return Arrays.stream(SkyGridBiomes.values()).map(SkyGridBiomes::getBiome).toList();
Expand Down
39 changes: 37 additions & 2 deletions src/main/java/world/bentobox/skygrid/generators/SkyGridChunks.java
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,35 @@ public SkyGridChunks(SkyGrid addon) {
addon.log("Done making chunks");
}

public Material getBlock(Environment env) {
BlockProbability prob = addon.getWorldStyles().get(env).getProb();
return prob.getBlock(random, false, false);
/*
// Get a random block and feed in the last block (true if cactus or cane)
Material blockMat = prob.getBlock(random, y == 0, false);
// If blockMat is not "a block" then cannot be generated
if (!blockMat.isAir() && !blockMat.isBlock()) {
blockMat = Material.STONE;
}
// Convert to deep
if (y < 0) {
if (blockMat == Material.STONE) {
blockMat = Material.DEEPSLATE;
} else if (blockMat == Material.COBBLESTONE) {
blockMat = Material.COBBLED_DEEPSLATE;
} else {
blockMat = Enums.getIfPresent(Material.class, "DEEPSLATE_" + blockMat.name()).or(blockMat);
}
}
return new SkyGridBlock(x, y, z, blockMat);*/
}

private List<SkyGridBlock> getChunk(BlockProbability prob) {
List<SkyGridBlock> result = new ArrayList<>();
for (int x = 1; x < 16; x += 4) {
for (int z = 1; z < 16; z += 4) {
for (int y = 0; y <= addon.getSettings().getIslandHeight(); y += 4) {
for (int y = -64; y <= addon.getSettings().getIslandHeight(); y += 4) {
setBlock(prob, x, y, z, result);
}
}
Expand Down Expand Up @@ -91,6 +114,18 @@ private void setBlock(BlockProbability prob, int x, int y, int z, List<SkyGridBl
if (!blockMat.isAir() && !blockMat.isBlock()) {
blockMat = Material.STONE;
}
// Convert to deep
if (y < 0) {
if (blockMat == Material.STONE) {
blockMat = Material.DEEPSLATE;

} else if (blockMat == Material.COBBLESTONE) {
blockMat = Material.COBBLED_DEEPSLATE;
} else {
blockMat = Enums.getIfPresent(Material.class, "DEEPSLATE_" + blockMat.name()).or(blockMat);
}
}

// Check if the block needs dirt
if (NEEDS_DIRT.contains(blockMat)) {
// Add dirt
Expand All @@ -111,7 +146,7 @@ private void setBlock(BlockProbability prob, int x, int y, int z, List<SkyGridBl
}
} else {
switch (blockMat) {
case CACTUS -> {
case CACTUS, DEAD_BUSH -> {
result.add(new SkyGridBlock(x, y, z, Material.SAND));
result.add(new SkyGridBlock(x, y - 1, z, Material.SANDSTONE));
result.add(new SkyGridBlock(x, y + 1, z, blockMat));
Expand Down
75 changes: 68 additions & 7 deletions src/main/java/world/bentobox/skygrid/generators/SkyGridGen.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
package world.bentobox.skygrid.generators;

import java.util.Collections;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.Tag;
import org.bukkit.World;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator;
Expand All @@ -18,33 +19,93 @@ public class SkyGridGen extends ChunkGenerator {
private final SkyGrid addon;

private final BlockPopulator populator;
private final SkyGridChunks preMade;

/**
* @param addon - addon
*/
public SkyGridGen(SkyGrid addon) {
this.addon = addon;
this.populator = new SkyGridPop(addon);
preMade = new SkyGridChunks(addon);
}

@Override
public void generateNoise(WorldInfo worldInfo, Random r, int x, int z, ChunkData result) {
result.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.AIR);
preMade.getSkyGridChunk(worldInfo.getEnvironment()).forEach(b -> result.setBlock(b.getX(), b.getY(), b.getZ(), b.getBd()));
public void generateNoise(WorldInfo worldInfo, Random r, int chunkX, int chunkZ, ChunkData result) {
Random rand = new Random(worldInfo.getSeed());
// Cut off anything higher than island height
result.setRegion(0, Math.min(addon.getSettings().getIslandHeight() + 1, worldInfo.getMaxHeight() - 1), 0, 16,
worldInfo.getMaxHeight(), 16,
Material.AIR);
for (int x = 0; x < 16; x++) {
for (int z = 0; z < 16; z++) {
for (int y = addon.getSettings().getIslandHeight(); y >= worldInfo.getMinHeight(); y--) {
// Check if the block is not the 4th block
if ((Math.floorMod(x, 4) != 0) || (Math.floorMod(z, 4) != 0) || (Math.floorMod(y, 4) != 0)) {
result.setBlock(x, y, z, Material.AIR);
} else {
Material m = result.getBlockData(x, y, z).getMaterial();
if (m == Material.AIR || m == Material.WATER) {
Material nextBlock = addon.getWorldStyles().get(worldInfo.getEnvironment()).getProb()
.getBlock(rand, y == worldInfo.getMinHeight(), true);
// Check for plants, etc. below this y
checkPlants(nextBlock, x, y, z, result);
}

}
}
}
}
}


private boolean checkPlants(Material nextBlock, int x, int y, int z, ChunkData result) {
if (Tag.SAPLINGS.isTagged(nextBlock) || Tag.FLOWERS.isTagged(nextBlock)
|| Tag.ITEMS_VILLAGER_PLANTABLE_SEEDS.isTagged(nextBlock)) {
result.setBlock(x, y, z, Material.DIRT);
result.setBlock(x, y + 1, z, nextBlock);
} else {
switch (nextBlock) {
case CACTUS, DEAD_BUSH -> {
result.setBlock(x, y, z, Material.SANDSTONE);
result.setBlock(x, y, z, Material.SAND);
result.setBlock(x, y + 2, z, nextBlock);
}
case NETHER_WART -> {
result.setBlock(x, y, z, Material.SOUL_SAND);
result.setBlock(x, y + 1, z, nextBlock);
}
case END_ROD, CHORUS_PLANT -> {
result.setBlock(x, y, z, Material.END_STONE);
result.setBlock(x, y + 1, z, nextBlock);
}

default -> {
result.setBlock(x, y, z, nextBlock);
return false;
}
}
}
return true;
}


@Override
public List<BlockPopulator> getDefaultPopulators(World world) {
return Collections.singletonList(populator);
List<BlockPopulator> list = new ArrayList<>();
list.addAll(super.getDefaultPopulators(world));
list.add(populator);
return list;
}

@Override
public Location getFixedSpawnLocation(World world, Random random) {
return new Location(world, 0, addon.getSettings().getIslandHeight() + 2D, 0);
}

@Override
public boolean shouldGenerateNoise() {
return true;
}

/**
* Gets if the server should generate Vanilla surface.
* @return true if the server should generate Vanilla surface
Expand Down

0 comments on commit ae61a9b

Please sign in to comment.