/Essentials/src/com/earth2me/essentials/Teleport.java
https://github.com/KoolSource/Essentials · Java · 271 lines · 234 code · 33 blank · 4 comment · 33 complexity · 6963f536158b194d0d921671dd74fe2f MD5 · raw file
- package com.earth2me.essentials;
- import com.earth2me.essentials.commands.NotEnoughArgumentsException;
- import java.util.Calendar;
- import java.util.GregorianCalendar;
- import java.util.logging.Logger;
- import org.bukkit.Location;
- import org.bukkit.entity.Entity;
- public class Teleport implements Runnable
- {
- private static final double MOVE_CONSTANT = 0.3;
- private static class Target
- {
- private final Location location;
- private final Entity entity;
- public Target(Location location)
- {
- this.location = location;
- this.entity = null;
- }
- public Target(Entity entity)
- {
- this.entity = entity;
- this.location = null;
- }
- public Location getLocation()
- {
- if (this.entity != null)
- {
- return this.entity.getLocation();
- }
- return location;
- }
- }
- private IUser user;
- private int teleTimer = -1;
- private long started; // time this task was initiated
- private long delay; // how long to delay the teleport
- private int health;
- // note that I initially stored a clone of the location for reference, but...
- // when comparing locations, I got incorrect mismatches (rounding errors, looked like)
- // so, the X/Y/Z values are stored instead and rounded off
- private long initX;
- private long initY;
- private long initZ;
- private Target teleportTarget;
- private Trade chargeFor;
- private final IEssentials ess;
- private static final Logger logger = Logger.getLogger("Minecraft");
- private void initTimer(long delay, Target target, Trade chargeFor)
- {
- this.started = System.currentTimeMillis();
- this.delay = delay;
- this.health = user.getHealth();
- this.initX = Math.round(user.getLocation().getX() * MOVE_CONSTANT);
- this.initY = Math.round(user.getLocation().getY() * MOVE_CONSTANT);
- this.initZ = Math.round(user.getLocation().getZ() * MOVE_CONSTANT);
- this.teleportTarget = target;
- this.chargeFor = chargeFor;
- }
- public void run()
- {
- if (user == null || !user.isOnline() || user.getLocation() == null)
- {
- cancel();
- return;
- }
- if (Math.round(user.getLocation().getX() * MOVE_CONSTANT) != initX
- || Math.round(user.getLocation().getY() * MOVE_CONSTANT) != initY
- || Math.round(user.getLocation().getZ() * MOVE_CONSTANT) != initZ
- || user.getHealth() < health)
- { // user moved, cancel teleport
- cancel(true);
- return;
- }
- health = user.getHealth(); // in case user healed, then later gets injured
- long now = System.currentTimeMillis();
- if (now > started + delay)
- {
- try
- {
- cooldown(false);
- user.sendMessage(Util.i18n("teleportationCommencing"));
- try
- {
- now(teleportTarget);
- if (chargeFor != null)
- {
- chargeFor.charge(user);
- }
- }
- catch (Throwable ex)
- {
- ess.showError(user.getBase(), ex, "teleport");
- }
- return;
- }
- catch (Exception ex)
- {
- user.sendMessage(Util.format("cooldownWithMessage", ex.getMessage()));
- }
- }
- }
- public Teleport(IUser user, IEssentials ess)
- {
- this.user = user;
- this.ess = ess;
- }
- public void respawn(Spawn spawn, Trade chargeFor) throws Exception
- {
- teleport(new Target(spawn.getSpawn(user.getGroup())), chargeFor);
- }
- public void warp(String warp, Trade chargeFor) throws Exception
- {
- Location loc = ess.getWarps().getWarp(warp);
- teleport(new Target(loc), chargeFor);
- user.sendMessage(Util.format("warpingTo", warp));
- }
- public void cooldown(boolean check) throws Exception
- {
- Calendar now = new GregorianCalendar();
- if (user.getLastTeleportTimestamp() > 0)
- {
- double cooldown = ess.getSettings().getTeleportCooldown();
- Calendar cooldownTime = new GregorianCalendar();
- cooldownTime.setTimeInMillis(user.getLastTeleportTimestamp());
- cooldownTime.add(Calendar.SECOND, (int)cooldown);
- cooldownTime.add(Calendar.MILLISECOND, (int)((cooldown * 1000.0) % 1000.0));
- if (cooldownTime.after(now) && !user.isAuthorized("essentials.teleport.cooldown.bypass"))
- {
- throw new Exception(Util.format("timeBeforeTeleport", Util.formatDateDiff(cooldownTime.getTimeInMillis())));
- }
- }
- // if justCheck is set, don't update lastTeleport; we're just checking
- if (!check)
- {
- user.setLastTeleportTimestamp(now.getTimeInMillis());
- }
- }
- public void cancel(boolean notifyUser)
- {
- if (teleTimer == -1)
- {
- return;
- }
- try
- {
- ess.getServer().getScheduler().cancelTask(teleTimer);
- if (notifyUser)
- {
- user.sendMessage(Util.i18n("pendingTeleportCancelled"));
- }
- }
- finally
- {
- teleTimer = -1;
- }
- }
- public void cancel()
- {
- cancel(false);
- }
- public void teleport(Location loc, Trade chargeFor) throws Exception
- {
- teleport(new Target(loc), chargeFor);
- }
- public void teleport(Entity entity, Trade chargeFor) throws Exception
- {
- teleport(new Target(entity), chargeFor);
- }
- private void teleport(Target target, Trade chargeFor) throws Exception
- {
- double delay = ess.getSettings().getTeleportDelay();
- if (chargeFor != null)
- {
- chargeFor.isAffordableFor(user);
- }
- cooldown(true);
- if (delay <= 0 || user.isAuthorized("essentials.teleport.timer.bypass"))
- {
- cooldown(false);
- now(target);
- if (chargeFor != null)
- {
- chargeFor.charge(user);
- }
- return;
- }
- cancel();
- Calendar c = new GregorianCalendar();
- c.add(Calendar.SECOND, (int)delay);
- c.add(Calendar.MILLISECOND, (int)((delay * 1000.0) % 1000.0));
- user.sendMessage(Util.format("dontMoveMessage", Util.formatDateDiff(c.getTimeInMillis())));
- initTimer((long)(delay * 1000.0), target, chargeFor);
- teleTimer = ess.scheduleSyncRepeatingTask(this, 10, 10);
- }
- private void now(Target target) throws Exception
- {
- cancel();
- user.setLastLocation();
- user.getBase().teleport(Util.getSafeDestination(target.getLocation()));
- }
- public void now(Location loc) throws Exception
- {
- cooldown(false);
- now(new Target(loc));
- }
- public void now(Location loc, Trade chargeFor) throws Exception
- {
- cooldown(false);
- chargeFor.charge(user);
- now(new Target(loc));
- }
- public void now(Entity entity, boolean cooldown) throws Exception
- {
- if (cooldown)
- {
- cooldown(false);
- }
- now(new Target(entity));
- }
- public void back(Trade chargeFor) throws Exception
- {
- teleport(new Target(user.getLastLocation()), chargeFor);
- }
- public void back() throws Exception
- {
- now(new Target(user.getLastLocation()));
- }
- public void home(IUser user, String home, Trade chargeFor) throws Exception
- {
- final Location loc = user.getHome(home);
- if (loc == null)
- {
- throw new NotEnoughArgumentsException();
- }
- teleport(new Target(loc), chargeFor);
- }
- }