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

* @return

True 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 player

The player holding an item

* @return

Whether 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 player

The player holding an item

* @param salvageMethod

The salvage method to check

* @param item

The item to be salvaged

* @return

Whether 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 player

The player holding an item

* @return

The 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 salvageMethod

The salvage method to get the cost for

* @param item

The item to be salvaged

* @param player

The player to provide the cost to

* @return

The 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 player

The player to check

* @param cost

The required cost

* @return

True 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 cost

The cost to format

* @return

The formatted cost

*/ @NotNull public static String format(double cost) { return economy.format(cost); } /** * Gets the cost of salvaging using the specified method * * @param salvageMethod

The salvage method to get cost for

* @param item

The item to be salvaged

* @return

The 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 player

The 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 player

The player to withdraw from

* @param salvageMethod

The 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 player

The player to withdraw from

* @param monetaryCost

The cost to withdraw

* @throws IllegalArgumentException

If 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 player

The player to calculate the cost for

* @return

The calculated cost

*/ private static double getHeldItemCost(@NotNull Player player) { return getCost(player.getInventory().getItemInMainHand()); } /** * Gets the cost of repairing the given item * * @param item

The item to be repaired

* @return

The 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 item

The item to calculate enchantment cost for

* @return

The 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 item

The enchanted book to calculate cost for

* @return

The 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 servicesManager

The services manager to use for finding a Vault provider

* @return

True if Vault was successfully set up

*/ private static boolean setupVault(@NotNull ServicesManager servicesManager) { // Setup Vault RegisteredServiceProvider economyProvider = servicesManager.getRegistration(Economy.class); if (economyProvider != null) { economy = economyProvider.getProvider(); return true; } else { // Disable if no economy plugin was found BlacksmithPlugin.error("Failed to load an economy plugin. Disabling..."); return false; } } }