block populators & respect world depth setting (#71)

This commit is contained in:
Huynh Tien 2021-12-21 13:14:33 +07:00 committed by GitHub
parent 03a5f9bc6c
commit 4a2e08c228
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 136 additions and 114 deletions

View File

@ -34,7 +34,7 @@ public class CaveBlock extends GameModeAddon
this.saveDefaultConfig(); this.saveDefaultConfig();
this.loadSettings(); this.loadSettings();
this.chunkGenerator = new ChunkGeneratorWorld(); this.chunkGenerator = new ChunkGeneratorWorld(this);
// Player Command // Player Command
this.playerCommand = new DefaultPlayerCommand(this) this.playerCommand = new DefaultPlayerCommand(this)

View File

@ -1,17 +1,17 @@
package world.bentobox.caveblock.generators; package world.bentobox.caveblock.generators;
import java.util.ArrayList;
import java.util.Collections;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.Random;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.World.Environment; import org.bukkit.World;
import org.bukkit.block.data.BlockData; import org.bukkit.generator.BiomeProvider;
import org.bukkit.generator.BlockPopulator;
import org.bukkit.generator.ChunkGenerator; import org.bukkit.generator.ChunkGenerator;
import org.bukkit.generator.WorldInfo; import org.bukkit.generator.WorldInfo;
import world.bentobox.caveblock.CaveBlock;
import world.bentobox.caveblock.Settings;
import world.bentobox.caveblock.generators.populators.EntitiesPopulator;
import world.bentobox.caveblock.generators.populators.FlatBiomeProvider;
import world.bentobox.caveblock.generators.populators.MaterialPopulator;
import world.bentobox.caveblock.generators.populators.NewMaterialPopulator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@ -20,115 +20,115 @@ import java.util.Random;
/** /**
* Class ChunkGeneratorWorld ... * Class ChunkGeneratorWorld ...
* *
* @author tastybento * @author BONNe
* Created on 27.01.2019
*/ */
public class ChunkGeneratorWorld extends ChunkGenerator { public class ChunkGeneratorWorld extends ChunkGenerator {
// ---------------------------------------------------------------------
// Section: Variables
// ---------------------------------------------------------------------
private static final int BLOB_SIZE = 1; private final CaveBlock addon;
private static final Map<Environment, List<Ore>> ORES; private final Settings settings;
static { private final List<BlockPopulator> blockPopulators;
Map<Environment, List<Ore>> ores = new EnumMap<>(Environment.class); private BiomeProvider biomeProvider;
// Source https://minecraft.fandom.com/wiki/Blob private boolean isNewGenerator;
List<Ore> worldOres = new ArrayList<>();
worldOres.add(new Ore(-64, 16, Material.DIAMOND_ORE, 1, 10, true)); // ---------------------------------------------------------------------
worldOres.add(new Ore(-64, 64, Material.LAPIS_ORE, 1, 7, true)); // Section: Constructor
worldOres.add(new Ore(-64, 30, Material.GOLD_ORE, 2, 9, true)); // ---------------------------------------------------------------------
worldOres.add(new Ore(0, 16, Material.TUFF, 2, 33, false));
worldOres.add(new Ore(-64, 16, Material.REDSTONE_ORE, 8, 8, true)); /**
worldOres.add(new Ore(0, 16, Material.GRAVEL, 8 , 33, false)); * @param addon - CaveBlock object
worldOres.add(new Ore(0, 79, Material.GRANITE, 5, 33, false)); */
worldOres.add(new Ore(0, 79, Material.ANDESITE,5, 33, false)); public ChunkGeneratorWorld(CaveBlock addon) {
worldOres.add(new Ore(0, 79, Material.DIORITE,5, 33, false)); this.addon = addon;
worldOres.add(new Ore(32, 320, Material.EMERALD_ORE, 11, 1, true)); this.settings = addon.getSettings();
worldOres.add(new Ore(95, 136, Material.COAL_ORE, 20, 17, false)); this.blockPopulators = new ArrayList<>(2);
worldOres.add(new Ore(0, 96, Material.COPPER_ORE, 20, 9, true));
worldOres.add(new Ore(-64, 320, Material.IRON_ORE, 20, 9, true)); reload();
worldOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false));
ores.put(Environment.NORMAL, worldOres);
List<Ore> netherOres = new ArrayList<>();
netherOres.add(new Ore(1, 22, Material.ANCIENT_DEBRIS, 1, 5, true));
netherOres.add(new Ore(-64, 30, Material.NETHER_GOLD_ORE, 2, 9, true));
netherOres.add(new Ore(0, 16, Material.GRAVEL, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.BASALT, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.BLACKSTONE, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.FIRE, 8 , 33, false));
netherOres.add(new Ore(200, 320, Material.GLOWSTONE, 8 , 33, false));
netherOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false));
netherOres.add(new Ore(-64, 320, Material.LAVA, 8 , 33, false));
netherOres.add(new Ore(0, 16, Material.MAGMA_BLOCK, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.CRIMSON_FUNGUS, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.WARPED_FUNGUS, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.CRIMSON_NYLIUM, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.WARPED_NYLIUM, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.SHROOMLIGHT, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.CRIMSON_STEM, 8 , 33, false));
netherOres.add(new Ore(0, 320, Material.WARPED_STEM, 8 , 33, false));
netherOres.add(new Ore(-64, 34, Material.SOUL_SOIL, 20, 17, false));
netherOres.add(new Ore(0, 96, Material.NETHER_QUARTZ_ORE, 20, 9, true));
netherOres.add(new Ore(-64, 320, Material.BONE_BLOCK, 20, 9, true));
ores.put(Environment.NETHER, netherOres);
List<Ore> endOres = new ArrayList<>();
endOres.add(new Ore(32, 320, Material.PURPUR_BLOCK, 11, 1, true));
endOres.add(new Ore(95, 136, Material.OBSIDIAN, 20, 17, false));
endOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8 , 33, false));
ores.put(Environment.THE_END, endOres);
ORES = Collections.unmodifiableMap(ores);
} }
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Section: Methods // Section: Methods
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
private Material getGroundCeilMaterial(World.Environment environment) {
return switch (environment) {
case NETHER -> this.settings.isNetherRoof() ? Material.BEDROCK : this.settings.getNetherMainBlock();
case THE_END -> this.settings.isEndFloor() ? Material.BEDROCK : this.settings.getEndMainBlock();
default -> this.settings.isNormalFloor() ? Material.BEDROCK : this.settings.getNormalMainBlock();
};
}
private Material getBaseMaterial(World.Environment environment) {
return switch (environment) {
case NETHER -> this.settings.getNetherMainBlock();
case THE_END -> this.settings.getEndMainBlock();
default -> this.settings.getNormalMainBlock();
};
}
@Override @Override
public void generateNoise(WorldInfo worldInfo, Random r, int x, int z, ChunkData chunkData) { public void generateBedrock(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) {
switch(worldInfo.getEnvironment()) { final int minHeight = worldInfo.getMinHeight();
default: Material material = getGroundCeilMaterial(worldInfo.getEnvironment());
chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.STONE); chunkData.setRegion(0, minHeight, 0, 16, minHeight + 1, 16, material);
chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, 7, 16, Material.DEEPSLATE); }
chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK);
break; @Override
public void generateSurface(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) {
final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.settings.getWorldDepth());
Material material = getGroundCeilMaterial(worldInfo.getEnvironment());
chunkData.setRegion(0, worldHeight - 1, 0, 16, worldHeight, 16, material);
}
@Override
public void generateNoise(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, ChunkData chunkData) {
final int minHeight = worldInfo.getMinHeight();
final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.settings.getWorldDepth());
final World.Environment environment = worldInfo.getEnvironment();
if (isNewGenerator) {
switch (environment) {
case NETHER: case NETHER:
chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.NETHERRACK); if (worldHeight + 1 > 34) {
chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, 34, 16, Material.SOUL_SAND); chunkData.setRegion(0, minHeight + 1, 0, 16, 34, 16, Material.SOUL_SAND);
chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK); chunkData.setRegion(0, 34, 0, 16, worldHeight - 1, 16, Material.NETHERRACK);
} else {
chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.NETHERRACK);
}
break; break;
case THE_END: case THE_END:
chunkData.setRegion(0, worldInfo.getMinHeight(), 0, 16, worldInfo.getMaxHeight(), 16, Material.END_STONE); chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.END_STONE);
chunkData.setRegion(0, worldInfo.getMaxHeight() - 1, 0, 16, worldInfo.getMaxHeight(), 16, Material.BEDROCK); break;
default:
if (worldHeight + 1 > 7) {
chunkData.setRegion(0, minHeight + 1, 0, 16, 7, 16, Material.DEEPSLATE);
chunkData.setRegion(0, 7, 0, 16, worldHeight - 1, 16, Material.STONE);
} else {
chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, Material.STONE);
}
break; break;
} }
} else {
// Generate ores Material material = getBaseMaterial(environment);
for (int y = worldInfo.getMinHeight(); y < worldInfo.getMaxHeight(); y++) { chunkData.setRegion(0, minHeight + 1, 0, 16, worldHeight - 1, 16, material);
for (Ore o: ORES.get(worldInfo.getEnvironment())) {
if (y > o.minY() && y < o.maxY() && r.nextInt(100) <= o.chance()) {
pasteBlob(chunkData, y, o, r);
if (o.cont()) {
break;
}
}
}
} }
} }
private void pasteBlob(ChunkData chunkData, int y, Ore o, Random r) { @Override
int offset = r.nextInt(16); public List<BlockPopulator> getDefaultPopulators(final World world) {
for (int x = Math.max(0, offset - BLOB_SIZE); x < Math.min(16, offset + BLOB_SIZE); x++) { return this.blockPopulators;
for (int z = Math.max(0, offset - BLOB_SIZE); z < Math.min(16, offset + BLOB_SIZE); z++) {
for (int yy = Math.max(chunkData.getMinHeight(), y - BLOB_SIZE); yy < Math.min(chunkData.getMaxHeight(),y + BLOB_SIZE); yy++) {
BlockData bd = chunkData.getBlockData(x, yy, z);
if (bd.getMaterial().isSolid() && r.nextBoolean()) {
chunkData.setBlock(x, yy, z, o.material());
}
}
}
} }
@Override
public BiomeProvider getDefaultBiomeProvider(WorldInfo worldInfo) {
return biomeProvider;
} }
@Override @Override
public boolean shouldGenerateSurface() { public boolean shouldGenerateSurface() {
return false; return true;
} }
@Override @Override
@ -138,12 +138,23 @@ public class ChunkGeneratorWorld extends ChunkGenerator {
@Override @Override
public boolean shouldGenerateCaves() { public boolean shouldGenerateCaves() {
return true; return this.isNewGenerator;
} }
@Override /**
public boolean shouldGenerateDecorations() { * Called when config is reloaded
return true; */
} public void reload() {
this.blockPopulators.clear();
this.isNewGenerator = this.settings.isNewMaterialGenerator();
if (this.isNewGenerator) {
this.blockPopulators.add(new NewMaterialPopulator(this.settings.getWorldDepth()));
this.biomeProvider = null;
} else {
this.blockPopulators.add(new MaterialPopulator(this.addon));
this.blockPopulators.add(new EntitiesPopulator(this.addon));
this.biomeProvider = new FlatBiomeProvider(this.addon);
}
}
} }

