package net.knarcraft.blacksmith.manager; import net.knarcraft.blacksmith.BlacksmithPlugin; import net.knarcraft.blacksmith.config.blacksmith.GlobalBlacksmithSettings; import net.knarcraft.blacksmith.config.scrapper.GlobalScrapperSettings; import net.knarcraft.blacksmith.property.SalvageMethod; import net.knarcraft.blacksmith.util.ItemHelper; import net.knarcraft.knarlib.formatting.StringReplacer; import net.milkbowl.vault.economy.Economy; import net.objecthunter.exp4j.Expression; import net.objecthunter.exp4j.ExpressionBuilder; import org.bukkit.Material; import org.bukkit.enchantments.Enchantment; import org.bukkit.entity.Player; import org.bukkit.inventory.ItemStack; import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.ServicesManager; import org.jetbrains.annotations.NotNull; /** * A class which deals with everything economy */ public class EconomyManager { private static Economy economy; private EconomyManager() { } /** * Sets up Vault economy support * * @param servicesManager
The services manager to use for finding a Vault provider
* @returnTrue if Vault was successfully set up
*/ public static boolean setUp(@NotNull ServicesManager servicesManager) { //If already set up, there is nothing to do if (economy != null) { return true; } return setupVault(servicesManager); } /** * Gets whether the given player cannot pay for re-forging their held item * * @param playerThe player holding an item
* @returnWhether the player cannot pay for the reforge
*/ public static boolean cannotPayForHeldItemReforge(@NotNull Player player) { return economy.getBalance(player) - getHeldItemCost(player) < 0; } /** * Gets whether the given player cannot pay for salvaging an item * * @param playerThe player holding an item
* @param salvageMethodThe salvage method to check
* @param itemThe item to be salvaged
* @returnWhether the player cannot pay for the salvage
*/ public static boolean cannotPayForSalvage(@NotNull Player player, @NotNull SalvageMethod salvageMethod, @NotNull ItemStack item) { // TODO: Account for advanced cost options return economy.getBalance(player) - getSalvageCost(salvageMethod, item, player) < 0; } /** * Gets the human-readable cost of the given player's held item * * @param playerThe player holding an item
* @returnThe formatted cost
*/ @NotNull public static String formatBlacksmithCost(@NotNull Player player) { double cost = getHeldItemCost(player); return economy.format(cost); } /** * Gets the human-readable cost of salvaging an item * * @param salvageMethodThe salvage method to get the cost for
* @param itemThe item to be salvaged
* @param playerThe player to provide the cost to
* @returnThe formatted cost
*/ @NotNull public static String formatSalvageCost(@NotNull SalvageMethod salvageMethod, @NotNull ItemStack item, @NotNull Player player) { return economy.format(getSalvageCost(salvageMethod, item, player)); } /** * Gets whether the given player has enough money to pay the given cost * * @param playerThe player to check
* @param costThe required cost
* @returnTrue if the player has enough money to cover the cost
*/ public static boolean hasEnough(@NotNull Player player, double cost) { return economy.getBalance(player) >= cost; } /** * Formats a number as an economy cost * * @param costThe cost to format
* @returnThe formatted cost
*/ @NotNull public static String format(double cost) { return economy.format(cost); } /** * Gets the cost of salvaging using the specified method * * @param salvageMethodThe salvage method to get cost for
* @param itemThe item to be salvaged
* @returnThe salvage cost
*/ private static double getSalvageCost(@NotNull SalvageMethod salvageMethod, @NotNull ItemStack item, @NotNull Player player) { GlobalScrapperSettings settings = BlacksmithPlugin.getInstance().getGlobalScrapperSettings(); double baseCost = switch (salvageMethod) { case SALVAGE, EXTENDED_SALVAGE -> settings.getSalvageCost(); case NETHERITE -> settings.getNetheriteSalvageCost(); case ARMOR_TRIM -> settings.getArmorTrimSalvageCost(); case ENCHANTED_BOOK -> getEnchantedBookSalvageCost(item); }; StringReplacer replacer = new StringReplacer(settings.getSalvageCostIncrease()); replacer.add("{cost}", String.valueOf(baseCost)); replacer.add("{timesUsed}", String.valueOf(PlayerUsageManager.getUsages(player, System.currentTimeMillis() - 3600000))); Expression expression = new ExpressionBuilder(replacer.replace()).build(); return Math.max(expression.evaluate(), baseCost); } /** * Withdraws the reforging cost from the given player * *The cost is automatically calculated from the item in the player's main hand.
* * @param playerThe player to withdraw from
*/ public static void withdrawBlacksmith(@NotNull Player player) { double cost = getHeldItemCost(player); if (cost > 0) { economy.withdrawPlayer(player, cost); } } /** * Withdraws the salvaging cost from the given player * * @param playerThe player to withdraw from
* @param salvageMethodThe salvage method to withdraw for
*/ public static void withdrawScrapper(@NotNull Player player, @NotNull SalvageMethod salvageMethod) { double cost = getSalvageCost(salvageMethod, player.getInventory().getItemInMainHand(), player); if (cost > 0) { economy.withdrawPlayer(player, cost); } } /** * Withdraws money from a player * * @param playerThe player to withdraw from
* @param monetaryCostThe cost to withdraw
* @throws IllegalArgumentExceptionIf a negative cost is given
*/ public static void withdraw(@NotNull Player player, double monetaryCost) { if (monetaryCost < 0) { throw new IllegalArgumentException("Cannot withdraw a negative amount"); } economy.withdrawPlayer(player, monetaryCost); } /** * Gets the cost of the item in the given player's main hand * * @param playerThe player to calculate the cost for
* @returnThe calculated cost
*/ private static double getHeldItemCost(@NotNull Player player) { return getCost(player.getInventory().getItemInMainHand()); } /** * Gets the cost of repairing the given item * * @param itemThe item to be repaired
* @returnThe cost of the repair
*/ private static double getCost(@NotNull ItemStack item) { GlobalBlacksmithSettings globalBlacksmithSettings = BlacksmithPlugin.getInstance().getGlobalBlacksmithSettings(); Material material = item.getType(); //Calculate the base price double price = globalBlacksmithSettings.getBasePrice(material); // Adjust price based on durability double pricePerDurabilityPoint = globalBlacksmithSettings.getPricePerDurabilityPoint(material); if (globalBlacksmithSettings.getUseNaturalCost()) { //Cost increases with damage price += ((double) ItemHelper.getDamage(item)) * pricePerDurabilityPoint; } else { //Cost decreases with damage price += ((double) ItemHelper.getDurability(item)) * pricePerDurabilityPoint; } //Increase price for any enchantments price += getEnchantmentCost(item); //Override the cost for anvils if (ItemHelper.isAnvil(material, true)) { price = globalBlacksmithSettings.getAnvilCost(material); } return price; } /** * Gets the cost resulting from all enchantments on the given item * * @param itemThe item to calculate enchantment cost for
* @returnThe resulting enchantment cost
*/ private static double getEnchantmentCost(@NotNull ItemStack item) { GlobalBlacksmithSettings settings = BlacksmithPlugin.getInstance().getGlobalBlacksmithSettings(); double price = 0; for (Enchantment enchantment : item.getEnchantments().keySet()) { price += settings.getEnchantmentCost(enchantment) * item.getEnchantmentLevel(enchantment); } return price; } /** * Gets the cost of scrapping an enchanted book * * @param itemThe enchanted book to calculate cost for
* @returnThe cost of scrapping the enchanted book
*/ private static double getEnchantedBookSalvageCost(@NotNull ItemStack item) { // TODO: Properly implement this /*GlobalScrapperSettings settings = BlacksmithPlugin.getInstance().getGlobalScrapperSettings(); double cost = settings.getEnchantedBookSalvageCost(); if (settings.multiplyEnchantedBookSalvageCost()) { cost *= SalvageHelper.getEnchantmentCount(item) - 1; } return SalvageHelper.getEnchantmentCount(item) * cost;*/ return 1000000; } /** * Sets up Vault for economy * * @param servicesManagerThe services manager to use for finding a Vault provider
* @returnTrue if Vault was successfully set up
*/ private static boolean setupVault(@NotNull ServicesManager servicesManager) { // Setup Vault RegisteredServiceProvider