mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2025-01-02 06:27:42 +01:00
Some more optimization & runnable -> block populator
This commit is contained in:
parent
7f0b29fd28
commit
b138c0dcc9
@ -168,7 +168,7 @@ public class MMOItems extends JavaPlugin {
|
|||||||
dropTableManager = new DropTableManager();
|
dropTableManager = new DropTableManager();
|
||||||
worldGenManager = new WorldGenManager();
|
worldGenManager = new WorldGenManager();
|
||||||
blockManager = new BlockManager();
|
blockManager = new BlockManager();
|
||||||
statManager.reload(false);
|
statManager.reload(false);
|
||||||
|
|
||||||
|
|
||||||
PluginUtils.hookDependencyIfPresent("Vault", u -> vaultSupport = new VaultSupport());
|
PluginUtils.hookDependencyIfPresent("Vault", u -> vaultSupport = new VaultSupport());
|
||||||
|
@ -1,171 +1,138 @@
|
|||||||
package net.Indyuce.mmoitems.api.block;
|
package net.Indyuce.mmoitems.api.block;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.Location;
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.World;
|
|
||||||
import org.bukkit.block.Biome;
|
import org.bukkit.block.Biome;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
import org.bukkit.configuration.ConfigurationSection;
|
import org.bukkit.configuration.ConfigurationSection;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class WorldGenTemplate {
|
public class WorldGenTemplate {
|
||||||
private final String id;
|
private final String id;
|
||||||
private final double chunkChance;
|
private final double chunkChance;
|
||||||
private final int minDepth, maxDepth, veinSize, veinCount;
|
private final int minDepth, maxDepth, veinSize, veinCount;
|
||||||
|
|
||||||
private final List<Material> replaceable = new ArrayList<>();
|
private final List<Material> replaceable = new ArrayList<>();
|
||||||
private final List<Material> bordering = new ArrayList<>();
|
private final List<Material> bordering = new ArrayList<>();
|
||||||
private final List<Material> notBordering = new ArrayList<>();
|
private final List<Material> notBordering = new ArrayList<>();
|
||||||
private final List<String> worldWhitelist = new ArrayList<>(), worldBlacklist = new ArrayList<>();
|
private final List<String> worldWhitelist = new ArrayList<>(), worldBlacklist = new ArrayList<>();
|
||||||
private final List<String> biomeWhitelist = new ArrayList<>(), biomeBlacklist = new ArrayList<>();
|
private final List<String> biomeWhitelist = new ArrayList<>(), biomeBlacklist = new ArrayList<>();
|
||||||
private final boolean slimeChunk;
|
private final boolean slimeChunk;
|
||||||
|
|
||||||
public WorldGenTemplate(ConfigurationSection config) {
|
public WorldGenTemplate(ConfigurationSection config) {
|
||||||
Validate.notNull(config, "Could not read gen template config");
|
Validate.notNull(config, "Could not read gen template config");
|
||||||
|
|
||||||
id = config.getName().toLowerCase().replace(" ", "-").replace("_", "-");
|
id = config.getName().toLowerCase().replace(" ", "-").replace("_", "-");
|
||||||
config.getStringList("replace").forEach(str -> replaceable.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
config.getStringList("replace").forEach(str -> replaceable.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
||||||
config.getStringList("bordering").forEach(str -> bordering.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
config.getStringList("bordering").forEach(str -> bordering.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
||||||
config.getStringList("not-bordering").forEach(str -> notBordering.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
config.getStringList("not-bordering").forEach(str -> notBordering.add(Material.valueOf(str.toUpperCase().replace("-", "_").replace(" ", "_"))));
|
||||||
|
|
||||||
for (String world : config.getStringList("worlds")) {
|
|
||||||
(world.startsWith("!") ? worldBlacklist : worldWhitelist).add(world.toLowerCase().replace("_", "-"));
|
|
||||||
}
|
|
||||||
for (String biome : config.getStringList("biomes")) {
|
|
||||||
(biome.startsWith("!") ? biomeBlacklist : biomeWhitelist).add(biome.toUpperCase().replace("-", "_").replace(" ", "_"));
|
|
||||||
}
|
|
||||||
chunkChance = config.getDouble("chunk-chance");
|
|
||||||
slimeChunk = config.getBoolean("slime-chunk", false);
|
|
||||||
|
|
||||||
String[] depth = config.getString("depth").split("=");
|
for (String world : config.getStringList("worlds")) {
|
||||||
minDepth = Integer.parseInt(depth[0]);
|
(world.startsWith("!") ? worldBlacklist : worldWhitelist).add(world.toLowerCase().replace("_", "-"));
|
||||||
maxDepth = Integer.parseInt(depth[1]);
|
|
||||||
|
|
||||||
//Validate.isTrue(minDepth >= 0, "Min depth must be greater than 0");
|
|
||||||
//Validate.isTrue(maxDepth < 256, "Max depth must be at most 255");
|
|
||||||
|
|
||||||
veinSize = config.getInt("vein-size");
|
|
||||||
veinCount = config.getInt("vein-count");
|
|
||||||
|
|
||||||
Validate.isTrue(veinSize > 0 && veinCount > 0, "Vein size and count must be at least 1");
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public double getChunkChance() {
|
|
||||||
return chunkChance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVeinSize() {
|
|
||||||
return veinSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getVeinCount() {
|
|
||||||
return veinCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMinDepth() {
|
|
||||||
return minDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getMaxDepth() {
|
|
||||||
return maxDepth;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canGenerateInWorld(World w) {
|
|
||||||
// check world list
|
|
||||||
String world = w.getName().toLowerCase().replace("_", "-");
|
|
||||||
if (!worldWhitelist.isEmpty() && !worldWhitelist.contains(world)) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
if (!worldBlacklist.isEmpty() && worldBlacklist.contains(world)) {
|
for (String biome : config.getStringList("biomes")) {
|
||||||
return false;
|
(biome.startsWith("!") ? biomeBlacklist : biomeWhitelist).add(biome.toUpperCase().replace("-", "_").replace(" ", "_"));
|
||||||
}
|
}
|
||||||
|
chunkChance = config.getDouble("chunk-chance");
|
||||||
|
slimeChunk = config.getBoolean("slime-chunk", false);
|
||||||
|
|
||||||
|
String[] depth = config.getString("depth").split("=");
|
||||||
|
minDepth = Integer.parseInt(depth[0]);
|
||||||
|
maxDepth = Integer.parseInt(depth[1]);
|
||||||
|
|
||||||
|
//Validate.isTrue(minDepth >= 0, "Min depth must be greater than 0");
|
||||||
|
//Validate.isTrue(maxDepth < 256, "Max depth must be at most 255");
|
||||||
|
|
||||||
|
veinSize = config.getInt("vein-size");
|
||||||
|
veinCount = config.getInt("vein-count");
|
||||||
|
|
||||||
|
Validate.isTrue(veinSize > 0 && veinCount > 0, "Vein size and count must be at least 1");
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public double getChunkChance() {
|
||||||
|
return chunkChance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVeinSize() {
|
||||||
|
return veinSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getVeinCount() {
|
||||||
|
return veinCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMinDepth() {
|
||||||
|
return minDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxDepth() {
|
||||||
|
return maxDepth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canGenerateInWorld(String worldName) {
|
||||||
|
// check world list
|
||||||
|
String world = worldName.toLowerCase().replace("_", "-");
|
||||||
|
if (!worldWhitelist.isEmpty() && !worldWhitelist.contains(world))
|
||||||
|
return false;
|
||||||
|
return worldBlacklist.isEmpty() || !worldBlacklist.contains(world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean canGenerate(Location pos) {
|
||||||
|
|
||||||
|
// check biome list
|
||||||
|
Biome biome = pos.getWorld().getBiome(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
||||||
|
if ((!biomeWhitelist.isEmpty() && !biomeWhitelist.contains(biome.name()))
|
||||||
|
|| (!biomeBlacklist.isEmpty() && biomeBlacklist.contains(biome.name())))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// check extra options
|
||||||
|
if (slimeChunk && !pos.getChunk().isSlimeChunk())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!bordering.isEmpty()) {
|
||||||
|
if (!checkIfBorderingBlocks(pos))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!notBordering.isEmpty())
|
||||||
|
return checkIfNotBorderingBlocks(pos);
|
||||||
|
|
||||||
|
// can generate if no restrictions applied
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean canGenerate(Location pos) {
|
|
||||||
|
|
||||||
// check biome list
|
public boolean canReplace(Material type) {
|
||||||
Biome biome = pos.getWorld().getBiome(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ());
|
return replaceable.isEmpty() || replaceable.contains(type);
|
||||||
if (!biomeWhitelist.isEmpty() && !biomeWhitelist.contains(biome.name())) {
|
}
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (!biomeBlacklist.isEmpty() && biomeBlacklist.contains(biome.name())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// check extra options
|
|
||||||
if (slimeChunk && !pos.getChunk().isSlimeChunk()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bordering.isEmpty()) {
|
|
||||||
if(!checkIfBorderingBlocks(pos)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!notBordering.isEmpty()) {
|
|
||||||
return checkIfNotBorderingBlocks(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
// can generate if no restrictions applied
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canReplace(Material type) {
|
public boolean canBorder(Material type) {
|
||||||
return replaceable.isEmpty() || replaceable.contains(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canBorder(Material type) {
|
|
||||||
return bordering.isEmpty() || bordering.contains(type);
|
return bordering.isEmpty() || bordering.contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkIfBorderingBlocks(Location pos) {
|
public boolean checkIfBorderingBlocks(Location pos) {
|
||||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.NORTH).getType())) {
|
return Arrays.stream(BlockFace.values())
|
||||||
return false;
|
.map(pos.getBlock()::getRelative)
|
||||||
}
|
.map(Block::getType)
|
||||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.EAST).getType())) {
|
.allMatch(this::canBorder);
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.SOUTH).getType())) {
|
public boolean canNotBorder(Material type) {
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.WEST).getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.UP).getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return canBorder(pos.getBlock().getRelative(BlockFace.DOWN).getType());
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean canNotBorder(Material type) {
|
|
||||||
return !notBordering.isEmpty() && notBordering.contains(type);
|
return !notBordering.isEmpty() && notBordering.contains(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean checkIfNotBorderingBlocks(Location pos) {
|
public boolean checkIfNotBorderingBlocks(Location pos) {
|
||||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.NORTH).getType())) {
|
return Arrays.stream(BlockFace.values())
|
||||||
return false;
|
.map(pos.getBlock()::getRelative)
|
||||||
}
|
.map(Block::getType)
|
||||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.EAST).getType())) {
|
.allMatch(this::canNotBorder);
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.SOUTH).getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.WEST).getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.UP).getType())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return !canNotBorder(pos.getBlock().getRelative(BlockFace.DOWN).getType());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,75 @@
|
|||||||
|
package net.Indyuce.mmoitems.api.world;
|
||||||
|
|
||||||
|
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||||
|
import net.Indyuce.mmoitems.api.block.WorldGenTemplate;
|
||||||
|
import net.Indyuce.mmoitems.manager.WorldGenManager;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.block.BlockFace;
|
||||||
|
import org.bukkit.generator.BlockPopulator;
|
||||||
|
import org.bukkit.generator.LimitedRegion;
|
||||||
|
import org.bukkit.generator.WorldInfo;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mmoitems
|
||||||
|
* 14/03/2023
|
||||||
|
*
|
||||||
|
* @author Roch Blondiaux (Kiwix).
|
||||||
|
*/
|
||||||
|
public class MMOBlockPopulator extends BlockPopulator {
|
||||||
|
|
||||||
|
private static final BlockFace[] faces = {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST, BlockFace.DOWN, BlockFace.UP};
|
||||||
|
|
||||||
|
private final WorldGenManager manager;
|
||||||
|
private final World world;
|
||||||
|
|
||||||
|
public MMOBlockPopulator(World world, WorldGenManager manager) {
|
||||||
|
this.manager = manager;
|
||||||
|
this.world = world;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void populate(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ, @NotNull LimitedRegion limitedRegion) {
|
||||||
|
final Map<CustomBlock, WorldGenTemplate> assigned = manager.assigned();
|
||||||
|
assigned.entrySet()
|
||||||
|
.stream()
|
||||||
|
.filter(entry -> entry.getValue().canGenerateInWorld(worldInfo.getName()))
|
||||||
|
.filter(entry -> entry.getValue().getMinDepth() >= worldInfo.getMinHeight())
|
||||||
|
.filter(entry -> entry.getValue().getMaxDepth() <= worldInfo.getMaxHeight())
|
||||||
|
.forEach(entry -> {
|
||||||
|
final CustomBlock block = entry.getKey();
|
||||||
|
final WorldGenTemplate template = entry.getValue();
|
||||||
|
if (random.nextDouble() > template.getChunkChance())
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int i = 0; i < template.getVeinCount(); i++) {
|
||||||
|
int x = chunkX * 16 + random.nextInt(16);
|
||||||
|
int y = random.nextInt(template.getMaxDepth() - template.getMinDepth() + 1) + template.getMinDepth();
|
||||||
|
int z = chunkZ * 16 + random.nextInt(16);
|
||||||
|
Location generatePoint = new Location(world, x, y, z);
|
||||||
|
|
||||||
|
if (!template.canGenerate(generatePoint) || generatePoint.getWorld() == null)
|
||||||
|
continue;
|
||||||
|
Block modify = generatePoint.getWorld().getBlockAt(generatePoint);
|
||||||
|
|
||||||
|
// MMOItems.log("Generating " + block.getId() + " at x: " + generatePoint.getBlockX() + " y: " + generatePoint.getBlockY() + " z: " + generatePoint.getBlockZ());
|
||||||
|
for (int j = 0; j < template.getVeinSize(); j++) {
|
||||||
|
if (!limitedRegion.isInRegion(modify.getLocation()))
|
||||||
|
continue;
|
||||||
|
if (template.canReplace(limitedRegion.getType(modify.getLocation()))) {
|
||||||
|
limitedRegion.setType(modify.getLocation(), block.getState().getType());
|
||||||
|
limitedRegion.setBlockData(modify.getLocation(), block.getState().getBlockData());
|
||||||
|
}
|
||||||
|
BlockFace nextFace = faces[random.nextInt(faces.length)];
|
||||||
|
modify = modify.getRelative(nextFace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,10 +1,15 @@
|
|||||||
package net.Indyuce.mmoitems.listener;
|
package net.Indyuce.mmoitems.listener;
|
||||||
|
|
||||||
|
import net.Indyuce.mmoitems.api.world.MMOBlockPopulator;
|
||||||
import net.Indyuce.mmoitems.manager.WorldGenManager;
|
import net.Indyuce.mmoitems.manager.WorldGenManager;
|
||||||
|
import org.bukkit.World;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
import org.bukkit.event.world.ChunkLoadEvent;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* mmoitems
|
* mmoitems
|
||||||
* 13/03/2023
|
* 13/03/2023
|
||||||
@ -19,9 +24,21 @@ public class WorldGenerationListener implements Listener {
|
|||||||
this.manager = manager;
|
this.manager = manager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// @EventHandler
|
||||||
|
// public void onWorldInit(WorldInitEvent e) {
|
||||||
|
// MMOItems.log("Initializing world " + e.getWorld().getName());
|
||||||
|
// final World world = e.getWorld();
|
||||||
|
// world.getPopulators().add(manager.populator(world));
|
||||||
|
// }
|
||||||
|
|
||||||
|
private final Map<String, MMOBlockPopulator> populatorMap = new HashMap<>();
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onChunkLoad(ChunkLoadEvent e) {
|
public void onChunkLoad(ChunkLoadEvent e) {
|
||||||
if (!e.isNewChunk()) return;
|
final World world = e.getWorld();
|
||||||
manager.populate(e);
|
if (!e.isNewChunk() || populatorMap.containsKey(world.getName())) return;
|
||||||
|
MMOBlockPopulator populator = manager.populator(world);
|
||||||
|
world.getPopulators().add(populator);
|
||||||
|
populatorMap.put(world.getName(), populator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,25 +4,17 @@ import net.Indyuce.mmoitems.MMOItems;
|
|||||||
import net.Indyuce.mmoitems.api.ConfigFile;
|
import net.Indyuce.mmoitems.api.ConfigFile;
|
||||||
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||||
import net.Indyuce.mmoitems.api.block.WorldGenTemplate;
|
import net.Indyuce.mmoitems.api.block.WorldGenTemplate;
|
||||||
|
import net.Indyuce.mmoitems.api.world.MMOBlockPopulator;
|
||||||
import net.Indyuce.mmoitems.listener.WorldGenerationListener;
|
import net.Indyuce.mmoitems.listener.WorldGenerationListener;
|
||||||
import net.Indyuce.mmoitems.tasks.CustomBlocksPopulateTask;
|
|
||||||
import net.Indyuce.mmoitems.util.Pair;
|
|
||||||
import org.apache.commons.lang.Validate;
|
import org.apache.commons.lang.Validate;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Location;
|
import org.bukkit.World;
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.block.BlockFace;
|
|
||||||
import org.bukkit.configuration.file.FileConfiguration;
|
import org.bukkit.configuration.file.FileConfiguration;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
import org.bukkit.event.world.ChunkLoadEvent;
|
|
||||||
import org.jetbrains.annotations.Blocking;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Queue;
|
|
||||||
import java.util.Random;
|
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue;
|
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
|
|
||||||
public class WorldGenManager implements Reloadable {
|
public class WorldGenManager implements Reloadable {
|
||||||
@ -34,13 +26,8 @@ public class WorldGenManager implements Reloadable {
|
|||||||
* world.
|
* world.
|
||||||
*/
|
*/
|
||||||
private final Map<CustomBlock, WorldGenTemplate> assigned = new HashMap<>();
|
private final Map<CustomBlock, WorldGenTemplate> assigned = new HashMap<>();
|
||||||
private final Queue<Pair<Location, CustomBlock>> modificationsQueue = new ConcurrentLinkedQueue<>();
|
|
||||||
|
|
||||||
private static final BlockFace[] faces = {BlockFace.NORTH, BlockFace.SOUTH, BlockFace.WEST, BlockFace.EAST, BlockFace.DOWN, BlockFace.UP};
|
|
||||||
private static final Random random = new Random();
|
|
||||||
|
|
||||||
private WorldGenerationListener listener;
|
private WorldGenerationListener listener;
|
||||||
private CustomBlocksPopulateTask task;
|
|
||||||
|
|
||||||
public WorldGenManager() {
|
public WorldGenManager() {
|
||||||
/*
|
/*
|
||||||
@ -67,48 +54,6 @@ public class WorldGenManager implements Reloadable {
|
|||||||
assigned.put(block, template);
|
assigned.put(block, template);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void populate(@NotNull ChunkLoadEvent e) {
|
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(MMOItems.plugin, () -> {
|
|
||||||
preprocess(e);
|
|
||||||
if (task != null && task.isRunning())
|
|
||||||
return;
|
|
||||||
task = new CustomBlocksPopulateTask(this);
|
|
||||||
task.start();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private @Blocking void preprocess(ChunkLoadEvent e) {
|
|
||||||
assigned.entrySet()
|
|
||||||
.stream()
|
|
||||||
.filter(entry -> entry.getValue().canGenerateInWorld(e.getWorld()))
|
|
||||||
.forEach(entry -> {
|
|
||||||
final CustomBlock block = entry.getKey();
|
|
||||||
final WorldGenTemplate template = entry.getValue();
|
|
||||||
if (random.nextDouble() > template.getChunkChance())
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int i = 0; i < template.getVeinCount(); i++) {
|
|
||||||
int y = random.nextInt(template.getMaxDepth() - template.getMinDepth() + 1) + template.getMinDepth();
|
|
||||||
Location generatePoint = e.getChunk().getBlock(random.nextInt(16), y, random.nextInt(16)).getLocation();
|
|
||||||
|
|
||||||
if (!template.canGenerate(generatePoint) || generatePoint.getWorld() == null)
|
|
||||||
continue;
|
|
||||||
Block modify = generatePoint.getWorld().getBlockAt(generatePoint);
|
|
||||||
|
|
||||||
for (int j = 0; j < template.getVeinSize(); j++) {
|
|
||||||
if (template.canReplace(modify.getType()))
|
|
||||||
this.modificationsQueue.add(Pair.of(modify.getLocation(), block));
|
|
||||||
BlockFace nextFace = faces[random.nextInt(faces.length)];
|
|
||||||
modify = modify.getRelative(nextFace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public Queue<Pair<Location, CustomBlock>> getModificationsQueue() {
|
|
||||||
return modificationsQueue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void reload() {
|
public void reload() {
|
||||||
// Listener
|
// Listener
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
@ -116,7 +61,6 @@ public class WorldGenManager implements Reloadable {
|
|||||||
|
|
||||||
assigned.clear();
|
assigned.clear();
|
||||||
templates.clear();
|
templates.clear();
|
||||||
modificationsQueue.clear();
|
|
||||||
|
|
||||||
FileConfiguration config = new ConfigFile("gen-templates").getConfig();
|
FileConfiguration config = new ConfigFile("gen-templates").getConfig();
|
||||||
for (String key : config.getKeys(false)) {
|
for (String key : config.getKeys(false)) {
|
||||||
@ -129,14 +73,22 @@ public class WorldGenManager implements Reloadable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Listeners
|
// Listeners
|
||||||
if (MMOItems.plugin.getLanguage().worldGenEnabled)
|
if (MMOItems.plugin.getLanguage().worldGenEnabled) {
|
||||||
Bukkit.getPluginManager().registerEvents(listener = new WorldGenerationListener(this), MMOItems.plugin);
|
listener = new WorldGenerationListener(this);
|
||||||
|
Bukkit.getPluginManager().registerEvents(listener, MMOItems.plugin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unload() {
|
public void unload() {
|
||||||
if (listener != null)
|
if (listener != null)
|
||||||
HandlerList.unregisterAll(listener);
|
HandlerList.unregisterAll(listener);
|
||||||
if (task != null)
|
}
|
||||||
task.stop();
|
|
||||||
|
public MMOBlockPopulator populator(@NotNull World world) {
|
||||||
|
return new MMOBlockPopulator(world, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<CustomBlock, WorldGenTemplate> assigned() {
|
||||||
|
return assigned;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
package net.Indyuce.mmoitems.tasks;
|
|
||||||
|
|
||||||
import net.Indyuce.mmoitems.MMOItems;
|
|
||||||
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
|
||||||
import net.Indyuce.mmoitems.manager.WorldGenManager;
|
|
||||||
import net.Indyuce.mmoitems.util.Pair;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.block.Block;
|
|
||||||
import org.bukkit.scheduler.BukkitRunnable;
|
|
||||||
|
|
||||||
import java.util.Queue;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* mmoitems
|
|
||||||
* 13/03/2023
|
|
||||||
*
|
|
||||||
* @author Roch Blondiaux (Kiwix).
|
|
||||||
*/
|
|
||||||
public class CustomBlocksPopulateTask extends BukkitRunnable {
|
|
||||||
|
|
||||||
private final WorldGenManager manager;
|
|
||||||
private boolean running = false;
|
|
||||||
|
|
||||||
public CustomBlocksPopulateTask(WorldGenManager manager) {
|
|
||||||
this.manager = manager;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
final Queue<Pair<Location, CustomBlock>> modificationsQueue = manager.getModificationsQueue();
|
|
||||||
final Pair<Location, CustomBlock> pair = modificationsQueue.poll();
|
|
||||||
|
|
||||||
// If the queue is empty, cancel the task
|
|
||||||
if (pair == null) {
|
|
||||||
this.stop();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If the chunk is not loaded, skip it
|
|
||||||
if (!pair.getKey().getChunk().isLoaded())
|
|
||||||
return;
|
|
||||||
|
|
||||||
// If the block is already modified, skip it
|
|
||||||
if (pair.getKey().getBlock().getBlockData().equals(pair.getValue().getState().getBlockData()))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Change the block
|
|
||||||
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> setBlockData(pair.getKey().getBlock(), pair.getValue()));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setBlockData(Block fModify, CustomBlock block) {
|
|
||||||
fModify.setType(block.getState().getType(), false);
|
|
||||||
fModify.setBlockData(block.getState().getBlockData(), false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void start() {
|
|
||||||
if (running) return;
|
|
||||||
running = true;
|
|
||||||
this.runTaskTimerAsynchronously(MMOItems.plugin, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void stop() {
|
|
||||||
if (!running) return;
|
|
||||||
running = false;
|
|
||||||
this.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRunning() {
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user