/*
* 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.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.UUID;
import me.eccentric_nz.TARDIS.TARDIS;
import me.eccentric_nz.TARDIS.api.Parameters;
import me.eccentric_nz.TARDIS.builders.BuildData;
import me.eccentric_nz.TARDIS.database.QueryFactory;
import me.eccentric_nz.TARDIS.database.ResultSetCurrentLocation;
import me.eccentric_nz.TARDIS.destroyers.DestroyData;
import me.eccentric_nz.TARDIS.enumeration.COMPASS;
import me.eccentric_nz.TARDIS.enumeration.FLAG;
import me.eccentric_nz.TARDIS.enumeration.PRESET;
import me.eccentric_nz.TARDIS.travel.TARDISTimeTravel;
import me.eccentric_nz.TARDIS.utility.TARDISMessage;
import org.bukkit.ChatColor;
import org.bukkit.Location;
import org.bukkit.World.Environment;
import org.bukkit.block.BlockFace;
import org.bukkit.entity.Player;
/**
* 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 TARDISHostileDisplacement {
private final TARDIS plugin;
private final List<Integer> angles;
private int count = 0;
public TARDISHostileDisplacement(TARDIS plugin) {
this.angles = Arrays.asList(0, 45, 90, 135, 180, 225, 270, 315);
this.plugin = plugin;
}
public void moveTARDIS(final int id, boolean cham, UUID uuid, Player hostile, PRESET preset) {
TARDISTimeTravel tt = new TARDISTimeTravel(plugin);
int r = plugin.getConfig().getInt("preferences.hads_distance");
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!");
}
boolean underwater = rsc.isSubmarine();
Location loc = new Location(rsc.getWorld(), rsc.getX(), rsc.getY(), rsc.getZ());
COMPASS d = rsc.getDirection();
Location l = loc.clone();
// randomise the direction
Collections.shuffle(angles);
for (Integer a : angles) {
count++;
int wx = (int) (l.getX() + r * Math.cos(a)); // x = cx + r * cos(a)
int wz = (int) (l.getZ() + r * Math.sin(a)); // z = cz + r * sin(a)
l.setX(wx);
l.setZ(wz);
boolean bool = true;
int y;
if (l.getWorld().getEnvironment().equals(Environment.NETHER)) {
y = plugin.getUtils().getHighestNetherBlock(l.getWorld(), wx, wz);
} else {
y = l.getWorld().getHighestBlockAt(l).getY();
}
l.setY(y);
if (l.getBlock().getRelative(BlockFace.DOWN).isLiquid() && !plugin.getConfig().getBoolean("travel.land_on_water") && !rsc.isSubmarine()) {
bool = false;
}
Player player = plugin.getServer().getPlayer(uuid);
if (bool) {
Location sub = null;
boolean safe;
if (rsc.isSubmarine()) {
sub = tt.submarine(l.getBlock(), d);
safe = (sub != null);
} else {
int[] start = tt.getStartLocation(l, d);
safe = (tt.safeLocation(start[0], y, start[2], start[1], start[3], l.getWorld(), d) < 1);
}
if (safe) {
Location fl = (rsc.isSubmarine()) ? sub : l;
if (plugin.getPluginRespect().getRespect(fl, new Parameters(player, FLAG.getNoMessageFlags()))) {
// set current
QueryFactory qf = new QueryFactory(plugin);
HashMap<String, Object> tid = new HashMap<String, Object>();
tid.put("tardis_id", id);
HashMap<String, Object> set = new HashMap<String, Object>();
set.put("world", fl.getWorld().getName());
set.put("x", fl.getBlockX());
set.put("y", fl.getBlockY());
set.put("z", fl.getBlockZ());
set.put("submarine", (rsc.isSubmarine()) ? 1 : 0);
qf.doUpdate("current", set, tid);
plugin.getTrackerKeeper().getDamage().remove(id);
// boolean mat = plugin.getConfig().getBoolean("police_box.materialise");
// long delay = (mat) ? 1L : 180L;
long delay = 1L;
// move TARDIS
plugin.getTrackerKeeper().getInVortex().add(id);
final DestroyData dd = new DestroyData(plugin, uuid.toString());
dd.setChameleon(cham);
dd.setDirection(d);
dd.setLocation(loc);
dd.setPlayer(player);
dd.setHide(false);
dd.setOutside(true);
dd.setSubmarine(rsc.isSubmarine());
dd.setTardisID(id);
dd.setBiome(rsc.getBiome());
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
plugin.getTrackerKeeper().getDematerialising().add(id);
plugin.getPresetDestroyer().destroyPreset(dd);
}
}, delay);
final BuildData bd = new BuildData(plugin, uuid.toString());
bd.setChameleon(cham);
bd.setDirection(d);
bd.setLocation(fl);
bd.setMalfunction(false);
bd.setOutside(true);
bd.setPlayer(player);
bd.setRebuild(false);
bd.setSubmarine(rsc.isSubmarine());
bd.setTardisID(id);
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable() {
@Override
public void run() {
plugin.getPresetBuilder().buildPreset(bd);
}
}, delay * 2);
// message time lord
String message = plugin.getPluginName() + ChatColor.RED + "H" + ChatColor.RESET + "ostile " + ChatColor.RED + "A" + ChatColor.RESET + "ction " + ChatColor.RED + "D" + ChatColor.RESET + "isplacement " + ChatColor.RED + "S" + ChatColor.RESET + "ystem " + plugin.getLanguage().getString("HADS_ENGAGED");
player.sendMessage(message);
String hads = fl.getWorld().getName() + ":" + fl.getBlockX() + ":" + fl.getBlockY() + ":" + fl.getBlockZ();
TARDISMessage.send(player, "HADS_LOC", hads);
if (player != hostile) {
hostile.sendMessage(message);
}
return;
} else {
TARDISMessage.send(player, "HADS_PROTECTED");
if (player != hostile) {
TARDISMessage.send(hostile, "HADS_PROTECTED");
}
return;
}
} else if (underwater) {
TARDISMessage.send(player, "HADS_NOT_SAFE");
} else if (count > 7) {
// only if count is 8 or more
// use dispersal instead...
new TARDISHostileDispersal(plugin).disperseTARDIS(id, cham, uuid, hostile, preset);
}
} else {
plugin.getTrackerKeeper().getDamage().remove(id);
TARDISMessage.send(player, "HADS_NO_WATER");
}
}
}
}