From 9f31d396ce7c27082c645a64d2f190dcdf406045 Mon Sep 17 00:00:00 2001 From: alexcrea Date: Fri, 5 Apr 2024 18:00:46 +0200 Subject: [PATCH] Add logic for custom recipe. Add default for custom recipe. --- .../alexcrea/cuanvil/config/ConfigHolder.java | 9 ++- .../io/delilaheve/AnvilEventListener.kt | 71 ++++++++++++++++++- .../cuanvil/recipe/AnvilCustomRecipe.kt | 61 ++++++++++++---- 3 files changed, 122 insertions(+), 19 deletions(-) diff --git a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java index 68d6f68..6fafded 100644 --- a/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java +++ b/src/main/java/xyz/alexcrea/cuanvil/config/ConfigHolder.java @@ -262,11 +262,15 @@ public abstract class ConfigHolder { // Class for custom anvil craft public static class CustomAnvilCraftHolder extends ResourceConfigHolder { - private final static String CUSTOM_CRAFT_FILE_NAME = "custom_recipes"; + private final static String CUSTOM_RECIPE_FILE_NAME = "custom_recipes"; CustomAnvilRecipeManager recipeManager; private CustomAnvilCraftHolder() { - super(CUSTOM_CRAFT_FILE_NAME); + super(CUSTOM_RECIPE_FILE_NAME); + } + + public CustomAnvilRecipeManager getRecipeManager() { + return recipeManager; } @Override @@ -274,7 +278,6 @@ public abstract class ConfigHolder { this.recipeManager = new CustomAnvilRecipeManager(); this.recipeManager.prepareRecipes(this.configuration); } - } diff --git a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt index eab2c6b..0718d81 100644 --- a/src/main/kotlin/io/delilaheve/AnvilEventListener.kt +++ b/src/main/kotlin/io/delilaheve/AnvilEventListener.kt @@ -11,6 +11,7 @@ import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe import io.delilaheve.util.ItemUtil.unitRepair import org.bukkit.GameMode import org.bukkit.Material +import org.bukkit.entity.Item import org.bukkit.entity.Player import org.bukkit.event.Event import org.bukkit.event.EventHandler @@ -25,6 +26,7 @@ import org.bukkit.inventory.ItemStack import org.bukkit.inventory.meta.Repairable import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.group.ConflictType +import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import kotlin.math.min @@ -58,6 +60,25 @@ class AnvilEventListener : Listener { val player = event.view.player if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return + // Test custom recipe + val recipe = getCustomRecipe(first, second) + if(recipe != null){ + val amount = getCustomRecipeAmount(recipe, first, second) + + val resultItem: ItemStack + if(amount <= 1){ + resultItem = recipe.resultItem!! + }else{ + resultItem = recipe.resultItem!!.clone() + resultItem.amount *= amount + } + + event.result = resultItem + handleAnvilXp(inventory, event, recipe.xpCostPerCraft * amount, true) + + return + } + // Test rename lonely item if (second == null) { val resultItem = first.clone() @@ -139,6 +160,7 @@ class AnvilEventListener : Listener { CustomAnvil.log("no anvil fuse type found") event.result = null } + } private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int { @@ -168,6 +190,13 @@ class AnvilEventListener : Listener { val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT) + // Test custom craft + val recipe = getCustomRecipe(leftItem, rightItem) + if(recipe != null){ + event.result = Event.Result.ALLOW + return + } + val canMerge = leftItem.canMergeWith(rightItem) val unitRepairResult = leftItem.getRepair(rightItem) val allowed = (rightItem == null) @@ -370,16 +399,50 @@ class AnvilEventListener : Listener { return rightValue + illegalPenalty } + private fun getCustomRecipe ( + leftItem: ItemStack, + rightItem: ItemStack?) : AnvilCustomRecipe? { + + val recipeList = ConfigHolder.CUSTOM_RECIPE_HOLDER.recipeManager.recipeByMat[leftItem.type] ?: return null + + for (recipe in recipeList) { + if(recipe.testItem(leftItem, rightItem)){ + return recipe + } + } + + return null + } + + private fun getCustomRecipeAmount( + recipe: AnvilCustomRecipe, + leftItem: ItemStack, + rightItem: ItemStack? + ): Int{ + return if(recipe.exactCount) { 1 } + else { + // test amount + val resultItem = recipe.resultItem!! // we know exist as the recipe was returned to us + val maxResultAmount = resultItem.type.maxStackSize/resultItem.amount + val maxLeftAmount = leftItem.amount/recipe.leftItem!!.amount + val maxRightAmount = if(rightItem == null){ 1 } else{ rightItem.amount/recipe.rightItem!!.amount } + + min(min(maxResultAmount, maxLeftAmount), maxRightAmount) + } + } + + /** * Display xp needed for the work on the anvil inventory */ private fun handleAnvilXp( inventory: AnvilInventory, event: PrepareAnvilEvent, - anvilCost: Int + anvilCost: Int, + ignoreRules: Boolean = false ) { // Test repair cost limit - val finalAnvilCost = if (ConfigOptions.limitRepairCost) { + val finalAnvilCost = if (ConfigOptions.limitRepairCost && !ignoreRules) { min(anvilCost, ConfigOptions.limitRepairValue) } else { anvilCost @@ -392,8 +455,10 @@ class AnvilEventListener : Listener { .server .scheduler .runTask(CustomAnvil.instance, Runnable { - if (ConfigOptions.removeRepairLimit) { + if (ConfigOptions.removeRepairLimit || ignoreRules) { inventory.maximumRepairCost = Int.MAX_VALUE + } else{ + inventory.maximumRepairCost = 40 // minecraft default } inventory.repairCost = finalAnvilCost diff --git a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt index 584271e..697c3d0 100644 --- a/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt +++ b/src/main/kotlin/xyz/alexcrea/cuanvil/recipe/AnvilCustomRecipe.kt @@ -8,8 +8,8 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant class AnvilCustomRecipe( val name: String, var exactCount: Boolean, - var exactLeft: Boolean, - var exactRight: Boolean, + //var exactLeft: Boolean, + //var exactRight: Boolean, var xpCostPerCraft: Int, @@ -21,8 +21,8 @@ class AnvilCustomRecipe( // Static config name companion object { const val EXACT_COUNT_CONFIG = "exact_count" - const val EXACT_LEFT_CONFIG = "exact_left" - const val EXACT_RIGHT_CONFIG = "exact_right" + //const val EXACT_LEFT_CONFIG = "exact_left" + //const val EXACT_RIGHT_CONFIG = "exact_right" const val XP_COST_CONFIG = "xp_cost" @@ -30,19 +30,32 @@ class AnvilCustomRecipe( const val RIGHT_ITEM_CONFIG = "right_item" const val RESULT_ITEM_CONFIG = "result_item" + + val DEFAULT_EXACT_COUNT_CONFIG = true + //val DEFAULT_EXACT_LEFT_CONFIG = true + //val DEFAULT_EXACT_RIGHT_CONFIG = true + + val DEFAULT_XP_COST_CONFIG = 1 + + val DEFAULT_LEFT_ITEM_CONFIG = null + val DEFAULT_RIGHT_ITEM_CONFIG = null + val DEFAULT_RESULT_ITEM_CONFIG = null + + val XP_COST_CONFIG_RANGE = 0..255 + fun getFromConfig(name: String, configSection: ConfigurationSection?): AnvilCustomRecipe? { if(configSection == null) return null; return AnvilCustomRecipe( name, - configSection.getBoolean(EXACT_COUNT_CONFIG, true), - configSection.getBoolean(EXACT_LEFT_CONFIG, true), - configSection.getBoolean(EXACT_RIGHT_CONFIG, true), + configSection.getBoolean(EXACT_COUNT_CONFIG, DEFAULT_EXACT_COUNT_CONFIG), + //configSection.getBoolean(EXACT_LEFT_CONFIG, true), + //configSection.getBoolean(EXACT_RIGHT_CONFIG, true), - configSection.getInt(XP_COST_CONFIG, 10), + configSection.getInt(XP_COST_CONFIG, DEFAULT_XP_COST_CONFIG), - configSection.getItemStack(LEFT_ITEM_CONFIG, null), - configSection.getItemStack(RIGHT_ITEM_CONFIG, null), - configSection.getItemStack(RESULT_ITEM_CONFIG, null), + configSection.getItemStack(LEFT_ITEM_CONFIG, DEFAULT_LEFT_ITEM_CONFIG), + configSection.getItemStack(RIGHT_ITEM_CONFIG, DEFAULT_RIGHT_ITEM_CONFIG), + configSection.getItemStack(RESULT_ITEM_CONFIG, DEFAULT_RESULT_ITEM_CONFIG), ) } @@ -64,8 +77,8 @@ class AnvilCustomRecipe( val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config fileConfig.set("$name.$EXACT_COUNT_CONFIG", exactCount) - fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft) - fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight) + //fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft) + //fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight) fileConfig.set("$name.$XP_COST_CONFIG", xpCostPerCraft) @@ -79,6 +92,28 @@ class AnvilCustomRecipe( } } + fun testItem(item1: ItemStack, item2: ItemStack?): Boolean { + // We assume this function can be call only if leftItem != null + + // Test is valid + if(!validate()) return false + + // test of left item + if(!leftItem!!.isSimilar(item1)) return false // Test similar + if(exactCount){ + if((leftItem!!.amount != item1.amount)) return false // test exact amount + }else if(item1.amount < leftItem!!.amount) return false // test if it has at least the amount we ask + + // we don't know if right item can be + if(rightItem == null){ // null test + if(item2 != null) return false + }else if(!rightItem!!.isSimilar(item2)) return false // test if similar when not null + else if(exactCount) { + if (rightItem!!.amount != item2!!.amount) return false // test exact amount + }else if(item2!!.amount < rightItem!!.amount) return false // test if it has at least the amount we ask + + return true + } }