diff --git a/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java b/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java index af5ba59..ef09a3a 100644 --- a/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java +++ b/src/main/java/net/apunch/blacksmith/BlacksmithPlugin.java @@ -115,7 +115,7 @@ public class BlacksmithPlugin extends JavaPlugin { }; } - public boolean isArmor(ItemStack item) { + public static boolean isArmor(ItemStack item) { return switch (item.getType()) { case LEATHER_HELMET, LEATHER_CHESTPLATE, LEATHER_LEGGINGS, LEATHER_BOOTS, CHAINMAIL_HELMET, CHAINMAIL_CHESTPLATE, CHAINMAIL_LEGGINGS, CHAINMAIL_BOOTS, GOLDEN_HELMET, GOLDEN_CHESTPLATE, diff --git a/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java b/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java index e21d50b..42c2bd0 100644 --- a/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java +++ b/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java @@ -1,15 +1,22 @@ package net.apunch.blacksmith; import net.apunch.blacksmith.util.Settings; +import net.citizensnpcs.api.CitizensAPI; import net.citizensnpcs.api.npc.NPC; import net.citizensnpcs.api.trait.Trait; import net.citizensnpcs.api.util.DataKey; import org.bukkit.Bukkit; import org.bukkit.Material; +import org.bukkit.entity.Entity; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; +import org.bukkit.event.Event; import org.bukkit.event.EventHandler; +import org.bukkit.event.EventPriority; +import org.bukkit.event.block.Action; +import org.bukkit.event.player.PlayerInteractEvent; import org.bukkit.inventory.ItemStack; +import org.bukkit.util.Vector; import java.util.ArrayList; import java.util.Calendar; @@ -51,6 +58,48 @@ public class BlacksmithTrait extends Trait { config.loadVariables(key); } + @EventHandler(priority = EventPriority.HIGHEST) + public void onClick(PlayerInteractEvent event) { + if (event.getHand() == null || (event.getAction() != Action.RIGHT_CLICK_AIR && event.getAction() != + Action.RIGHT_CLICK_BLOCK)) { + return; + } + Entity target = getTarget(event.getPlayer(), event.getPlayer().getLocation().getNearbyEntities(15, 10, 15)); + if (!CitizensAPI.getNPCRegistry().isNPC(target) || + !CitizensAPI.getNPCRegistry().getNPC(target).hasTrait(BlacksmithTrait.class)) { + return; + } + + ItemStack usedItem = event.getPlayer().getInventory().getItem(event.getHand()); + if (usedItem != null && BlacksmithPlugin.isArmor(usedItem)) { + event.setUseItemInHand(Event.Result.DENY); + event.getPlayer().updateInventory(); + } + } + + public static T getTarget(final Entity entity, final Iterable entities) { + if (entity == null) { + return null; + } + T target = null; + final double threshold = 1; + for (final T other : entities) { + final Vector n = other.getLocation().toVector() + .subtract(entity.getLocation().toVector()); + if (entity.getLocation().getDirection().normalize().crossProduct(n) + .lengthSquared() < threshold + && n.normalize().dot( + entity.getLocation().getDirection().normalize()) >= 0) { + if (target == null || + target.getLocation().distanceSquared(entity.getLocation()) > + other.getLocation().distanceSquared(entity.getLocation())) { + target = other; + } + } + } + return target; + } + @EventHandler public void onRightClick(net.citizensnpcs.api.event.NPCRightClickEvent event) { if (this.npc != event.getNPC()) { @@ -78,7 +127,8 @@ public class BlacksmithTrait extends Trait { if (session != null) { //timeout - if (System.currentTimeMillis() > _sessionStart + 10 * 1000 || this.npc.getEntity().getLocation().distance(session.getPlayer().getLocation()) > 20) { + if (System.currentTimeMillis() > _sessionStart + 10 * 1000 || + this.npc.getEntity().getLocation().distance(session.getPlayer().getLocation()) > 20) { session = null; } } @@ -86,23 +136,21 @@ public class BlacksmithTrait extends Trait { if (session != null) { if (!session.isInSession(player)) { - player.sendMessage(config.getBusyWithPlayerMessage()); return; - } if (session.isRunning()) { player.sendMessage(config.getBusyReforgingMessage()); return; } - if (session.handleClick()) { + if (session.endSession()) { session = null; } else { reforge(npc, player); } } else { - if ((!plugin.isTool(hand) && !plugin.isArmor(hand)) + if ((!plugin.isTool(hand) && !BlacksmithPlugin.isArmor(hand)) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType()))) { player.sendMessage(config.getInvalidItemMessage()); return; diff --git a/src/main/java/net/apunch/blacksmith/ReforgeSession.java b/src/main/java/net/apunch/blacksmith/ReforgeSession.java index 4107dbc..a4f6d69 100644 --- a/src/main/java/net/apunch/blacksmith/ReforgeSession.java +++ b/src/main/java/net/apunch/blacksmith/ReforgeSession.java @@ -109,9 +109,10 @@ class ReforgeSession implements Runnable { } // Return if the session should end - boolean handleClick() { + boolean endSession() { // Prevent player from switching items during session - if (!itemToReforge.equals(player.getInventory().getItemInMainHand())) { + ItemStack itemInHand = player.getInventory().getItemInMainHand(); + if (!itemToReforge.equals(itemInHand)) { player.sendMessage(config.getItemChangedMessage()); return true; }