Blacksmith/src/main/java/net/apunch/blacksmith/BlacksmithTrait.java

197 lines
7.0 KiB
Java

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<Material> reforgeAbleItems = new ArrayList<>();
private final Map<UUID, Calendar> 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 extends Entity> T getTarget(final Entity entity, final Iterable<T> 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("<price>", cost).replace("<item>",
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);
}
}