move a lot of function to AnvilMergeLogic.kt

This commit is contained in:
alexcrea 2026-06-02 13:29:26 +02:00
parent bf8144ad06
commit 7a705f3bfc
Signed by: alexcrea
GPG key ID: E346CD16413450E3
19 changed files with 373 additions and 305 deletions

View file

@ -6,8 +6,8 @@ import org.bukkit.event.inventory.PrepareAnvilEvent;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.util.AnvilUseType; import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost; import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost;
/** /**
* Called after custom anvil processed the click on the result on the anvil inventory. * Called after custom anvil processed the click on the result on the anvil inventory.
@ -18,8 +18,12 @@ import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost;
* and {@link CAEarlyPreAnvilBypassEvent} for your use case * and {@link CAEarlyPreAnvilBypassEvent} for your use case
* <p> * <p>
* A null result will cancel this pre anvil event * A null result will cancel this pre anvil event
*
* @deprecated Prepare anvil Event should not be provided as it can be called on result and therefor not have prepare anvil event
* TODO a replacement is necessary but not yet made
*/ */
@SuppressWarnings("unused") @SuppressWarnings("unused")
@Deprecated(forRemoval = true, since = "1.17.0")
public class CATreatAnvilResultEvent extends Event { public class CATreatAnvilResultEvent extends Event {
private static final HandlerList HANDLERS = new HandlerList(); private static final HandlerList HANDLERS = new HandlerList();

View file

@ -2,7 +2,7 @@ package xyz.alexcrea.cuanvil.config;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import xyz.alexcrea.cuanvil.util.AnvilUseType; import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
import java.util.EnumMap; import java.util.EnumMap;

View file

@ -11,11 +11,11 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta; import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.WorkPenaltyType; import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui; import xyz.alexcrea.cuanvil.gui.config.global.BasicConfigGui;
import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions; import xyz.alexcrea.cuanvil.gui.util.GuiGlobalActions;
import xyz.alexcrea.cuanvil.util.AnvilUseType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.EnumMap; import java.util.EnumMap;

View file

@ -2,10 +2,10 @@ package xyz.alexcrea.cuanvil.update.plugin;
import io.delilaheve.util.ConfigOptions; import io.delilaheve.util.ConfigOptions;
import org.bukkit.configuration.file.FileConfiguration; import org.bukkit.configuration.file.FileConfiguration;
import xyz.alexcrea.cuanvil.anvil.AnvilUseType;
import xyz.alexcrea.cuanvil.config.ConfigHolder; import xyz.alexcrea.cuanvil.config.ConfigHolder;
import xyz.alexcrea.cuanvil.config.WorkPenaltyType; import xyz.alexcrea.cuanvil.config.WorkPenaltyType;
import xyz.alexcrea.cuanvil.gui.config.settings.WorkPenaltyTypeSettingGui; import xyz.alexcrea.cuanvil.gui.config.settings.WorkPenaltyTypeSettingGui;
import xyz.alexcrea.cuanvil.util.AnvilUseType;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import java.util.EnumMap; import java.util.EnumMap;

View file

@ -4,14 +4,13 @@ import io.delilaheve.CustomAnvil
import io.delilaheve.util.EnchantmentUtil.enchantmentName import io.delilaheve.util.EnchantmentUtil.enchantmentName
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.config.WorkPenaltyType import xyz.alexcrea.cuanvil.config.WorkPenaltyType
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.enchant.CAEnchantment import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.update.Version
import xyz.alexcrea.cuanvil.util.AnvilUseType
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
import java.math.BigDecimal import java.math.BigDecimal
import java.util.* import java.util.*

View file

@ -0,0 +1,271 @@
package xyz.alexcrea.cuanvil.anvil
import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.EnchantmentUtil.combineWith
import io.delilaheve.util.ItemUtil.findEnchantments
import io.delilaheve.util.ItemUtil.isEnchantedBook
import io.delilaheve.util.ItemUtil.repairFrom
import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.ChatColor
import org.bukkit.Material
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.util.CasedStringUtil
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
object AnvilMergeUtil {
open class AnvilResult {
companion object {
val EMPTY = AnvilResult(null, AnvilCost())
}
val item: ItemStack?
val cost: AnvilCost
val ignoreXpRules: Boolean
constructor(item: ItemStack?, cost: AnvilCost, ignoreXpRules: Boolean = false) {
this.item = item
this.cost = cost
this.ignoreXpRules = ignoreXpRules
}
fun isEmpty(): Boolean {
return item == null
}
}
class UnitRepairResult: AnvilResult {
companion object {
val EMPTY = UnitRepairResult(null, AnvilCost(), 0)
}
val repairAmount: Int
constructor(item: ItemStack?, cost: AnvilCost, repairAmount: Int) : super(item, cost) {
this.repairAmount = repairAmount
}
}
fun doRenaming(inventory: AnvilInventory,
player: Player, first: ItemStack
): AnvilResult {
val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
// Test/stop if nothing changed.
if (first == resultItem) {
CustomAnvil.log("no right item, But input is same as output")
return AnvilResult.EMPTY
}
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.RENAME_ONLY, cost)
return AnvilResult(result, cost)
}
private fun processDialogPCD(it: ItemMeta, player: HumanEntity) {
val keepDialog = ConfigOptions.canUseDialogRename(player) && ConfigOptions.shouldKeepRenameText
val pdc = it.persistentDataContainer
if(!keepDialog)
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
else {
val text = AnvilRenameDialogUtil.anvilRenameDialog.currentText(player)
if(text == null || text.isBlank())
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
else pdc.set(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY, PersistentDataType.STRING, text)
}
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
// Can be null
var renameText = ChatColor.stripColor(inventory.renameText)
var sumCost = 0
var useColor = false
if (ConfigOptions.renameColorPossible && renameText != null) {
val component = AnvilColorUtil.handleColor(
renameText,
AnvilColorUtil.renamePermission(player))
if (component != null) {
renameText = MiniMessageUtil.legacy_mm.serialize(component)
sumCost += ConfigOptions.useOfColorCost
useColor = true
}
}
// Rename item and add renaming cost
resultItem.itemMeta?.let {
val hasDisplayName = it.hasDisplayName()
val displayName = if (!hasDisplayName) null
else if (useColor) it.displayName
else ChatColor.stripColor(it.displayName)
if (!displayName.contentEquals(renameText) && !(displayName == null &&
renameText == "" ||
//TODO on recent paper check effective name instead
renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase())
)) {
it.setDisplayName(renameText)
processDialogPCD(it, player)
resultItem.itemMeta = it
sumCost += ConfigOptions.itemRenameCost
}
return sumCost
}
return 0
}
fun doMerge(
inventory: AnvilInventory,
player: Player,
first: ItemStack, second: ItemStack
): AnvilResult {
val newEnchants = first.findEnchantments()
.combineWith(second.findEnchantments(), first, player)
var hasChanged = !isIdentical(first.findEnchantments(), newEnchants)
val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost()
if(hasChanged){
resultItem.setEnchantmentsUnsafe(newEnchants)
// Calculate enchantment cost
AnvilXpUtil.getRightValues(second, resultItem, cost)
}
// Calculate repair cost
if (!first.isEnchantedBook() && !second.isEnchantedBook()) {
// we only need to be concerned with repair when neither item is a book
val repaired = resultItem.repairFrom(first, second)
cost.repair = if (repaired) ConfigOptions.itemRepairCost else 0
hasChanged = hasChanged || repaired
}
// Test/stop if nothing changed.
if (!hasChanged) {
CustomAnvil.log("Mergeable with second, But input is same as output")
return AnvilResult.EMPTY
}
// As calculatePenalty edit result, we need to calculate penalty after checking equality
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
// Calculate rename cost
cost.rename = handleRename(resultItem, inventory, player)
val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.MERGE, cost)
return AnvilResult(result, cost)
}
private fun isIdentical(
firstEnchants: MutableMap<CAEnchantment, Int>,
resultEnchants: MutableMap<CAEnchantment, Int>
): Boolean {
if(firstEnchants.size != resultEnchants.size) return false
for (entry in resultEnchants) {
if(firstEnchants.getOrDefault(entry.key, entry.value-1) != entry.value) return false
}
return true
}
// return true if a custom recipe exist with these ingredients
fun testCustomRecipe(
player: Player,
first: ItemStack, second: ItemStack?
): AnvilResult {
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
if (recipe == null) return AnvilResult.EMPTY
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second)
val resultItem: ItemStack = DependencyManager.cloneItem(player, recipe.resultItem!!)
resultItem.amount *= amount
// Maybe add an option on custom craft to ignore/not ignore penalty ??
val xpCost = recipe.determineCost(amount, first, resultItem)
val cost = AnvilCost()
cost.recipe = if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
else AnvilXpUtil.calculateLevelForXp(xpCost)
val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
return AnvilResult(result, cost, true)
}
fun testUnitRepair(
inventory: AnvilInventory,
player: Player,
first: ItemStack, second: ItemStack
): UnitRepairResult {
val unitRepairAmount = first.getRepair(second) ?: return UnitRepairResult.EMPTY
val resultItem = DependencyManager.cloneItem(player, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if (repairAmount > 0)
cost.repair = repairAmount * ConfigOptions.unitRepairCost
// We do not care about right item penalty for unit repair
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.UNIT_REPAIR)
// Test/stop if nothing changed.
if (first == resultItem) {
CustomAnvil.log("unit repair, But input is same as output")
return UnitRepairResult.EMPTY
}
val result = DependencyManager.tryTreatAnvilResult(resultItem, AnvilUseType.UNIT_REPAIR, cost)
return UnitRepairResult(result, cost, repairAmount)
}
fun testLoreEdit(
player: Player,
first: ItemStack, second: ItemStack
): AnvilResult {
val type = second.type
var resultItem: ItemStack? = null
val cost = AnvilCost()
if (Material.WRITABLE_BOOK == type) {
resultItem = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, cost)
} else if (Material.PAPER == type) {
resultItem = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, cost)
}
if (resultItem.isAir || first == resultItem) {
CustomAnvil.log("lore edit, But input is same as output")
return AnvilResult.EMPTY
}
return AnvilResult(resultItem, cost)
}
}

