package com.github.jamesnorris.ablockalypse.aspect; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import org.bukkit.ChatColor; import org.bukkit.Location; import com.github.jamesnorris.ablockalypse.Ablockalypse; import com.github.jamesnorris.ablockalypse.DataContainer; import com.github.jamesnorris.ablockalypse.behavior.MapDatable; import com.github.jamesnorris.ablockalypse.enumerated.Setting; import com.github.jamesnorris.ablockalypse.enumerated.ZAEffect; import com.github.jamesnorris.ablockalypse.threading.Task; import com.github.jamesnorris.ablockalypse.utility.AblockalypseUtility; import com.github.jamesnorris.ablockalypse.utility.SerialLocation; import com.github.jamesnorris.mcpath.PathNode; import com.github.jamesnorris.mcpath.Pathfinder; public class Teleporter extends SpecificGameAspect implements MapDatable { public static final ZAEffect[] LINKED_EFFECTS = new ZAEffect[] {ZAEffect.TELEPORTATION, ZAEffect.FLAMES}; public static final ZAEffect[] TELEPORT_EFFECTS = new ZAEffect[] {ZAEffect.POTION_BREAK, ZAEffect.TELEPORTATION, ZAEffect.SMOKE}; private Game game; private Location location; private double linkTime = Double.MAX_VALUE; private boolean linked = false; private DataContainer data = Ablockalypse.getData(); private UUID uuid = UUID.randomUUID(); private Task warning; public Teleporter(Game game, Location location) { this(game, location, false); } public Teleporter(Game game, Location location, boolean linked) { super(game, location, !game.hasStarted()); this.game = game; this.location = location; setLinked(linked);// so the warning can be instantiated load(); } public Teleporter(Map<String, Object> savings) { this(Ablockalypse.getData().getGame((String) savings.get("game_name"), true), SerialLocation.returnLocation((SerialLocation) savings.get("location")), (Boolean) savings.get("is_linked")); linkTime = (Double) savings.get("link_time"); uuid = savings.get("uuid") == null ? uuid : (UUID) savings.get("uuid"); } public double getExactLinkTime() { calculateApproximateRequiredLinkTime(); return linkTime; } public int getLinkTime() { return (int) Math.round(getExactLinkTime()); } @Override public int getLoadPriority() { return 2; } @Override public Location getLocation() { return location; } @Override public Location getPointClosestToOrigin() { return location; } @Override public Map<String, Object> getSave() { Map<String, Object> savings = new HashMap<String, Object>(); savings.put("uuid", getUUID()); savings.put("game_name", game.getName()); savings.put("is_linked", linked); savings.put("link_time", linkTime); savings.put("location", location == null ? null : new SerialLocation(location)); return savings; } @Override public UUID getUUID() { return uuid; } public boolean isLinked() { return linked; } @Override public boolean isPowered() { return super.isPowered() || !((Boolean) Setting.TELEPORTERS_REQUIRE_POWER.getSetting()); } @Override public void onGameEnd() { setLinked(false); setBlinking(true); } @Override public void onGameStart() { setBlinking(false); } @Override public void paste(Location pointClosestToOrigin) { location = pointClosestToOrigin; refreshBlinker(); } public void playEffects(ZAEffect[] effects) { for (ZAEffect effect : effects) { effect.play(location.clone().add(0, 1.5, 0)); } } public void refresh() { if (warning != null) { data.objects.remove(warning); } Teleporter mainframe = game.getMainframe(); if (mainframe == null || !mainframe.equals(this)) { if (!isPowered()) { warning = AblockalypseUtility.scheduleNearbyWarning(location, ChatColor.GRAY + "The teleporter is not powered.", 1, 2.5, 1, 10000); return; } if (linked) { warning = AblockalypseUtility.scheduleNearbyWarning(location, ChatColor.GRAY + "Press " + ChatColor.AQUA + "SHIFT" + ChatColor.GRAY + " to teleport.", 1, 2.5, 1, 10000); } else { warning = AblockalypseUtility.scheduleNearbyWarning(location, ChatColor.GRAY + "Click on the teleporter to link it to the mainframe.", 2, 3.5, 2, 10000); } } } @Override public void remove() { if (warning != null) { data.objects.remove(warning); } super.remove(); } public void setLinked(boolean linked) { this.linked = linked; refresh(); } public void setLinkTime(double linkTime) { this.linkTime = linkTime; } protected void calculateApproximateRequiredLinkTime() { if (game.getMainframe().getLocation().getWorld().equals(location.getWorld())) { List<PathNode> nodes = new Pathfinder(location, game.getMainframe().getLocation(), AblockalypseUtility.getGoals(location.getWorld(), .891D, 1.031D, 2D, 0)).calculate((Integer) Setting.MAX_PATHFINDER_NODES.getSetting()).getNodes(); linkTime = Math.sqrt(nodes.get(nodes.size()).G) / 4;// 1/4 second per block } else { linkTime = -1; } } }