From e7817fa405addf8533db00efcc048997b45538e9 Mon Sep 17 00:00:00 2001 From: tastybento Date: Fri, 6 May 2016 20:54:10 -0700 Subject: [PATCH] Changed how biomes are set. --- pom.xml | 2 +- .../askyblock/ASkyBlockAPI.java | 9 +- .../askyblock/commands/AdminCmd.java | 13 +- .../askyblock/panels/BiomesPanel.java | 105 +++----------- .../askyblock/panels/SetBiome.java | 137 ++++++++++++++++++ 5 files changed, 175 insertions(+), 91 deletions(-) create mode 100644 src/com/wasteofplastic/askyblock/panels/SetBiome.java diff --git a/pom.xml b/pom.xml index 25053d460..c67221240 100644 --- a/pom.xml +++ b/pom.xml @@ -161,5 +161,5 @@ http://maven.sk89q.com/repo/ - 3.0.0.6 + 3.0.0.7 diff --git a/src/com/wasteofplastic/askyblock/ASkyBlockAPI.java b/src/com/wasteofplastic/askyblock/ASkyBlockAPI.java index 82c7a5aa0..b2cae566d 100644 --- a/src/com/wasteofplastic/askyblock/ASkyBlockAPI.java +++ b/src/com/wasteofplastic/askyblock/ASkyBlockAPI.java @@ -30,6 +30,8 @@ import org.bukkit.block.Biome; import org.bukkit.entity.Player; +import com.wasteofplastic.askyblock.panels.SetBiome; + /** * Provides a programming interface * @@ -271,7 +273,12 @@ public boolean playerIsOnIsland(Player player) { * @return true if the setting was successful */ public boolean setIslandBiome(Location islandLoc, Biome biomeType) { - return plugin.getBiomes().setIslandBiome(islandLoc, biomeType); + Island island = plugin.getGrid().getIslandAt(islandLoc); + if (island != null) { + new SetBiome(plugin, island, biomeType); + return true; + } + return false; } /** diff --git a/src/com/wasteofplastic/askyblock/commands/AdminCmd.java b/src/com/wasteofplastic/askyblock/commands/AdminCmd.java index 0ad6ef88f..078717c6d 100644 --- a/src/com/wasteofplastic/askyblock/commands/AdminCmd.java +++ b/src/com/wasteofplastic/askyblock/commands/AdminCmd.java @@ -1390,6 +1390,11 @@ public void run() { if (plugin.getPlayers().inTeam(playerUUID)) { playerUUID = plugin.getPlayers().getTeamLeader(playerUUID); } + Island island = plugin.getGrid().getIsland(playerUUID); + if (island == null) { + sender.sendMessage(ChatColor.RED + plugin.myLocale().errorNoIsland); + return true; + } // Check if biome is valid Biome biome = null; String biomeName = split[2].toUpperCase(); @@ -1421,11 +1426,7 @@ public void run() { } // Okay clear to set biome // Actually set the biome - if (plugin.getPlayers().inTeam(playerUUID) && plugin.getPlayers().getTeamIslandLocation(playerUUID) != null) { - plugin.getBiomes().setIslandBiome(plugin.getPlayers().getTeamIslandLocation(playerUUID), biome); - } else { - plugin.getBiomes().setIslandBiome(plugin.getPlayers().getIslandLocation(playerUUID), biome); - } + plugin.getBiomes().setIslandBiome(island,biome); sender.sendMessage(ChatColor.GREEN + plugin.myLocale().biomeSet.replace("[biome]", biomeName)); Player targetPlayer = plugin.getServer().getPlayer(playerUUID); if (targetPlayer != null) { @@ -1623,7 +1624,7 @@ public void run() { private void deleteIslands(Island island, CommandSender sender) { plugin.getGrid().removePlayersFromIsland(island,null); // Reset the biome - plugin.getBiomes().setIslandBiome(island.getCenter(), Settings.defaultBiome); + plugin.getBiomes().setIslandBiome(island, Settings.defaultBiome); new DeleteIslandChunk(plugin, island); //new DeleteIslandByBlock(plugin, island); plugin.getGrid().saveGrid(); diff --git a/src/com/wasteofplastic/askyblock/panels/BiomesPanel.java b/src/com/wasteofplastic/askyblock/panels/BiomesPanel.java index 44f2560c2..a7e393f24 100644 --- a/src/com/wasteofplastic/askyblock/panels/BiomesPanel.java +++ b/src/com/wasteofplastic/askyblock/panels/BiomesPanel.java @@ -39,6 +39,7 @@ import org.bukkit.event.inventory.InventoryClickEvent; import org.bukkit.event.world.ChunkLoadEvent; import org.bukkit.inventory.Inventory; +import org.bukkit.scheduler.BukkitRunnable; import org.bukkit.util.Vector; import com.wasteofplastic.askyblock.ASkyBlock; @@ -159,6 +160,21 @@ public void onInventoryClick(InventoryClickEvent event) { event.setCancelled(true); // plugin.getLogger().info("DEBUG: slot is " + slot); // Do something + // Check this player has an island + Island island = plugin.getGrid().getIsland(playerUUID); + if (island == null) { + player.sendMessage(ChatColor.RED + plugin.myLocale().errorNoIsland); + return; + } + // Check ownership + if (!island.getOwner().equals(playerUUID)) { + player.sendMessage(ChatColor.RED + plugin.myLocale(player.getUniqueId()).levelerrornotYourIsland); + return; + } + if (!plugin.getGrid().playerIsOnIsland(player)) { + player.sendMessage(ChatColor.RED + plugin.myLocale(player.getUniqueId()).challengeserrorNotOnIsland); + return; + } Biome biome = thisPanel.get(slot).getBiome(); if (biome != null) { event.setCancelled(true); @@ -178,11 +194,7 @@ public void onInventoryClick(InventoryClickEvent event) { } player.closeInventory(); // Closes the inventory // Actually set the biome - if (plugin.getPlayers().inTeam(playerUUID) && plugin.getPlayers().getTeamIslandLocation(playerUUID) != null) { - setIslandBiome(plugin.getPlayers().getTeamIslandLocation(playerUUID), biome); - } else { - setIslandBiome(plugin.getPlayers().getIslandLocation(player.getUniqueId()), biome); - } + setIslandBiome(island, biome); player.sendMessage(ChatColor.GREEN + plugin.myLocale().biomeSet.replace("[biome]", thisPanel.get(slot).getName())); } return; @@ -192,87 +204,13 @@ public void onInventoryClick(InventoryClickEvent event) { /** * Sets all blocks in an island to a specified biome type * - * @param islandLoc + * @param island * @param biomeType */ - public boolean setIslandBiome(final Location islandLoc, final Biome biomeType) { + public boolean setIslandBiome(final Island island, final Biome biomeType) { //plugin.getLogger().info("DEBUG: Biome is " + biomeType); - final Island island = plugin.getGrid().getIslandAt(islandLoc); if (island != null) { - // Update the settings so they can be checked later - island.setBiome(biomeType); - //island.getCenter().getBlock().setBiome(biomeType); - // Get a snapshot of the island - final World world = island.getCenter().getWorld(); - // If the biome is dry, then we need to remove the water, ice, snow, etc. - switch (biomeType) { - case MESA: - case DESERT: - case JUNGLE: - case SAVANNA: - case SWAMPLAND: - case HELL: - // Get the chunks - //plugin.getLogger().info("DEBUG: get the chunks"); - List chunkSnapshot = new ArrayList(); - for (int x = island.getMinProtectedX() /16; x <= (island.getMinProtectedX() + island.getProtectionSize() - 1)/16; x++) { - for (int z = island.getMinProtectedZ() /16; z <= (island.getMinProtectedZ() + island.getProtectionSize() - 1)/16; z++) { - chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot()); - } - } - //plugin.getLogger().info("DEBUG: size of chunk ss = " + chunkSnapshot.size()); - final List finalChunk = chunkSnapshot; - plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { - - @SuppressWarnings("deprecation") - @Override - public void run() { - //System.out.println("DEBUG: running async task"); - HashMap blocksToRemove = new HashMap(); - // Go through island space and find the offending columns - for (ChunkSnapshot chunk: finalChunk) { - for (int x = 0; x< 16; x++) { - for (int z = 0; z < 16; z++) { - // Check if it is snow, ice or water - for (int yy = world.getMaxHeight()-1; yy >= Settings.sea_level; yy--) { - int type = chunk.getBlockTypeId(x, yy, z); - if (type == Material.ICE.getId() || type == Material.SNOW.getId() || type == Material.SNOW_BLOCK.getId() - || type == Material.WATER.getId() || type == Material.STATIONARY_WATER.getId()) { - //System.out.println("DEBUG: offending block found " + Material.getMaterial(type) + " @ " + (chunk.getX()*16 + x) + " " + yy + " " + (chunk.getZ()*16 + z)); - blocksToRemove.put(new Vector(chunk.getX()*16 + x,yy,chunk.getZ()*16 + z), type); - } else if (type != Material.AIR.getId()){ - // Hit a non-offending block so break and store this column of vectors - break; - } - } - } - } - } - // Now get rid of the blocks - if (!blocksToRemove.isEmpty()) { - //plugin.getLogger().info("DEBUG: There are blocks to remove " + blocksToRemove.size()); - final HashMap blocks = blocksToRemove; - // Kick of a sync task - plugin.getServer().getScheduler().runTask(plugin, new Runnable() { - - @Override - public void run() { - //plugin.getLogger().info("DEBUG: Running sync task"); - for (Entry entry: blocks.entrySet()) { - if (entry.getValue() == Material.WATER.getId() || entry.getValue() == Material.STATIONARY_WATER.getId()) { - if (biomeType.equals(Biome.HELL)) { - // Remove water from Hell - entry.getKey().toLocation(world).getBlock().setType(Material.AIR); - } - } else { - entry.getKey().toLocation(world).getBlock().setType(Material.AIR); - } - } - }}); - } - }}); - default: - } + new SetBiome(plugin, island, biomeType); return true; } else { return false; @@ -284,6 +222,7 @@ public void run() { * if it exists. Does not apply to spawn. * @param e */ + /* @EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = false) public void onChunkLoad(ChunkLoadEvent e) { // Check if the grid is ready. If it is doing an import, it may not be. @@ -358,6 +297,6 @@ public void onChunkLoad(ChunkLoadEvent e) { } } - } + }*/ } \ No newline at end of file diff --git a/src/com/wasteofplastic/askyblock/panels/SetBiome.java b/src/com/wasteofplastic/askyblock/panels/SetBiome.java new file mode 100644 index 000000000..d0fbac396 --- /dev/null +++ b/src/com/wasteofplastic/askyblock/panels/SetBiome.java @@ -0,0 +1,137 @@ +package com.wasteofplastic.askyblock.panels; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map.Entry; + +import org.bukkit.ChunkSnapshot; +import org.bukkit.Material; +import org.bukkit.World; +import org.bukkit.block.Biome; +import org.bukkit.scheduler.BukkitRunnable; +import org.bukkit.util.Vector; + +import com.wasteofplastic.askyblock.ASkyBlock; +import com.wasteofplastic.askyblock.Island; +import com.wasteofplastic.askyblock.Settings; + +public class SetBiome { + private static final int SPEED = 10000; + private int xDone = 0; + private int zDone = 0; + private boolean inProgress = false; + + public SetBiome(final ASkyBlock plugin, final Island island, final Biome biomeType) { + final World world = island.getCenter().getWorld(); + // Update the settings so they can be checked later + island.setBiome(biomeType); + xDone = island.getMinX(); + zDone = island.getMinZ(); + new BukkitRunnable() { + @Override + public void run() { + if (inProgress) { + return; + } + inProgress = true; + int count = 0; + //plugin.getLogger().info("DEBUG: Restart xDone = " + xDone + " zDone = " + zDone); + //plugin.getLogger().info("DEBUG: max x = " + (island.getMinX() + island.getIslandDistance())); + while (xDone < (island.getMinX() + island.getIslandDistance())) { + while(zDone < (island.getMinZ() + island.getIslandDistance())) { + world.setBiome(xDone, zDone, biomeType); + //plugin.getLogger().info("DEBUG: xDone = " + xDone + " zDone = " + zDone); + if (count++ > SPEED) { + //plugin.getLogger().info("DEBUG: set " + SPEED + " blocks"); + inProgress = false; + return; + } + zDone++; + } + zDone = island.getMinZ(); + xDone++; + } + //plugin.getLogger().info("DEBUG: END xDone = " + xDone + " zDone = " + zDone); + this.cancel(); + } + }.runTaskTimer(plugin, 0L, 20L); // Work every second + + // Get a snapshot of the island + + // If the biome is dry, then we need to remove the water, ice, snow, etc. + switch (biomeType) { + case MESA: + case DESERT: + case JUNGLE: + case SAVANNA: + case SWAMPLAND: + case HELL: + // Get the chunks + //plugin.getLogger().info("DEBUG: get the chunks"); + List chunkSnapshot = new ArrayList(); + for (int x = island.getMinProtectedX() /16; x <= (island.getMinProtectedX() + island.getProtectionSize() - 1)/16; x++) { + for (int z = island.getMinProtectedZ() /16; z <= (island.getMinProtectedZ() + island.getProtectionSize() - 1)/16; z++) { + boolean loaded = world.getChunkAt(x, z).isLoaded(); + chunkSnapshot.add(world.getChunkAt(x, z).getChunkSnapshot()); + if (!loaded) { + world.getChunkAt(x, z).unload(); + } + } + } + //plugin.getLogger().info("DEBUG: size of chunk ss = " + chunkSnapshot.size()); + final List finalChunk = chunkSnapshot; + plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() { + + @SuppressWarnings("deprecation") + @Override + public void run() { + //System.out.println("DEBUG: running async task"); + HashMap blocksToRemove = new HashMap(); + // Go through island space and find the offending columns + for (ChunkSnapshot chunk: finalChunk) { + for (int x = 0; x< 16; x++) { + for (int z = 0; z < 16; z++) { + // Check if it is snow, ice or water + for (int yy = world.getMaxHeight()-1; yy >= Settings.sea_level; yy--) { + int type = chunk.getBlockTypeId(x, yy, z); + if (type == Material.ICE.getId() || type == Material.SNOW.getId() || type == Material.SNOW_BLOCK.getId() + || type == Material.WATER.getId() || type == Material.STATIONARY_WATER.getId()) { + //System.out.println("DEBUG: offending block found " + Material.getMaterial(type) + " @ " + (chunk.getX()*16 + x) + " " + yy + " " + (chunk.getZ()*16 + z)); + blocksToRemove.put(new Vector(chunk.getX()*16 + x,yy,chunk.getZ()*16 + z), type); + } else if (type != Material.AIR.getId()){ + // Hit a non-offending block so break and store this column of vectors + break; + } + } + } + } + } + // Now get rid of the blocks + if (!blocksToRemove.isEmpty()) { + //plugin.getLogger().info("DEBUG: There are blocks to remove " + blocksToRemove.size()); + final HashMap blocks = blocksToRemove; + // Kick of a sync task + plugin.getServer().getScheduler().runTask(plugin, new Runnable() { + + @Override + public void run() { + //plugin.getLogger().info("DEBUG: Running sync task"); + for (Entry entry: blocks.entrySet()) { + if (entry.getValue() == Material.WATER.getId() || entry.getValue() == Material.STATIONARY_WATER.getId()) { + if (biomeType.equals(Biome.HELL)) { + // Remove water from Hell + entry.getKey().toLocation(world).getBlock().setType(Material.AIR); + } + } else { + entry.getKey().toLocation(world).getBlock().setType(Material.AIR); + } + } + }}); + } + }}); + default: + } + } + +}