From 11f78a2cddca8bc0ca271da721b6172e95d5c970 Mon Sep 17 00:00:00 2001 From: minoneer Date: Fri, 3 Jan 2025 11:35:53 +0100 Subject: [PATCH] Update world generators to new generation model (#72) * Update world generators to new generation model Makes some biome-related things typesafe as a side effect. Resolves #68 * Copy biome list for tab completion purposes * Fix logging of biome to island config when using the biome GUI --- .../ultimateskyblock/api/IslandInfo.java | 23 +++- .../talabrek/ultimateskyblock/Settings.java | 40 ++++--- .../command/admin/AdminIslandCommand.java | 35 +++--- .../command/completion/BiomeTabCompleter.java | 3 +- .../command/island/BiomeCommand.java | 64 +++++----- .../placeholder/PlaceholderReplacerImpl.java | 2 +- .../ultimateskyblock/island/IslandInfo.java | 25 ++-- .../ultimateskyblock/menu/BiomeMenuItem.java | 11 +- .../ultimateskyblock/menu/SkyBlockMenu.java | 43 ++++--- .../talabrek/ultimateskyblock/uSkyBlock.java | 30 ++--- .../world/ChunkRegenerator.java | 74 +++--------- .../world/SingleBiomeProvider.java | 26 +++++ .../world/SkyBlockChunkGenerator.java | 29 ++--- .../world/SkyBlockNetherChunkGenerator.java | 110 +++++++++--------- uSkyBlock-Core/src/main/resources/config.yml | 7 +- 15 files changed, 266 insertions(+), 256 deletions(-) create mode 100644 uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SingleBiomeProvider.java diff --git a/uSkyBlock-API/src/main/java/us/talabrek/ultimateskyblock/api/IslandInfo.java b/uSkyBlock-API/src/main/java/us/talabrek/ultimateskyblock/api/IslandInfo.java index facb2c4e1..70649b32b 100644 --- a/uSkyBlock-API/src/main/java/us/talabrek/ultimateskyblock/api/IslandInfo.java +++ b/uSkyBlock-API/src/main/java/us/talabrek/ultimateskyblock/api/IslandInfo.java @@ -3,11 +3,13 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.OfflinePlayer; +import org.bukkit.block.Biome; import org.bukkit.entity.Player; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Set; @@ -75,9 +77,28 @@ public interface IslandInfo { /** * The name of the biome. + * + * @deprecated Unsafe String value, use {@link #getIslandBiome()} or {@link #getBiomeName()} instead. + * @return The name of the biome. + */ + @Deprecated(since="3.1.0") + default String getBiome() { + return getIslandBiome().name().toUpperCase(Locale.ROOT); + } + + /** + * The biome of the island. + * + * @return The iceland's biome. + */ + Biome getIslandBiome(); + + /** + * The name of the biome. + * * @return The name of the biome. */ - String getBiome(); + String getBiomeName(); /** * The current party-size of the island. diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/Settings.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/Settings.java index 5db004e54..13858905a 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/Settings.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/Settings.java @@ -1,16 +1,18 @@ package us.talabrek.ultimateskyblock; import dk.lockfuglsang.minecraft.po.I18nUtil; +import dk.lockfuglsang.minecraft.util.ItemStackUtil; +import org.bukkit.Registry; +import org.bukkit.block.Biome; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.inventory.ItemStack; -import us.talabrek.ultimateskyblock.command.island.BiomeCommand; import us.talabrek.ultimateskyblock.handler.WorldEditHandler; -import dk.lockfuglsang.minecraft.util.ItemStackUtil; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Set; +import java.util.logging.Level; import java.util.logging.Logger; public class Settings { @@ -32,7 +34,8 @@ public class Settings { public static int general_cooldownInfo; public static int general_cooldownRestart; public static int general_biomeChange; - public static String general_defaultBiome; + public static Biome general_defaultBiome; + public static Biome general_defaultNetherBiome; public static boolean extras_sendToSpawn; public static boolean extras_respawnAtIsland; public static boolean extras_obsidianToLava; @@ -87,14 +90,9 @@ public static boolean loadPluginConfig(FileConfiguration config) { } catch (Exception e) { general_biomeChange = 3600; } - try { - general_defaultBiome = config.getString("options.general.defaultBiome"); - if (!BiomeCommand.biomeExists(general_defaultBiome)) { - general_defaultBiome = "OCEAN"; - } - } catch (Exception e) { - general_defaultBiome = "OCEAN"; - } + general_defaultBiome = loadBiome(config, "options.general.defaultBiome", Biome.OCEAN); + general_defaultNetherBiome = loadBiome(config, "options.general.defaultNetherBiome", Biome.NETHER_WASTES); + try { general_cooldownRestart = config.getInt("options.general.cooldownRestart"); if (general_cooldownRestart < 0) { @@ -120,9 +118,7 @@ public static boolean loadPluginConfig(FileConfiguration config) { changed = true; } general_spawnSize = config.getInt("options.general.spawnSize", 50); - island_chestItems = ItemStackUtil.createItemList( - config.getStringList("options.island.chestItems") - ); + island_chestItems = ItemStackUtil.createItemList(config.getStringList("options.island.chestItems")); island_schematicName = config.getString("options.island.schematicName"); if (island_schematicName == null || "yourschematicname".equals(island_schematicName) || "uSkyBlockDefault".equals(island_schematicName)) { @@ -159,10 +155,24 @@ public static boolean loadPluginConfig(FileConfiguration config) { changed = true; } nether_lava_level = config.getInt("nether.lava_level", config.getInt("nether.lava-level", 32)); - nether_height = config.getInt("nether.height", island_height/2); + nether_height = config.getInt("nether.height", island_height / 2); return changed; } + private static Biome loadBiome(FileConfiguration config, String path, Biome defaultBiome) { + try { + String biomeKey = config.getString(path, defaultBiome.getKey().getKey()); + Biome parsedBiome = Registry.BIOME.match(biomeKey); + if (parsedBiome == null) { + log.log(Level.WARNING, "Invalid Biome in '{0}': {1}", new Object[]{path, biomeKey}); + parsedBiome = defaultBiome; + } + return parsedBiome; + } catch (Exception e) { + return defaultBiome; + } + } + public static List getIslandChestItems() { return ItemStackUtil.clone(island_chestItems); } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/admin/AdminIslandCommand.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/admin/AdminIslandCommand.java index d6be6428c..d9b4b6dcc 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/admin/AdminIslandCommand.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/admin/AdminIslandCommand.java @@ -108,7 +108,11 @@ public boolean execute(CommandSender sender, String alias, Map d sender.sendMessage(tr("\u00a74That player has no island.")); return false; } - setBiome(sender, playerInfo, plugin.getIslandInfo(playerInfo), args[1]); + Biome biome = plugin.getBiome(args[0]); + if (biome == null) { + return false; + } + setBiome(sender, playerInfo, plugin.getIslandInfo(playerInfo), biome); return true; } else if (args.length == 1 && sender instanceof Player) { Biome biome = plugin.getBiome(args[0]); @@ -121,7 +125,7 @@ public boolean execute(CommandSender sender, String alias, Map d sender.sendMessage(tr("\u00a74No valid island at your location")); return false; } - setBiome(sender, islandInfo, biome.name()); + setBiome(sender, islandInfo, biome); return true; } return false; @@ -132,8 +136,7 @@ public boolean execute(CommandSender sender, String alias, Map d public boolean execute(CommandSender sender, String alias, Map data, String... args) { String cmd = "/usb island purge"; IslandInfo islandInfo = null; - if (args.length == 0 && sender instanceof Player) { - Player player = (Player) sender; + if (args.length == 0 && sender instanceof Player player) { String islandName = WorldGuardHandler.getIslandNameAt(player.getLocation()); islandInfo = plugin.getIslandInfo(islandName); } else if (args.length == 1) { @@ -186,29 +189,21 @@ private void removePlayerFromIsland(CommandSender sender, PlayerInfo playerInfo, playerInfo.save(); } - private void setBiome(CommandSender sender, IslandInfo islandInfo, String biome) { - if (uSkyBlock.getInstance().setBiome(islandInfo.getIslandLocation(), biome)) { - islandInfo.setBiome(biome); - sender.sendMessage(tr("\u00a7eChanged biome of {0}s island to {1}.", islandInfo.getLeader(), biome)); - } else { - islandInfo.setBiome("OCEAN"); - sender.sendMessage(tr("\u00a7eChanged biome of {0}s island to OCEAN.", islandInfo.getLeader())); - } + private void setBiome(CommandSender sender, IslandInfo islandInfo, Biome biome) { + uSkyBlock.getInstance().setBiome(islandInfo.getIslandLocation(), biome); + islandInfo.setBiome(biome); + sender.sendMessage(tr("\u00a7eChanged biome of {0}s island to {1}.", islandInfo.getLeader(), biome)); sender.sendMessage(tr("\u00a7aYou may need to go to spawn, or relog, to see the changes.")); } - private void setBiome(CommandSender sender, PlayerInfo playerInfo, IslandInfo islandInfo, String biome) { + private void setBiome(CommandSender sender, PlayerInfo playerInfo, IslandInfo islandInfo, Biome biome) { if (playerInfo == null || !playerInfo.getHasIsland()) { sender.sendMessage(tr("\u00a74That player has no island.")); return; } - if (uSkyBlock.getInstance().setBiome(playerInfo.getIslandLocation(), biome)) { - islandInfo.setBiome(biome); - sender.sendMessage(tr("\u00a7e{0} has had their biome changed to {1}.", playerInfo.getPlayerName(), biome)); - } else { - islandInfo.setBiome("OCEAN"); - sender.sendMessage(tr("\u00a7e{0} has had their biome changed to OCEAN.", playerInfo.getPlayerName())); - } + uSkyBlock.getInstance().setBiome(playerInfo.getIslandLocation(), biome); + islandInfo.setBiome(biome); + sender.sendMessage(tr("\u00a7e{0} has had their biome changed to {1}.", playerInfo.getPlayerName(), biome)); sender.sendMessage(tr("\u00a7aYou may need to go to spawn, or relog, to see the changes.")); } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/completion/BiomeTabCompleter.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/completion/BiomeTabCompleter.java index f2c05fcf0..3c7690ec4 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/completion/BiomeTabCompleter.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/completion/BiomeTabCompleter.java @@ -11,10 +11,9 @@ * TabCompleter for Biomes. */ public class BiomeTabCompleter extends AbstractTabCompleter { - private static final List BIOMES = new ArrayList<>(BiomeCommand.BIOMES.keySet()); @Override protected List getTabList(CommandSender commandSender, String term) { - return filter(BIOMES, term); + return filter(new ArrayList<>(BiomeCommand.AVAILABLE_BIOMES), term); } } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/island/BiomeCommand.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/island/BiomeCommand.java index 04eb9dfff..c6f66620d 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/island/BiomeCommand.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/command/island/BiomeCommand.java @@ -4,6 +4,7 @@ import com.sk89q.worldguard.protection.regions.ProtectedRegion; import org.bukkit.Chunk; import org.bukkit.Location; +import org.bukkit.Registry; import org.bukkit.block.Biome; import org.bukkit.entity.Player; import us.talabrek.ultimateskyblock.Settings; @@ -14,29 +15,22 @@ import us.talabrek.ultimateskyblock.player.PlayerInfo; import us.talabrek.ultimateskyblock.uSkyBlock; -import java.util.HashMap; +import java.util.List; import java.util.Map; import static dk.lockfuglsang.minecraft.po.I18nUtil.marktr; import static dk.lockfuglsang.minecraft.po.I18nUtil.tr; public class BiomeCommand extends RequireIslandCommand { - public static final Map BIOMES = new HashMap<>() { - { - for (Biome biome : Biome.values()) { - if (!biome.name().equalsIgnoreCase("custom")) { - put(biome.name().toLowerCase(), biome); - } - } - } - }; + public static final List AVAILABLE_BIOMES = + Registry.BIOME.stream().map(biome -> biome.getKey().getKey()).sorted().toList(); private final SkyBlockMenu menu; public BiomeCommand(uSkyBlock plugin, SkyBlockMenu menu) { super(plugin, "biome|b", null, "biome ?radius", marktr("change the biome of the island")); this.menu = menu; addFeaturePermission("usb.exempt.cooldown.biome", tr("exempt player from biome-cooldown")); - for (String biome : BIOMES.keySet()) { + for (String biome : AVAILABLE_BIOMES) { addFeaturePermission("usb.biome." + biome, tr("Let the player change their islands biome to {0}", biome.toUpperCase())); } } @@ -51,7 +45,7 @@ protected boolean doExecute(String alias, final Player player, PlayerInfo pi, fi } } if (args.length >= 1) { - final String biome = args[0].toLowerCase(); + final String biomeKey = args[0].toLowerCase(); if (!island.hasPerm(player, "canChangeBiome")) { player.sendMessage(tr("\u00a74You do not have permission to change the biome of this island!")); return true; @@ -62,8 +56,9 @@ protected boolean doExecute(String alias, final Player player, PlayerInfo pi, fi player.sendMessage(tr("\u00a7eYou must be on your island to change the biome!")); return true; } - if (!biomeExists(biome)) { - player.sendMessage(tr("\u00a7cYou have misspelled the biome name. Must be one of {0}", BIOMES.keySet())); + Biome biome = Registry.BIOME.match(biomeKey); + if (biome == null) { + player.sendMessage(tr("\u00a7cYou have misspelled the biome name. Must be one of {0}", AVAILABLE_BIOMES)); return true; } int cooldown = plugin.getCooldownHandler().getCooldown(player, "biome"); @@ -71,7 +66,7 @@ protected boolean doExecute(String alias, final Player player, PlayerInfo pi, fi player.sendMessage(tr("\u00a7eYou can change your biome again in {0,number,#} minutes.", cooldown / 60)); return true; } - if (!player.hasPermission("usb.biome." + biome.toLowerCase())) { + if (!player.hasPermission("usb.biome." + biomeKey.toLowerCase())) { player.sendMessage(tr("\u00a7cYou do not have permission to change your biome to that type.")); return true; } @@ -82,6 +77,8 @@ protected boolean doExecute(String alias, final Player player, PlayerInfo pi, fi minP.subtract(buffer, 0, buffer); maxP.add(buffer, 0, buffer); } + boolean changeEntireIslandBiome; + if (args.length == 2 && args[1].matches("[0-9]+")) { int radius = Integer.parseInt(args[1], 10); minP = BlockVector3.at(Math.max(location.getBlockX() - radius, minP.getBlockX()), @@ -90,39 +87,34 @@ protected boolean doExecute(String alias, final Player player, PlayerInfo pi, fi maxP = BlockVector3.at(Math.min(location.getBlockX() + radius, maxP.getBlockX()), Math.min(location.getBlockY() + radius, maxP.getBlockY()), Math.min(location.getBlockZ() + radius, maxP.getBlockZ())); - player.sendMessage(tr("\u00a77The pixies are busy changing the biome near you to \u00a79{0}\u00a77, be patient.", biome)); + changeEntireIslandBiome = false; + player.sendMessage(tr("\u00a77The pixies are busy changing the biome near you to \u00a79{0}\u00a77, be patient.", biomeKey)); } else if (args.length == 2 && args[1].equalsIgnoreCase("chunk")) { Chunk chunk = location.clone().getChunk(); - minP = BlockVector3.at(chunk.getX() << 4, 0, chunk.getZ() << 4); + minP = BlockVector3.at(chunk.getX() << 4, location.getWorld().getMinHeight(), chunk.getZ() << 4); maxP = BlockVector3.at((chunk.getX() << 4) + 15, location.getWorld().getMaxHeight(), (chunk.getZ() << 4) + 15); - player.sendMessage(tr("\u00a77The pixies are busy changing the biome in your current chunk to \u00a79{0}\u00a77, be patient.", biome)); + changeEntireIslandBiome = false; + player.sendMessage(tr("\u00a77The pixies are busy changing the biome in your current chunk to \u00a79{0}\u00a77, be patient.", biomeKey)); } else if (args.length < 2 || args[1].equalsIgnoreCase("all")) { - player.sendMessage(tr("\u00a77The pixies are busy changing the biome of your island to \u00a79{0}\u00a77, be patient.", biome)); - } - Biome biomeEnum = BIOMES.get(biome); - if (biomeEnum == null) { - player.sendMessage(tr("\u00a7eInvalid biome {0} supplied!", biome)); + changeEntireIslandBiome = true; + player.sendMessage(tr("\u00a77The pixies are busy changing the biome of your island to \u00a79{0}\u00a77, be patient.", biomeKey)); + } else { + player.sendMessage(tr("\u00a7cInvalid arguments. Use /is biome [radius|chunk|all]")); return true; } - new SetBiomeTask(plugin, player.getWorld(), minP, maxP, biomeEnum, () -> { - if (args.length == 1) { + new SetBiomeTask(plugin, player.getWorld(), minP, maxP, biome, () -> { + String biomeName = biome.getKey().getKey(); + if (changeEntireIslandBiome) { island.setBiome(biome); - player.sendMessage(tr("\u00a7aYou have changed your island''s biome to {0}", biome.toUpperCase())); - island.sendMessageToIslandGroup(true, marktr("{0} changed the island biome to {1}"), player.getName(), biome.toUpperCase()); + player.sendMessage(tr("\u00a7aYou have changed your island''s biome to {0}", biomeName)); + island.sendMessageToIslandGroup(true, marktr("{0} changed the island biome to {1}"), player.getName(), biomeName); plugin.getCooldownHandler().resetCooldown(player, "biome", Settings.general_biomeChange); } else { - player.sendMessage(tr("\u00a7aYou have changed {0} blocks around you to the {1} biome", args[1], biome.toUpperCase())); - island.sendMessageToIslandGroup(true, marktr("{0} created an area with {1} biome"), player.getName(), biome.toUpperCase()); + player.sendMessage(tr("\u00a7aYou have changed {0} blocks around you to the {1} biome", args[1], biomeName)); + island.sendMessageToIslandGroup(true, marktr("{0} created an area with {1} biome"), player.getName(), biomeName); } }).runTask(plugin); } return true; } - - public static boolean biomeExists(String biomeName) { - if (biomeName == null) { - return false; - } - return BIOMES.containsKey(biomeName.toLowerCase()); - } } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/handler/placeholder/PlaceholderReplacerImpl.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/handler/placeholder/PlaceholderReplacerImpl.java index 4670cf514..1e3692ab4 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/handler/placeholder/PlaceholderReplacerImpl.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/handler/placeholder/PlaceholderReplacerImpl.java @@ -109,7 +109,7 @@ private String lookup(IslandInfo islandInfo, String placeholder) { case "usb_island_animals": return "" + plugin.getLimitLogic().getCreatureCount(islandInfo).get(LimitLogic.CreatureType.ANIMAL); case "usb_island_villagers": return "" + plugin.getLimitLogic().getCreatureCount(islandInfo).get(LimitLogic.CreatureType.VILLAGER); case "usb_island_partysize": return "" + islandInfo.getPartySize(); - case "usb_island_biome": return islandInfo.getBiome(); + case "usb_island_biome": return islandInfo.getBiomeName(); case "usb_island_bans": return ""+islandInfo.getBans(); case "usb_island_members": return ""+islandInfo.getMembers(); case "usb_island_trustees": return ""+islandInfo.getTrustees(); diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/island/IslandInfo.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/island/IslandInfo.java index 32c56cf10..485dc10ba 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/island/IslandInfo.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/island/IslandInfo.java @@ -6,6 +6,8 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.OfflinePlayer; +import org.bukkit.Registry; +import org.bukkit.block.Biome; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.YamlConfiguration; @@ -390,15 +392,24 @@ public boolean hasPerm(UUID uuid, String perm) { } @Override - public String getBiome() { - return config.getString("general.biome", Settings.general_defaultBiome).toUpperCase(); + public Biome getIslandBiome() { + String biomeKey = config.getString("general.biome", Settings.general_defaultBiome.getKey().getKey()); + Biome biome = Registry.BIOME.match(biomeKey); + if (biome != null) { + return biome; + } else { + return Settings.general_defaultNetherBiome; + } } - public void setBiome(@NotNull String biome) { - Validate.notNull(biome, "Biome cannot be null"); - Validate.notEmpty(biome, "Biome cannot be empty"); + @Override + public String getBiomeName() { + return getIslandBiome().getKey().getKey(); + } - config.set("general.biome", biome.toUpperCase()); + public void setBiome(@NotNull Biome biome) { + Validate.notNull(biome, "Biome cannot be null"); + config.set("general.biome", biome.getKey().getKey()); save(); } @@ -981,7 +992,7 @@ public String toString() { String str = "\u00a7bIsland Info:\n"; str += ChatColor.GRAY + " - level: " + ChatColor.DARK_AQUA + String.format("%5.2f", getLevel()) + "\n"; str += ChatColor.GRAY + " - location: " + ChatColor.DARK_AQUA + name + "\n"; - str += ChatColor.GRAY + " - biome: " + ChatColor.DARK_AQUA + getBiome() + "\n"; + str += ChatColor.GRAY + " - biome: " + ChatColor.DARK_AQUA + getBiomeName() + "\n"; str += ChatColor.GRAY + " - schematic: " + ChatColor.DARK_AQUA + getSchematicName() + "\n"; str += ChatColor.GRAY + " - warp: " + ChatColor.DARK_AQUA + hasWarp() + "\n"; if (hasWarp()) { diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/BiomeMenuItem.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/BiomeMenuItem.java index 513a3c5ca..cf8a07b3d 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/BiomeMenuItem.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/BiomeMenuItem.java @@ -1,16 +1,17 @@ package us.talabrek.ultimateskyblock.menu; +import org.bukkit.block.Biome; import org.bukkit.inventory.ItemStack; public class BiomeMenuItem { private final ItemStack icon; - private final String name; + private final Biome biome; private final String title; private final String description; - public BiomeMenuItem(ItemStack icon, String name, String title, String description) { + public BiomeMenuItem(ItemStack icon, Biome biome, String title, String description) { this.icon = icon; - this.name = name; + this.biome = biome; this.title = title; this.description = description; } @@ -19,8 +20,8 @@ public ItemStack getIcon() { return icon.clone(); } - public String getId() { - return name; + public Biome getBiome() { + return biome; } public String getTitle() { diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/SkyBlockMenu.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/SkyBlockMenu.java index 19ba6c7f5..d0ab18b09 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/SkyBlockMenu.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/menu/SkyBlockMenu.java @@ -5,6 +5,7 @@ import dk.lockfuglsang.minecraft.util.TimeUtil; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.block.Biome; import org.bukkit.configuration.ConfigurationSection; import org.bukkit.entity.Player; import org.bukkit.event.inventory.InventoryClickEvent; @@ -15,7 +16,6 @@ import org.bukkit.profile.PlayerProfile; import org.bukkit.scheduler.BukkitTask; import us.talabrek.ultimateskyblock.challenge.ChallengeLogic; -import us.talabrek.ultimateskyblock.command.island.BiomeCommand; import us.talabrek.ultimateskyblock.island.IslandInfo; import us.talabrek.ultimateskyblock.player.IslandPerk; import us.talabrek.ultimateskyblock.player.PlayerInfo; @@ -87,55 +87,55 @@ public class SkyBlockMenu { ); private final List biomeMenus = Arrays.asList( new BiomeMenuItem(new ItemStack(Material.TROPICAL_FISH, 1), - "ocean", tr("Ocean"), + Biome.OCEAN, tr("Ocean"), tr("The ocean biome is the basic\nstarting biome for all islands.\npassive mobs like animals will\nnot spawn. Hostile mobs will\nspawn normally.") ), new BiomeMenuItem(new ItemStack(Material.SPRUCE_SAPLING, 1), - "forest", tr("Forest"), + Biome.FOREST, tr("Forest"), tr("The forest biome will allow\nyour island to spawn passive.\nmobs like animals (including\nwolves). Hostile mobs will\nspawn normally.") ), new BiomeMenuItem(new ItemStack(Material.SAND, 1), - "desert", tr("Desert"), + Biome.DESERT, tr("Desert"), tr("The desert biome makes it so\nthat there is no rain or snow\non your island. Passive mobs\nwon't spawn. Hostile mobs will\nspawn normally.") ), new BiomeMenuItem(new ItemStack(Material.JUNGLE_SAPLING, 1), - "jungle", tr("Jungle"), + Biome.JUNGLE, tr("Jungle"), tr("The jungle biome is bright\nand colorful. Passive mobs\n(including ocelots) will\nspawn. Hostile mobs will\nspawn normally.") ), new BiomeMenuItem(new ItemStack(Material.LILY_PAD, 1), - "swamp", tr("Swampland"), + Biome.SWAMP, tr("Swampland"), tr("The swamp biome is dark\nand dull. Passive mobs\nwill spawn normally and\nslimes have a small chance\nto spawn at night depending\non the moon phase.") ), new BiomeMenuItem(new ItemStack(Material.SNOW, 1), - "taiga", tr("Taiga"), + Biome.TAIGA, tr("Taiga"), tr("The taiga biome has snow\ninstead of rain. Passive\nmobs will spawn normally\n(including wolves) and\nhostile mobs will spawn.") ), new BiomeMenuItem(new ItemStack(Material.RED_MUSHROOM, 1), - "mushroom_fields", tr("Mushroom"), + Biome.MUSHROOM_FIELDS, tr("Mushroom"), tr("The mushroom biome is\nbright and colorful.\nMooshrooms are the only\nmobs that will spawn.\nNo other passive or\nhostile mobs will spawn.") ), new BiomeMenuItem(new ItemStack(Material.NETHER_BRICK, 1), - "nether_wastes", tr("Hell"), + Biome.NETHER_WASTES, tr("Hell"), tr("The hell biome looks\ndark and dead. Some\nmobs from the nether will\nspawn in this biome\n(excluding ghasts and\nblazes).") ), new BiomeMenuItem(new ItemStack(Material.ENDER_EYE, 1), - "the_end", tr("Sky"), + Biome.THE_END, tr("Sky"), tr("The sky biome gives your\nisland a special dark sky.\nOnly endermen will spawn\nin this biome.") ), new BiomeMenuItem(new ItemStack(Material.TALL_GRASS, 1), - "plains", tr("Plains"), + Biome.PLAINS, tr("Plains"), tr("The plains biome has rain\ninstead of snow. Passive\nmobs will spawn normally\n(including horses) and\nhostile mobs will spawn.") ), new BiomeMenuItem(new ItemStack(Material.EMERALD_ORE, 1), - "windswept_hills", tr("Extreme Hills"), + Biome.WINDSWEPT_HILLS, tr("Extreme Hills"), tr("The extreme hills biome.\nPassive mobs will spawn \nnormally and hostile\nmobs will spawn.") ), new BiomeMenuItem(new ItemStack(Material.ROSE_BUSH, 1), - "flower_forest", tr("Flower Forest"), + Biome.FLOWER_FOREST, tr("Flower Forest"), tr("The flower forest biome.\nPassive mobs will spawn \nnormally and hostile\nmobs will spawn.") ), new BiomeMenuItem(new ItemStack(Material.PRISMARINE_SHARD, 1), - "deep_ocean", tr("Deep Ocean"), + Biome.DEEP_OCEAN, tr("Deep Ocean"), tr(""" The deep-ocean biome is an advanced biome. Passive mobs like animals will @@ -144,7 +144,7 @@ public class SkyBlockMenu { spawn normally.""") ), new BiomeMenuItem(new ItemStack(Material.PACKED_ICE, 1), - "snowy_plains", tr("Ice Plains"), + Biome.SNOWY_PLAINS, tr("Ice Plains"), tr("The ice-plains biome is an advanced biome.\nMobs will spawn naturally.\nincluding polar-bears") ) ); @@ -297,17 +297,14 @@ public Inventory displayBiomeGUI(final Player player) { sign.setItemMeta(meta4); menu.addItem(sign); lores.clear(); - String currentBiome = plugin.getIslandInfo(player).getBiome(); + Biome currentBiome = plugin.getIslandInfo(player).getIslandBiome(); for (BiomeMenuItem biomeMenu : biomeMenus) { - if (!BiomeCommand.biomeExists(biomeMenu.getId())) { - continue; // Skip it - } ItemStack menuItem = biomeMenu.getIcon(); meta4 = requireNonNull(requireNonNull(menuItem.getItemMeta())); - if (player.hasPermission("usb.biome." + biomeMenu.getId())) { + if (player.hasPermission("usb.biome." + biomeMenu.getBiome().getKey().getKey())) { meta4.setDisplayName("\u00a7a" + tr("Biome: {0}", biomeMenu.getTitle())); addLore(lores, "\u00a7f", biomeMenu.getDescription()); - if (biomeMenu.getId().equalsIgnoreCase(currentBiome)) { + if (biomeMenu.getBiome().equals(currentBiome)) { addLore(lores, tr("\u00a72\u00a7lThis is your current biome.")); } else { addLore(lores, tr("\u00a7e\u00a7lClick to change to this biome.")); @@ -641,7 +638,7 @@ private Inventory createMainMenu(Player player) { menuItem = new ItemStack(Material.JUNGLE_SAPLING, 1); meta4 = requireNonNull(requireNonNull(menuItem.getItemMeta())); meta4.setDisplayName("\u00a7a\u00a7l" + tr("Change Island Biome")); - lores.add(tr("\u00a7eCurrent Biome: \u00a7b{0}", islandInfo.getBiome())); + lores.add(tr("\u00a7eCurrent Biome: \u00a7b{0}", islandInfo.getBiomeName())); addLore(lores, "\u00a7f", tr("The island biome affects things\nlike grass color and spawning\nof both animals and monsters.")); if (islandInfo.hasPerm(player, "canChangeBiome")) { addLore(lores, tr("\u00a7e\u00a7lClick here to change biomes.")); @@ -1091,7 +1088,7 @@ private void onClickBiomeMenu(InventoryClickEvent event, ItemStack currentItem, ItemStack menuIcon = biomeMenu.getIcon(); if (currentItem.getType() == menuIcon.getType()) { String radius = PlayerUtil.getMetadata(p, "biome.radius", "all"); - p.performCommand("island biome " + biomeMenu.getId() + " " + radius); + p.performCommand("island biome " + biomeMenu.getBiome().getKey().getKey() + " " + radius); return; } } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/uSkyBlock.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/uSkyBlock.java index c9edf4545..76bc4b750 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/uSkyBlock.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/uSkyBlock.java @@ -10,6 +10,7 @@ import dk.lockfuglsang.minecraft.util.VersionUtil; import org.bukkit.Bukkit; import org.bukkit.Location; +import org.bukkit.Registry; import org.bukkit.block.Biome; import org.bukkit.command.CommandSender; import org.bukkit.configuration.file.FileConfiguration; @@ -47,8 +48,17 @@ import us.talabrek.ultimateskyblock.command.IslandCommand; import us.talabrek.ultimateskyblock.command.admin.DebugCommand; import us.talabrek.ultimateskyblock.command.admin.SetMaintenanceCommand; -import us.talabrek.ultimateskyblock.command.island.BiomeCommand; -import us.talabrek.ultimateskyblock.event.*; +import us.talabrek.ultimateskyblock.event.ExploitEvents; +import us.talabrek.ultimateskyblock.event.GriefEvents; +import us.talabrek.ultimateskyblock.event.InternalEvents; +import us.talabrek.ultimateskyblock.event.ItemDropEvents; +import us.talabrek.ultimateskyblock.event.MenuEvents; +import us.talabrek.ultimateskyblock.event.NetherTerraFormEvents; +import us.talabrek.ultimateskyblock.event.PlayerEvents; +import us.talabrek.ultimateskyblock.event.SpawnEvents; +import us.talabrek.ultimateskyblock.event.ToolMenuEvents; +import us.talabrek.ultimateskyblock.event.WitherTagEvents; +import us.talabrek.ultimateskyblock.event.WorldGuardEvents; import us.talabrek.ultimateskyblock.handler.AsyncWorldEditHandler; import us.talabrek.ultimateskyblock.handler.ConfirmHandler; import us.talabrek.ultimateskyblock.handler.CooldownHandler; @@ -593,19 +603,13 @@ public PlayerInfo getPlayerInfo(String playerName) { return playerLogic.getPlayerInfo(playerName); } - public boolean setBiome(final Location loc, final String bName) { - Biome biome = getBiome(bName); - if (biome == null) return false; - setBiome(loc, biome); - return true; - } - - public Biome getBiome(String bName) { - if (bName == null) return null; - return BiomeCommand.BIOMES.get(bName.toLowerCase()); + // TODO: move these to Biome/World related classes + public @Nullable Biome getBiome(String biomeName) { + if (biomeName == null) return null; + return Registry.BIOME.match(biomeName); } - private void setBiome(Location loc, Biome biome) { + public void setBiome(Location loc, Biome biome) { new SetBiomeTask(this, loc, biome, null).runTask(this); } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/ChunkRegenerator.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/ChunkRegenerator.java index 15140ab1b..291aa2def 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/ChunkRegenerator.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/ChunkRegenerator.java @@ -1,27 +1,24 @@ package us.talabrek.ultimateskyblock.world; import org.apache.commons.lang3.Validate; +import org.bukkit.Bukkit; import org.bukkit.Chunk; import org.bukkit.World; -import org.bukkit.block.Biome; import org.bukkit.entity.Entity; import org.bukkit.entity.Player; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.ChunkGenerator; -import org.bukkit.generator.ChunkGenerator.BiomeGrid; import org.bukkit.generator.ChunkGenerator.ChunkData; import org.bukkit.scheduler.BukkitScheduler; import org.bukkit.scheduler.BukkitTask; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import us.talabrek.ultimateskyblock.Settings; import us.talabrek.ultimateskyblock.uSkyBlock; import java.util.Arrays; import java.util.List; import java.util.Random; -import static org.bukkit.World.Environment; - /** * Class responsible for regenerating chunks. */ @@ -52,7 +49,7 @@ public void regenerateChunks(@NotNull List chunkList, @Nullable Runnable task = scheduler.runTaskTimer(plugin, () -> { for (int i = 0; i <= CHUNKS_PER_TICK; i++) { if (!chunkList.isEmpty()) { - Chunk chunk = chunkList.remove(0); + Chunk chunk = chunkList.removeFirst(); regenerateChunk(chunk); } else { if (onCompletion != null) { @@ -74,15 +71,25 @@ public void regenerateChunk(@NotNull Chunk chunk) { spawnTeleportPlayers(chunk); - Random random = new Random(); - BiomeGrid biomeGrid = new DefaultBiomeGrid(world.getEnvironment()); - ChunkData chunkData = chunkGen.generateChunkData(world, random, chunk.getX(), chunk.getZ(), biomeGrid); + Random random = new Random(world.getSeed() + (long) chunk.getX() * (long) chunk.getZ()); + + World world = chunk.getWorld(); + + ChunkData chunkData = Bukkit.createChunkData(world); + chunkGen.generateNoise(world, random, chunk.getX(), chunk.getZ(), chunkData); + chunkGen.generateSurface(world, random, chunk.getX(), chunk.getZ(), chunkData); + chunkGen.generateBedrock(world, random, chunk.getX(), chunk.getZ(), chunkData); + chunkGen.generateCaves(world, random, chunk.getX(), chunk.getZ(), chunkData); + + BiomeProvider biomeProvider = chunkGen.getDefaultBiomeProvider(world); for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - for (int y = 0; y < chunk.getWorld().getMaxHeight(); y++) { + for (int y = world.getMinHeight(); y < world.getMaxHeight(); y++) { + if (biomeProvider != null) { + chunk.getBlock(x, y, z).setBiome(biomeProvider.getBiome(world, x, y, z)); + } chunk.getBlock(x, y, z).setBlockData(chunkData.getBlockData(x, y, z)); - chunk.getBlock(x, y, z).setBiome(biomeGrid.getBiome(x, y, z)); } } } @@ -111,49 +118,4 @@ private void spawnTeleportPlayers(@NotNull Chunk chunk) { } } } - - /** - * Default BiomeGrid used by uSkyBlock when regenerating chunks. - */ - static class DefaultBiomeGrid implements BiomeGrid { - private Biome defaultBiome; - - DefaultBiomeGrid(Environment env) { - switch (env) { - case THE_END: - defaultBiome = Biome.THE_END; - break; - case NETHER: - defaultBiome = Biome.NETHER_WASTES; - break; - default: - defaultBiome = Biome.valueOf(Settings.general_defaultBiome); - break; - } - } - - @NotNull - @Deprecated - @Override - public Biome getBiome(int x, int z) { - return defaultBiome; - } - - @NotNull - @Override - public Biome getBiome(int x, int y, int z) { - return defaultBiome; - } - - @Deprecated - @Override - public void setBiome(int x, int z, @NotNull Biome bio) { - defaultBiome = bio; - } - - @Override - public void setBiome(int x, int y, int z, @NotNull Biome bio) { - defaultBiome = bio; - } - } } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SingleBiomeProvider.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SingleBiomeProvider.java new file mode 100644 index 000000000..819a28403 --- /dev/null +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SingleBiomeProvider.java @@ -0,0 +1,26 @@ +package us.talabrek.ultimateskyblock.world; + +import org.bukkit.block.Biome; +import org.bukkit.generator.BiomeProvider; +import org.bukkit.generator.WorldInfo; +import org.jetbrains.annotations.NotNull; + +import java.util.List; + +public class SingleBiomeProvider extends BiomeProvider { + private final Biome biome; + + public SingleBiomeProvider(Biome biome) { + this.biome = biome; + } + + @Override + public @NotNull Biome getBiome(@NotNull WorldInfo worldInfo, int x, int y, int z) { + return biome; + } + + @Override + public @NotNull List getBiomes(@NotNull WorldInfo worldInfo) { + return List.of(biome); + } +} diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockChunkGenerator.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockChunkGenerator.java index b0c60005e..f0ede4c3c 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockChunkGenerator.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockChunkGenerator.java @@ -2,38 +2,33 @@ import org.bukkit.Location; import org.bukkit.World; -import org.bukkit.block.Biome; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; +import org.bukkit.generator.WorldInfo; +import org.jetbrains.annotations.NotNull; import us.talabrek.ultimateskyblock.Settings; -import java.util.ArrayList; import java.util.List; import java.util.Random; +/** + * A chunk generator that generates an empty world with a single biome. + */ public class SkyBlockChunkGenerator extends ChunkGenerator { - private static final List emptyBlockPopulatorList = new ArrayList<>(); - @Override - public ChunkData generateChunkData(World world, Random random, int cx, int cz, BiomeGrid biome) { - ChunkData chunkData = createChunkData(world); - for (int x = 0; x <= 15; x++) { - for (int z = 0; z <= 15; z++) { - for (int y = 0; y < world.getMaxHeight(); y++) { - biome.setBiome(x, y, z, Biome.valueOf(Settings.general_defaultBiome)); - } - } - } - return chunkData; + @NotNull + public List getDefaultPopulators(@NotNull World world) { + return List.of(); } @Override - public List getDefaultPopulators(World world) { - return emptyBlockPopulatorList; + public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) { + return new SingleBiomeProvider(Settings.general_defaultBiome); } @Override - public Location getFixedSpawnLocation(World world, Random random) { + public Location getFixedSpawnLocation(@NotNull World world, @NotNull Random random) { return new Location(world, 0.5d, Settings.island_height, 0.5d); } } diff --git a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockNetherChunkGenerator.java b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockNetherChunkGenerator.java index 24cc648c8..c6b826ded 100644 --- a/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockNetherChunkGenerator.java +++ b/uSkyBlock-Core/src/main/java/us/talabrek/ultimateskyblock/world/SkyBlockNetherChunkGenerator.java @@ -3,97 +3,91 @@ import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; -import org.bukkit.block.Biome; +import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BlockPopulator; import org.bukkit.generator.ChunkGenerator; +import org.bukkit.generator.WorldInfo; +import org.jetbrains.annotations.NotNull; import us.talabrek.ultimateskyblock.Settings; -import java.util.ArrayList; import java.util.List; import java.util.Random; public class SkyBlockNetherChunkGenerator extends ChunkGenerator { - private static final List emptyBlockPopulatorList = new ArrayList(); + + // The nether height limits intentionally differ from World.getMinHeight() and World.getMaxHeight() to reflect + // vanilla nether limits. + private static final int MIN_HEIGHT = 0; + private static final int MAX_HEIGHT = 128; @Override - public ChunkData generateChunkData(World world, Random random, int cx, int cz, BiomeGrid biome) { - ChunkData chunkData = createChunkData(world); - for (int x = 0; x <= 15; x++) { - for (int z = 0; z <= 15; z++) { - for (int y = 0; y < world.getMaxHeight(); y++) { - biome.setBiome(x, y, z, Biome.NETHER_WASTES); - } - } - } - int y = 0; - // Solid floor + public void generateNoise(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ, @NotNull ChunkData chunkData) { + // Generate lava sea + chunkData.setRegion(0, MIN_HEIGHT, 0, 16, Settings.nether_lava_level + 1, 16, Material.LAVA); + + // Generate netherrack ceiling + + // First layer with holes + int y = MAX_HEIGHT - 8; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - chunkData.setBlock(x, y, z, Material.BEDROCK); + if (random.nextDouble() >= 0.20) { // 20% air + chunkData.setBlock(x, y, z, Material.NETHERRACK); + } } } - // Bedrock with holes in it - for (y = 1; y <= 5; y++) { - double yThreshold = 0.10 * y; + + // Solid block above + chunkData.setRegion(0, MAX_HEIGHT - 7, 0, 16, MAX_HEIGHT, 16, Material.NETHERRACK); + } + + @Override + public void generateBedrock(@NotNull WorldInfo worldInfo, @NotNull Random random, int chunkX, int chunkZ, @NotNull ChunkData chunkData) { + // Solid bedrock floor + chunkData.setRegion(0, MIN_HEIGHT, 0, 16, MIN_HEIGHT + 1, 16, Material.BEDROCK); + + // Bedrock floor with holes in it + for (int yOffset = 1; yOffset < 6; yOffset++) { + double yThreshold = 0.10 * yOffset; // 90% - 50% bedrock + int y = MIN_HEIGHT + yOffset; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - if (random.nextDouble() >= yThreshold) { // 10%-50% air + if (random.nextDouble() >= yThreshold) { chunkData.setBlock(x, y, z, Material.BEDROCK); - } else { - chunkData.setBlock(x, y, z, Material.LAVA); } } } } - for (y = 6; y <= Settings.nether_lava_level; y++) { - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - chunkData.setBlock(x, y, z, Material.LAVA); - } - } - } - y = 120; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - if (random.nextDouble() >= 0.20) { // 20% air - chunkData.setBlock(x, y, z, Material.NETHERRACK); - } - } - } - y = 121; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - chunkData.setBlock(x, y, z, Material.NETHERRACK); - } - } - for (y = 122; y <= 126; y++) { - double yThreashold = 0.20 * (127 - y); + + // Bedrock ceiling with holes in it + for (int yOffset = 1; yOffset < 6; yOffset++) { + double yThreshold = 0.20 * (yOffset); // 20% - 100% bedrock + int y = MAX_HEIGHT - yOffset - 1; for (int x = 0; x < 16; x++) { for (int z = 0; z < 16; z++) { - if (random.nextDouble() >= yThreashold) { // 20%-100% bedrock + if (random.nextDouble() >= yThreshold) { chunkData.setBlock(x, y, z, Material.BEDROCK); - } else { - chunkData.setBlock(x, y, z, Material.NETHERRACK); } } } } - y = 127; - for (int x = 0; x < 16; x++) { - for (int z = 0; z < 16; z++) { - chunkData.setBlock(x, y, z, Material.BEDROCK); - } - } - return chunkData; + + // Solid bedrock ceiling + chunkData.setRegion(0, MAX_HEIGHT - 1, 0, 16, MAX_HEIGHT, 16, Material.BEDROCK); + } + + @Override + public @NotNull List getDefaultPopulators(@NotNull World world) { + return List.of(); } @Override - public List getDefaultPopulators(World world) { - return emptyBlockPopulatorList; + public BiomeProvider getDefaultBiomeProvider(@NotNull WorldInfo worldInfo) { + return new SingleBiomeProvider(Settings.general_defaultNetherBiome); } @Override - public Location getFixedSpawnLocation(World world, Random random) { - return new Location(world, 0, Settings.nether_height, 0); + public Location getFixedSpawnLocation(@NotNull World world, @NotNull Random random) { + return new Location(world, 0, Settings.nether_height, 0); } } diff --git a/uSkyBlock-Core/src/main/resources/config.yml b/uSkyBlock-Core/src/main/resources/config.yml index f09239e9b..8f3ee1020 100644 --- a/uSkyBlock-Core/src/main/resources/config.yml +++ b/uSkyBlock-Core/src/main/resources/config.yml @@ -16,7 +16,10 @@ options: biomeChange: 60 # [string] The default biome assigned to new islands - defaultBiome: OCEAN + defaultBiome: ocean + + # [string] The default biome assigned to new islands + defaultNetherBiome: nether_wastes # [integer] The number of milliseconds between the same notification is sent to the player. # This is used when events are triggered heavily - i.e. item-pickup-prevention, damage-prevention etc. @@ -462,7 +465,7 @@ placeholder: servercommandplaceholder: false # DO NOT TOUCH THE FIELDS BELOW -version: 109 +version: 110 force-replace: options.party.invite-timeout: 100 options.island.islandTeleportDelay: 5