View file

@ -1,60 +1,60 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.anvil
import org.bukkit.Material import org.bukkit.Material
import xyz.alexcrea.cuanvil.config.WorkPenaltyType.WorkPenaltyPart import xyz.alexcrea.cuanvil.config.WorkPenaltyType
import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.anvil.AnvilUseTypeUtil
enum class AnvilUseType( enum class AnvilUseType(
val typeName: String, val path: String, val typeName: String, val path: String,
val defaultPenalty: WorkPenaltyPart, val defaultPenalty: WorkPenaltyType.WorkPenaltyPart,
val displayName: String, val displayMat: Material val displayName: String, val displayMat: Material
) { ) {
RENAME_ONLY( RENAME_ONLY(
"rename_only", "rename_only",
WorkPenaltyPart(false, true), WorkPenaltyType.WorkPenaltyPart(false, true),
"Rename Only", Material.NAME_TAG "Rename Only", Material.NAME_TAG
), ),
MERGE( MERGE(
"merge", "merge",
WorkPenaltyPart(true, true), WorkPenaltyType.WorkPenaltyPart(true, true),
"Merge", Material.ANVIL "Merge", Material.ANVIL
), ),
UNIT_REPAIR( UNIT_REPAIR(
"unit_repair", "unit_repair",
WorkPenaltyPart(true, true), WorkPenaltyType.WorkPenaltyPart(true, true),
"Unit Repair", Material.DIAMOND "Unit Repair", Material.DIAMOND
), ),
CUSTOM_CRAFT( CUSTOM_CRAFT(
"custom_craft", "custom_craft",
WorkPenaltyPart(false, false), WorkPenaltyType.WorkPenaltyPart(false, false),
"Custom Craft", Material.CRAFTING_TABLE "Custom Craft", Material.CRAFTING_TABLE
), ),
LORE_EDIT_BOOK_APPEND( LORE_EDIT_BOOK_APPEND(
"lore_edit_book_append", "lore_edit.book_and_quil.append", "lore_edit_book_append", "lore_edit.book_and_quil.append",
WorkPenaltyPart(false, false), WorkPenaltyType.WorkPenaltyPart(false, false),
"Book Add", Material.WRITABLE_BOOK "Book Add", Material.WRITABLE_BOOK
), ),
LORE_EDIT_BOOK_REMOVE( LORE_EDIT_BOOK_REMOVE(
"lore_edit_book_remove", "lore_edit.book_and_quil.remove", "lore_edit_book_remove", "lore_edit.book_and_quil.remove",
WorkPenaltyPart(false, false), WorkPenaltyType.WorkPenaltyPart(false, false),
"Book Remove", Material.WRITABLE_BOOK "Book Remove", Material.WRITABLE_BOOK
), ),
LORE_EDIT_PAPER_APPEND( LORE_EDIT_PAPER_APPEND(
"lore_edit_paper_append", "lore_edit.paper.append_line", "lore_edit_paper_append", "lore_edit.paper.append_line",
WorkPenaltyPart(false, false), WorkPenaltyType.WorkPenaltyPart(false, false),
"Paper Add", Material.WRITABLE_BOOK "Paper Add", Material.WRITABLE_BOOK
), ),
LORE_EDIT_PAPER_REMOVE( LORE_EDIT_PAPER_REMOVE(
"lore_edit_paper_remove", "lore_edit.paper.remove_line", "lore_edit_paper_remove", "lore_edit.paper.remove_line",
WorkPenaltyPart(false, false), WorkPenaltyType.WorkPenaltyPart(false, false),
"Paper Remove", Material.WRITABLE_BOOK "Paper Remove", Material.WRITABLE_BOOK
), ),
; ;
constructor( constructor(
typeName: String, typeName: String,
defaultPenalty: WorkPenaltyPart, defaultPenalty: WorkPenaltyType.WorkPenaltyPart,
displayName: String, displayMat: Material displayName: String, displayMat: Material
) : ) :
this( this(

View file

@ -13,6 +13,7 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.Inventory import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAClickResultBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAEarlyPreAnvilBypassEvent
import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent import xyz.alexcrea.cuanvil.api.event.listener.CAPreAnvilBypassEvent
@ -30,9 +31,8 @@ import xyz.alexcrea.cuanvil.dependency.scheduler.TaskScheduler
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.util.AnvilUseType
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import java.util.logging.Level import java.util.logging.Level
object DependencyManager { object DependencyManager {
@ -234,19 +234,20 @@ object DependencyManager {
// Return null if there was an issue // Return null if there was an issue
fun tryTreatAnvilResult( fun tryTreatAnvilResult(
event: PrepareAnvilEvent,
result: ItemStack, result: ItemStack,
useType: AnvilUseType, useType: AnvilUseType,
cost: AnvilXpUtil.AnvilCost cost: AnvilXpUtil.AnvilCost
): ItemStack? { ): ItemStack? {
val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost) //TODO
/*val treatEvent = CATreatAnvilResultEvent(event, useType, result, cost)
try { try {
unsafeTryTreatAnvilResult(treatEvent) unsafeTryTreatAnvilResult(treatEvent)
return treatEvent.result return treatEvent.result
} catch (e: Exception) { } catch (e: Exception) {
logExceptionAndClear(event.view.player, event.inventory, e) logExceptionAndClear(event.view.player, event.inventory, e)
return null return null
} }*/
return result
} }
private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) { private fun unsafeTryTreatAnvilResult(event: CATreatAnvilResultEvent) {
@ -295,11 +296,11 @@ object DependencyManager {
} }
// Clone item and use plugin specific clone if needed // Clone item and use plugin specific clone if needed
fun cloneItem(event: PrepareAnvilEvent, item: ItemStack): ItemStack { fun cloneItem(player: HumanEntity, item: ItemStack): ItemStack {
try { try {
return unsafeCloneItem(item) return unsafeCloneItem(item)
} catch (e: Exception) { } catch (e: Exception) {
logException(event.view.player, e) logException(player, e)
return item.clone() return item.clone()
} }
} }

View file

@ -15,9 +15,9 @@ import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError import xyz.alexcrea.cuanvil.util.MetricsUtil.trackError
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import java.util.logging.Level import java.util.logging.Level
import kotlin.reflect.KClass import kotlin.reflect.KClass

View file

@ -10,8 +10,8 @@ import valorless.havenbags.HavenBags
import valorless.havenbags.features.BagSkin import valorless.havenbags.features.BagSkin
import valorless.havenbags.features.BagUpgrade import valorless.havenbags.features.BagUpgrade
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener
import xyz.alexcrea.cuanvil.util.AnvilXpUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
class HavenBagsDependency { class HavenBagsDependency {

View file

@ -16,6 +16,7 @@ import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.BookMeta import org.bukkit.inventory.meta.BookMeta
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
@ -23,13 +24,12 @@ import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_OUTPUT_SLOT
import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe import xyz.alexcrea.cuanvil.recipe.AnvilCustomRecipe
import xyz.alexcrea.cuanvil.util.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.AnvilUseType
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.CustomRecipeUtil import xyz.alexcrea.cuanvil.util.CustomRecipeUtil
import xyz.alexcrea.cuanvil.util.MiniMessageUtil import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
import xyz.alexcrea.cuanvil.util.anvil.AnvilLoreEditUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.config.LoreEditType
import java.util.* import java.util.*

View file

@ -1,18 +1,8 @@
package xyz.alexcrea.cuanvil.listener package xyz.alexcrea.cuanvil.listener
import com.github.stefvanschie.inventoryframework.util.InventoryViewUtil
import com.jankominek.disenchantment.utils.AnvilCostUtils
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.EnchantmentUtil.combineWith
import io.delilaheve.util.ItemUtil.canMergeWith import io.delilaheve.util.ItemUtil.canMergeWith
import io.delilaheve.util.ItemUtil.findEnchantments
import io.delilaheve.util.ItemUtil.isEnchantedBook
import io.delilaheve.util.ItemUtil.repairFrom
import io.delilaheve.util.ItemUtil.setEnchantmentsUnsafe
import io.delilaheve.util.ItemUtil.unitRepair
import org.bukkit.ChatColor
import org.bukkit.Material
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
@ -20,18 +10,20 @@ import org.bukkit.event.EventPriority
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory import org.bukkit.inventory.AnvilInventory
import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.EnchantmentStorageMeta import org.bukkit.inventory.meta.EnchantmentStorageMeta
import org.bukkit.inventory.meta.ItemMeta import org.bukkit.inventory.meta.ItemMeta
import org.bukkit.persistence.PersistentDataType import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.AnvilResult
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.doMerge
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.doRenaming
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testCustomRecipe
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testLoreEdit
import xyz.alexcrea.cuanvil.anvil.AnvilMergeUtil.testUnitRepair
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.util.JustForEasierHotswapUtil
import xyz.alexcrea.cuanvil.enchant.CAEnchantment
import xyz.alexcrea.cuanvil.util.*
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil.AnvilCost
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
/** /**
@ -73,8 +65,8 @@ class PrepareAnvilListener : Listener {
val second = inventory.getItem(ANVIL_INPUT_RIGHT) val second = inventory.getItem(ANVIL_INPUT_RIGHT)
if(IS_EMPTY_TEST) { if(IS_EMPTY_TEST) {
setNoResult(event, player, view)
IS_EMPTY_TEST = false IS_EMPTY_TEST = false
applyResult(event, player, AnvilResult.EMPTY)
return return
} }
@ -86,7 +78,7 @@ class PrepareAnvilListener : Listener {
if (isImmutable(first) || isImmutable(second)) { if (isImmutable(first) || isImmutable(second)) {
CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable") CustomAnvil.verboseLog("Skipping anvil process as one of the two item is immutable")
setNoResult(event, player, view) applyResult(event, player, AnvilResult.EMPTY)
return return
} }
@ -99,42 +91,44 @@ class PrepareAnvilListener : Listener {
if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return if (!player.hasPermission(CustomAnvil.affectedByPluginPermission)) return
if(first == null) { val result = getResult(inventory, player, first, second)
setNoResult(event, player, view) applyResult(event, player, result)
return
} }
fun getResult(
inventory: AnvilInventory,
player: Player,
first: ItemStack?, second: ItemStack?) : AnvilResult
{
if(first == null)
return AnvilResult.EMPTY
// Test custom recipe // Test custom recipe
if (testCustomRecipe(event, inventory, player, first, second)) return var result = testCustomRecipe(player, first, second)
if (!result.isEmpty())
return result
// Test rename lonely item // Test rename lonely item
val shouldTryRename = second.isAir val shouldTryRename = second.isAir
CustomAnvil.verboseLog("checking air in main logic: $shouldTryRename") CustomAnvil.verboseLog("checking air in main logic: $shouldTryRename")
if (shouldTryRename) { if (shouldTryRename)
if(!doRenaming(event, inventory, player, first)) return doRenaming(inventory, player, first)
setNoResult(event, player, view)
return
}
// Test for merge // Test for merge
if (first.canMergeWith(second!!)) { if (first.canMergeWith(second!!))
if(!doMerge(event, inventory, player, first, second)) return doMerge(inventory, player, first, second)
setNoResult(event, player, view)
return
}
// Test for unit repair // Test for unit repair
if (testUnitRepair(event, inventory, player, first, second)) return result = testUnitRepair(inventory, player, first, second)
if (!result.isEmpty())
return result
// Test for lore edit // Test for lore edit
if (testLoreEdit(event, inventory, player, first, second)) return result = testLoreEdit(player, first, second)
if (!result.isEmpty())
return result
setNoResult(event, player, view) return AnvilResult.EMPTY
}
private fun setNoResult(event: PrepareAnvilEvent, player: Player, view: InventoryView) {
event.result = null
AnvilXpUtil.onNoResult(player, view)
} }
private fun tryRenameDialog( private fun tryRenameDialog(
@ -146,20 +140,6 @@ class PrepareAnvilListener : Listener {
AnvilRenameDialogUtil.anvilRenameDialog.tryShowDialog(player, event) AnvilRenameDialogUtil.anvilRenameDialog.tryShowDialog(player, event)
} }
private fun processDialogPCD(it: ItemMeta, player: HumanEntity) {
val keepDialog = ConfigOptions.canUseDialogRename(player) && ConfigOptions.shouldKeepRenameText
val pdc = it.persistentDataContainer
if(!keepDialog)
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
else {
val text = AnvilRenameDialogUtil.anvilRenameDialog.currentText(player)
if(text == null || text.isBlank())
pdc.remove(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY)
else pdc.set(AnvilRenameDialog.PCD_KEEP_RENAME_TEXT_KEY, PersistentDataType.STRING, text)
}
}
private fun isImmutable(item: ItemStack?): Boolean { private fun isImmutable(item: ItemStack?): Boolean {
if (item.isAir) return false if (item.isAir) return false
@ -186,203 +166,14 @@ class PrepareAnvilListener : Listener {
return false return false
} }
// return true if a custom recipe exist with these ingredients private fun applyResult(event: PrepareAnvilEvent, player: Player, result: AnvilResult) {
private fun testCustomRecipe( event.result = result.item
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: Player,
first: ItemStack, second: ItemStack?
): Boolean {
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
CustomAnvil.verboseLog("custom recipe not null? ${recipe != null}")
if (recipe == null) return false
val amount = CustomRecipeUtil.getCustomRecipeAmount(recipe, first, second) if(result.item == null) {
AnvilXpUtil.onNoResult(player, event.view)
val resultItem: ItemStack = DependencyManager.cloneItem(event, recipe.resultItem!!) return
resultItem.amount *= amount }
AnvilXpUtil.setAnvilInvCost(event.inventory, event.view, player, result.cost, result.ignoreXpRules)
// Maybe add an option on custom craft to ignore/not ignore penalty ??
val xpCost = recipe.determineCost(amount, first, resultItem)
val cost = AnvilCost()
cost.recipe = if (recipe.removeExactLinearXp) AnvilXpUtil.calculateMinimumLevelForXp(xpCost)
else AnvilXpUtil.calculateLevelForXp(xpCost)
event.result = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.CUSTOM_CRAFT, cost)
AnvilXpUtil.setAnvilInvCost(inventory, event.view, player, cost, true)
return true
} }
private fun doRenaming(
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: Player, first: ItemStack
): Boolean {
val resultItem = DependencyManager.cloneItem(event, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
// Test/stop if nothing changed.
if (first == resultItem) {
CustomAnvil.log("no right item, But input is same as output")
return false
}
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.RENAME_ONLY)
event.result = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.RENAME_ONLY, cost)
AnvilXpUtil.setAnvilInvCost(inventory, event.view, player, cost)
return true
}
private fun handleRename(resultItem: ItemStack, inventory: AnvilInventory, player: HumanEntity): Int {
// Can be null
var renameText = ChatColor.stripColor(inventory.renameText)
var sumCost = 0
var useColor = false
if (ConfigOptions.renameColorPossible && renameText != null) {
val component = AnvilColorUtil.handleColor(
renameText,
AnvilColorUtil.renamePermission(player))
if (component != null) {
renameText = MiniMessageUtil.legacy_mm.serialize(component)
sumCost += ConfigOptions.useOfColorCost
useColor = true
}
}
// Rename item and add renaming cost
resultItem.itemMeta?.let {
val hasDisplayName = it.hasDisplayName()
val displayName = if (!hasDisplayName) null
else if (useColor) it.displayName
else ChatColor.stripColor(it.displayName)
if (!displayName.contentEquals(renameText) && !(displayName == null &&
renameText == "" ||
//TODO on recent paper check effective name instead
renameText == CasedStringUtil.snakeToUpperSpacedCase(resultItem.type.name.lowercase())
)) {
it.setDisplayName(renameText)
processDialogPCD(it, player)
resultItem.itemMeta = it
sumCost += ConfigOptions.itemRenameCost
}
return sumCost
}
return 0
}
private fun doMerge(
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: Player,
first: ItemStack, second: ItemStack
): Boolean {
val newEnchants = first.findEnchantments()
.combineWith(second.findEnchantments(), first, player)
var hasChanged = !isIdentical(first.findEnchantments(), newEnchants)
val resultItem = DependencyManager.cloneItem(event, first)
val cost = AnvilCost()
if(hasChanged){
resultItem.setEnchantmentsUnsafe(newEnchants)
// Calculate enchantment cost
AnvilXpUtil.getRightValues(second, resultItem, cost)
}
// Calculate repair cost
if (!first.isEnchantedBook() && !second.isEnchantedBook()) {
// we only need to be concerned with repair when neither item is a book
val repaired = resultItem.repairFrom(first, second)
cost.repair = if (repaired) ConfigOptions.itemRepairCost else 0
hasChanged = hasChanged || repaired
}
// Test/stop if nothing changed.
if (!hasChanged) {
CustomAnvil.log("Mergeable with second, But input is same as output")
return false
}
// As calculatePenalty edit result, we need to calculate penalty after checking equality
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, second, resultItem, AnvilUseType.MERGE)
// Calculate rename cost
cost.rename = handleRename(resultItem, inventory, player)
// Finally, we set result
event.result = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.MERGE, cost)
AnvilXpUtil.setAnvilInvCost(inventory, event.view, player, cost)
return true
}
private fun isIdentical(
firstEnchants: MutableMap<CAEnchantment, Int>,
resultEnchants: MutableMap<CAEnchantment, Int>
): Boolean {
if(firstEnchants.size != resultEnchants.size) return false
for (entry in resultEnchants) {
if(firstEnchants.getOrDefault(entry.key, entry.value-1) != entry.value) return false
}
return true
}
// return true if there is a valid unit repair with these ingredients
private fun testUnitRepair(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: Player,
first: ItemStack, second: ItemStack
): Boolean {
val unitRepairAmount = first.getRepair(second) ?: return false
val resultItem = DependencyManager.cloneItem(event, first)
val cost = AnvilCost()
cost.rename = handleRename(resultItem, inventory, player)
val repairAmount = resultItem.unitRepair(second.amount, unitRepairAmount)
if (repairAmount > 0) {
cost.repair = repairAmount * ConfigOptions.unitRepairCost
}
// We do not care about right item penalty for unit repair
cost.workPenalty = AnvilXpUtil.calculatePenalty(first, null, resultItem, AnvilUseType.UNIT_REPAIR)
// Test/stop if nothing changed.
if (first == resultItem) {
CustomAnvil.log("unit repair, But input is same as output")
event.result = null
return true
}
event.result = DependencyManager.tryTreatAnvilResult(event, resultItem, AnvilUseType.UNIT_REPAIR, cost)
AnvilXpUtil.setAnvilInvCost(inventory, event.view, player, cost)
return true
}
private fun testLoreEdit(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: Player,
first: ItemStack, second: ItemStack
): Boolean {
val type = second.type
var result: ItemStack? = null
val cost = AnvilCost()
if (Material.WRITABLE_BOOK == type) {
result = AnvilLoreEditUtil.tryLoreEditByBook(player, first, second, cost)
} else if (Material.PAPER == type) {
result = AnvilLoreEditUtil.tryLoreEditByPaper(player, first, second, cost)
}
if (result.isAir || first == result) {
CustomAnvil.log("lore edit, But input is same as output")
event.result = null
return false
}
event.result = result
AnvilXpUtil.setAnvilInvCost(inventory, event.view, player, cost)
return true
}
} }

View file

@ -3,11 +3,11 @@ package xyz.alexcrea.cuanvil.recipe
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.configuration.ConfigurationSection import org.bukkit.configuration.ConfigurationSection
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant import xyz.alexcrea.cuanvil.gui.util.GuiSharedConstant
import xyz.alexcrea.cuanvil.util.AnvilUseType
import xyz.alexcrea.cuanvil.util.AnvilXpUtil
import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir import xyz.alexcrea.cuanvil.util.MaterialUtil.isAir
import xyz.alexcrea.cuanvil.util.anvil.AnvilXpUtil
class AnvilCustomRecipe( class AnvilCustomRecipe(
val name: String, val name: String,

View file

@ -1,11 +1,11 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util.anvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.permissions.Permissible import org.bukkit.permissions.Permissible
import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import java.util.regex.Matcher import java.util.regex.Matcher
import java.util.regex.Pattern import java.util.regex.Pattern
import kotlin.text.indexOf
object AnvilColorUtil { object AnvilColorUtil {
private val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string private val HEX_PATTERN: Pattern = Pattern.compile("#[A-Fa-f0-9]{6}") // pattern to find hexadecimal string

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util.anvil
import net.kyori.adventure.text.Component import net.kyori.adventure.text.Component
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
@ -8,7 +8,7 @@ import org.bukkit.permissions.Permissible
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.componentLore
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentLore
import xyz.alexcrea.cuanvil.util.AnvilXpUtil.AnvilCost import xyz.alexcrea.cuanvil.util.MiniMessageUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil
import xyz.alexcrea.cuanvil.util.config.LoreEditType import xyz.alexcrea.cuanvil.util.config.LoreEditType
import java.util.* import java.util.*
@ -31,7 +31,7 @@ object AnvilLoreEditUtil {
player: Permissible, player: Permissible,
first: ItemStack, first: ItemStack,
book: BookMeta, book: BookMeta,
cost: AnvilCost cost: AnvilXpUtil.AnvilCost
): ItemStack? { ): ItemStack? {
if (!hasLoreEditByBookPermission(player)) return null if (!hasLoreEditByBookPermission(player)) return null
@ -60,7 +60,7 @@ object AnvilLoreEditUtil {
return result return result
} }
fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, cost: AnvilCost): ItemStack? { fun handleLoreRemoveByBook(player: Permissible, first: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
if (!hasLoreEditByBookPermission(player)) return null if (!hasLoreEditByBookPermission(player)) return null
// remove lore // remove lore
@ -116,7 +116,7 @@ object AnvilLoreEditUtil {
return null return null
} }
fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack, cost: AnvilCost): ItemStack? { fun tryLoreEditByBook(player: HumanEntity, first: ItemStack, second: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
val isAppend = bookLoreEditIsAppend(first, second) ?: return null val isAppend = bookLoreEditIsAppend(first, second) ?: return null
val meta = second.itemMeta as BookMeta val meta = second.itemMeta as BookMeta
@ -147,7 +147,7 @@ object AnvilLoreEditUtil {
player: Permissible, player: Permissible,
first: ItemStack, first: ItemStack,
second: ItemStack, second: ItemStack,
cost: AnvilCost cost: AnvilXpUtil.AnvilCost
): ItemStack? { ): ItemStack? {
if (!hasLoreEditByPaperPermission(player)) return null if (!hasLoreEditByPaperPermission(player)) return null
@ -181,7 +181,7 @@ object AnvilLoreEditUtil {
return result return result
} }
fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, cost: AnvilCost): ItemStack? { fun handleLoreRemoveByPaper(player: Permissible, first: ItemStack, cost: AnvilXpUtil.AnvilCost): ItemStack? {
if (!hasLoreEditByPaperPermission(player)) return null if (!hasLoreEditByPaperPermission(player)) return null
// remove lore line // remove lore line
@ -223,7 +223,7 @@ object AnvilLoreEditUtil {
player: HumanEntity, player: HumanEntity,
first: ItemStack, first: ItemStack,
second: ItemStack, second: ItemStack,
cost: AnvilCost cost: AnvilXpUtil.AnvilCost
): ItemStack? { ): ItemStack? {
val isAppend = paperLoreEditIsAppend(first, second) ?: return null val isAppend = paperLoreEditIsAppend(first, second) ?: return null
@ -232,7 +232,7 @@ object AnvilLoreEditUtil {
} }
private fun baseEditLoreXpCost( private fun baseEditLoreXpCost(
cost: AnvilCost, cost: AnvilXpUtil.AnvilCost,
first: ItemStack, first: ItemStack,
result: ItemStack, result: ItemStack,
editType: LoreEditType editType: LoreEditType

View file

@ -1,4 +1,4 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util.anvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions

View file

@ -1,8 +1,7 @@
package xyz.alexcrea.cuanvil.util package xyz.alexcrea.cuanvil.util.anvil
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
import io.delilaheve.util.EnchantmentUtil.enchantmentName import io.delilaheve.util.EnchantmentUtil.enchantmentName
import io.delilaheve.util.ItemUtil.findEnchantments import io.delilaheve.util.ItemUtil.findEnchantments
import io.delilaheve.util.ItemUtil.isEnchantedBook import io.delilaheve.util.ItemUtil.isEnchantedBook
@ -15,13 +14,16 @@ import org.bukkit.inventory.InventoryView
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import org.bukkit.inventory.meta.Repairable import org.bukkit.inventory.meta.Repairable
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.config.ConfigHolder import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import xyz.alexcrea.cuanvil.util.AnvilTitleUtil
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
import java.math.BigDecimal import java.math.BigDecimal
import kotlin.math.min import kotlin.math.min
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
object AnvilXpUtil { object AnvilXpUtil {

View file

@ -1,6 +1,6 @@
package xyz.alexcrea.cuanvil.util.config package xyz.alexcrea.cuanvil.util.config
import xyz.alexcrea.cuanvil.util.AnvilUseType import xyz.alexcrea.cuanvil.anvil.AnvilUseType
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_COLOR_CODE import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_COLOR_CODE
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_HEX_COLOR import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_HEX_COLOR
import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_MINIMESSAGE import xyz.alexcrea.cuanvil.util.config.LoreEditConfigUtil.ALLOW_MINIMESSAGE

View file

@ -8,7 +8,7 @@ import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialog
import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialogImpl import xyz.alexcrea.cuanvil.dialog.AnvilRenameDialogImpl
import xyz.alexcrea.cuanvil.update.UpdateUtils import xyz.alexcrea.cuanvil.update.UpdateUtils
import xyz.alexcrea.cuanvil.util.AnvilColorUtil import xyz.alexcrea.cuanvil.util.anvil.AnvilColorUtil
object AnvilRenameDialogUtil { object AnvilRenameDialogUtil {