package net.apunch.blacksmith; import net.apunch.blacksmith.config.Settings; import net.citizensnpcs.api.npc.NPC; import org.bukkit.NamespacedKey; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.LivingEntity; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.meta.Damageable; import org.bukkit.inventory.meta.ItemMeta; import java.util.Calendar; import java.util.Objects; import java.util.Random; /** * A representation of the session between a player and a blacksmith */ public class ReforgeSession implements Runnable { private final BlacksmithTrait blacksmithTrait; private final Player player; private final NPC npc; private final ItemStack itemToReforge; private int taskId; private final Settings config; private static final String[] enchantments = new String[Enchantment.values().length]; /** * Instantiates a new session * * @param blacksmithTrait
A reference to the blacksmith trait
* @param playerThe player initiating the session
* @param npcThe Blacksmith NPC involved in the session
* @param configThe config to use for the session
*/ ReforgeSession(BlacksmithTrait blacksmithTrait, Player player, NPC npc, Settings config) { this.blacksmithTrait = blacksmithTrait; this.player = player; this.npc = npc; itemToReforge = player.getInventory().getItemInMainHand(); this.config = config; int i = 0; for (Enchantment enchantment : Enchantment.values()) { enchantments[i++] = enchantment.getKey().asString(); } } @Override public void run() { player.sendMessage(reforgeItemInHand() ? config.getSuccessMessage() : config.getFailMessage()); if (npc.getEntity() instanceof Player) { ((Player) npc.getEntity()).getInventory().setItemInMainHand(null); } else { Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null); } if (!config.getDisableDelay()) { if (config.getDropItem()) { player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), itemToReforge); } else { player.getInventory().addItem(itemToReforge); } } else { player.getInventory().setItemInMainHand(itemToReforge); } blacksmithTrait.unsetSession(); // Start cool down Calendar wait = Calendar.getInstance(); wait.add(Calendar.SECOND, config.getReforgeCoolDown()); blacksmithTrait.addCoolDown(player.getUniqueId(), wait); } private boolean reforgeItemInHand() { Random random = new Random(); if (random.nextInt(100) < config.getFailChance()) { for (Enchantment enchantment : itemToReforge.getEnchantments().keySet()) { // Remove or downgrade enchantments if (random.nextBoolean()) { itemToReforge.removeEnchantment(enchantment); } else { if (itemToReforge.getEnchantmentLevel(enchantment) > 1) { itemToReforge.removeEnchantment(enchantment); itemToReforge.addEnchantment(enchantment, 1); } } } // Damage the item short reforgeDurability = BlacksmithPlugin.getDurability(itemToReforge); short durability = (short) (reforgeDurability + reforgeDurability * random.nextInt(8)); short maxDurability = itemToReforge.getType().getMaxDurability(); if (durability <= 0) { durability = (short) (maxDurability / 3); } else if (reforgeDurability + durability > maxDurability) { durability = (short) (maxDurability - random.nextInt(maxDurability - 25)); } updateDamage(itemToReforge, maxDurability - durability); return false; } else { updateDamage(itemToReforge, 0); // Add random enchantments int roll = random.nextInt(100); if (roll < config.getExtraEnchantmentChance() && itemToReforge.getEnchantments().keySet().size() < config.getMaxEnchantments()) { Enchantment enchantment = Enchantment.getByKey(NamespacedKey.fromString(enchantments[random.nextInt(enchantments.length)])); if (Objects.requireNonNull(enchantment).canEnchantItem(itemToReforge)) { int randomBound = enchantment.getMaxLevel() - enchantment.getStartLevel(); //A workaround for the random method's bound sometimes being negative if (randomBound >= 0) { itemToReforge.addEnchantment(enchantment, random.nextInt(randomBound) + enchantment.getStartLevel()); } } } return true; } } private void updateDamage(ItemStack item, int newDamage) { ItemMeta meta = item.getItemMeta(); Damageable damageable = (Damageable) meta; damageable.setDamage(newDamage); item.setItemMeta(meta); } // Return if the session should end boolean endSession() { // Prevent player from switching items during session ItemStack itemInHand = player.getInventory().getItemInMainHand(); if (!itemToReforge.equals(itemInHand)) { player.sendMessage(config.getItemChangedMessage()); return true; } if (!BlacksmithPlugin.getInstance().doesPlayerHaveEnough(player)) { player.sendMessage(config.getInsufficientFundsMessage()); return true; } return false; } boolean isRunning() { return BlacksmithPlugin.getInstance().getServer().getScheduler().isQueued(taskId); } boolean isInSession(Player other) { return player.getName().equals(other.getName()); } void beginReforge() { if (!config.getDisableCoolDown()) { taskId = BlacksmithPlugin.getInstance().getServer().getScheduler().scheduleSyncDelayedTask( BlacksmithPlugin.getInstance(), this, (new Random().nextInt(config.getMaxReforgeDelay()) + config.getMinReforgeDelay()) * 20L); } else { taskId = BlacksmithPlugin.getInstance().getServer().getScheduler().scheduleSyncDelayedTask( BlacksmithPlugin.getInstance(), this, 0); } } public Player getPlayer() { return player; } }