From b3e7cf9fafd7fdd0f4f2baa82527c663f3d96f19 Mon Sep 17 00:00:00 2001 From: BONNe Date: Sun, 3 Feb 2019 16:08:27 +0200 Subject: [PATCH] Add ability to enable beacon even if roof is made of bedrock. (#5) - Add multiple event listeners that detects if blocks should be replaced or not. - Add new config option, that allows to enable/disable beacon enabling. --- .../world/bentobox/caveblock/CaveBlock.java | 2 + .../world/bentobox/caveblock/Settings.java | 29 ++- .../caveblock/listeners/BeaconEnabler.java | 203 ++++++++++++++++++ src/main/resources/config.yml | 9 +- 4 files changed, 238 insertions(+), 5 deletions(-) create mode 100644 src/main/java/world/bentobox/caveblock/listeners/BeaconEnabler.java diff --git a/src/main/java/world/bentobox/caveblock/CaveBlock.java b/src/main/java/world/bentobox/caveblock/CaveBlock.java index bc1acf7..c170de6 100644 --- a/src/main/java/world/bentobox/caveblock/CaveBlock.java +++ b/src/main/java/world/bentobox/caveblock/CaveBlock.java @@ -13,6 +13,7 @@ import world.bentobox.bentobox.api.configuration.WorldSettings; import world.bentobox.caveblock.commands.AdminCommand; import world.bentobox.caveblock.commands.IslandCommand; import world.bentobox.caveblock.generators.ChunkGeneratorWorld; +import world.bentobox.caveblock.listeners.BeaconEnabler; import world.bentobox.caveblock.listeners.CustomHeightLimitations; @@ -164,6 +165,7 @@ public class CaveBlock extends GameModeAddon } this.getServer().getPluginManager().registerEvents(new CustomHeightLimitations(this), this.getPlugin()); + this.getServer().getPluginManager().registerEvents(new BeaconEnabler(this), this.getPlugin()); } diff --git a/src/main/java/world/bentobox/caveblock/Settings.java b/src/main/java/world/bentobox/caveblock/Settings.java index beb4830..a1571bd 100644 --- a/src/main/java/world/bentobox/caveblock/Settings.java +++ b/src/main/java/world/bentobox/caveblock/Settings.java @@ -818,6 +818,16 @@ public class Settings implements DataObject, WorldSettings } + /** + * This method returns the beaconAllowed object. + * @return the beaconAllowed object. + */ + public boolean isBeaconAllowed() + { + return beaconAllowed; + } + + // --------------------------------------------------------------------- // Section: Setters // --------------------------------------------------------------------- @@ -1593,6 +1603,17 @@ public class Settings implements DataObject, WorldSettings } + /** + * This method sets the beaconAllowed object value. + * @param beaconAllowed the beaconAllowed object new value. + * + */ + public void setBeaconAllowed(boolean beaconAllowed) + { + this.beaconAllowed = beaconAllowed; + } + + /** * @return the debug */ @@ -1701,7 +1722,6 @@ public class Settings implements DataObject, WorldSettings @ConfigEntry(path = "world.sky-walking") private boolean skyWalking; - @ConfigComment("") @ConfigComment("Enables different ways how to get to other worlds.") @ConfigComment("If players fall into void, then they will be teleported:") @ConfigComment(" - to nether if falls into void from over world") @@ -1710,6 +1730,13 @@ public class Settings implements DataObject, WorldSettings @ConfigEntry(path = "world.alternative-teleports") private boolean alternativeTeleports; + @ConfigComment("Enables ability to use beacon, if world roof is made of Bedrock. It will replace") + @ConfigComment("bedrock with black stained glass and on beacon placing, and replace it with bedrock if") + @ConfigComment("beacon is destroyed.") + @ConfigComment("This will not do anything, if roof is not made of bedrock.") + @ConfigEntry(path = "world.allow-beacon") + private boolean beaconAllowed; + @ConfigComment("") @ConfigComment("Make over world roof of bedrock, if false, it will be made from stone") @ConfigEntry(path = "world.normal.roof", needsReset = true) diff --git a/src/main/java/world/bentobox/caveblock/listeners/BeaconEnabler.java b/src/main/java/world/bentobox/caveblock/listeners/BeaconEnabler.java new file mode 100644 index 0000000..61a8f4f --- /dev/null +++ b/src/main/java/world/bentobox/caveblock/listeners/BeaconEnabler.java @@ -0,0 +1,203 @@ +package world.bentobox.caveblock.listeners; + + +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Block; +import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockBreakEvent; +import org.bukkit.event.block.BlockDamageEvent; +import org.bukkit.event.block.BlockExplodeEvent; +import org.bukkit.event.block.BlockPlaceEvent; +import org.bukkit.event.entity.EntityExplodeEvent; + +import world.bentobox.bentobox.util.Util; +import world.bentobox.caveblock.CaveBlock; +import world.bentobox.caveblock.Settings; + + +/** + * This class allows to enable beacon in CaveBlock, if cave roof is made of bedrock. + * It will replace Bedrock with black glass. + */ +public class BeaconEnabler implements Listener +{ + /** + * Constructor BeaconEnabler creates a new BeaconEnabler instance. + * + * @param addon of type CaveBlock + */ + public BeaconEnabler(CaveBlock addon) + { + this.addon = addon; + this.settings = addon.getSettings(); + } + + + /** + * Method onBlockPlacement detects if beacon is placed and replace roof bedrock with black glass. + * + * @param event of type BlockPlaceEvent + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onBlockPlacement(BlockPlaceEvent event) + { + World world = event.getPlayer().getWorld(); + + if (!Util.sameWorld(this.addon.getOverWorld(), world) || + !this.settings.isBeaconAllowed() || + !this.isRoofEnabled(world) || + !event.getBlock().getType().equals(Material.BEACON)) + { + // This should work only if it is cave block world or world has roof from bedrock. Otherwise, + // players can dig till top themself. + return; + } + + + Block roofBlock = world.getBlockAt(event.getBlock().getX(), this.settings.getWorldDepth() - 1, event.getBlock().getZ()); + + if (roofBlock.getType().equals(Material.BEDROCK)) + { + // Replace only bedrock. + roofBlock.setType(Material.BLACK_STAINED_GLASS); + } + } + + + /** + * Method onBlockBreak detects if beacon is destroyed and replace roof black glass with bedrock. + * + * @param event of type BlockBreakEvent + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onBlockBreak(BlockBreakEvent event) + { + World world = event.getPlayer().getWorld(); + + if (!Util.sameWorld(this.addon.getOverWorld(), world) || + !this.isRoofEnabled(world) || + !this.settings.isBeaconAllowed() || + !event.getBlock().getType().equals(Material.BEACON)) + { + // This should work only if it is cave block world or world has roof from bedrock. + return; + } + + Block roofBlock = world.getBlockAt(event.getBlock().getX(), this.settings.getWorldDepth() - 1, event.getBlock().getZ()); + + if (roofBlock.getType().equals(Material.BLACK_STAINED_GLASS)) + { + // Replace only black glass. + roofBlock.setType(Material.BEDROCK); + } + } + + + /** + * Method onBlockDamage detects if user tries to destroy black glass on roof and disable it. + * + * @param event of type BlockDamageEvent + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onBlockDamage(BlockDamageEvent event) + { + World world = event.getPlayer().getWorld(); + + if (!Util.sameWorld(this.addon.getOverWorld(), world) || + !this.isRoofEnabled(world) || + !this.settings.isBeaconAllowed() || + event.getBlock().getY() != this.settings.getWorldDepth() - 1) + { + // This should work only if it is cave block world or world has roof from bedrock. + return; + } + + // Cancel break event if it is black glass. + event.setCancelled(event.getBlock().getType().equals(Material.BLACK_STAINED_GLASS)); + } + + + /** + * Method onBlockExplode detects if explosion tries to destroy black glass on roof and disable it. + * + * @param event of type BlockExplodeEvent + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onBlockExplode(BlockExplodeEvent event) + { + World world = event.getBlock().getWorld(); + + if (!Util.sameWorld(this.addon.getOverWorld(), world) || + !this.isRoofEnabled(world) || + !this.settings.isBeaconAllowed() || + event.getBlock().getY() < this.settings.getWorldDepth() - 9) + { + // This should work only if it is cave block world or world has roof from bedrock. + return; + } + + final int blockY = this.settings.getWorldDepth() - 1; + + // Remove all black stained glass from explosion block list if it is on the roof. + event.blockList().removeIf(block -> + block.getY() == blockY && block.getType().equals(Material.BLACK_STAINED_GLASS)); + } + + + /** + * Method onEntityExplode detects if explosion tries to destroy black glass on roof and disable it. + * + * @param event of type EntityExplodeEvent + */ + @EventHandler(priority = EventPriority.LOWEST) + public void onEntityExplode(EntityExplodeEvent event) + { + World world = event.getLocation().getWorld(); + + if (!Util.sameWorld(this.addon.getOverWorld(), world) || + !this.isRoofEnabled(world) || + !this.settings.isBeaconAllowed() || + event.getLocation().getY() < this.settings.getWorldDepth() - 9) + { + // This should work only if it is cave block world or world has roof from bedrock. + return; + } + + final int blockY = this.settings.getWorldDepth() - 1; + + // Remove all black stained glass from explosion block list if it is on the roof. + event.blockList().removeIf(block -> + block.getY() == blockY && block.getType().equals(Material.BLACK_STAINED_GLASS)); + } + + + /** + * This method checks if in given world bedrock roof is enabled. + * @param world World that must be checked. + * @return true - bedrock roof is enabled, otherwise false + */ + private boolean isRoofEnabled(World world) + { + return world.getEnvironment().equals(World.Environment.NORMAL) && this.settings.isNormalRoof() || + world.getEnvironment().equals(World.Environment.NETHER) && this.settings.isNetherRoof() || + world.getEnvironment().equals(World.Environment.THE_END) && this.settings.isEndRoof(); + } + + +// --------------------------------------------------------------------- +// Section: Variables +// --------------------------------------------------------------------- + + /** + * CaveBlock addon. + */ + private CaveBlock addon; + + /** + * Addon settings. + */ + private Settings settings; +} diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 94466be..dd5a831 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -57,16 +57,17 @@ world: # # Allows to walk over the world roof. sky-walking: false - # # Enables different ways how to get to other worlds. # If players fall into void, then they will be teleported: # - to nether if falls into void from over world # - to the end if falls into void from nether # - to over world if falls into void from the end alternative-teleports: true - # - # This disabled default portals from obsidian or end portal. - disable-default-portal: true + # Enables ability to use beacon, if world roof is made of Bedrock. It will replace + # bedrock with black stained glass and on beacon placing, and replace it with bedrock if + # beacon is destroyed. + # This will not do anything, if roof is not made of bedrock. + allow-beacon: false normal: # # Make over world roof of bedrock, if false, it will be made from stone