package com.sk89q.craftbook.mechanics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.block.Block;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.block.BlockBreakEvent;
import org.bukkit.event.block.BlockFromToEvent;
import org.bukkit.event.block.BlockPlaceEvent;
import com.sk89q.craftbook.AbstractCraftBookMechanic;
import com.sk89q.craftbook.util.BlockUtil;
import com.sk89q.craftbook.util.EventUtil;
import com.sk89q.craftbook.util.LocationUtil;
import com.sk89q.craftbook.util.events.SourcedBlockRedstoneEvent;
import com.sk89q.util.yaml.YAMLProcessor;
public class Sponge extends AbstractCraftBookMechanic {
@EventHandler(priority = EventPriority.HIGH)
public void onBlockFromTo(BlockFromToEvent event) {
if(event.getBlock().getType() != Material.WATER && event.getBlock().getType() != Material.STATIONARY_WATER) return;
if(!BlockUtil.isBlockReplacable(event.getToBlock().getType())) return;
if(!EventUtil.passesFilter(event)) return;
for (int cx = -radius; cx <= radius; cx++) {
for (int cy = -radius; cy <= radius; cy++) {
for (int cz = -radius; cz <= radius; cz++) {
Block sponge = event.getToBlock().getRelative(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(sponge.getLocation(), event.getToBlock().getLocation(), radius)) continue;
if(redstone && !sponge.isBlockIndirectlyPowered()) continue;
if(sponge.getType() == Material.SPONGE) {
event.setCancelled(true);
return;
}
}
}
}
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockPlace(BlockPlaceEvent event) {
if(event.getBlock().getType() != Material.SPONGE) return;
if(redstone && !event.getBlock().isBlockIndirectlyPowered()) return;
if(!EventUtil.passesFilter(event)) return;
removeWater(event.getBlock());
}
@EventHandler(priority = EventPriority.HIGH)
public void onBlockBreak(BlockBreakEvent event) {
if(event.getBlock().getType() != Material.SPONGE) return;
if(redstone && !event.getBlock().isBlockIndirectlyPowered()) return;
if(!EventUtil.passesFilter(event)) return;
addWater(event.getBlock());
}
@EventHandler(priority = EventPriority.HIGH)
public void onRedstoneChange(SourcedBlockRedstoneEvent event) {
if(!redstone) return;
if(event.getBlock().getType() != Material.SPONGE) return;
if(event.isMinor()) return;
if(!EventUtil.passesFilter(event)) return;
if(!event.isOn())
addWater(event.getBlock());
else
removeWater(event.getBlock());
}
public void removeWater(Block block) {
for (int cx = -radius; cx <= radius; cx++) {
for (int cy = -radius; cy <= radius; cy++) {
for (int cz = -radius; cz <= radius; cz++) {
Block water = block.getRelative(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius)) continue;
if(water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
water.setType(Material.AIR);
}
}
}
}
}
public void addWater(Block block) {
int cx,cy,cz;
// The negative x edge
cx = block.getX() - radius - 1;
for (cy = block.getY() - radius - 1; cy <= block.getY() + radius + 1; cy++) {
for (cz = block.getZ() - radius - 1; cz <= block.getZ() + radius + 1; cz++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(1, 0, 0).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(1, 0, 0));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(1, 0, 0).setType(Material.WATER);
}
}
}
}
// The positive x edge
cx = block.getX() + radius + 1;
for (cy = block.getY() - radius - 1; cy <= block.getY() + radius + 1; cy++) {
for (cz = block.getZ() - radius - 1; cz <= block.getZ() + radius + 1; cz++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(-1, 0, 0).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(-1, 0, 0));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(-1, 0, 0).setType(Material.WATER);
}
}
}
}
// The negative y edge
/*cy = block.getY() - radius - 1;
for (cx = block.getX() - radius - 1; cx <= block.getX() + radius + 1; cx++) {
for (int cz = block.getZ() - radius - 1; cz <= block.getZ() + radius + 1; cz++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(CraftBookPlugin.inst().getConfiguration().spongeCircleRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(0, 1, 0).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(0, 1, 0));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(0, 1, 0).setType(Material.WATER);
}
}
}
}*/
// The positive y edge
cy = block.getY() + radius + 1;
for (cx = block.getX() - radius - 1; cx <= block.getX() + radius + 1; cx++) {
for (cz = block.getZ() - radius - 1; cz <= block.getZ() + radius + 1; cz++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(0, -1, 0).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(0, -1, 0));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(0, -1, 0).setType(Material.WATER);
}
}
}
}
// The negative z edge
cz = block.getZ() - radius - 1;
for (cx = block.getX() - radius - 1; cx <= block.getX() + radius + 1; cx++) {
for (cy = block.getY() - radius - 1; cy <= block.getY() + radius + 1; cy++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(0, 0, 1).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(0, 0, 1));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(0, 0, 1).setType(Material.WATER);
}
}
}
}
// The positive z edge
cz = block.getZ() + radius + 1;
for (cx = block.getX() - radius - 1; cx <= block.getX() + radius + 1; cx++) {
for (cy = block.getY() - radius - 1; cy <= block.getY() + radius + 1; cy++) {
Block water = block.getWorld().getBlockAt(cx, cy, cz);
if(circularRadius && !LocationUtil.isWithinSphericalRadius(water.getLocation(), block.getLocation(), radius+1.5)) continue;
if (water.getType() == Material.WATER || water.getType() == Material.STATIONARY_WATER) {
if(BlockUtil.isBlockReplacable(water.getRelative(0, 0, -1).getType())) {
BlockFromToEvent event = new BlockFromToEvent(water, water.getRelative(0, 0, -1));
Bukkit.getPluginManager().callEvent(event);
if(!event.isCancelled())
water.getRelative(0, 0, -1).setType(Material.WATER);
}
}
}
}
}
int radius;
boolean circularRadius;
boolean redstone;
@Override
public void loadConfiguration (YAMLProcessor config, String path) {
config.setComment(path + "radius", "The maximum radius of the sponge.");
radius = config.getInt(path + "radius", 5);
config.setComment(path + "circular-radius", "Whether the radius should be circular or square.");
circularRadius = config.getBoolean(path + "circular-radius", true);
config.setComment(path + "require-redstone", "Whether to require redstone to suck up water or not.");
redstone = config.getBoolean(path + "require-redstone", false);
}
}