diff --git a/src/main/java/net/knarcraft/blacksmith/config/blacksmith/BlacksmithSetting.java b/src/main/java/net/knarcraft/blacksmith/config/blacksmith/BlacksmithSetting.java index 285585a..5f35405 100644 --- a/src/main/java/net/knarcraft/blacksmith/config/blacksmith/BlacksmithSetting.java +++ b/src/main/java/net/knarcraft/blacksmith/config/blacksmith/BlacksmithSetting.java @@ -75,8 +75,8 @@ public enum BlacksmithSetting implements Setting { */ REFORGE_ABLE_ITEMS("reforgeAbleItems", SettingValueType.REFORGE_ABLE_ITEMS, "", "The items a blacksmith is able to reforge. Setting this only " + - "allows NPCs to repair the listed items. This should be set for each individual NPC, and should not be set" + - " here, unless you want to restrict NPCs which have not been set up yet.", true, false), + "allows NPCs to repair the listed items. This should be set for each individual NPC.", + true, false), /** * The setting for the title used to display which kind of blacksmith the NPC is diff --git a/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperNPCSettings.java b/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperNPCSettings.java index d23f8f6..563c705 100644 --- a/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperNPCSettings.java +++ b/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperNPCSettings.java @@ -136,6 +136,7 @@ public class ScrapperNPCSettings implements TraitSettings { * * @return

The message to use for displaying salvage cost

*/ + @NotNull public String getCostMessage() { return asString(ScrapperSetting.COST_MESSAGE); } @@ -310,4 +311,34 @@ public class ScrapperNPCSettings implements TraitSettings { return asString(ScrapperSetting.INSUFFICIENT_FUNDS_MESSAGE); } + /** + * Gets the message to display if an item is too damaged to produce any salvage + * + * @return

The no salvage message

+ */ + @NotNull + public String getTooDamagedMessage() { + return asString(ScrapperSetting.TOO_DAMAGED_FOR_SALVAGE_MESSAGE); + } + + /** + * Gets the message to display when explaining that full salvage will be given for an item + * + * @return

The full salvage message

+ */ + @NotNull + public String getFullSalvageMessage() { + return asString(ScrapperSetting.FULL_SALVAGE_MESSAGE); + } + + /** + * Gets the message to display when explaining that only partial salvage will be given for an item + * + * @return

The partial salvage message

+ */ + @NotNull + public String getPartialSalvageMessage() { + return asString(ScrapperSetting.PARTIAL_SALVAGE_MESSAGE); + } + } diff --git a/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperSetting.java b/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperSetting.java index e05cbc7..e758daa 100644 --- a/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperSetting.java +++ b/src/main/java/net/knarcraft/blacksmith/config/scrapper/ScrapperSetting.java @@ -34,8 +34,8 @@ public enum ScrapperSetting implements Setting { */ SALVAGE_ABLE_ITEMS("salvageAbleItems", SettingValueType.REFORGE_ABLE_ITEMS, "", "The items a blacksmith is able to salvage. Setting this only " + - "allows NPCs to repair the listed items. This should be set for each individual NPC, and should not be " + - "set here, unless you want to restrict NPCs which have not been set up yet", true, false), + "allows NPCs to repair the listed items. This should be set for each individual NPC", + true, false), /** * The maximum amount of seconds a player may need to wait for the reforging to finish @@ -151,9 +151,23 @@ public enum ScrapperSetting implements Setting { * The message displayed when displaying the cost of reforging the held item to the player */ COST_MESSAGE("costMessage", SettingValueType.STRING, - "&eIt will cost &a{cost}&e to salvage that item! Click again to salvage!", + "&eIt will cost &a{cost}&e to salvage that item! {yield} Click again to salvage!", "The message to display when informing a player about the salvaging cost", true, true), + /** + * The message displayed when explaining that all items will be returned as salvage + */ + FULL_SALVAGE_MESSAGE("fullSalvageMessage", SettingValueType.STRING, + "&aI should be able to extract all components from that pristine item.&r", + "The message to display when explaining expected full yield as part of the cost message", true, true), + + /** + * The message displayed when explaining that only some items will be returned as salvage + */ + PARTIAL_SALVAGE_MESSAGE("partialSalvageMessage", SettingValueType.STRING, + "&cI cannot extract all components from that damaged item.&r", + "The message to display when explaining expected partial yield as part of the cost message", true, true), + /*------------------ | Global settings | ------------------*/ diff --git a/src/main/java/net/knarcraft/blacksmith/trait/ScrapperTrait.java b/src/main/java/net/knarcraft/blacksmith/trait/ScrapperTrait.java index 0bcb2bb..832f03c 100644 --- a/src/main/java/net/knarcraft/blacksmith/trait/ScrapperTrait.java +++ b/src/main/java/net/knarcraft/blacksmith/trait/ScrapperTrait.java @@ -45,6 +45,7 @@ public class ScrapperTrait extends CustomTrait { * * @return

The current settings for this NPC

*/ + @SuppressWarnings("unused") @NotNull public ScrapperNPCSettings getSettings() { return config; @@ -80,14 +81,18 @@ public class ScrapperTrait extends CustomTrait { List salvageAbleItems = this.config.getSalvageAbleItems(); boolean extended = this.config.extendedSalvageEnabled(); - List salvage = getSalvage(player.getServer(), itemInHand, salvageAbleItems, extended); + if (!canBeSalvaged(player.getServer(), itemInHand, salvageAbleItems, extended)) { + sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholder(config.getInvalidItemMessage(), + "{title}", config.getScrapperTitle())); + return; + } + + List salvage = getSalvage(itemInHand, extended); // If extended mode is disabled, only allow repairable items to be salvaged - boolean notHoldingSalvageable = salvage == null || salvage.isEmpty(); - if (notHoldingSalvageable) { - String invalidMessage = StringFormatter.replacePlaceholder(config.getInvalidItemMessage(), - "{title}", config.getScrapperTitle()); - sendNPCMessage(this.npc, player, invalidMessage); + boolean noUsefulSalvage = salvage == null || salvage.isEmpty(); + if (noUsefulSalvage) { + sendNPCMessage(this.npc, player, config.getTooDamagedMessage()); return; } @@ -96,7 +101,16 @@ public class ScrapperTrait extends CustomTrait { session = new SalvageSession(this, player, npc, config, salvage); //Tell the player the cost of repairing the item String cost = EconomyManager.formatScrapperCost(); - sendNPCMessage(this.npc, player, config.getCostMessage().replace("{cost}", cost)); + + String expectedYield; + if (ItemHelper.getDamage(itemInHand) <= 0) { + expectedYield = config.getFullSalvageMessage(); + } else { + expectedYield = config.getPartialSalvageMessage(); + } + + sendNPCMessage(this.npc, player, StringFormatter.replacePlaceholders(config.getCostMessage(), + List.of("{cost}", "{yield}"), List.of(cost, expectedYield))); } @Override @@ -105,23 +119,30 @@ public class ScrapperTrait extends CustomTrait { } /** - * Gets salvage for an item, if it's salvage-able + * Gets whether this scrapper can salvage the given item * * @param server

The server to get recipes from

- * @param item

The item to calculate salvage for

+ * @param item

The item to check

* @param salvageAbleItems

The items this scrapper can salvage

* @param extended

Whether extended salvage is enabled

+ * @return

True if the item can be theoretically salvaged

+ */ + private boolean canBeSalvaged(@NotNull Server server, @NotNull ItemStack item, + @NotNull List salvageAbleItems, boolean extended) { + return (extended || ItemHelper.isRepairable(item)) && ItemHelper.isSalvageable(server, item) && + (salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType())) && + SalvageHelper.hasRecipe(item); + } + + /** + * Gets salvage for an item, if it's salvage-able + * + * @param item

The item to calculate salvage for

+ * @param extended

Whether extended salvage is enabled

* @return

The possible salvage, or null if not salvage-able

*/ @Nullable - private List getSalvage(@NotNull Server server, @NotNull ItemStack item, - @NotNull List salvageAbleItems, boolean extended) { - boolean isSalvageable = (extended || ItemHelper.isRepairable(item)) && ItemHelper.isSalvageable(server, item) && - (salvageAbleItems.isEmpty() || salvageAbleItems.contains(item.getType())); - if (!isSalvageable) { - return null; - } - + private List getSalvage(@NotNull ItemStack item, boolean extended) { // Get the salvage, for the item, but ignore some materials if set, and the item isn't at full durability Set ignoredSalvage = BlacksmithPlugin.getInstance().getGlobalScrapperSettings().getIgnoredSalvage( item.getType()); diff --git a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java index a60ef18..99b511a 100644 --- a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java +++ b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java @@ -1,5 +1,6 @@ package net.knarcraft.blacksmith.util; +import org.bukkit.Bukkit; import org.bukkit.Material; import org.bukkit.Server; import org.bukkit.enchantments.Enchantment; @@ -24,6 +25,23 @@ public final class SalvageHelper { private static final Random random = new Random(); + /** + * Gets whether the given item has a valid crafting recipe + * + * @param item

The item to check

+ * @return

True if the item has a valid crafting recipe

+ */ + public static boolean hasRecipe(@NotNull ItemStack item) { + List recipes = Bukkit.getRecipesFor(new ItemStack(item.getType(), item.getAmount())); + for (Recipe recipe : recipes) { + if (recipe instanceof ShapedRecipe || recipe instanceof ShapelessRecipe) { + return true; + } + } + + return false; + } + /** * Gets the sum of all enchantment levels for the given item * diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 533a637..669b256 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -197,4 +197,10 @@ 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! Click again to salvage!" \ No newline at end of file + costMessage: "&eIt will cost &a{cost}&e to salvage that item! {yield} &eClick again to salvage!" + + # 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" + + # The yield message to display if trying to salvage a damaged item + partialSalvageMessage: "&cI cannot extract all components from that damaged item.&r" \ No newline at end of file