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> chunkSnapshot = new ArrayList<ChunkSnapshot>();
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<ChunkSnapshot> finalChunk = chunkSnapshot;
plugin.getServer().getScheduler().runTaskAsynchronously(plugin, new Runnable() {
@SuppressWarnings("deprecation")
@Override
public void run() {
//System.out.println("DEBUG: running async task");
HashMap<Vector,Integer> blocksToRemove = new HashMap<Vector, Integer>();
// 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.seaHeight; 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<Vector, Integer> 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<Vector, Integer> 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:
}
}
}