diff --git a/.idea/workspace.xml b/.idea/workspace.xml
index 9f28f09..f9b53ba 100644
--- a/.idea/workspace.xml
+++ b/.idea/workspace.xml
@@ -1,7 +1,12 @@
-
+
+
+
+
+
+
@@ -17,6 +22,14 @@
+
+
+
+
+
+
+
+
@@ -68,9 +81,11 @@
+
-
+
+
\ No newline at end of file
diff --git a/src/me/Percyqaz/Lodestone/CompassListener.java b/src/me/Percyqaz/Lodestone/CompassListener.java
index aec86d1..ee67939 100644
--- a/src/me/Percyqaz/Lodestone/CompassListener.java
+++ b/src/me/Percyqaz/Lodestone/CompassListener.java
@@ -1,6 +1,7 @@
package me.Percyqaz.Lodestone;
import org.bukkit.*;
+import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
@@ -11,22 +12,125 @@
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.CompassMeta;
-public class CompassListener implements Listener {
+import java.util.HashMap;
+import java.util.Map;
- @EventHandler(priority = EventPriority.LOWEST)
- public void Compass(PlayerInteractEvent e) {
- Player p = e.getPlayer();
- ItemStack item = p.getInventory().getItemInMainHand();
- if (e.getHand() == EquipmentSlot.HAND && item.getType() == Material.COMPASS && e.getAction() == Action.RIGHT_CLICK_AIR) {
- CompassMeta itemMeta = (CompassMeta)item.getItemMeta();
+public class CompassListener implements Listener
+{
+ Lodestone plugin;
+ FileConfiguration config;
+ long cooldownTimeMillis;
+ long warmupTimeTicks;
+ Map cooldowns = new HashMap<>();
+
+ public CompassListener(Lodestone plugin, FileConfiguration config)
+ {
+ this.config = config;
+ this.plugin = plugin;
+
+ cooldownTimeMillis = (long)(config.getInt("cooldownSeconds")) * 1000L;
+ warmupTimeTicks = (long)(config.getInt("warmupSeconds")) * 20L;
+
+ // Cooldown must always be at least as long as warmup
+ cooldownTimeMillis = Math.max(cooldownTimeMillis, warmupTimeTicks * 50L);
+ }
+
+ void resetPlayerCooldown(String name)
+ {
+ long now = System.currentTimeMillis();
+ cooldowns.put(name, now - cooldownTimeMillis);
+ }
+
+ /// Returns 0 if no cooldown, else a positive number of seconds cooldown
+ int checkPlayerCooldown(String name)
+ {
+ long now = System.currentTimeMillis();
+ if (cooldowns.containsKey(name))
+ {
+ if (cooldowns.get(name) + cooldownTimeMillis < now)
+ {
+ cooldowns.put(name, now);
+ return 0;
+ }
+ return (int)((cooldowns.get(name) + cooldownTimeMillis - now) / 1000L) + 1;
+ }
+ cooldowns.put(name, now);
+ return 0;
+ }
+
+ void PerformTeleport(Player player, Location oldLoc)
+ {
+ // Need to check player hasn't moved, is still holding a teleport compass
+ if (player.getLocation().distanceSquared(oldLoc) > 0 && !player.isDead())
+ {
+ player.sendMessage(config.getString("teleportFailedMovedBeforeTeleport"));
+ resetPlayerCooldown(player.getName());
+ return;
+ }
+
+ ItemStack item = player.getInventory().getItemInMainHand();
+
+ if (item.getType() == Material.COMPASS) {
+ CompassMeta itemMeta = (CompassMeta) item.getItemMeta();
if (itemMeta.hasLodestone() && itemMeta.isLodestoneTracked()) {
- String teleportMessage = itemMeta.hasDisplayName() ? " Teleported to " + ChatColor.GREEN + itemMeta.getDisplayName() : "";
- p.sendMessage(ChatColor.BLUE + "Whoosh!" + teleportMessage);
+
+ String teleportMessage =
+ itemMeta.hasDisplayName()
+ ? config.getString("teleportSucceededNamedLocation").replace("%location%", itemMeta.getDisplayName())
+ : config.getString("teleportSucceeded");
+ player.sendMessage(teleportMessage);
+ player.spawnParticle(Particle.CLOUD, oldLoc.add(0.0f, 1.0f, 0.0f), 50);
+
Location pos = itemMeta.getLodestone();
- p.teleport(pos.add(0.5, 1.5, 0.5));
+ player.teleport(pos.add(0.5, 1.5, 0.5));
item.setAmount(item.getAmount() - 1);
- e.setCancelled(true);
+
+ player.spawnParticle(Particle.CLOUD, player.getLocation().add(0.0f, 1.0f, 0.0f), 50);
+ return;
+ }
+ }
+
+ player.sendMessage(config.getString("teleportFailedCompassNotInHand"));
+ resetPlayerCooldown(player.getName());
+ }
+
+ /// Returns true if a teleport went through and false otherwise
+ Boolean handlePlayerClickCompass(Player player, ItemStack item)
+ {
+ // Assert: Player's main hand is a compass, they have just right clicked air with it
+ // Assert: Item passed in is the main-hand compass
+
+ CompassMeta itemMeta = (CompassMeta)item.getItemMeta();
+ if (itemMeta.hasLodestone() && itemMeta.isLodestoneTracked())
+ {
+ int cooldown = checkPlayerCooldown(player.getName());
+ if (cooldown > 0)
+ {
+ player.sendMessage(config.getString("teleportFailedWaitForCooldown").replace("%cooldown%", String.valueOf(cooldown)));
+ return false;
}
+
+ // Success: Player has right clicked with a valid lodestone compass
+ Location oldLoc = player.getLocation();
+ Bukkit.getServer().getScheduler().scheduleSyncDelayedTask(
+ plugin,
+ () -> PerformTeleport(player, oldLoc),
+ warmupTimeTicks
+ );
+ player.spawnParticle(Particle.ENCHANTMENT_TABLE, oldLoc.add(0.0f, 1.0f, 0.0f), 50);
+ return true;
+ }
+ return false;
+ }
+
+ @EventHandler(priority = EventPriority.LOWEST)
+ public void Compass(PlayerInteractEvent e)
+ {
+ Player p = e.getPlayer();
+ ItemStack item = p.getInventory().getItemInMainHand();
+ if (e.getHand() == EquipmentSlot.HAND && item.getType() == Material.COMPASS && e.getAction() == Action.RIGHT_CLICK_AIR)
+ {
+ if (handlePlayerClickCompass(p, item)) e.setCancelled(true);
}
}
}
diff --git a/src/me/Percyqaz/Lodestone/Lodestone.java b/src/me/Percyqaz/Lodestone/Lodestone.java
index ba9b971..eb5a9e2 100644
--- a/src/me/Percyqaz/Lodestone/Lodestone.java
+++ b/src/me/Percyqaz/Lodestone/Lodestone.java
@@ -1,11 +1,26 @@
package me.Percyqaz.Lodestone;
+import org.bukkit.configuration.file.FileConfiguration;
import org.bukkit.plugin.java.JavaPlugin;
public class Lodestone extends JavaPlugin {
+
+ FileConfiguration config = getConfig();
+
@Override
public void onEnable() {
+ config.addDefault("cooldownSeconds", 60);
+ config.addDefault("warmupSeconds", 2);
+ config.addDefault("teleportFailedWaitForCooldown", "§4You cannot teleport for another %cooldown% seconds!");
+ config.addDefault("teleportFailedMovedBeforeTeleport", "§4Teleport cancelled because you moved!");
+ config.addDefault("teleportFailedCompassNotInHand", "§4Teleport cancelled because the compass is no longer in your hand!");
+ config.addDefault("teleportSucceeded", "§9Whoosh!");
+ config.addDefault("teleportSucceededNamedLocation", "§9Whoosh! Teleported to §a%location%");
+
+ config.options().copyDefaults(true);
+ saveConfig();
+
this.getLogger().info("Listening to right clicks");
- getServer().getPluginManager().registerEvents(new CompassListener(), this);
+ getServer().getPluginManager().registerEvents(new CompassListener(this, config), this);
}
}
diff --git a/src/plugin.yml b/src/plugin.yml
index 07ab986..e146041 100644
--- a/src/plugin.yml
+++ b/src/plugin.yml
@@ -1,5 +1,5 @@
name: Lodestone
-version: 1.0
+version: 2.0
author: Percyqaz
main: me.Percyqaz.Lodestone.Lodestone
-api-version: 1.16
\ No newline at end of file
+api-version: 1.18
\ No newline at end of file