Implements netherite salvaging #24
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	EpicKnarvik97/Blacksmith/pipeline/head This commit looks good
				
			This commit is contained in:
		@@ -0,0 +1,23 @@
 | 
			
		||||
package net.knarcraft.blacksmith.config;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A representation of the different ways an item can be salvaged
 | 
			
		||||
 */
 | 
			
		||||
public enum SalvageMethod {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Salvaging the item normally by returning the item's crafting recipe
 | 
			
		||||
     */
 | 
			
		||||
    SALVAGE,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Removing the armor trim from an item
 | 
			
		||||
     */
 | 
			
		||||
    ARMOR_TRIM,
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Un-doing netherite application for an item
 | 
			
		||||
     */
 | 
			
		||||
    NETHERITE,
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -22,7 +22,8 @@ public enum SmithPreset {
 | 
			
		||||
    /**
 | 
			
		||||
     * A blacksmith capable of re-forging everything
 | 
			
		||||
     */
 | 
			
		||||
    BLACKSMITH(new SmithPresetFilter[]{}),
 | 
			
		||||
    BLACKSMITH(new SmithPresetFilter[]{SmithPresetFilter.GOLD, SmithPresetFilter.IRON, SmithPresetFilter.DIAMOND,
 | 
			
		||||
            SmithPresetFilter.NETHERITE}),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * A blacksmith capable of re-forging all weapons (including shields)
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
 | 
			
		||||
     *
 | 
			
		||||
     * @param instance <p>A reference to the blacksmith plugin</p>
 | 
			
		||||
     */
 | 
			
		||||
    public GlobalScrapperSettings(BlacksmithPlugin instance) {
 | 
			
		||||
    public GlobalScrapperSettings(@NotNull BlacksmithPlugin instance) {
 | 
			
		||||
        this.instance = instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -78,7 +78,8 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
 | 
			
		||||
     * @param scrapperSetting <p>The setting to get</p>
 | 
			
		||||
     * @return <p>The current raw setting value</p>
 | 
			
		||||
     */
 | 
			
		||||
    public @NotNull Object getRawValue(@NotNull ScrapperSetting scrapperSetting) {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public Object getRawValue(@NotNull ScrapperSetting scrapperSetting) {
 | 
			
		||||
        return this.settings.get(scrapperSetting);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -87,6 +88,7 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The current value of the default NPC settings</p>
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public Map<ScrapperSetting, Object> getDefaultNPCSettings() {
 | 
			
		||||
        return new HashMap<>(this.settings);
 | 
			
		||||
    }
 | 
			
		||||
@@ -108,10 +110,22 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
 | 
			
		||||
     * @param setting <p>The setting to get the value of</p>
 | 
			
		||||
     * @return <p>The value of the given setting as a boolean</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean asBoolean(ScrapperSetting setting) {
 | 
			
		||||
    public boolean asBoolean(@NotNull ScrapperSetting setting) {
 | 
			
		||||
        return ConfigHelper.asBoolean(getValue(setting));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the given value as a double
 | 
			
		||||
     *
 | 
			
		||||
     * <p>This will throw an exception if used for a non-double setting</p>
 | 
			
		||||
     *
 | 
			
		||||
     * @param setting <p>The setting to get the value of</p>
 | 
			
		||||
     * @return <p>The value of the given setting as a double</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double asDouble(@NotNull ScrapperSetting setting) {
 | 
			
		||||
        return ConfigHelper.asDouble(getValue(setting));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the value of a setting, using the default if not set
 | 
			
		||||
     *
 | 
			
		||||
@@ -173,12 +187,30 @@ public class GlobalScrapperSettings implements Settings<ScrapperSetting> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the cost of using a scrapper
 | 
			
		||||
     * Gets the cost of using a scrapper to salvage an item
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The cost of using a scrapper</p>
 | 
			
		||||
     * @return <p>The cost of using a scrapper to salvage an item</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getCost() {
 | 
			
		||||
        return ConfigHelper.asDouble(getValue(ScrapperSetting.USE_COST));
 | 
			
		||||
    public double getSalvageCost() {
 | 
			
		||||
        return asDouble(ScrapperSetting.SALVAGE_COST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the cost of using a scrapper to remove armor trim
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The cost of using a scrapper to remove armor trim</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getArmorTrimSalvageCost() {
 | 
			
		||||
        return asDouble(ScrapperSetting.ARMOR_TRIM_SALVAGE_COST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the cost of using a scrapper to remove netherite from an item
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The cost of using a scrapper to remove netherite from an item</p>
 | 
			
		||||
     */
 | 
			
		||||
    public double getNetheriteSalvageCost() {
 | 
			
		||||
        return asDouble(ScrapperSetting.NETHERITE_SALVAGE_COST);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -151,6 +151,16 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
 | 
			
		||||
        return asString(ScrapperSetting.COST_MESSAGE_ARMOR_TRIM);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the message to use for displaying netherite salvage cost
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The message to use for displaying netherite salvage cost</p>
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getNetheriteCostMessage() {
 | 
			
		||||
        return asString(ScrapperSetting.COST_MESSAGE_NETHERITE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getCoolDownUnexpiredMessage() {
 | 
			
		||||
@@ -316,6 +326,15 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
 | 
			
		||||
        return asBoolean(ScrapperSetting.SALVAGE_ARMOR_TRIMS);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether salvage of netherite items is enabled
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>True if this scrapper can salvage netherite items</p>
 | 
			
		||||
     */
 | 
			
		||||
    public boolean salvageNetherite() {
 | 
			
		||||
        return asBoolean(ScrapperSetting.SALVAGE_NETHERITE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the title of this scrapper NPC
 | 
			
		||||
     *
 | 
			
		||||
@@ -415,4 +434,14 @@ public class ScrapperNPCSettings implements TraitSettings<ScrapperSetting> {
 | 
			
		||||
        return asString(ScrapperSetting.ARMOR_TRIM_SALVAGE_NOT_FOUND_MESSAGE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the message to display when explaining that this scrapper is unable to salvage netherite items
 | 
			
		||||
     *
 | 
			
		||||
     * @return <p>The message to display when explaining that this scrapper is unable to salvage netherite items</p>
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getCannotSalvageNetheriteMessage() {
 | 
			
		||||
        return asString(ScrapperSetting.CANNOT_SALVAGE_NETHERITE_MESSAGE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
     * <p>If set to false, the item will be directly put in the player's inventory instead</p>
 | 
			
		||||
     */
 | 
			
		||||
    DROP_ITEM("dropItem", SettingValueType.BOOLEAN, true, "Whether the " +
 | 
			
		||||
            "item will drop materials resulting from scrapping on the ground, instead of putting them into the user's" +
 | 
			
		||||
            "item will drop materials resulting from salvaging on the ground, instead of putting them into the user's" +
 | 
			
		||||
            " inventory", true, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -85,6 +85,12 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
     */
 | 
			
		||||
    SALVAGE_ARMOR_TRIMS("salvageArmorTrims", SettingValueType.BOOLEAN, true,
 | 
			
		||||
            "Whether to enable salvaging of armor trims.", true, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The setting for whether the NPC should allow salvaging netherite items to diamond items
 | 
			
		||||
     */
 | 
			
		||||
    SALVAGE_NETHERITE("salvageNetherite", SettingValueType.BOOLEAN, true,
 | 
			
		||||
            "Whether to enable salvaging of netherite items", true, false),
 | 
			
		||||
    
 | 
			
		||||
    /*-----------
 | 
			
		||||
     | Messages |
 | 
			
		||||
@@ -164,16 +170,23 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
     * The message displayed when displaying the cost of salvaging the held item to the player
 | 
			
		||||
     */
 | 
			
		||||
    COST_MESSAGE("costMessage", SettingValueType.STRING,
 | 
			
		||||
            "&eIt will cost &a{cost}&e to salvage that item! {yield} Click again to salvage!",
 | 
			
		||||
            "&eIt will cost &a{cost}&e to salvage that &a{item}&e! {yield} &eClick again to salvage!",
 | 
			
		||||
            "The message to display when informing a player about the salvaging cost", true, true),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The message displayed when displaying the cost of salvaging the armor trim of the held item to the player
 | 
			
		||||
     */
 | 
			
		||||
    COST_MESSAGE_ARMOR_TRIM("costMessageArmorTrim", SettingValueType.STRING,
 | 
			
		||||
            "&eIt will cost &a{cost}&e to salvage that armor trim!",
 | 
			
		||||
            "&eIt will cost &a{cost}&e to salvage that &a{item}&e's armor trim!",
 | 
			
		||||
            "The message to display when explaining the shown item's armor trim's salvage cost", true, true),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The message displayed when displaying the cost of salvaging the netherite of the held item to the player
 | 
			
		||||
     */
 | 
			
		||||
    COST_MESSAGE_NETHERITE("costMessageNetherite", SettingValueType.STRING,
 | 
			
		||||
            "&eIt will cost &a{cost}&e to salvage that &a{item}&e into diamond!",
 | 
			
		||||
            "The message to display when explaining the shown item's netherite salvage cost", true, true),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The message displayed when explaining that all items will be returned as salvage
 | 
			
		||||
     */
 | 
			
		||||
@@ -209,21 +222,40 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
            "&cI'm sorry, but I don't know how to salvage that armor trim!",
 | 
			
		||||
            "The message to display if the correct materials to return for the armor trim are unknown", true, true),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The message displayed when explaining that netherite salvage is disabled
 | 
			
		||||
     */
 | 
			
		||||
    CANNOT_SALVAGE_NETHERITE_MESSAGE("cannotSalvageNetheriteMessage", SettingValueType.STRING,
 | 
			
		||||
            "&cI'm sorry, but I'm unable to salvage netherite items!",
 | 
			
		||||
            "The message to display when asked to salvage netherite items, and that option is disabled", true, true),
 | 
			
		||||
 | 
			
		||||
    /*------------------
 | 
			
		||||
     | Global settings |
 | 
			
		||||
     ------------------*/
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The setting for the use cost of using the scrapper
 | 
			
		||||
     * The setting for the salvage cost
 | 
			
		||||
     */
 | 
			
		||||
    USE_COST("basePrice", SettingValueType.POSITIVE_DOUBLE, 0, "The cost of using a scrapper",
 | 
			
		||||
            false, false),
 | 
			
		||||
    SALVAGE_COST("salvagePrice", SettingValueType.POSITIVE_DOUBLE, 0,
 | 
			
		||||
            "The cost of using a scrapper to salvage an item", false, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The setting for the armor trim salvage cost
 | 
			
		||||
     */
 | 
			
		||||
    ARMOR_TRIM_SALVAGE_COST("armorTrimSalvagePrice", SettingValueType.POSITIVE_DOUBLE, 5,
 | 
			
		||||
            "The cost of using the scrapper to remove armor trim", false, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * The setting for the netherite salvage cost
 | 
			
		||||
     */
 | 
			
		||||
    NETHERITE_SALVAGE_COST("netheriteSalvagePrice", SettingValueType.POSITIVE_DOUBLE, 15,
 | 
			
		||||
            "The cost of using the scrapper to remove netherite from an item", false, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Whether to display exact time in minutes and seconds when displaying a remaining cool-down
 | 
			
		||||
     */
 | 
			
		||||
    SHOW_EXACT_TIME("showExactTime", SettingValueType.BOOLEAN, "false", "Exact time displays the " +
 | 
			
		||||
            "exact number of seconds and minutes remaining as part of the scrapping cool-down and scrapping delay " +
 | 
			
		||||
            "exact number of seconds and minutes remaining as part of the salvaging cool-down and salvaging delay " +
 | 
			
		||||
            "messages, instead of just vaguely hinting at the remaining time.", false, false),
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -263,7 +295,7 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
     * @param isPerNPC    <p>Whether this setting is per-NPC or global</p>
 | 
			
		||||
     * @param isMessage   <p>Whether this option is for an NPC message</p>
 | 
			
		||||
     */
 | 
			
		||||
    ScrapperSetting(String key, SettingValueType valueType, Object value,
 | 
			
		||||
    ScrapperSetting(@NotNull String key, @NotNull SettingValueType valueType, @NotNull Object value,
 | 
			
		||||
                    @NotNull String description, boolean isPerNPC, boolean isMessage) {
 | 
			
		||||
        if (isPerNPC) {
 | 
			
		||||
            if (isMessage) {
 | 
			
		||||
@@ -289,32 +321,38 @@ public enum ScrapperSetting implements Setting {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull String getPath() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getPath() {
 | 
			
		||||
        return this.path;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull String getChildPath() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getChildPath() {
 | 
			
		||||
        return this.childPath;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull Object getDefaultValue() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public Object getDefaultValue() {
 | 
			
		||||
        return this.value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull String getCommandName() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getCommandName() {
 | 
			
		||||
        return this.commandName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull SettingValueType getValueType() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public SettingValueType getValueType() {
 | 
			
		||||
        return this.valueType;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NotNull String getDescription() {
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public String getDescription() {
 | 
			
		||||
        return this.description;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,9 @@
 | 
			
		||||
package net.knarcraft.blacksmith.manager;
 | 
			
		||||
 | 
			
		||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SalvageMethod;
 | 
			
		||||
import net.knarcraft.blacksmith.config.blacksmith.GlobalBlacksmithSettings;
 | 
			
		||||
import net.knarcraft.blacksmith.config.scrapper.GlobalScrapperSettings;
 | 
			
		||||
import net.knarcraft.blacksmith.util.ItemHelper;
 | 
			
		||||
import net.milkbowl.vault.economy.Economy;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
@@ -54,11 +56,12 @@ public class EconomyManager {
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether the given player cannot pay for salvaging an item
 | 
			
		||||
     *
 | 
			
		||||
     * @param player <p>The player holding an item</p>
 | 
			
		||||
     * @param player        <p>The player holding an item</p>
 | 
			
		||||
     * @param salvageMethod <p>The salvage method to check</p>
 | 
			
		||||
     * @return <p>Whether the player cannot pay for the salvage</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean cannotPayForSalvage(@NotNull Player player) {
 | 
			
		||||
        return economy.getBalance(player) - BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost() < 0;
 | 
			
		||||
    public static boolean cannotPayForSalvage(@NotNull Player player, @NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        return economy.getBalance(player) - getSalvageCost(salvageMethod) < 0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -76,12 +79,27 @@ public class EconomyManager {
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the human-readable cost of salvaging an item
 | 
			
		||||
     *
 | 
			
		||||
     * @param salvageMethod <p>The salvage method to get the cost for</p>
 | 
			
		||||
     * @return <p>The formatted cost</p>
 | 
			
		||||
     */
 | 
			
		||||
    @NotNull
 | 
			
		||||
    public static String formatScrapperCost() {
 | 
			
		||||
        double cost = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost();
 | 
			
		||||
        return economy.format(cost);
 | 
			
		||||
    public static String formatSalvageCost(@NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        return economy.format(getSalvageCost(salvageMethod));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the cost of salvaging using the specified method
 | 
			
		||||
     *
 | 
			
		||||
     * @param salvageMethod <p>The salvage method to get cost for</p>
 | 
			
		||||
     * @return <p>The salvage cost</p>
 | 
			
		||||
     */
 | 
			
		||||
    private static double getSalvageCost(@NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        GlobalScrapperSettings settings = BlacksmithPlugin.getInstance().getGlobalScrapperSettings();
 | 
			
		||||
        return switch (salvageMethod) {
 | 
			
		||||
            case SALVAGE -> settings.getSalvageCost();
 | 
			
		||||
            case NETHERITE -> settings.getNetheriteSalvageCost();
 | 
			
		||||
            case ARMOR_TRIM -> settings.getArmorTrimSalvageCost();
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -101,10 +119,11 @@ public class EconomyManager {
 | 
			
		||||
    /**
 | 
			
		||||
     * Withdraws the salvaging cost from the given player
 | 
			
		||||
     *
 | 
			
		||||
     * @param player <p>The player to withdraw from</p>
 | 
			
		||||
     * @param player        <p>The player to withdraw from</p>
 | 
			
		||||
     * @param salvageMethod <p>The salvage method to withdraw for</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void withdrawScrapper(Player player) {
 | 
			
		||||
        double cost = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getCost();
 | 
			
		||||
    public static void withdrawScrapper(@NotNull Player player, @NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        double cost = getSalvageCost(salvageMethod);
 | 
			
		||||
        if (cost > 0) {
 | 
			
		||||
            economy.withdrawPlayer(player, cost);
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -7,7 +7,7 @@ import net.knarcraft.blacksmith.config.Settings;
 | 
			
		||||
import net.knarcraft.blacksmith.config.TraitSettings;
 | 
			
		||||
import net.knarcraft.blacksmith.formatting.TimeFormatter;
 | 
			
		||||
import net.knarcraft.blacksmith.manager.EconomyManager;
 | 
			
		||||
import net.knarcraft.blacksmith.util.ItemHelper;
 | 
			
		||||
import net.knarcraft.blacksmith.util.SalvageHelper;
 | 
			
		||||
import net.knarcraft.knarlib.formatting.StringFormatter;
 | 
			
		||||
import org.bukkit.entity.LivingEntity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
@@ -181,8 +181,8 @@ public abstract class CustomTrait<K extends Setting> extends Trait {
 | 
			
		||||
 | 
			
		||||
        if (isBlacksmith) {
 | 
			
		||||
            EconomyManager.withdrawBlacksmith(player);
 | 
			
		||||
        } else {
 | 
			
		||||
            EconomyManager.withdrawScrapper(player);
 | 
			
		||||
        } else if (this.session instanceof SalvageSession salvageSession) {
 | 
			
		||||
            EconomyManager.withdrawScrapper(player, salvageSession.salvageMethod);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        session.scheduleAction();
 | 
			
		||||
@@ -198,7 +198,7 @@ public abstract class CustomTrait<K extends Setting> extends Trait {
 | 
			
		||||
        //Remove the item from the player's inventory
 | 
			
		||||
        if (!isBlacksmith) {
 | 
			
		||||
            // For scrappers, just reduce the amounts of items, unless the remaining stack is salvaged
 | 
			
		||||
            int amount = ItemHelper.getRequiredAmountForSalvage(player.getServer(), heldItem);
 | 
			
		||||
            int amount = SalvageHelper.getRequiredAmountForSalvage(player.getServer(), heldItem);
 | 
			
		||||
            if (amount != heldItem.getAmount()) {
 | 
			
		||||
                heldItem.setAmount(heldItem.getAmount() - amount);
 | 
			
		||||
                playerInventory.setItemInMainHand(heldItem);
 | 
			
		||||
 
 | 
			
		||||
@@ -69,14 +69,14 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isSessionInvalid() {
 | 
			
		||||
        // Prevent player from switching items during session
 | 
			
		||||
        ItemStack itemInHand = player.getInventory().getItemInMainHand();
 | 
			
		||||
        ItemStack itemInHand = this.player.getInventory().getItemInMainHand();
 | 
			
		||||
        if (!itemToReforge.equals(itemInHand)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, config.getItemChangedMessage());
 | 
			
		||||
            sendNPCMessage(this.npc, this.player, this.config.getItemChangedMessage());
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        // The player is unable to pay
 | 
			
		||||
        if (EconomyManager.cannotPayForHeldItemReforge(player)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, config.getInsufficientFundsMessage());
 | 
			
		||||
        if (EconomyManager.cannotPayForHeldItemReforge(this.player)) {
 | 
			
		||||
            sendNPCMessage(this.npc, this.player, this.config.getInsufficientFundsMessage());
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -84,9 +84,9 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected int getActionDelay() {
 | 
			
		||||
        if (config.getMaxReforgeDelay() > 0) {
 | 
			
		||||
        if (this.config.getMaxReforgeDelay() > 0) {
 | 
			
		||||
            //Finish the reforging after a random delay between the max and min
 | 
			
		||||
            return new Random().nextInt(config.getMaxReforgeDelay()) + config.getMinReforgeDelay();
 | 
			
		||||
            return new Random().nextInt(this.config.getMaxReforgeDelay()) + this.config.getMinReforgeDelay();
 | 
			
		||||
        } else {
 | 
			
		||||
            //Finish the salvaging as soon as possible
 | 
			
		||||
            return 0;
 | 
			
		||||
@@ -98,41 +98,41 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        sendNPCMessage(this.npc, player, reforgeItem() ? config.getSuccessMessage() : config.getFailMessage());
 | 
			
		||||
        sendNPCMessage(this.npc, this.player, reforgeItem() ? this.config.getSuccessMessage() : this.config.getFailMessage());
 | 
			
		||||
 | 
			
		||||
        //Stop the reforged item from displaying in the blacksmith's hand
 | 
			
		||||
        if (npc.getEntity() instanceof Player) {
 | 
			
		||||
            ((Player) npc.getEntity()).getInventory().setItemInMainHand(null);
 | 
			
		||||
        if (this.npc.getEntity() instanceof Player) {
 | 
			
		||||
            ((Player) this.npc.getEntity()).getInventory().setItemInMainHand(null);
 | 
			
		||||
        } else {
 | 
			
		||||
            Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null);
 | 
			
		||||
            Objects.requireNonNull(((LivingEntity) this.npc.getEntity()).getEquipment()).setItemInMainHand(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Give the item back to the player
 | 
			
		||||
        giveReforgedItem();
 | 
			
		||||
 | 
			
		||||
        //Mark this blacksmith as available
 | 
			
		||||
        blacksmithTrait.unsetSession();
 | 
			
		||||
        this.blacksmithTrait.unsetSession();
 | 
			
		||||
 | 
			
		||||
        // Start cool-down
 | 
			
		||||
        Calendar wait = Calendar.getInstance();
 | 
			
		||||
        wait.add(Calendar.SECOND, config.getReforgeCoolDown());
 | 
			
		||||
        blacksmithTrait.addCoolDown(player.getUniqueId(), wait);
 | 
			
		||||
        wait.add(Calendar.SECOND, this.config.getReforgeCoolDown());
 | 
			
		||||
        this.blacksmithTrait.addCoolDown(this.player.getUniqueId(), wait);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gives the reforged item back to the player
 | 
			
		||||
     */
 | 
			
		||||
    private void giveReforgedItem() {
 | 
			
		||||
        if (config.getMaxReforgeDelay() > 0) {
 | 
			
		||||
        if (this.config.getMaxReforgeDelay() > 0) {
 | 
			
		||||
            //If the player isn't online, or the player cannot fit the item, drop the item to prevent it from disappearing
 | 
			
		||||
            if (config.getDropItem() || !player.isOnline() || player.getInventory().firstEmpty() == -1) {
 | 
			
		||||
                player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), itemToReforge);
 | 
			
		||||
            if (this.config.getDropItem() || !this.player.isOnline() || this.player.getInventory().firstEmpty() == -1) {
 | 
			
		||||
                this.player.getWorld().dropItemNaturally(this.npc.getEntity().getLocation(), this.itemToReforge);
 | 
			
		||||
            } else {
 | 
			
		||||
                player.getInventory().addItem(itemToReforge);
 | 
			
		||||
                this.player.getInventory().addItem(this.itemToReforge);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            //It can be assumed as this happens instantly, that the player still has the item's previous slot selected
 | 
			
		||||
            player.getInventory().setItemInMainHand(itemToReforge);
 | 
			
		||||
            this.player.getInventory().setItemInMainHand(this.itemToReforge);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -142,7 +142,7 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
     * @return <p>Whether the reforge was successful. False if the blacksmith failed to fully repair the item.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean reforgeItem() {
 | 
			
		||||
        if (random.nextInt(100) < config.getFailChance()) {
 | 
			
		||||
        if (random.nextInt(100) < this.config.getFailChance()) {
 | 
			
		||||
            failReforge();
 | 
			
		||||
            return false;
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -156,18 +156,18 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
     */
 | 
			
		||||
    private void succeedReforge() {
 | 
			
		||||
        // Remove any damage done to the item
 | 
			
		||||
        updateDamage(itemToReforge, 0);
 | 
			
		||||
        updateDamage(this.itemToReforge, 0);
 | 
			
		||||
 | 
			
		||||
        //Replace damaged anvils with a normal anvil
 | 
			
		||||
        if (ItemHelper.isAnvil(itemToReforge.getType(), true)) {
 | 
			
		||||
            itemToReforge.setType(Material.ANVIL);
 | 
			
		||||
        if (ItemHelper.isAnvil(this.itemToReforge.getType(), true)) {
 | 
			
		||||
            this.itemToReforge.setType(Material.ANVIL);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //See if a random roll (0-99) is less than extraEnchantmentChance, and add a random enchantment
 | 
			
		||||
        int roll = random.nextInt(100);
 | 
			
		||||
        if (roll < config.getExtraEnchantmentChance() &&
 | 
			
		||||
                itemToReforge.getEnchantments().keySet().size() < config.getMaxEnchantments() &&
 | 
			
		||||
                !ItemHelper.isAnvil(itemToReforge.getType(), false)) {
 | 
			
		||||
        if (roll < this.config.getExtraEnchantmentChance() &&
 | 
			
		||||
                this.itemToReforge.getEnchantments().keySet().size() < this.config.getMaxEnchantments() &&
 | 
			
		||||
                !ItemHelper.isAnvil(this.itemToReforge.getType(), false)) {
 | 
			
		||||
            addRandomEnchantment();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -180,12 +180,12 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
        List<Enchantment> usableEnchantments = new ArrayList<>();
 | 
			
		||||
        for (String enchantmentName : enchantments) {
 | 
			
		||||
            Enchantment enchantment = InputParsingHelper.matchEnchantment(enchantmentName);
 | 
			
		||||
            if (enchantment != null && enchantment.canEnchantItem(itemToReforge)) {
 | 
			
		||||
            if (enchantment != null && enchantment.canEnchantItem(this.itemToReforge)) {
 | 
			
		||||
                usableEnchantments.add(enchantment);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        //Remove any enchantments in the block list
 | 
			
		||||
        usableEnchantments.removeAll(blacksmithTrait.getSettings().getEnchantmentBlockList());
 | 
			
		||||
        usableEnchantments.removeAll(this.blacksmithTrait.getSettings().getEnchantmentBlockList());
 | 
			
		||||
 | 
			
		||||
        //In case all usable enchantments have been blocked, abort
 | 
			
		||||
        if (usableEnchantments.isEmpty()) {
 | 
			
		||||
@@ -198,10 +198,10 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
            int randomBound = randomEnchantment.getMaxLevel() + 1;
 | 
			
		||||
            //A workaround for the random method's bound sometimes being negative
 | 
			
		||||
            if (randomBound >= 0) {
 | 
			
		||||
                int existingLevel = itemToReforge.getEnchantmentLevel(randomEnchantment);
 | 
			
		||||
                int existingLevel = this.itemToReforge.getEnchantmentLevel(randomEnchantment);
 | 
			
		||||
                /* Add a random enchantment whose level is no lower than the start level, and no lower than the
 | 
			
		||||
                existing level (to prevent making the item worse) */
 | 
			
		||||
                itemToReforge.addEnchantment(randomEnchantment, Math.max(Math.max(random.nextInt(randomBound),
 | 
			
		||||
                this.itemToReforge.addEnchantment(randomEnchantment, Math.max(Math.max(random.nextInt(randomBound),
 | 
			
		||||
                        randomEnchantment.getStartLevel()), existingLevel));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -211,20 +211,20 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
     * The method to run when a blacksmith fails re-forging an item
 | 
			
		||||
     */
 | 
			
		||||
    private void failReforge() {
 | 
			
		||||
        if (config.getFailRemovesEnchantments()) {
 | 
			
		||||
        if (this.config.getFailRemovesEnchantments()) {
 | 
			
		||||
            removeOrDowngradeEnchantments();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Damage the item
 | 
			
		||||
        short currentItemDurability = ItemHelper.getDurability(itemToReforge);
 | 
			
		||||
        short currentItemDurability = ItemHelper.getDurability(this.itemToReforge);
 | 
			
		||||
        short newDurability = (short) (currentItemDurability + (currentItemDurability * random.nextInt(8)));
 | 
			
		||||
        short maxDurability = itemToReforge.getType().getMaxDurability();
 | 
			
		||||
        short maxDurability = this.itemToReforge.getType().getMaxDurability();
 | 
			
		||||
        if (newDurability <= 0) {
 | 
			
		||||
            newDurability = (short) (maxDurability / 3);
 | 
			
		||||
        } else if (currentItemDurability + newDurability > maxDurability) {
 | 
			
		||||
            newDurability = (short) (maxDurability - random.nextInt(maxDurability - 25));
 | 
			
		||||
        }
 | 
			
		||||
        updateDamage(itemToReforge, maxDurability - newDurability);
 | 
			
		||||
        updateDamage(this.itemToReforge, maxDurability - newDurability);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -232,13 +232,13 @@ public class ReforgeSession extends Session implements Runnable {
 | 
			
		||||
     */
 | 
			
		||||
    private void removeOrDowngradeEnchantments() {
 | 
			
		||||
        //Remove or downgrade existing enchantments
 | 
			
		||||
        for (Enchantment enchantment : itemToReforge.getEnchantments().keySet()) {
 | 
			
		||||
        for (Enchantment enchantment : this.itemToReforge.getEnchantments().keySet()) {
 | 
			
		||||
            //Completely remove the enchantment, downgrade it, or keep it if lucky and already level 1
 | 
			
		||||
            if (random.nextBoolean()) {
 | 
			
		||||
                itemToReforge.removeEnchantment(enchantment);
 | 
			
		||||
            } else if (itemToReforge.getEnchantmentLevel(enchantment) > 1) {
 | 
			
		||||
                itemToReforge.removeEnchantment(enchantment);
 | 
			
		||||
                itemToReforge.addEnchantment(enchantment, 1);
 | 
			
		||||
                this.itemToReforge.removeEnchantment(enchantment);
 | 
			
		||||
            } else if (this.itemToReforge.getEnchantmentLevel(enchantment) > 1) {
 | 
			
		||||
                this.itemToReforge.removeEnchantment(enchantment);
 | 
			
		||||
                this.itemToReforge.addEnchantment(enchantment, 1);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,7 @@
 | 
			
		||||
package net.knarcraft.blacksmith.trait;
 | 
			
		||||
 | 
			
		||||
import net.citizensnpcs.api.npc.NPC;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SalvageMethod;
 | 
			
		||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
 | 
			
		||||
import net.knarcraft.blacksmith.manager.EconomyManager;
 | 
			
		||||
import net.knarcraft.blacksmith.util.ItemHelper;
 | 
			
		||||
@@ -30,6 +31,7 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
    private final ScrapperNPCSettings config;
 | 
			
		||||
    private final List<ItemStack> salvage;
 | 
			
		||||
    private final int enchantmentLevels;
 | 
			
		||||
    protected final SalvageMethod salvageMethod;
 | 
			
		||||
    private static final Random random = new Random();
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -39,9 +41,11 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
     * @param player        <p>The player initiating the session</p>
 | 
			
		||||
     * @param npc           <p>The scrapper NPC involved in the session</p>
 | 
			
		||||
     * @param config        <p>The config to use for the session</p>
 | 
			
		||||
     * @param salvageMethod <p>The salvage method performed in this session</p>
 | 
			
		||||
     */
 | 
			
		||||
    SalvageSession(@NotNull ScrapperTrait scrapperTrait, @NotNull Player player, @NotNull NPC npc,
 | 
			
		||||
                   @NotNull ScrapperNPCSettings config, @NotNull List<ItemStack> salvage) {
 | 
			
		||||
                   @NotNull ScrapperNPCSettings config, @NotNull List<ItemStack> salvage,
 | 
			
		||||
                   @NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        super(player);
 | 
			
		||||
        this.scrapperTrait = scrapperTrait;
 | 
			
		||||
        this.npc = npc;
 | 
			
		||||
@@ -49,19 +53,20 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
        this.config = config;
 | 
			
		||||
        this.salvage = salvage;
 | 
			
		||||
        this.enchantmentLevels = SalvageHelper.getTotalEnchantmentLevels(this.itemToSalvage);
 | 
			
		||||
        this.salvageMethod = salvageMethod;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean isSessionInvalid() {
 | 
			
		||||
        // Prevent player from switching items during session
 | 
			
		||||
        ItemStack itemInHand = player.getInventory().getItemInMainHand();
 | 
			
		||||
        ItemStack itemInHand = this.player.getInventory().getItemInMainHand();
 | 
			
		||||
        if (!itemToSalvage.equals(itemInHand)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, config.getItemChangedMessage());
 | 
			
		||||
            sendNPCMessage(this.npc, this.player, this.config.getItemChangedMessage());
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (EconomyManager.cannotPayForSalvage(player)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, config.getInsufficientFundsMessage());
 | 
			
		||||
        if (EconomyManager.cannotPayForSalvage(this.player, this.salvageMethod)) {
 | 
			
		||||
            sendNPCMessage(this.npc, this.player, this.config.getInsufficientFundsMessage());
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
@@ -69,9 +74,9 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    protected int getActionDelay() {
 | 
			
		||||
        if (config.getMaxSalvageDelay() > 0) {
 | 
			
		||||
        if (this.config.getMaxSalvageDelay() > 0) {
 | 
			
		||||
            //Finish the salvaging after a random delay between the max and min
 | 
			
		||||
            return new Random().nextInt(config.getMaxSalvageDelay()) + config.getMinSalvageDelay();
 | 
			
		||||
            return new Random().nextInt(this.config.getMaxSalvageDelay()) + this.config.getMinSalvageDelay();
 | 
			
		||||
        } else {
 | 
			
		||||
            //Finish the salvaging as soon as possible
 | 
			
		||||
            return 0;
 | 
			
		||||
@@ -83,22 +88,22 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void run() {
 | 
			
		||||
        sendNPCMessage(this.npc, player, salvageItem() ? config.getSuccessMessage() : config.getFailMessage());
 | 
			
		||||
        sendNPCMessage(this.npc, this.player, salvageItem() ? this.config.getSuccessMessage() : this.config.getFailMessage());
 | 
			
		||||
 | 
			
		||||
        //Stop the reforged item from displaying in the scrapper's hand
 | 
			
		||||
        if (npc.getEntity() instanceof Player) {
 | 
			
		||||
            ((Player) npc.getEntity()).getInventory().setItemInMainHand(null);
 | 
			
		||||
        if (this.npc.getEntity() instanceof Player) {
 | 
			
		||||
            ((Player) this.npc.getEntity()).getInventory().setItemInMainHand(null);
 | 
			
		||||
        } else {
 | 
			
		||||
            Objects.requireNonNull(((LivingEntity) npc.getEntity()).getEquipment()).setItemInMainHand(null);
 | 
			
		||||
            Objects.requireNonNull(((LivingEntity) this.npc.getEntity()).getEquipment()).setItemInMainHand(null);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Mark this scrapper as available
 | 
			
		||||
        scrapperTrait.unsetSession();
 | 
			
		||||
        this.scrapperTrait.unsetSession();
 | 
			
		||||
 | 
			
		||||
        // Start cool-down
 | 
			
		||||
        Calendar wait = Calendar.getInstance();
 | 
			
		||||
        wait.add(Calendar.SECOND, config.getSalvageCoolDown());
 | 
			
		||||
        scrapperTrait.addCoolDown(player.getUniqueId(), wait);
 | 
			
		||||
        wait.add(Calendar.SECOND, this.config.getSalvageCoolDown());
 | 
			
		||||
        this.scrapperTrait.addCoolDown(this.player.getUniqueId(), wait);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -107,7 +112,7 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
     * @return <p>True if the salvage was successful. False otherwise.</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean salvageItem() {
 | 
			
		||||
        if (random.nextInt(100) < config.getFailChance()) {
 | 
			
		||||
        if (random.nextInt(100) < this.config.getFailChance()) {
 | 
			
		||||
            failSalvage();
 | 
			
		||||
            return false;
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -121,19 +126,19 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
     * The method to run when a crapper fails salvaging an item
 | 
			
		||||
     */
 | 
			
		||||
    private void failSalvage() {
 | 
			
		||||
        if (itemToSalvage.getItemMeta() instanceof Damageable) {
 | 
			
		||||
        if (this.itemToSalvage.getItemMeta() instanceof Damageable) {
 | 
			
		||||
            //Damage the item
 | 
			
		||||
            short currentItemDurability = ItemHelper.getDurability(itemToSalvage);
 | 
			
		||||
            short currentItemDurability = ItemHelper.getDurability(this.itemToSalvage);
 | 
			
		||||
            short newDurability = (short) (currentItemDurability + (currentItemDurability * random.nextInt(8)));
 | 
			
		||||
            short maxDurability = itemToSalvage.getType().getMaxDurability();
 | 
			
		||||
            short maxDurability = this.itemToSalvage.getType().getMaxDurability();
 | 
			
		||||
            if (newDurability <= 0) {
 | 
			
		||||
                newDurability = (short) (maxDurability / 3);
 | 
			
		||||
            } else if (currentItemDurability + newDurability > maxDurability) {
 | 
			
		||||
                newDurability = (short) (maxDurability - random.nextInt(maxDurability - 25));
 | 
			
		||||
            }
 | 
			
		||||
            updateDamage(itemToSalvage, maxDurability - newDurability);
 | 
			
		||||
            updateDamage(this.itemToSalvage, maxDurability - newDurability);
 | 
			
		||||
        } else {
 | 
			
		||||
            itemToSalvage.setAmount(Math.max(itemToSalvage.getAmount() - 1, 1));
 | 
			
		||||
            this.itemToSalvage.setAmount(Math.max(this.itemToSalvage.getAmount() - 1, 1));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -143,20 +148,20 @@ public class SalvageSession extends Session implements Runnable {
 | 
			
		||||
    private void giveSalvage() {
 | 
			
		||||
        // TODO: Find a better calculation than 1 enchantment level = 1 exp level
 | 
			
		||||
        // Gives the player back some of the EXP used on an item
 | 
			
		||||
        player.giveExpLevels(enchantmentLevels);
 | 
			
		||||
        if (config.getDropItem() || !player.isOnline() || player.getInventory().firstEmpty() == -1) {
 | 
			
		||||
        this.player.giveExpLevels(this.enchantmentLevels);
 | 
			
		||||
        if (this.config.getDropItem() || !this.player.isOnline() || this.player.getInventory().firstEmpty() == -1) {
 | 
			
		||||
            // If the player isn't online, or the player cannot fit the item, drop the item to prevent it from
 | 
			
		||||
            // disappearing, even if drop item is disabled.
 | 
			
		||||
            for (ItemStack item : salvage) {
 | 
			
		||||
                player.getWorld().dropItemNaturally(npc.getEntity().getLocation(), item);
 | 
			
		||||
            for (ItemStack item : this.salvage) {
 | 
			
		||||
                this.player.getWorld().dropItemNaturally(this.npc.getEntity().getLocation(), item);
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            for (ItemStack item : salvage) {
 | 
			
		||||
                if (ItemHelper.canFitItem(player.getInventory(), item)) {
 | 
			
		||||
                    player.getInventory().addItem(item);
 | 
			
		||||
            for (ItemStack item : this.salvage) {
 | 
			
		||||
                if (ItemHelper.canFitItem(this.player.getInventory(), item)) {
 | 
			
		||||
                    this.player.getInventory().addItem(item);
 | 
			
		||||
                } else {
 | 
			
		||||
                    // If the player cannot fit all the salvage, drop it on the ground
 | 
			
		||||
                    player.getWorld().dropItemNaturally(player.getLocation(), item);
 | 
			
		||||
                    this.player.getWorld().dropItemNaturally(this.player.getLocation(), item);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -2,15 +2,18 @@ package net.knarcraft.blacksmith.trait;
 | 
			
		||||
 | 
			
		||||
import net.citizensnpcs.api.util.DataKey;
 | 
			
		||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SalvageMethod;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SmithPreset;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SmithPresetFilter;
 | 
			
		||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperNPCSettings;
 | 
			
		||||
import net.knarcraft.blacksmith.config.scrapper.ScrapperSetting;
 | 
			
		||||
import net.knarcraft.blacksmith.manager.EconomyManager;
 | 
			
		||||
import net.knarcraft.blacksmith.util.ItemHelper;
 | 
			
		||||
import net.knarcraft.blacksmith.util.SalvageHelper;
 | 
			
		||||
import net.knarcraft.knarlib.formatting.StringFormatter;
 | 
			
		||||
import net.knarcraft.knarlib.formatting.StringReplacer;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Server;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.meta.ArmorMeta;
 | 
			
		||||
@@ -82,7 +85,7 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
 | 
			
		||||
        boolean extended = getSettings().extendedSalvageEnabled();
 | 
			
		||||
 | 
			
		||||
        // Check if the item can be salvaged
 | 
			
		||||
        if (!canBeSalvaged(player.getServer(), itemInHand, salvageAbleItems, extended)) {
 | 
			
		||||
        if (!canBeSalvaged(itemInHand, salvageAbleItems, extended)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
 | 
			
		||||
                    "{title}", getSettings().getScrapperTitle()));
 | 
			
		||||
            return;
 | 
			
		||||
@@ -91,18 +94,35 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
 | 
			
		||||
        List<ItemStack> salvage = null;
 | 
			
		||||
 | 
			
		||||
        // Deal with armor trim salvage
 | 
			
		||||
        boolean salvagingArmorTrim = false;
 | 
			
		||||
        SalvageMethod salvageMethod = SalvageMethod.SALVAGE;
 | 
			
		||||
        if (itemInHand.getItemMeta() instanceof ArmorMeta armorMeta && armorMeta.hasTrim()) {
 | 
			
		||||
            if (!getSettings().salvageArmorTrims()) {
 | 
			
		||||
                sendNPCMessage(this.npc, player, getSettings().getCannotSalvageArmorTrimMessage());
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            salvage = SalvageHelper.getTrimSalvage(itemInHand, armorMeta);
 | 
			
		||||
            salvage = SalvageHelper.getArmorTrimSalvage(itemInHand, armorMeta);
 | 
			
		||||
            if (salvage == null) {
 | 
			
		||||
                sendNPCMessage(this.npc, player, getSettings().getArmorTrimSalvageNotFoundMessage());
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            salvagingArmorTrim = true;
 | 
			
		||||
            salvageMethod = SalvageMethod.ARMOR_TRIM;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Remove the netherite ingot from the item
 | 
			
		||||
        if (salvage == null && SmithPreset.BLACKSMITH.getFilteredMaterials(SmithPresetFilter.NETHERITE).contains(itemInHand.getType())) {
 | 
			
		||||
            if (!getSettings().salvageNetherite()) {
 | 
			
		||||
                sendNPCMessage(this.npc, player, getSettings().getCannotSalvageNetheriteMessage());
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            salvage = SalvageHelper.getNetheriteSalvage(itemInHand);
 | 
			
		||||
            salvageMethod = SalvageMethod.NETHERITE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // As there is no recipe for netherite items, the check needs to be after the netherite salvage check
 | 
			
		||||
        if (salvageMethod == SalvageMethod.SALVAGE && !SalvageHelper.isSalvageable(player.getServer(), itemInHand)) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getInvalidItemMessage(),
 | 
			
		||||
                    "{title}", getSettings().getScrapperTitle()));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        // Check if the item is enchanted, and whether this blacksmith can salvage it
 | 
			
		||||
@@ -121,26 +141,53 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //Start a new scrapper session for the player
 | 
			
		||||
        startSession(player, salvage, salvageMethod);
 | 
			
		||||
        // Print the cost to the player
 | 
			
		||||
        printCostMessage(player, itemInHand, EconomyManager.formatSalvageCost(salvageMethod), salvageMethod);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Prints a message to the given player, explaining the cost of salvaging the held item
 | 
			
		||||
     *
 | 
			
		||||
     * @param player        <p>The player that interacted with the scrapper</p>
 | 
			
		||||
     * @param itemInHand    <p>The item the player wants to salvage</p>
 | 
			
		||||
     * @param cost          <p>The cost of salvaging the item</p>
 | 
			
		||||
     * @param salvageMethod <p>The type of salvage performed</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void printCostMessage(@NotNull Player player, @NotNull ItemStack itemInHand, @NotNull String cost,
 | 
			
		||||
                                  @NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        StringReplacer replacer = new StringReplacer();
 | 
			
		||||
        replacer.add("{cost}", cost);
 | 
			
		||||
        replacer.add("{item}", itemInHand.getType().name().toLowerCase().replace('_', ' '));
 | 
			
		||||
        if (salvageMethod == SalvageMethod.ARMOR_TRIM) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, replacer.replace(getSettings().getArmorTrimCostMessage()));
 | 
			
		||||
        } else if (salvageMethod == SalvageMethod.SALVAGE) {
 | 
			
		||||
            String expectedYield;
 | 
			
		||||
            if (ItemHelper.getDamage(itemInHand) <= 0) {
 | 
			
		||||
                expectedYield = getSettings().getFullSalvageMessage();
 | 
			
		||||
            } else {
 | 
			
		||||
                expectedYield = getSettings().getPartialSalvageMessage();
 | 
			
		||||
            }
 | 
			
		||||
            replacer.add("{yield}", expectedYield);
 | 
			
		||||
            sendNPCMessage(this.npc, player, replacer.replace(getSettings().getCostMessage()));
 | 
			
		||||
        } else if (salvageMethod == SalvageMethod.NETHERITE) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, replacer.replace(getSettings().getNetheriteCostMessage()));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Starts a new scrapper session
 | 
			
		||||
     *
 | 
			
		||||
     * @param player        <p>The player to start the session for</p>
 | 
			
		||||
     * @param salvage       <p>The salvage to return to the player</p>
 | 
			
		||||
     * @param salvageMethod <p>The type of salvage performed</p>
 | 
			
		||||
     */
 | 
			
		||||
    private void startSession(@NotNull Player player, @NotNull List<ItemStack> salvage,
 | 
			
		||||
                              @NotNull SalvageMethod salvageMethod) {
 | 
			
		||||
        //Start a new scrapper session for the player
 | 
			
		||||
        currentSessionStartTime = System.currentTimeMillis();
 | 
			
		||||
        session = new SalvageSession(this, player, npc, getSettings(), salvage);
 | 
			
		||||
        //Tell the player the cost of repairing the item
 | 
			
		||||
        String cost = EconomyManager.formatScrapperCost();
 | 
			
		||||
 | 
			
		||||
        String expectedYield;
 | 
			
		||||
        if (ItemHelper.getDamage(itemInHand) <= 0) {
 | 
			
		||||
            expectedYield = getSettings().getFullSalvageMessage();
 | 
			
		||||
        } else {
 | 
			
		||||
            expectedYield = getSettings().getPartialSalvageMessage();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (salvagingArmorTrim) {
 | 
			
		||||
            sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(getSettings().getArmorTrimCostMessage(),
 | 
			
		||||
                    "{cost}", cost));
 | 
			
		||||
        } else {
 | 
			
		||||
            sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(getSettings().getCostMessage(),
 | 
			
		||||
                    List.of("{cost}", "{yield}"), List.of(cost, expectedYield)));
 | 
			
		||||
        }
 | 
			
		||||
        session = new SalvageSession(this, player, npc, getSettings(), salvage, salvageMethod);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -151,17 +198,14 @@ public class ScrapperTrait extends CustomTrait<ScrapperSetting> {
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether this scrapper can salvage the given item
 | 
			
		||||
     *
 | 
			
		||||
     * @param server           <p>The server to get recipes from</p>
 | 
			
		||||
     * @param item             <p>The item to check</p>
 | 
			
		||||
     * @param salvageAbleItems <p>The items this scrapper can salvage</p>
 | 
			
		||||
     * @param extended         <p>Whether extended salvage is enabled</p>
 | 
			
		||||
     * @return <p>True if the item can be theoretically salvaged</p>
 | 
			
		||||
     */
 | 
			
		||||
    private boolean canBeSalvaged(@NotNull Server server, @NotNull ItemStack item,
 | 
			
		||||
                                  @NotNull List<Material> salvageAbleItems, boolean extended) {
 | 
			
		||||
        return (extended || ItemHelper.isRepairable(item)) && ItemHelper.isSalvageable(server, item) &&
 | 
			
		||||
                (salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType())) &&
 | 
			
		||||
                SalvageHelper.hasRecipe(item);
 | 
			
		||||
    private boolean canBeSalvaged(@NotNull ItemStack item, @NotNull List<Material> salvageAbleItems, boolean extended) {
 | 
			
		||||
        return (extended || ItemHelper.isRepairable(item)) &&
 | 
			
		||||
                (salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType()));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 
 | 
			
		||||
@@ -110,6 +110,7 @@ public final class ConfigHelper {
 | 
			
		||||
    /**
 | 
			
		||||
     * Changes all configuration values from the old name to the new name
 | 
			
		||||
     *
 | 
			
		||||
     * @param dataFolderPath       <p>The path to this plugin's data</p>
 | 
			
		||||
     * @param currentConfiguration <p>The current config to back up</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static void migrateConfig(@NotNull String dataFolderPath, @NotNull FileConfiguration currentConfiguration) {
 | 
			
		||||
 
 | 
			
		||||
@@ -3,11 +3,8 @@ package net.knarcraft.blacksmith.util;
 | 
			
		||||
import net.knarcraft.blacksmith.BlacksmithPlugin;
 | 
			
		||||
import net.knarcraft.blacksmith.config.SmithPreset;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Server;
 | 
			
		||||
import org.bukkit.inventory.CraftingRecipe;
 | 
			
		||||
import org.bukkit.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.bukkit.inventory.Recipe;
 | 
			
		||||
import org.bukkit.inventory.meta.Damageable;
 | 
			
		||||
import org.bukkit.inventory.meta.ItemMeta;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
@@ -168,40 +165,6 @@ public final class ItemHelper {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks whether the given item can be salvaged, assuming no restrictions apply
 | 
			
		||||
     *
 | 
			
		||||
     * @param server <p>The server to get recipes from</p>
 | 
			
		||||
     * @param item   <p>The item to check</p>
 | 
			
		||||
     * @return <p>True if the item can be salvaged</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean isSalvageable(@NotNull Server server, @NotNull ItemStack item) {
 | 
			
		||||
        for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
 | 
			
		||||
            // Only crafting recipes are allowed.
 | 
			
		||||
            if ((recipe instanceof CraftingRecipe) && item.getAmount() >= recipe.getResult().getAmount()) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the amount of an item that's required to salvage that item
 | 
			
		||||
     *
 | 
			
		||||
     * @param server <p>The server to get recipes from</p>
 | 
			
		||||
     * @param item   <p>The item to check</p>
 | 
			
		||||
     * @return <p>The number of items required for salvage, or -1 if the recipe was not found</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static int getRequiredAmountForSalvage(@NotNull Server server, @NotNull ItemStack item) {
 | 
			
		||||
        for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
 | 
			
		||||
            // Only crafting recipes are allowed.
 | 
			
		||||
            if (recipe instanceof CraftingRecipe) {
 | 
			
		||||
                return recipe.getResult().getAmount();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return -1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets all materials matching the given material wildcard
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,5 @@
 | 
			
		||||
package net.knarcraft.blacksmith.util;
 | 
			
		||||
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Server;
 | 
			
		||||
import org.bukkit.enchantments.Enchantment;
 | 
			
		||||
@@ -43,6 +42,29 @@ public final class SalvageHelper {
 | 
			
		||||
        trimMaterialToMaterial.put(TrimMaterial.REDSTONE, Material.REDSTONE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets salvage for a given netherite item
 | 
			
		||||
     *
 | 
			
		||||
     * @param item <p>The netherite armor/tool to salvage</p>
 | 
			
		||||
     * @return <p></p>
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static List<ItemStack> getNetheriteSalvage(@NotNull ItemStack item) {
 | 
			
		||||
        Material newMaterial = Material.matchMaterial(item.getType().name().replace("NETHERITE", "DIAMOND"));
 | 
			
		||||
        if (newMaterial == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
        }
 | 
			
		||||
        ItemStack clone = item.clone();
 | 
			
		||||
        clone.setType(newMaterial);
 | 
			
		||||
 | 
			
		||||
        List<ItemStack> salvage = new ArrayList<>();
 | 
			
		||||
        salvage.add(clone);
 | 
			
		||||
        salvage.add(new ItemStack(Material.NETHERITE_INGOT, 1));
 | 
			
		||||
        salvage.add(new ItemStack(Material.NETHERITE_UPGRADE_SMITHING_TEMPLATE, 1));
 | 
			
		||||
 | 
			
		||||
        return salvage;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets salvage for the given armor trim
 | 
			
		||||
     *
 | 
			
		||||
@@ -51,7 +73,7 @@ public final class SalvageHelper {
 | 
			
		||||
     * @return <p>The salvage, or null if salvage could not be calculated</p>
 | 
			
		||||
     */
 | 
			
		||||
    @Nullable
 | 
			
		||||
    public static List<ItemStack> getTrimSalvage(@NotNull ItemStack item, @NotNull ArmorMeta armorMeta) {
 | 
			
		||||
    public static List<ItemStack> getArmorTrimSalvage(@NotNull ItemStack item, @NotNull ArmorMeta armorMeta) {
 | 
			
		||||
        ArmorTrim armorTrim = armorMeta.getTrim();
 | 
			
		||||
        if (armorTrim == null) {
 | 
			
		||||
            return null;
 | 
			
		||||
@@ -82,22 +104,41 @@ public final class SalvageHelper {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets whether the given item has a valid crafting recipe
 | 
			
		||||
     * Checks whether the given item can be salvaged, assuming no restrictions apply
 | 
			
		||||
     *
 | 
			
		||||
     * @param item <p>The item to check</p>
 | 
			
		||||
     * @return <p>True if the item has a valid crafting recipe</p>
 | 
			
		||||
     * @param server <p>The server to get recipes from</p>
 | 
			
		||||
     * @param item   <p>The item to check</p>
 | 
			
		||||
     * @return <p>True if the item can be salvaged</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static boolean hasRecipe(@NotNull ItemStack item) {
 | 
			
		||||
        List<Recipe> recipes = Bukkit.getRecipesFor(new ItemStack(item.getType(), item.getAmount()));
 | 
			
		||||
    public static boolean isSalvageable(@NotNull Server server, @NotNull ItemStack item) {
 | 
			
		||||
        List<Recipe> recipes = server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()));
 | 
			
		||||
        for (Recipe recipe : recipes) {
 | 
			
		||||
            if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
 | 
			
		||||
            // Only crafting recipes are allowed.
 | 
			
		||||
            if ((recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) &&
 | 
			
		||||
                    item.getAmount() >= recipe.getResult().getAmount()) {
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the amount of an item that's required to salvage that item
 | 
			
		||||
     *
 | 
			
		||||
     * @param server <p>The server to get recipes from</p>
 | 
			
		||||
     * @param item   <p>The item to check</p>
 | 
			
		||||
     * @return <p>The number of items required for salvage, or -1 if the recipe was not found</p>
 | 
			
		||||
     */
 | 
			
		||||
    public static int getRequiredAmountForSalvage(@NotNull Server server, @NotNull ItemStack item) {
 | 
			
		||||
        for (Recipe recipe : server.getRecipesFor(new ItemStack(item.getType(), item.getAmount()))) {
 | 
			
		||||
            // Only crafting recipes are allowed.
 | 
			
		||||
            if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) {
 | 
			
		||||
                return recipe.getResult().getAmount();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return 1;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Gets the sum of all enchantment levels for the given item
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -116,8 +116,8 @@ blacksmith:
 | 
			
		||||
scrapper:
 | 
			
		||||
  # The settings which apply to all Scrapper NPCs. These can also be changed using the /scrapperConfig command
 | 
			
		||||
  global:
 | 
			
		||||
    # Exact time displays the exact number of seconds and minutes remaining as part of the scrapping cool-down and
 | 
			
		||||
    #  scrapping delay messages, instead of just vaguely hinting at the remaining time.
 | 
			
		||||
    # Exact time displays the exact number of seconds and minutes remaining as part of the salvaging cool-down and
 | 
			
		||||
    #  salvaging delay messages, instead of just vaguely hinting at the remaining time.
 | 
			
		||||
    showExactTime: false
 | 
			
		||||
    
 | 
			
		||||
    # Whether enchanted salvaged items should return some amount of exp upon salvage
 | 
			
		||||
@@ -130,14 +130,20 @@ scrapper:
 | 
			
		||||
    trashSalvage:
 | 
			
		||||
      - "*_SHOVEL;*_PICKAXE;*_AXE;*_HOE;*_SWORD;SHIELD;*_BOW:STICK"
 | 
			
		||||
    
 | 
			
		||||
    # The cost of using the scrapper
 | 
			
		||||
    basePrice: 0
 | 
			
		||||
    # The cost of using a scrapper to salvage an item
 | 
			
		||||
    salvagePrice: 0
 | 
			
		||||
    
 | 
			
		||||
    # The cost of using the scrapper to remove armor trim
 | 
			
		||||
    armorTrimSalvagePrice: 5
 | 
			
		||||
    
 | 
			
		||||
    # The cost of using the scrapper to remove netherite from an item
 | 
			
		||||
    netheriteSalvagePrice: 15
 | 
			
		||||
  
 | 
			
		||||
  # The settings which are set to any new scrapper NPC. To change any of these settings for an existing NPC, you must 
 | 
			
		||||
  # change the Citizens NPC file, or use the /scrapper command
 | 
			
		||||
  defaults:
 | 
			
		||||
    
 | 
			
		||||
    # Whether the item will drop materials resulting from scrapping on the ground, instead of putting them into the user's inventory
 | 
			
		||||
    # Whether the item will drop materials resulting from salvaging on the ground, instead of putting them into the user's inventory
 | 
			
		||||
    dropItem: true
 | 
			
		||||
    
 | 
			
		||||
    # The chance to fail a salvage, thus destroying the item (0-100)
 | 
			
		||||
@@ -170,6 +176,9 @@ scrapper:
 | 
			
		||||
    # Whether to enable salvaging of armor trims
 | 
			
		||||
    salvageArmorTrims: true
 | 
			
		||||
    
 | 
			
		||||
    # Whether to enable salvaging of netherite items
 | 
			
		||||
    salvageNetherite: true
 | 
			
		||||
    
 | 
			
		||||
    # Default values for messages used by NPCs
 | 
			
		||||
    messages:
 | 
			
		||||
      # The message to display when another player is using the scrapper
 | 
			
		||||
@@ -203,10 +212,13 @@ scrapper:
 | 
			
		||||
      insufficientFundsMessage: "&cYou don't have enough money to salvage an item!"
 | 
			
		||||
      
 | 
			
		||||
      # The message to display when explaining the shown item's salvage cost
 | 
			
		||||
      costMessage: "&eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage!"
 | 
			
		||||
      costMessage: "&eIt will cost &a{cost}&e to salvage that &a{item}&e! {yield} &eClick again to salvage!"
 | 
			
		||||
      
 | 
			
		||||
      # The message to display when explaining the shown item's armor trim's salvage cost
 | 
			
		||||
      costMessageArmorTrim: "&eIt will cost &a{cost}&e to salvage that armor trim!"
 | 
			
		||||
      costMessageArmorTrim: "&eIt will cost &a{cost}&e to salvage that &a{item}&e's armor trim!"
 | 
			
		||||
      
 | 
			
		||||
      # The message to display when explaining the shown item's netherite salvage cost
 | 
			
		||||
      costMessageNetherite: "&eIt will cost &a{cost}&e to salvage that &a{item}&e into diamond!"
 | 
			
		||||
      
 | 
			
		||||
      # The yield message to display if trying to salvage a non-damaged item
 | 
			
		||||
      fullSalvageMessage: "&aI should be able to extract all components from that pristine item.&r"
 | 
			
		||||
@@ -221,4 +233,7 @@ scrapper:
 | 
			
		||||
      cannotSalvageArmorTrimMessage: "&cI'm sorry, but I'm unable to salvage armor trims!"
 | 
			
		||||
      
 | 
			
		||||
      # The message to display if the correct materials to return for the armor trim are unknown
 | 
			
		||||
      armorTrimSalvageNotFoundMessage: "&cI'm sorry, but I don't know how to salvage that armor trim!"
 | 
			
		||||
      armorTrimSalvageNotFoundMessage: "&cI'm sorry, but I don't know how to salvage that armor trim!"
 | 
			
		||||
      
 | 
			
		||||
      # The message to display when asked to salvage netherite items, and that option is disabled
 | 
			
		||||
      cannotSalvageNetheriteMessage: "&cI'm sorry, but I'm unable to salvage netherite items!"
 | 
			
		||||
		Reference in New Issue
	
	Block a user