mirror of
https://gitlab.com/phoenix-dvpmt/mmoitems.git
synced 2024-12-22 04:37:42 +01:00
Merge branch '752-gen-templates-custom-block-spawning-doesn-t-work-at-all' into 'master'
World generation optimized See merge request phoenix-dvpmt/mmoitems!57
This commit is contained in:
commit
724eb97b90
@ -254,7 +254,6 @@ public class MMOItems extends JavaPlugin {
|
||||
|
||||
@Override
|
||||
public void onDisable() {
|
||||
|
||||
// Support for early plugin disabling
|
||||
if (!hasLoadedSuccessfully)
|
||||
return;
|
||||
@ -269,6 +268,9 @@ public class MMOItems extends JavaPlugin {
|
||||
for (Player player : Bukkit.getOnlinePlayers())
|
||||
if (player.getOpenInventory() != null && player.getOpenInventory().getTopInventory().getHolder() instanceof PluginInventory)
|
||||
player.closeInventory();
|
||||
|
||||
// WorldGen
|
||||
this.worldGenManager.unload();
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
|
@ -1,16 +1,17 @@
|
||||
package net.Indyuce.mmoitems.api.block;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.Material;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.block.Biome;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.configuration.ConfigurationSection;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class WorldGenTemplate {
|
||||
private final String id;
|
||||
private final double chunkChance;
|
||||
@ -77,43 +78,33 @@ public class WorldGenTemplate {
|
||||
return maxDepth;
|
||||
}
|
||||
|
||||
public boolean canGenerateInWorld(World w) {
|
||||
public boolean canGenerateInWorld(String worldName) {
|
||||
// check world list
|
||||
String world = w.getName().toLowerCase().replace("_", "-");
|
||||
if (!worldWhitelist.isEmpty() && !worldWhitelist.contains(world)) {
|
||||
String world = worldName.toLowerCase().replace("_", "-");
|
||||
if (!worldWhitelist.isEmpty() && !worldWhitelist.contains(world))
|
||||
return false;
|
||||
}
|
||||
if (!worldBlacklist.isEmpty() && worldBlacklist.contains(world)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
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())) {
|
||||
if ((!biomeWhitelist.isEmpty() && !biomeWhitelist.contains(biome.name()))
|
||||
|| (!biomeBlacklist.isEmpty() && biomeBlacklist.contains(biome.name())))
|
||||
return false;
|
||||
}
|
||||
if (!biomeBlacklist.isEmpty() && biomeBlacklist.contains(biome.name())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// check extra options
|
||||
if (slimeChunk && !pos.getChunk().isSlimeChunk()) {
|
||||
if (slimeChunk && !pos.getChunk().isSlimeChunk())
|
||||
return false;
|
||||
|
||||
if (!bordering.isEmpty()) {
|
||||
if (!checkIfBorderingBlocks(pos))
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!bordering.isEmpty()) {
|
||||
if(!checkIfBorderingBlocks(pos)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(!notBordering.isEmpty()) {
|
||||
if (!notBordering.isEmpty())
|
||||
return checkIfNotBorderingBlocks(pos);
|
||||
}
|
||||
|
||||
// can generate if no restrictions applied
|
||||
return true;
|
||||
@ -128,22 +119,10 @@ public class WorldGenTemplate {
|
||||
}
|
||||
|
||||
public boolean checkIfBorderingBlocks(Location pos) {
|
||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.NORTH).getType())) {
|
||||
return false;
|
||||
}
|
||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.EAST).getType())) {
|
||||
return false;
|
||||
}
|
||||
if(!canBorder(pos.getBlock().getRelative(BlockFace.SOUTH).getType())) {
|
||||
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());
|
||||
return Arrays.stream(BlockFace.values())
|
||||
.map(pos.getBlock()::getRelative)
|
||||
.map(Block::getType)
|
||||
.allMatch(this::canBorder);
|
||||
}
|
||||
|
||||
public boolean canNotBorder(Material type) {
|
||||
@ -151,21 +130,9 @@ public class WorldGenTemplate {
|
||||
}
|
||||
|
||||
public boolean checkIfNotBorderingBlocks(Location pos) {
|
||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.NORTH).getType())) {
|
||||
return false;
|
||||
}
|
||||
if(canNotBorder(pos.getBlock().getRelative(BlockFace.EAST).getType())) {
|
||||
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());
|
||||
return Arrays.stream(BlockFace.values())
|
||||
.map(pos.getBlock()::getRelative)
|
||||
.map(Block::getType)
|
||||
.allMatch(this::canNotBorder);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package net.Indyuce.mmoitems.listener;
|
||||
|
||||
import net.Indyuce.mmoitems.api.world.MMOBlockPopulator;
|
||||
import net.Indyuce.mmoitems.manager.WorldGenManager;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* mmoitems
|
||||
* 13/03/2023
|
||||
*
|
||||
* @author Roch Blondiaux (Kiwix).
|
||||
*/
|
||||
public class WorldGenerationListener implements Listener {
|
||||
|
||||
private final WorldGenManager manager;
|
||||
|
||||
public WorldGenerationListener(WorldGenManager 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
|
||||
public void onChunkLoad(ChunkLoadEvent e) {
|
||||
final World world = e.getWorld();
|
||||
if (!e.isNewChunk() || populatorMap.containsKey(world.getName())) return;
|
||||
MMOBlockPopulator populator = manager.populator(world);
|
||||
world.getPopulators().add(populator);
|
||||
populatorMap.put(world.getName(), populator);
|
||||
}
|
||||
}
|
@ -4,22 +4,20 @@ import net.Indyuce.mmoitems.MMOItems;
|
||||
import net.Indyuce.mmoitems.api.ConfigFile;
|
||||
import net.Indyuce.mmoitems.api.block.CustomBlock;
|
||||
import net.Indyuce.mmoitems.api.block.WorldGenTemplate;
|
||||
import net.Indyuce.mmoitems.api.world.MMOBlockPopulator;
|
||||
import net.Indyuce.mmoitems.listener.WorldGenerationListener;
|
||||
import org.apache.commons.lang.Validate;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.block.Block;
|
||||
import org.bukkit.block.BlockFace;
|
||||
import org.bukkit.World;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.event.EventHandler;
|
||||
import org.bukkit.event.Listener;
|
||||
import org.bukkit.event.world.ChunkLoadEvent;
|
||||
import org.bukkit.event.HandlerList;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.logging.Level;
|
||||
|
||||
public class WorldGenManager implements Listener, Reloadable {
|
||||
public class WorldGenManager implements Reloadable {
|
||||
private final Map<String, WorldGenTemplate> templates = new HashMap<>();
|
||||
|
||||
/*
|
||||
@ -29,20 +27,15 @@ public class WorldGenManager implements Listener, Reloadable {
|
||||
*/
|
||||
private final Map<CustomBlock, WorldGenTemplate> assigned = new HashMap<>();
|
||||
|
||||
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;
|
||||
|
||||
public WorldGenManager() {
|
||||
|
||||
/*
|
||||
* load the worldGenManager even if world gen is not enabled so that if
|
||||
* admins temporarily disable it, there is no console error spam saying
|
||||
* MI could not find corresponding gen template in config
|
||||
*/
|
||||
reload();
|
||||
|
||||
if (MMOItems.plugin.getLanguage().worldGenEnabled)
|
||||
Bukkit.getPluginManager().registerEvents(this, MMOItems.plugin);
|
||||
}
|
||||
|
||||
public WorldGenTemplate getOrThrow(String id) {
|
||||
@ -61,45 +54,16 @@ public class WorldGenManager implements Listener, Reloadable {
|
||||
assigned.put(block, template);
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
public void a(ChunkLoadEvent event) {
|
||||
if(event.isNewChunk()) {
|
||||
Bukkit.getScheduler().runTaskAsynchronously(MMOItems.plugin, () -> assigned.forEach((block, template) -> {
|
||||
if(!template.canGenerateInWorld(event.getWorld())) {
|
||||
return;
|
||||
}
|
||||
if(random.nextDouble() < template.getChunkChance())
|
||||
for(int i = 0; i < template.getVeinCount(); i++) {
|
||||
int y = random.nextInt(template.getMaxDepth() - template.getMinDepth() + 1) + template.getMinDepth();
|
||||
Location generatePoint = event.getChunk().getBlock(random.nextInt(16), y, random.nextInt(16)).getLocation();
|
||||
|
||||
if(template.canGenerate(generatePoint)) {
|
||||
Block modify = generatePoint.getWorld().getBlockAt(generatePoint);
|
||||
|
||||
for(int j = 0; j < template.getVeinSize(); j++) {
|
||||
if(template.canReplace(modify.getType())) {
|
||||
final Block fModify = modify;
|
||||
Bukkit.getScheduler().runTask(MMOItems.plugin, () -> {
|
||||
fModify.setType(block.getState().getType(), false);
|
||||
fModify.setBlockData(block.getState().getBlockData(), false);
|
||||
});
|
||||
}
|
||||
|
||||
BlockFace nextFace = faces[random.nextInt(faces.length)];
|
||||
modify = modify.getRelative(nextFace);
|
||||
}
|
||||
}
|
||||
}
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public void reload() {
|
||||
// Listener
|
||||
if (listener != null)
|
||||
HandlerList.unregisterAll(listener);
|
||||
|
||||
assigned.clear();
|
||||
templates.clear();
|
||||
|
||||
FileConfiguration config = new ConfigFile("gen-templates").getConfig();
|
||||
for(String key : config.getKeys(false)) {
|
||||
for (String key : config.getKeys(false)) {
|
||||
try {
|
||||
WorldGenTemplate template = new WorldGenTemplate(config.getConfigurationSection(key));
|
||||
templates.put(template.getId(), template);
|
||||
@ -107,5 +71,24 @@ public class WorldGenManager implements Listener, Reloadable {
|
||||
MMOItems.plugin.getLogger().log(Level.WARNING, "An error occurred when loading gen template '" + key + "': " + exception.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Listeners
|
||||
if (MMOItems.plugin.getLanguage().worldGenEnabled) {
|
||||
listener = new WorldGenerationListener(this);
|
||||
Bukkit.getPluginManager().registerEvents(listener, MMOItems.plugin);
|
||||
}
|
||||
}
|
||||
|
||||
public void unload() {
|
||||
if (listener != null)
|
||||
HandlerList.unregisterAll(listener);
|
||||
}
|
||||
|
||||
public MMOBlockPopulator populator(@NotNull World world) {
|
||||
return new MMOBlockPopulator(world, this);
|
||||
}
|
||||
|
||||
public Map<CustomBlock, WorldGenTemplate> assigned() {
|
||||
return assigned;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user