/* * Copyright (C) 2014 eccentric_nz * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If ChatColor.RESET, see <http://www.gnu.org/licenses/>. */ package me.eccentric_nz.TARDIS.hads; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.UUID; import me.eccentric_nz.TARDIS.TARDIS; import me.eccentric_nz.TARDIS.database.ResultSetCurrentLocation; import me.eccentric_nz.TARDIS.enumeration.COMPASS; import me.eccentric_nz.TARDIS.enumeration.PRESET; import me.eccentric_nz.TARDIS.move.TARDISDoorCloser; import me.eccentric_nz.TARDIS.utility.TARDISBlockSetters; import org.bukkit.Chunk; import org.bukkit.Location; import org.bukkit.Material; import org.bukkit.World; import org.bukkit.block.Biome; import org.bukkit.block.Block; import org.bukkit.block.BlockFace; import org.bukkit.entity.FallingBlock; import org.bukkit.entity.Player; import org.bukkit.util.Vector; /** * The Hostile Action Displacement System, or HADS, was one of the defence * mechanisms of the Doctor's TARDIS. When the outer shell of the vessel came * under attack, the unit dematerialised the TARDIS and re-materialised it a * short distance away after the attacker had gone, in a safer locale. The HADS * had to be manually set, and the Doctor often forgot to do so. * * @author eccentric_nz */ public class TARDISHostileDispersal { private final TARDIS plugin; private final List<Material> has_colour; private final List<Material> replace_with_barrier; public TARDISHostileDispersal(TARDIS plugin) { this.plugin = plugin; this.has_colour = Arrays.asList(Material.WOOL, Material.STAINED_GLASS, Material.STAINED_GLASS_PANE, Material.STAINED_CLAY); this.replace_with_barrier = buildList(); } @SuppressWarnings("deprecation") public void disperseTARDIS(final int id, boolean cham, UUID uuid, Player hostile, PRESET preset) { HashMap<String, Object> wherecl = new HashMap<String, Object>(); wherecl.put("tardis_id", id); ResultSetCurrentLocation rsc = new ResultSetCurrentLocation(plugin, wherecl); if (!rsc.resultSet()) { plugin.debug("Could not get current TARDIS location for HADS!"); } if (rsc.isSubmarine()) { // underwater use displacement new TARDISHostileDisplacement(plugin).moveTARDIS(id, cham, uuid, hostile, preset); return; } Location l = new Location(rsc.getWorld(), rsc.getX(), rsc.getY(), rsc.getZ()); COMPASS d = rsc.getDirection(); Biome biome = rsc.getBiome(); if (plugin.getConfig().getBoolean("preferences.walk_in_tardis")) { // always remove the portal if (plugin.getTrackerKeeper().getPortals().containsKey(l)) { plugin.getTrackerKeeper().getPortals().remove(l); } // toggle the doors if neccessary new TARDISDoorCloser(plugin, uuid, id).closeDoors(); } final World w = l.getWorld(); // make sure chunk is loaded Chunk chunk = w.getChunkAt(l); while (!chunk.isLoaded()) { chunk.load(); } final int sbx = l.getBlockX() - 1; final int sby; if (preset.equals(PRESET.SUBMERGED)) { sby = l.getBlockY() - 1; } else { sby = l.getBlockY(); } final int sbz = l.getBlockZ() - 1; // reset biome and it's not The End if (!plugin.getUtils().restoreBiome(l, biome)) { // remove TARDIS from tracker plugin.getTrackerKeeper().getDematerialising().remove(Integer.valueOf(id)); } // remove problem blocks first switch (preset) { case GRAVESTONE: // remove flower int flowerx; int flowery = (l.getBlockY() + 1); int flowerz; switch (d) { case NORTH: flowerx = l.getBlockX(); flowerz = l.getBlockZ() + 1; break; case WEST: flowerx = l.getBlockX() + 1; flowerz = l.getBlockZ(); break; case SOUTH: flowerx = l.getBlockX(); flowerz = l.getBlockZ() - 1; break; default: flowerx = l.getBlockX() - 1; flowerz = l.getBlockZ(); break; } TARDISBlockSetters.setBlock(w, flowerx, flowery, flowerz, 0, (byte) 0); break; case DUCK: plugin.getPresetDestroyer().destroyDuckEyes(l, d); break; case MINESHAFT: plugin.getPresetDestroyer().destroyMineshaftTorches(l, d); break; case LAMP: plugin.getPresetDestroyer().destroyLampTrapdoors(l, d); break; default: break; } plugin.getTrackerKeeper().getDematerialising().remove(Integer.valueOf(id)); plugin.getGeneralKeeper().getTardisChunkList().remove(l.getChunk()); // remove door plugin.getPresetDestroyer().destroyDoor(id); // remove torch plugin.getPresetDestroyer().destroyLamp(l, preset); // remove sign plugin.getPresetDestroyer().destroySign(l, d, preset); if (preset.equals(PRESET.JUNK_MODE)) { plugin.getPresetDestroyer().destroyHandbrake(l, d); } // remove blue wool final List<FallingBlock> falls = new ArrayList<FallingBlock>(); byte tmp = 0; for (int yy = 0; yy < 4; yy++) { for (int xx = 0; xx < 3; xx++) { for (int zz = 0; zz < 3; zz++) { Block b = w.getBlockAt((sbx + xx), (sby + yy), (sbz + zz)); if (yy == 0) { Block under = b.getRelative(BlockFace.DOWN); if (replace_with_barrier.contains(under.getType())) { plugin.getBlockUtils().setUnderDoorBlock(w, (sbx + xx), (sby + yy) - 1, (sbz + zz), id, false); } } if (!b.getType().equals(Material.AIR)) { float v = (float) -0.5 + (float) (Math.random() * ((0.5 - -0.5) + 1)); byte colour = (has_colour.contains(b.getType())) ? b.getData() : plugin.getBuildKeeper().getStainedGlassLookup().getStain().get(b.getTypeId()); if (yy == 1 && xx == 0 && zz == 0) { tmp = colour; } FallingBlock fb = w.spawnFallingBlock(b.getLocation(), Material.CARPET, colour); falls.add(fb); fb.setDropItem(false); fb.setVelocity(new Vector(v, v, v)); b.setType(Material.AIR); } } } } final byte data = tmp; // schedule task to remove fallen blocks plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { @Override public void run() { for (FallingBlock f : falls) { f.getLocation().getBlock().setType(Material.AIR); f.remove(); } } }, 10L); plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() { @Override public void run() { // set carpet base at location for (int xx = 0; xx < 3; xx++) { for (int zz = 0; zz < 3; zz++) { Block block = w.getBlockAt((sbx + xx), (sby), (sbz + zz)); block.setType(Material.CARPET); block.setData(data); } } } }, 15L); plugin.getTrackerKeeper().getDispersed().put(uuid, l); plugin.getTrackerKeeper().getDispersedTARDII().add(id); } private List<Material> buildList() { List<Material> list = new ArrayList<Material>(); for (Integer i : plugin.getBlocksConfig().getIntegerList("under_door_blocks")) { list.add(Material.getMaterial(i)); } return list; } }