diff --git a/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java b/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java index 9d33bfb..4292fa0 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilder.java @@ -14,7 +14,10 @@ public class AnvilRecipeBuilder { private @NotNull String name; private boolean exactCount; - private int xpCostPerCraft; + private int levelCostPerCraft; + private int linearXpCostPerCraft; + + private boolean removeExactLinearXp; private @Nullable ItemStack leftItem; private @Nullable ItemStack rightItem; @@ -23,7 +26,7 @@ public class AnvilRecipeBuilder { /** * Instantiates a new Anvil recipe builder. * exact count default to true. - * xp cost per craft default to 1. + * xp level and linear cost per craft default to 0. * * @param name The recipe name */ @@ -31,7 +34,9 @@ public class AnvilRecipeBuilder { this.name = name; this.exactCount = true; - this.xpCostPerCraft = 1; + this.levelCostPerCraft = 0; + this.linearXpCostPerCraft = 0; + this.removeExactLinearXp = false; this.leftItem = null; this.rightItem = null; @@ -60,7 +65,7 @@ public class AnvilRecipeBuilder { } /** - * Get if the recipe is exact count. + * Get if the recipe is exact count. (default 0) *

* Exact count mean the recipe can only be crafted 1 by 1. * If set to false, then it will craft as much as possible in 1 go and will keep unused material onto the anvil inventory. @@ -86,12 +91,14 @@ public class AnvilRecipeBuilder { } /** - * Get the xp level cost per craft. + * Get the xp level cost per craft. (default 0) * * @return The xp level cost per craft + * @deprecated use {@link #getLevelCostPerCraft() getLevelCostPerCraft} instead */ + @Deprecated(since = "1.13.0") public int getXpCostPerCraft() { - return xpCostPerCraft; + return getLevelCostPerCraft(); } /** @@ -99,9 +106,78 @@ public class AnvilRecipeBuilder { * * @param xpCostPerCraft The xp level cost per craft * @return This recipe builder instance. + * @deprecated use {@link #setLevelCostPerCraft(int) setLevelCostPerCraft} instead */ + @Deprecated(since = "1.13.0") public AnvilRecipeBuilder setXpCostPerCraft(int xpCostPerCraft) { - this.xpCostPerCraft = xpCostPerCraft; + return setLevelCostPerCraft(xpCostPerCraft); + } + + /** + * Get the xp level cost per craft. (default 0) + * + * @return The xp level cost per craft + */ + public int getLevelCostPerCraft() { + return levelCostPerCraft; + } + + /** + * Sets the xp level cost per craft. + * + * @param levelCostPerCraft The xp level cost per craft + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setLevelCostPerCraft(int levelCostPerCraft) { + this.levelCostPerCraft = levelCostPerCraft; + return this; + } + + /** + * Get the linear xp cost (not xp level cost) per craft. + * + * @return The xp level cost per craft + */ + public int getLinearXpCostPerCraft() { + return linearXpCostPerCraft; + } + + /** + * Sets the linear xp cost (not xp level cost) per craft. + * + * @param linearXpCostPerCraft The linear xp cost per craft + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setLinearXpCostPerCraft(int linearXpCostPerCraft) { + this.linearXpCostPerCraft = linearXpCostPerCraft; + return this; + } + + /** + * Get if the linear xp should get removed by an exact amount. + *

+ * If false (default) level cost will be the level that would be reached by a player with this amount of xp. + * If true will require the level that has at least the specified level of xp then on click remove only the necessary xp + *

+ * linear xp cost are applied after level cost + * @return if we should remove the exact amount of linear xp + */ + public boolean isRemoveExactLinearXp() { + return removeExactLinearXp; + } + + /** + * Set if the linear xp should get removed by an exact amount. + *

+ * If false (default) level cost will be the level that would be reached by a player with this amount of xp. + * If true will require the level that has at least the specified level of xp then on click remove only the necessary xp + *

+ * linear xp cost are applied after level cost + * @param removeExactLinearXp if we should remove the exact amount of linear xp + * @return This recipe builder instance. + */ + public AnvilRecipeBuilder setRemoveExactLinearXp(boolean removeExactLinearXp) { + this.removeExactLinearXp = removeExactLinearXp; return this; } @@ -182,12 +258,14 @@ public class AnvilRecipeBuilder { */ @Nullable // null if missing argument public AnvilCustomRecipe build() { - if(leftItem == null || resultItem == null) return null; + if (leftItem == null || resultItem == null) return null; return new AnvilCustomRecipe( this.name, this.exactCount, - this.xpCostPerCraft, + this.levelCostPerCraft, + this.linearXpCostPerCraft, + this.removeExactLinearXp, this.leftItem, this.rightItem, this.resultItem ); } @@ -198,7 +276,7 @@ public class AnvilRecipeBuilder { * * @return True if successful. */ - public boolean registerIfAbsent(){ + public boolean registerIfAbsent() { return CustomAnvilRecipeApi.addRecipe(this); } diff --git a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java index feaa8dd..e21ad75 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java +++ b/src/main/java/xyz/alexcrea/cuanvil/gui/config/global/CustomRecipeConfigGui.java @@ -14,7 +14,7 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.util.CasedStringUtil; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collection; public class CustomRecipeConfigGui extends MappedGuiListConfigGui getRecipeLore(AnvilCustomRecipe recipe) { + boolean shouldWork = recipe.validate(); + + ArrayList lore = new ArrayList<>(); + lore.add("§7Is valid: §" + (shouldWork ? "aYes" : "cNo")); + lore.add("§7Exact count: §" + (recipe.getExactCount() ? "aYes" : "cNo")); + lore.add("§7Recipe Level Cost: §e" + recipe.getLevelCostPerCraft()); + lore.add("§7Recipe Linear Xp Cost: §e" + recipe.getXpCostPerCraft()); + if (recipe.getXpCostPerCraft() != 0) { + lore.add("§7Exact Linear xp remove: §" + (recipe.getRemoveExactLinearXp() ? "aYes" : "cNo")); + } + return lore; + } + @Override protected LazyElement newInstanceOfGui(AnvilCustomRecipe generic, GuiItem item) { return new LazyElement<>(item, () -> new CustomRecipeSubSettingGui(this, generic)); @@ -87,7 +94,11 @@ public class CustomRecipeConfigGui extends MappedGuiListConfigGui (Math.sqrt((xp + 9).toDouble()) - 3).toInt() + xp <= 1507 -> { + val inner = (2.0 / 5.0) * (xp - 7839.0 / 40.0) + (81.0 / 10.0 + Math.sqrt(inner)).toInt() + } + + else -> { + val inner = (2.0 / 9.0) * (xp - 54215.0 / 72.0) + (325.0 / 18.0 + Math.sqrt(inner)).toInt() + } + } + } + + /** + * Calculate the minimum level necessary to have at least `xp` + */ + fun calculateMinimumLevelForXp(xp: Int): Int { + return calculateLevelForXp(xp - 1) + 1 + } + + /** + * Calculate the minimum amount of xp necessary to reach `level` + * @author provided by kFor + */ + fun calculateXpForLevel(level: Int): Int { + return when { + level <= 16 -> (level * level + 6 * level) + level <= 31 -> (2.5 * level * level - 40.5 * level + 360).toInt() + else -> (4.5 * level * level - 162.5 * level + 2220).toInt() + } + } + } \ No newline at end of file diff --git a/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java b/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java index 48efc6b..10ea252 100644 --- a/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java +++ b/src/test/java/io/delilaheve/util/EnchantmentUtilTests.java @@ -88,16 +88,16 @@ public class EnchantmentUtilTests extends ConfigResetCustomAnvilTest { ); // Test with no permission - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData2); + nullResultData.executeTest(anvil, player); + nullResultData2.executeTest(anvil, player); // Add permission PermissionAttachment attachment = player.addAttachment(plugin); attachment.setPermission(permission, true); // Test with new permission - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); + legalResultData.executeTest(anvil, player); + legalResultData2.executeTest(anvil, player); } @Test @@ -161,24 +161,24 @@ public class EnchantmentUtilTests extends ConfigResetCustomAnvilTest { ); // Test failing result first - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData2); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData3); + nullResultData2.executeTest(anvil, player); + nullResultData3.executeTest(anvil, player); // Test working sharpness 2 - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); // Set merge limit to 2 & test ConfigHolder.DEFAULT_CONFIG.getConfig().set("disable-merge-over.minecraft:sharpness", 1); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); // Add permission PermissionAttachment attachment = player.addAttachment(plugin); attachment.setPermission(permission, true); // Test working sharpness 2 - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData3); + legalResultData.executeTest(anvil, player); + legalResultData2.executeTest(anvil, player); + legalResultData3.executeTest(anvil, player); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java index 60df37e..19f1d6f 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/anvil/AnvilFuseTests.java @@ -67,7 +67,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { 5 ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); + data.executeTest(anvil, player); } @Test @@ -87,7 +87,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { 5 ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); + data.executeTest(anvil, player); } @Test @@ -101,7 +101,7 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { null ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); + data.executeTest(anvil, player); } // Note: currently anvil can only have null name. maybe handle differently later @@ -117,10 +117,10 @@ public class AnvilFuseTests extends SharedCustomAnvilTest { AnvilFuseTestData data = new AnvilFuseTestData( base, null, expected, expected, null, - 1, 1, null + 1, null, 1 ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, data); + data.executeTest(anvil, player); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilderTest.java b/src/test/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilderTest.java index 2b57bda..d9ff329 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilderTest.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/AnvilRecipeBuilderTest.java @@ -12,10 +12,15 @@ import static org.junit.jupiter.api.Assertions.*; public class AnvilRecipeBuilderTest extends SharedOnlyMockBukkit { private AnvilRecipeBuilder builder; + private AnvilRecipeBuilder builder2; @BeforeEach public void setup() { builder = new AnvilRecipeBuilder("test"); + builder2 = new AnvilRecipeBuilder("test"); + + builder2.setLeftItem(new ItemStack(Material.STICK)); + builder2.setResultItem(new ItemStack(Material.STICK)); } @Test @@ -38,6 +43,7 @@ public class AnvilRecipeBuilderTest extends SharedOnlyMockBukkit { .setResultItem(new ItemStack(Material.STICK)); assertNotNull(builder.build()); + assertNotNull(builder2.build()); } @Test @@ -63,23 +69,39 @@ public class AnvilRecipeBuilderTest extends SharedOnlyMockBukkit { @Test void setXpCostPerCraft(){ - assertEquals(1, builder.getXpCostPerCraft()); - builder.setXpCostPerCraft(2); - assertEquals(2, builder.getXpCostPerCraft()); + assertEquals(0, builder2.getLevelCostPerCraft()); + assertEquals(0, builder2.build().getLevelCostPerCraft()); + builder2.setLevelCostPerCraft(2); + assertEquals(2, builder2.getLevelCostPerCraft()); + assertEquals(2, builder2.build().getLevelCostPerCraft()); } + @Test + void setLinearXpCostPerCraft(){ + assertEquals(0, builder2.getLinearXpCostPerCraft()); + assertEquals(0, builder2.build().getXpCostPerCraft()); + builder2.setLinearXpCostPerCraft(2); + assertEquals(2, builder2.getLinearXpCostPerCraft()); + assertEquals(2, builder2.build().getXpCostPerCraft()); + } + + @Test void setExactCount(){ - assertTrue(builder.isExactCount()); - builder.setExactCount(false); - assertFalse(builder.isExactCount()); + assertTrue(builder2.isExactCount()); + assertTrue(builder2.build().getExactCount()); + builder2.setExactCount(false); + assertFalse(builder2.isExactCount()); + assertFalse(builder2.build().getExactCount()); } @Test void setName(){ - assertEquals("test", builder.getName()); - builder.setName("other"); - assertEquals("other", builder.getName()); + assertEquals("test", builder2.getName()); + assertEquals("test", builder2.build().getName()); + builder2.setName("other"); + assertEquals("other", builder2.getName()); + assertEquals("other", builder2.build().getName()); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java index b1d7564..1a9a256 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/ConflictApiTests.java @@ -71,7 +71,7 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { Assertions.assertNotNull(sharpness); // Testing default conflict (illegal item should not be produced) - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); // Try to find & remove conflict EnchantConflictGroup conflict = findGroup("sword_enchant_conflict"); @@ -79,7 +79,7 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { // Test what happen when we remove the conflict (illegal item should be allowed) ConflictAPI.removeConflict(conflict); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); // We create and add a new conflict ConflictBuilder builder = new ConflictBuilder("sword_enchant_conflict"); @@ -88,11 +88,11 @@ public class ConflictApiTests extends ConfigResetCustomAnvilTest { // Nothing should change as it is not new: it was previously deleted Assertions.assertFalse(builder.registerIfNew()); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); // Now the conflict should be registered and conflict should exist Assertions.assertTrue(builder.registerIfAbsent()); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); } @Test diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java index 3ebdd7c..651b873 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/CustomAnvilRecipeApiTests.java @@ -1,6 +1,7 @@ package xyz.alexcrea.cuanvil.api; import org.bukkit.Material; +import org.bukkit.event.Event; import org.bukkit.event.inventory.InventoryType; import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.Inventory; @@ -11,10 +12,11 @@ import org.junit.jupiter.api.Test; import org.mockbukkit.mockbukkit.entity.PlayerMock; import org.mockbukkit.mockbukkit.inventory.ItemStackMock; import xyz.alexcrea.cuanvil.config.ConfigHolder; +import xyz.alexcrea.cuanvil.data.AnvilClickTestData; +import xyz.alexcrea.cuanvil.data.TestDataContainer; import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe; import xyz.alexcrea.cuanvil.tests.ConfigResetCustomAnvilTest; import xyz.alexcrea.cuanvil.data.AnvilFuseTestData; -import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; import static org.junit.jupiter.api.Assertions.*; @@ -57,14 +59,14 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { ); // Testing default conflict (no recipe exist) - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); // Add and test recipe AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); - builder.setExactCount(true).setLeftItem(stick).setResultItem(stick).setXpCostPerCraft(2); + builder.setExactCount(true).setLeftItem(stick).setResultItem(stick).setLevelCostPerCraft(2); assertTrue(builder.registerIfAbsent()); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); AnvilCustomRecipe recipe = getByName(recipeName); assertNotNull(recipe); @@ -72,21 +74,21 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { // Remove recipe assertTrue(CustomAnvilRecipeApi.removeRecipe(recipe)); assertFalse(CustomAnvilRecipeApi.removeRecipe(recipe)); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); recipe = getByName(recipeName); assertNull(recipe); // Try to add deleted recipe with no override (should not add) assertFalse(CustomAnvilRecipeApi.addRecipe(builder, false)); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); recipe = getByName(recipeName); assertNull(recipe); // Try to add deleted recipe with override (should add) assertTrue(CustomAnvilRecipeApi.addRecipe(builder, true)); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); recipe = getByName(recipeName); assertNotNull(recipe); @@ -119,25 +121,134 @@ public class CustomAnvilRecipeApiTests extends ConfigResetCustomAnvilTest { null, null ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); builder.setExactCount(false) .setLeftItem(stick) .setResultItem(stick2) - .setXpCostPerCraft(2); + .setLevelCostPerCraft(2); assertTrue(builder.registerIfAbsent()); // Now working test - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData1); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData2); + legalResultData1.executeTest(anvil, player); + legalResultData2.executeTest(anvil, player); + } + + @Test + public void testLinearXpCost() { + String recipeName = "stick_recipe"; + ItemStack stick = new ItemStackMock(Material.STICK); + ItemStack stick2 = new ItemStackMock(Material.STICK, 2); + ItemStack stick5 = new ItemStackMock(Material.STICK, 5); + ItemStack stick10 = new ItemStackMock(Material.STICK, 10); + + + AnvilFuseTestData nullResultData = new AnvilFuseTestData( + stick, stick, + null + ); + + TestDataContainer legalResultData1 = new TestDataContainer(new AnvilFuseTestData( + stick, stick, + null, stick2, null, + 1, + null, null + ), new AnvilClickTestData( + null, null, null, stick2, + 1, + Event.Result.DENY, true, Event.Result.DENY + + )); + + TestDataContainer legalResultData2 = new TestDataContainer(new AnvilFuseTestData( + stick5, stick, + null, stick10, null, + 4, + null, null + ), new AnvilClickTestData( + null, null, null, stick10, + 4, + Event.Result.DENY, true, Event.Result.DENY + + )); + + nullResultData.executeTest(anvil, player); + + AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); + builder.setExactCount(false) + .setLeftItem(stick) + .setResultItem(stick2) + .setLevelCostPerCraft(0) + .setLinearXpCostPerCraft(10); + + assertTrue(builder.registerIfAbsent()); + + // Now working test + legalResultData1.executeTest(anvil, player); + legalResultData2.executeTest(anvil, player); + } + + @Test + public void testLinearXpCostRemoveExact() { + String recipeName = "stick_recipe"; + ItemStack stick = new ItemStackMock(Material.STICK); + ItemStack stick2 = new ItemStackMock(Material.STICK, 2); + ItemStack stick5 = new ItemStackMock(Material.STICK, 5); + ItemStack stick10 = new ItemStackMock(Material.STICK, 10); + + AnvilFuseTestData nullResultData = new AnvilFuseTestData( + stick, stick, + null + ); + + TestDataContainer legalResultData1 = new TestDataContainer(new AnvilFuseTestData( + stick, stick, + null, stick2, null, + 2, + null, null + ), new AnvilClickTestData( + null, null, null, stick2, + 2, + Event.Result.DENY, true, Event.Result.DENY + + )); + + TestDataContainer legalResultData2 = new TestDataContainer(new AnvilFuseTestData( + stick5, stick, + null, stick10, null, + 5, + null, null + ), new AnvilClickTestData( + null, null, null, stick10, + 5, + Event.Result.DENY, true, Event.Result.DENY + )); + + nullResultData.executeTest(anvil, player); + + AnvilRecipeBuilder builder = new AnvilRecipeBuilder(recipeName); + builder.setExactCount(false) + .setLeftItem(stick) + .setResultItem(stick2) + .setLinearXpCostPerCraft(10) + .setRemoveExactLinearXp(true); + + assertTrue(builder.registerIfAbsent()); + + // Now working test + legalResultData1.executeTest(anvil, player); + //TODO check exp ? + System.out.printf(String.valueOf(player.getExp())); + legalResultData2.executeTest(anvil, player); + //TODO check exp ? } @Nullable - public static AnvilCustomRecipe getByName(String name){ + public static AnvilCustomRecipe getByName(String name) { for (AnvilCustomRecipe registeredRecipe : CustomAnvilRecipeApi.getRegisteredRecipes()) { - if(registeredRecipe.getName().contentEquals(name)){ + if (registeredRecipe.getName().contentEquals(name)) { return registeredRecipe; } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java b/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java index 8166797..adda4e1 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java +++ b/src/test/java/xyz/alexcrea/cuanvil/api/UnitRepairApiTests.java @@ -58,7 +58,7 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { 2 ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); } @Test @@ -76,7 +76,7 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { // Remove unit repair assertTrue(UnitRepairApi.removeUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE)); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); // see override assertFalse(UnitRepairApi.addUnitRepair(Material.DIAMOND, Material.DIAMOND_PICKAXE, 0.25)); @@ -107,12 +107,12 @@ public class UnitRepairApiTests extends ConfigResetCustomAnvilTest { 2 ); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, nullResultData); + nullResultData.executeTest(anvil, player); // Add unit repair assertTrue(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE)); assertFalse(UnitRepairApi.addUnitRepair(Material.STICK, Material.DIAMOND_PICKAXE)); - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, legalResultData); + legalResultData.executeTest(anvil, player); } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java index 65d7ddb..002b194 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java +++ b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilClickTestData.java @@ -1,8 +1,11 @@ package xyz.alexcrea.cuanvil.data; +import org.bukkit.entity.Player; import org.bukkit.event.Event; +import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; public record AnvilClickTestData( @Nullable ItemStack leftItem, @@ -47,4 +50,8 @@ public record AnvilClickTestData( int levelCost) { this(expectedCursor, levelCost, null); } + + public void executeTest(AnvilInventory anvil, Player player){ + AnvilFuseTestUtil.executeAnvilClickTest(anvil, player, this); + } } diff --git a/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java index a01d0ab..8542d41 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java +++ b/src/test/java/xyz/alexcrea/cuanvil/data/AnvilFuseTestData.java @@ -1,7 +1,10 @@ package xyz.alexcrea.cuanvil.data; +import org.bukkit.entity.HumanEntity; +import org.bukkit.inventory.AnvilInventory; import org.bukkit.inventory.ItemStack; import org.jetbrains.annotations.Nullable; +import xyz.alexcrea.cuanvil.util.AnvilFuseTestUtil; public record AnvilFuseTestData( @Nullable ItemStack leftItem, @@ -51,4 +54,8 @@ public record AnvilFuseTestData( ); } + public void executeTest(AnvilInventory anvil, HumanEntity player){ + AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, this); + } + } diff --git a/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java b/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java index 2c8ff93..b4f47a5 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java +++ b/src/test/java/xyz/alexcrea/cuanvil/data/TestDataContainer.java @@ -16,17 +16,17 @@ public record TestDataContainer( ) { public void executeTest(AnvilInventory anvil, Player player) { - executeFuseTest(anvil, player); - if (clickData != null) executeClickTest(anvil, player); + fuseData.executeTest(anvil, player); + if (clickData != null) clickData.executeTest(anvil, player); } public void executeFuseTest(AnvilInventory anvil, HumanEntity player) { - AnvilFuseTestUtil.executeAnvilFuseTest(anvil, player, fuseData); + fuseData.executeTest(anvil, player); } public void executeClickTest(AnvilInventory anvil, Player player) { Assertions.assertNotNull(clickData); - AnvilFuseTestUtil.executeAnvilClickTest(anvil, player, clickData); + clickData.executeTest(anvil, player); } public @NotNull TestDataContainer nullifyResult() { diff --git a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java index b73b884..1d3c5f4 100644 --- a/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java +++ b/src/test/java/xyz/alexcrea/cuanvil/util/AnvilFuseTestUtil.java @@ -110,22 +110,60 @@ public class AnvilFuseTestUtil { Assertions.assertEquals(player.getOpenInventory().getTopInventory(), anvil, "Openned inventory is not anvil"); + ItemStack afterLeft = data.expectedAfterLeftPlaced(); + ItemStack afterRight = data.expectedAfterRightPlaced(); + ItemStack afterBoth = data.expectedResult(); + // Fist, test null result(s) + // Test with only the left item - anvil.setItem(1, null); // We clear the right slot in case something was there - testPlacingItem(anvil, player, - 0, data.expectedPriceAfterLeftPlaced(), - data.leftItem(), data.expectedAfterLeftPlaced()); + if(afterLeft == null){ + anvil.setItem(1, null); // We clear the right slot in case something was there + testPlacingItem(anvil, player, + 0, data.expectedPriceAfterLeftPlaced(), + data.leftItem(), null); + } // Test with only the right item - anvil.setItem(0, null); // We only want the right item. so we remove the left one - testPlacingItem(anvil, player, - 1, data.expectedPriceAfterRightPlaced(), - data.rightItem(), data.expectedAfterRightPlaced()); + if(afterRight == null){ + anvil.setItem(0, null); // We only want the right item. so we remove the left one + testPlacingItem(anvil, player, + 1, data.expectedPriceAfterRightPlaced(), + data.rightItem(), null); + } // Test with both placed - testPlacingItem(anvil, player, - 0, data.expectedPriceAfterBothPlaced(), - data.leftItem(), data.expectedResult()); + if(afterBoth == null){ + anvil.setItem(0, data.leftItem()); + testPlacingItem(anvil, player, + 1, data.expectedPriceAfterBothPlaced(), + data.rightItem(), data.expectedResult()); + } + + // Then, test non null result(s) + + // Test with only the left item + if(afterLeft != null){ + anvil.setItem(1, null); // We clear the right slot in case something was there + testPlacingItem(anvil, player, + 0, data.expectedPriceAfterLeftPlaced(), + data.leftItem(), afterLeft); + } + + // Test with only the right item + if(afterRight != null){ + anvil.setItem(0, null); // We only want the right item. so we remove the left one + testPlacingItem(anvil, player, + 1, data.expectedPriceAfterRightPlaced(), + data.rightItem(), afterRight); + } + + // Test with both placed + if(afterBoth != null){ + anvil.setItem(0, data.leftItem()); + testPlacingItem(anvil, player, + 1, data.expectedPriceAfterBothPlaced(), + data.rightItem(), afterBoth); + } } public static void executeAnvilClickTest( @@ -139,6 +177,7 @@ public class AnvilFuseTestUtil { ItemStack result = anvil.getResult(); player.setLevel(0); + player.setExp(0); player.setItemOnCursor(null); // Do a test with not enough level @@ -151,6 +190,7 @@ public class AnvilFuseTestUtil { assertEqual(null, player.getItemOnCursor()); } player.setLevel(data.levelCost()); + player.setExp(0); player.setItemOnCursor(null); simulateClick(anvil, player, data.expectedResult()); @@ -208,7 +248,7 @@ public class AnvilFuseTestUtil { public static void assertEqual(@Nullable ItemStack expected, @Nullable ItemStack other) { boolean secondIsAir = isAir(other); if (isAir(expected)) - Assertions.assertTrue(secondIsAir, "Item " + other + " was not air but was expected to be"); + Assertions.assertTrue(secondIsAir, "Item " + other + " was not air but was expected to be."); else { Assertions.assertFalse(secondIsAir, "Item " + other + " is air but was expected to be " + expected); @@ -225,7 +265,7 @@ public class AnvilFuseTestUtil { public static void assertPriceEqual(Integer expectedPrice, int price) { if (expectedPrice == null) return; - Assertions.assertEquals(expectedPrice, price); + Assertions.assertEquals(expectedPrice, price, "Price of anvil fuse was wrong"); } }