From bf1b59076c00c1d88de4db289b450c411c18cceb Mon Sep 17 00:00:00 2001 From: tastybento Date: Sun, 3 Feb 2019 16:27:30 -0800 Subject: [PATCH] Removes the end trophy island After looking at the server code, it does not appear to be possible to prevent the end island from generating. However, it can be tricked to place it very high up by placing a bedrock block at 0,255,0. Then 1 second after it is generated, it can be removed. This results in the end island owner at 0,0 only being able to build up to 250 blocks high instead of 255. I added a simple block place listener to prevent placing of blocks above 250 because they will be deleted any time the chunk is loaded. If there's a better way to do this, I'm open to it! --- .../bentobox/listeners/BlockEndDragon.java | 72 ++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java index c29b39d73..5f9c2b4f1 100644 --- a/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java +++ b/src/main/java/world/bentobox/bentobox/listeners/BlockEndDragon.java @@ -1,14 +1,32 @@ package world.bentobox.bentobox.listeners; +import java.util.Arrays; +import java.util.List; + +import org.bukkit.Bukkit; +import org.bukkit.Material; +import org.bukkit.World.Environment; import org.bukkit.entity.EntityType; import org.bukkit.event.EventHandler; import org.bukkit.event.EventPriority; import org.bukkit.event.Listener; +import org.bukkit.event.block.BlockPlaceEvent; import org.bukkit.event.entity.CreatureSpawnEvent; +import org.bukkit.event.world.ChunkLoadEvent; import world.bentobox.bentobox.BentoBox; +import world.bentobox.bentobox.util.Pair; public class BlockEndDragon implements Listener { + + private static final List> CHUNKS = Arrays.asList( + new Pair(0,0), + new Pair(-1,0), + new Pair(-1, -1), + new Pair(0, -1)); + + private static final int DEAD_ZONE_Y = 250; + private BentoBox plugin; public BlockEndDragon(BentoBox plugin) { @@ -17,7 +35,7 @@ public class BlockEndDragon implements Listener { /** * This handles end dragon spawning prevention - * + * * @param e - event * @return true if dragon can spawn, false if not */ @@ -33,4 +51,56 @@ public class BlockEndDragon implements Listener { } + /** + * This listener aims to delete the end trophy from the end when it is generated + * It is added by special code in the server that can't be overidden so the only + * option is to delete it manually. This means that any island at 0,0 will have + * a dead zone of a few blocks directly above it. Hopefully this will not be a + * major issue. + * @param e - event + */ + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEnd(ChunkLoadEvent e) { + if (!e.getWorld().getEnvironment().equals(Environment.THE_END) + || !plugin.getIWM().inWorld(e.getWorld()) + || !plugin.getIWM().isEndGenerate(e.getWorld()) + || !plugin.getIWM().isEndIslands(e.getWorld()) + || !CHUNKS.contains(new Pair(e.getChunk().getX(), e.getChunk().getZ()))) { + return; + } + // Setting a bedrock block here forces the spike to be placed as high as possible + if (e.getChunk().getX() == 0 && e.getChunk().getZ() == 0) { + e.getChunk().getBlock(0, 255, 0).setType(Material.BEDROCK); + } + // Remove trophy spike / exit portal after a while + Bukkit.getScheduler().runTaskLater(plugin, () -> { + for (int x = 0; x < 16; x++) { + for (int z = 0; z < 16; z++) { + for (int y = DEAD_ZONE_Y; y < e.getWorld().getMaxHeight(); y++) { + e.getChunk().getBlock(x, y, z).setType(Material.AIR); + } + } + } + }, 20L); + } + + /** + * Silently prevents block placing in the dead zone. + * This is just a simple protection. If the player uses fancy ways to get blocks + * into the dead zone it'll just mean they get deleted next time the chunks are loaded. + * @param e - event + */ + @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true) + public void onEndBlockPlace(BlockPlaceEvent e) { + if (e.getBlock().getY() < DEAD_ZONE_Y + || !e.getBlock().getWorld().getEnvironment().equals(Environment.THE_END) + || !plugin.getIWM().inWorld(e.getBlock().getWorld()) + || !plugin.getIWM().isEndGenerate(e.getBlock().getWorld()) + || !plugin.getIWM().isEndIslands(e.getBlock().getWorld()) + || !CHUNKS.contains(new Pair(e.getBlock().getChunk().getX(), e.getBlock().getChunk().getZ())) + ) { + return; + } + e.setCancelled(true); + } }