reforgeAbleItems = config.getReforgeAbleItems();
if ((!this.config.getRepairAnvils() || !ItemHelper.isAnvil(hand.getType(), false)) &&
- (!isRepairable(hand) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType())))) {
+ (!ItemHelper.isRepairable(hand) || (!reforgeAbleItems.isEmpty() && !reforgeAbleItems.contains(hand.getType())))) {
String invalidMessage = StringFormatter.replacePlaceholder(config.getInvalidItemMessage(),
"{title}", config.getBlacksmithTitle());
sendNPCMessage(this.npc, player, invalidMessage);
@@ -225,14 +223,4 @@ public class BlacksmithTrait extends Trait {
player.getInventory().setItemInMainHand(null);
}
- /**
- * Gets whether the given item is repairable
- *
- * @param item The item to check
- * @return True if the item is repairable
- */
- public static boolean isRepairable(ItemStack item) {
- return item.getItemMeta() instanceof Damageable && EnchantmentTarget.BREAKABLE.includes(item);
- }
-
}
diff --git a/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java b/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
index 4010b30..6d604c4 100644
--- a/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
+++ b/src/main/java/net/knarcraft/blacksmith/util/ItemHelper.java
@@ -17,6 +17,16 @@ public final class ItemHelper {
}
+ /**
+ * Gets whether the given item is repairable
+ *
+ * @param item The item to check
+ * @return True if the item is repairable
+ */
+ public static boolean isRepairable(ItemStack item) {
+ return item.getItemMeta() instanceof Damageable && EnchantmentTarget.BREAKABLE.includes(item);
+ }
+
/**
* Gets the max durability of an item
*
diff --git a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
index a3ac408..8ba5e83 100644
--- a/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
+++ b/src/main/java/net/knarcraft/blacksmith/util/SalvageHelper.java
@@ -1,8 +1,7 @@
package net.knarcraft.blacksmith.util;
-import net.knarcraft.blacksmith.trait.BlacksmithTrait;
-import org.bukkit.Bukkit;
import org.bukkit.Material;
+import org.bukkit.Server;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.Recipe;
import org.bukkit.inventory.ShapedRecipe;
@@ -24,17 +23,19 @@ public final class SalvageHelper {
*
* Note: Only items craft-able in a crafting table are salvageable. Netherite gear is therefore not salvageable.
*
- * @param salvagedItem The item stack to salvage
+ * @param server The server to get recipes from
+ * @param salvagedItem The item stack to salvage
+ * @param ignoredSalvage Any material which should not be returned as part of the salvage.
* @return The items to return to the user, or null if not salvageable
*/
- public static List getSalvage(ItemStack salvagedItem) {
+ public static List getSalvage(Server server, ItemStack salvagedItem, List ignoredSalvage) {
if (salvagedItem == null || salvagedItem.getAmount() < 1 ||
- !BlacksmithTrait.isRepairable(salvagedItem)) {
+ !ItemHelper.isRepairable(salvagedItem)) {
return null;
}
- for (Recipe recipe : Bukkit.getServer().getRecipesFor(salvagedItem)) {
- List salvage = getRecipeSalvage(recipe, salvagedItem);
+ for (Recipe recipe : server.getRecipesFor(salvagedItem)) {
+ List salvage = getRecipeSalvage(recipe, salvagedItem, ignoredSalvage);
if (salvage != null) {
return salvage;
}
@@ -46,11 +47,13 @@ public final class SalvageHelper {
/**
* Gets the salvage resulting from the given recipe and the given item
*
- * @param recipe The recipe to get salvage for
- * @param salvagedItem The item to be salvaged
+ * @param recipe The recipe to get salvage for
+ * @param salvagedItem The item to be salvaged
+ * @param ignoredSalvage Any material which should not be returned as part of the salvage.
* @return A list of items, or null if not a valid type of recipe
*/
- private static List getRecipeSalvage(Recipe recipe, ItemStack salvagedItem) {
+ private static List getRecipeSalvage(Recipe recipe, ItemStack salvagedItem,
+ List ignoredSalvage) {
List ingredients;
if (recipe instanceof ShapedRecipe shapedRecipe) {
ingredients = getIngredients(shapedRecipe);
@@ -63,6 +66,11 @@ public final class SalvageHelper {
//Make things easier by eliminating identical stacks
ingredients = combineStacks(ingredients);
+ //Purge any ignored salvage to only calculate salvage using the remaining items
+ if (ignoredSalvage != null) {
+ ingredients.removeIf((item) -> ignoredSalvage.contains(item.getType()));
+ }
+
//Make sure to give salvage for all items if a stack > 1 is provided
List salvage = new ArrayList<>();
for (int i = 0; i < salvagedItem.getAmount(); i++) {
diff --git a/src/test/java/net/knarcraft/blacksmith/CustomServerMock.java b/src/test/java/net/knarcraft/blacksmith/CustomServerMock.java
new file mode 100644
index 0000000..32b32fc
--- /dev/null
+++ b/src/test/java/net/knarcraft/blacksmith/CustomServerMock.java
@@ -0,0 +1,31 @@
+package net.knarcraft.blacksmith;
+
+import be.seeseemelk.mockbukkit.ServerMock;
+import org.bukkit.Material;
+import org.bukkit.NamespacedKey;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.Recipe;
+import org.bukkit.inventory.ShapedRecipe;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A custom server mock specifically for making the SalvageHelperTest work
+ */
+public class CustomServerMock extends ServerMock {
+
+ public @NotNull List getRecipesFor(@NotNull ItemStack itemStack) {
+ List validRecipes = new ArrayList<>();
+ if (itemStack.getType() == Material.DIAMOND_PICKAXE) {
+ ShapedRecipe recipe = new ShapedRecipe(NamespacedKey.minecraft("diamond_pickaxe"), itemStack);
+ recipe.shape("ddd", "asa", "asa");
+ recipe.setIngredient('d', Material.DIAMOND);
+ recipe.setIngredient('s', Material.STICK);
+ validRecipes.add(recipe);
+ }
+ return validRecipes;
+ }
+
+}
diff --git a/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java b/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java
new file mode 100644
index 0000000..3bd2391
--- /dev/null
+++ b/src/test/java/net/knarcraft/blacksmith/util/SalvageHelperTest.java
@@ -0,0 +1,76 @@
+package net.knarcraft.blacksmith.util;
+
+import be.seeseemelk.mockbukkit.MockBukkit;
+import net.knarcraft.blacksmith.CustomServerMock;
+import org.bukkit.Material;
+import org.bukkit.Server;
+import org.bukkit.inventory.ItemStack;
+import org.bukkit.inventory.meta.Damageable;
+import org.bukkit.inventory.meta.ItemMeta;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Test;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+
+/**
+ * A test class to test salvaging
+ */
+public class SalvageHelperTest {
+
+ private static Server server;
+
+ @BeforeAll
+ public static void setUp() {
+ server = MockBukkit.mock(new CustomServerMock());
+ }
+
+ @Test
+ public void getNullForInvalidItemTest() {
+ //Assert that a non-reforge-able item will return null
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.POTATO, 1), null));
+ }
+
+ @Test
+ public void getNullForLessThanOneItemTest() {
+ //Assert that 0 or 1 items will return null
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_AXE, 0), null));
+ assertNull(SalvageHelper.getSalvage(server, new ItemStack(Material.IRON_SWORD, -1), null));
+ }
+
+ @Test
+ public void getFullSalvageTest() {
+ Set expectedSalvage = new HashSet<>();
+ expectedSalvage.add(new ItemStack(Material.DIAMOND, 3));
+ expectedSalvage.add(new ItemStack(Material.STICK, 2));
+ ItemStack itemToSalvage = new ItemStack(Material.DIAMOND_PICKAXE, 1);
+ //Note: Conversion to sets makes sure the order doesn't matter
+ assertEquals(expectedSalvage, new HashSet<>(SalvageHelper.getSalvage(server, itemToSalvage, null)));
+ }
+
+ @Test
+ public void getNonFullSalvageTest() {
+ List expectedSalvage = new ArrayList<>();
+ expectedSalvage.add(new ItemStack(Material.DIAMOND, 3));
+ expectedSalvage.add(new ItemStack(Material.STICK, 2));
+ ItemStack itemToSalvage = new ItemStack(Material.DIAMOND_PICKAXE, 1);
+ ItemMeta meta = itemToSalvage.getItemMeta();
+ Damageable damageable = (Damageable) meta;
+ if (damageable != null) {
+ damageable.setDamage(100);
+ }
+ itemToSalvage.setItemMeta(meta);
+ List salvage = SalvageHelper.getSalvage(server, itemToSalvage, null);
+ //Assert that some items are given
+ assertNotEquals(salvage, new ArrayList<>());
+ //Assert that a damaged item won't give full salvage
+ assertNotEquals(expectedSalvage, salvage);
+ }
+
+}