Add logic for custom recipe. Add default for custom recipe.

This commit is contained in:
alexcrea 2024-04-05 18:00:46 +02:00
parent 39ae8845b5
commit 9f31d396ce
3 changed files with 122 additions and 19 deletions

View file

@ -262,11 +262,15 @@ public abstract class ConfigHolder {
// Class for custom anvil craft // Class for custom anvil craft
public static class CustomAnvilCraftHolder extends ResourceConfigHolder { 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; CustomAnvilRecipeManager recipeManager;
private CustomAnvilCraftHolder() { private CustomAnvilCraftHolder() {
super(CUSTOM_CRAFT_FILE_NAME); super(CUSTOM_RECIPE_FILE_NAME);
}
public CustomAnvilRecipeManager getRecipeManager() {
return recipeManager;
} }
@Override @Override
@ -274,7 +278,6 @@ public abstract class ConfigHolder {
this.recipeManager = new CustomAnvilRecipeManager(); this.recipeManager = new CustomAnvilRecipeManager();
this.recipeManager.prepareRecipes(this.configuration); this.recipeManager.prepareRecipes(this.configuration);
} }
} }

View file

@ -11,6 +11,7 @@ import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.Material import org.bukkit.Material
import org.bukkit.entity.Item
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.Event import org.bukkit.event.Event
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@ -25,6 +26,7 @@ import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable import org.bukkit.inventory.meta.Repairable
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import kotlin.math.min import kotlin.math.min
@ -58,6 +60,25 @@ class AnvilEventListener : Listener {
val player = event.view.player val player = event.view.player
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return 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 // Test rename lonely item
if (second == null) { if (second == null) {
val resultItem = first.clone() val resultItem = first.clone()
@ -139,6 +160,7 @@ class AnvilEventListener : Listener {
CustomAnvil.log("no anvil fuse type found") CustomAnvil.log("no anvil fuse type found")
event.result = null event.result = null
} }
} }
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int { private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory): Int {
@ -168,6 +190,13 @@ class AnvilEventListener : Listener {
val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return val leftItem = inventory.getItem(ANVIL_INPUT_LEFT) ?: return
val rightItem = inventory.getItem(ANVIL_INPUT_RIGHT) 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 canMerge = leftItem.canMergeWith(rightItem)
val unitRepairResult = leftItem.getRepair(rightItem) val unitRepairResult = leftItem.getRepair(rightItem)
val allowed = (rightItem == null) val allowed = (rightItem == null)
@ -370,16 +399,50 @@ class AnvilEventListener : Listener {
return rightValue + illegalPenalty 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 * Display xp needed for the work on the anvil inventory
*/ */
private fun handleAnvilXp( private fun handleAnvilXp(
inventory: AnvilInventory, inventory: AnvilInventory,
event: PrepareAnvilEvent, event: PrepareAnvilEvent,
anvilCost: Int anvilCost: Int,
ignoreRules: Boolean = false
) { ) {
// Test repair cost limit // Test repair cost limit
val finalAnvilCost = if (ConfigOptions.limitRepairCost) { val finalAnvilCost = if (ConfigOptions.limitRepairCost && !ignoreRules) {
min(anvilCost, ConfigOptions.limitRepairValue) min(anvilCost, ConfigOptions.limitRepairValue)
} else { } else {
anvilCost anvilCost
@ -392,8 +455,10 @@ class AnvilEventListener : Listener {
.server .server
.scheduler .scheduler
.runTask(CustomAnvil.instance, Runnable { .runTask(CustomAnvil.instance, Runnable {
if (ConfigOptions.removeRepairLimit) { if (ConfigOptions.removeRepairLimit || ignoreRules) {
inventory.maximumRepairCost = Int.MAX_VALUE inventory.maximumRepairCost = Int.MAX_VALUE
} else{
inventory.maximumRepairCost = 40 // minecraft default
} }
inventory.repairCost = finalAnvilCost inventory.repairCost = finalAnvilCost

View file

@ -8,8 +8,8 @@ import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
class AnvilCustomRecipe( class AnvilCustomRecipe(
val name: String, val name: String,
var exactCount: Boolean, var exactCount: Boolean,
var exactLeft: Boolean, //var exactLeft: Boolean,
var exactRight: Boolean, //var exactRight: Boolean,
var xpCostPerCraft: Int, var xpCostPerCraft: Int,
@ -21,8 +21,8 @@ class AnvilCustomRecipe(
// Static config name // Static config name
companion object { companion object {
const val EXACT_COUNT_CONFIG = "exact_count" const val EXACT_COUNT_CONFIG = "exact_count"
const val EXACT_LEFT_CONFIG = "exact_left" //const val EXACT_LEFT_CONFIG = "exact_left"
const val EXACT_RIGHT_CONFIG = "exact_right" //const val EXACT_RIGHT_CONFIG = "exact_right"
const val XP_COST_CONFIG = "xp_cost" const val XP_COST_CONFIG = "xp_cost"
@ -30,19 +30,32 @@ class AnvilCustomRecipe(
const val RIGHT_ITEM_CONFIG = "right_item" const val RIGHT_ITEM_CONFIG = "right_item"
const val RESULT_ITEM_CONFIG = "result_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? { fun getFromConfig(name: String, configSection: ConfigurationSection?): AnvilCustomRecipe? {
if(configSection == null) return null; if(configSection == null) return null;
return AnvilCustomRecipe( return AnvilCustomRecipe(
name, name,
configSection.getBoolean(EXACT_COUNT_CONFIG, true), configSection.getBoolean(EXACT_COUNT_CONFIG, DEFAULT_EXACT_COUNT_CONFIG),
configSection.getBoolean(EXACT_LEFT_CONFIG, true), //configSection.getBoolean(EXACT_LEFT_CONFIG, true),
configSection.getBoolean(EXACT_RIGHT_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(LEFT_ITEM_CONFIG, DEFAULT_LEFT_ITEM_CONFIG),
configSection.getItemStack(RIGHT_ITEM_CONFIG, null), configSection.getItemStack(RIGHT_ITEM_CONFIG, DEFAULT_RIGHT_ITEM_CONFIG),
configSection.getItemStack(RESULT_ITEM_CONFIG, null), configSection.getItemStack(RESULT_ITEM_CONFIG, DEFAULT_RESULT_ITEM_CONFIG),
) )
} }
@ -64,8 +77,8 @@ class AnvilCustomRecipe(
val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config val fileConfig = ConfigHolder.CUSTOM_RECIPE_HOLDER.config
fileConfig.set("$name.$EXACT_COUNT_CONFIG", exactCount) fileConfig.set("$name.$EXACT_COUNT_CONFIG", exactCount)
fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft) //fileConfig.set("$name.$EXACT_LEFT_CONFIG", exactLeft)
fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight) //fileConfig.set("$name.$EXACT_RIGHT_CONFIG", exactRight)
fileConfig.set("$name.$XP_COST_CONFIG", xpCostPerCraft) 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
}
} }