View File

@ -11,10 +11,15 @@ import world.bentobox.caveblock.generators.Ore;
import java.util.*; import java.util.*;
/**
* @author tastybento
*/
public class NewMaterialPopulator extends BlockPopulator { public class NewMaterialPopulator extends BlockPopulator {
private final Map<World.Environment, List<Ore>> ores = new EnumMap<>(World.Environment.class); private static final int BLOB_SIZE = 1;
private static final Map<World.Environment, List<Ore>> ORES;
public NewMaterialPopulator() { static {
Map<World.Environment, List<Ore>> ores = new EnumMap<>(World.Environment.class);
// Source https://minecraft.fandom.com/wiki/Blob // Source https://minecraft.fandom.com/wiki/Blob
List<Ore> worldOres = new ArrayList<>(); List<Ore> worldOres = new ArrayList<>();
worldOres.add(new Ore(-64, 16, Material.DIAMOND_ORE, 1, 10, true)); worldOres.add(new Ore(-64, 16, Material.DIAMOND_ORE, 1, 10, true));
@ -59,12 +64,20 @@ public class NewMaterialPopulator extends BlockPopulator {
endOres.add(new Ore(95, 136, Material.OBSIDIAN, 20, 17, false)); endOres.add(new Ore(95, 136, Material.OBSIDIAN, 20, 17, false));
endOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8, 33, false)); endOres.add(new Ore(-64, 320, Material.CAVE_AIR, 8, 33, false));
ores.put(World.Environment.THE_END, endOres); ores.put(World.Environment.THE_END, endOres);
ORES = Collections.unmodifiableMap(ores);
}
private final int worldDepth;
public NewMaterialPopulator(int worldDepth) {
this.worldDepth = worldDepth;
} }
@Override @Override
public void populate(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion) { public void populate(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion) {
for (int y = worldInfo.getMinHeight(); y < worldInfo.getMaxHeight(); y++) { final int worldHeight = Math.min(worldInfo.getMaxHeight(), this.worldDepth);
for (Ore o : ores.get(worldInfo.getEnvironment())) { for (int y = worldInfo.getMinHeight(); y < worldHeight - 1; y++) {
for (Ore o : ORES.get(worldInfo.getEnvironment())) {
if (y > o.minY() && y < o.maxY() && random.nextInt(100) <= o.chance()) { if (y > o.minY() && y < o.maxY() && random.nextInt(100) <= o.chance()) {
pasteBlob(worldInfo, random, chunkX, chunkZ, limitedRegion, y, o); pasteBlob(worldInfo, random, chunkX, chunkZ, limitedRegion, y, o);
if (o.cont()) { if (o.cont()) {
@ -76,12 +89,10 @@ public class NewMaterialPopulator extends BlockPopulator {
} }
private void pasteBlob(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion, int y, Ore o) { private void pasteBlob(WorldInfo worldInfo, Random random, int chunkX, int chunkZ, LimitedRegion limitedRegion, int y, Ore o) {
//int blobSize = (int) (((double)random.nextInt(o.blob()) / 3) + 1);
int blobSize = 1;
int offset = random.nextInt(16); int offset = random.nextInt(16);
for (int x = Math.max(0, offset - blobSize); x < Math.min(16, offset + blobSize); x++) { for (int x = Math.max(0, offset - BLOB_SIZE); x < Math.min(16, offset + BLOB_SIZE); x++) {
for (int z = Math.max(0, offset - blobSize); z < Math.min(16, offset + blobSize); z++) { for (int z = Math.max(0, offset - BLOB_SIZE); z < Math.min(16, offset + BLOB_SIZE); z++) {
for (int yy = Math.max(worldInfo.getMinHeight(), y - blobSize); yy < Math.min(worldInfo.getMaxHeight(), y + blobSize); yy++) { for (int yy = Math.max(worldInfo.getMinHeight(), y - BLOB_SIZE); yy < Math.min(worldInfo.getMaxHeight(), y + BLOB_SIZE); yy++) {
Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ); Location location = Utils.getLocationFromChunkLocation(x, yy, z, chunkX, chunkZ);
if (!limitedRegion.isInRegion(location)) { if (!limitedRegion.isInRegion(location)) {
continue; continue;