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; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.UUID; public class BlacksmithTrait extends Trait { private final BlacksmithPlugin plugin; private final List reforgeAbleItems = new ArrayList<>(); private final Map coolDowns = new HashMap<>(); private ReforgeSession session; private final Settings config; public BlacksmithTrait() { super("blacksmith"); plugin = (BlacksmithPlugin) Bukkit.getServer().getPluginManager().getPlugin("Blacksmith"); this.config = BlacksmithPlugin.getInstance().getSettings(); } public void addCoolDown(UUID playerUUID, Calendar waitUntil) { coolDowns.put(playerUUID, waitUntil); } public void unsetSession() { this.session = null; } @Override public void load(DataKey key) { for (DataKey sub : key.getRelative("reforgeable-items").getIntegerSubKeys()) { if (Material.getMaterial(sub.getString("").toUpperCase().replace('-', '_')) != null) { reforgeAbleItems.add(Material.getMaterial(sub.getString("").toUpperCase().replace('-', '_'))); } } 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()) { return; } Player player = event.getClicker(); if ((config.getDisableCoolDown() & (coolDowns.get(player.getUniqueId()) != (null)))) { coolDowns.remove(player.getUniqueId()); } if (!player.hasPermission("blacksmith.reforge")) { return; } if (coolDowns.get(player.getUniqueId()) != null) { if (!Calendar.getInstance().after(coolDowns.get(player.getUniqueId()))) { player.sendMessage(config.getCoolDownUnexpiredMessage()); return; } coolDowns.remove(player.getUniqueId()); } ItemStack hand = player.getInventory().getItemInMainHand(); if (session != null) { //timeout if (System.currentTimeMillis() > _sessionStart + 10 * 1000 || this.npc.getEntity().getLocation().distance(session.getPlayer().getLocation()) > 20) { session = null; } } if (session != null) { if (!session.isInSession(player)) { player.sendMessage(config.getBusyWithPlayerMessage()); return; } if (session.isRunning()) { player.sendMessage(config.getBusyReforgingMessage()); return; } if (session.endSession()) { session = null; } else { reforge(npc, player); } } else { if ((!plugin.isTool(hand) && !BlacksmithPlugin.isArmor(hand)) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType()))) { player.sendMessage(config.getInvalidItemMessage()); return; } String cost = plugin.formatCost(player); _sessionStart = System.currentTimeMillis(); session = new ReforgeSession(this, player, npc, config); player.sendMessage(config.getCostMessage().replace("", cost).replace("", hand.getType().name().toLowerCase().replace('_', ' '))); } } private long _sessionStart = System.currentTimeMillis(); @Override public void save(DataKey key) { for (int i = 0; i < reforgeAbleItems.size(); i++) { key.getRelative("reforgeable-items").setString(String.valueOf(i), reforgeAbleItems.get(i).name().toLowerCase().replace('_', '-')); } config.saveVariables(key); } private void reforge(NPC npc, Player player) { player.sendMessage(config.getStartReforgeMessage()); //plugin.deposit(npc, player); // CitiTrader dependency outdated and broken plugin.withdraw(player); session.beginReforge(); if (npc.getEntity() instanceof Player) { ((Player) npc.getEntity()).getInventory().setItemInMainHand(player.getInventory().getItemInMainHand()); } else { Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(player.getInventory().getItemInMainHand()); } player.getInventory().setItemInMainHand(null); } }