result work for unity repair and custom craft

This commit is contained in:
alexcrea 2026-05-30 03:53:31 +02:00
parent 2d31a7f5a8
commit bf8144ad06
Signed by: alexcrea
GPG key ID: E346CD16413450E3
3 changed files with 90 additions and 55 deletions

View file

@ -109,7 +109,7 @@ public class CATreatAnvilResultEvent extends Event {
*/ */
@Deprecated(forRemoval = true, since = "1.17.0") @Deprecated(forRemoval = true, since = "1.17.0")
public int getLevelCost() { public int getLevelCost() {
return cost.sum(); return cost.asXpCost();
} }
/** /**
@ -131,7 +131,7 @@ public class CATreatAnvilResultEvent extends Event {
*/ */
@Deprecated(forRemoval = true, since = "1.17.0") @Deprecated(forRemoval = true, since = "1.17.0")
public void setLevelCost(int levelCost) { public void setLevelCost(int levelCost) {
cost.setGeneric(levelCost - cost.getGeneric() - cost.sum()); cost.setGeneric(levelCost - cost.getGeneric() - cost.asXpCost());
} }
/** /**

View file

@ -17,6 +17,7 @@ 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.dependency.DependencyManager import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName import xyz.alexcrea.cuanvil.dependency.util.PlatformUtil.setComponentDisplayName
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_LEFT
import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT import xyz.alexcrea.cuanvil.listener.PrepareAnvilListener.Companion.ANVIL_INPUT_RIGHT
@ -32,7 +33,6 @@ import xyz.alexcrea.cuanvil.util.UnitRepairUtil.getRepair
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.*
import java.util.concurrent.atomic.AtomicInteger
import java.util.concurrent.atomic.AtomicReference import java.util.concurrent.atomic.AtomicReference
import kotlin.math.min import kotlin.math.min
@ -89,6 +89,7 @@ class AnvilResultListener : Listener {
// Rename // Rename
if (rightItem == null) { if (rightItem == null) {
// BRUH
event.result = Event.Result.ALLOW event.result = Event.Result.ALLOW
return return
} }
@ -246,14 +247,13 @@ class AnvilResultListener : Listener {
rightItem: ItemStack?, rightItem: ItemStack?,
rightRemoveCount: Int, rightRemoveCount: Int,
output: ItemStack, output: ItemStack,
repairCost: Int, cost: AnvilCost,
): Boolean { ): Boolean {
// To avoid vanilla, we cancel the event // To avoid vanilla, we cancel the event
event.result = Event.Result.DENY event.result = Event.Result.DENY
event.isCancelled = true event.isCancelled = true
// Assumed if player do not have enough xp then it returned MIN_VALUE if (!cost.valid) return false
if (repairCost == Int.MIN_VALUE) return false
// Where should we get the item // Where should we get the item
val slotDestination = getActionSlot(event, player) val slotDestination = getActionSlot(event, player)
@ -261,6 +261,13 @@ class AnvilResultListener : Listener {
// If not creative middle click... // If not creative middle click...
if (event.click != ClickType.MIDDLE) { if (event.click != ClickType.MIDDLE) {
if(cost.isMonetary) {
val result = EconomyManager.economy!!.remove(player, cost.asMonetaryCost())
if(!result) return false
} else {
player.level -= cost.asXpCost()
}
// We remove what should be removed // We remove what should be removed
if (leftItem != null) leftItem.amount -= leftRemoveCount if (leftItem != null) leftItem.amount -= leftRemoveCount
inventory.setItem(ANVIL_INPUT_LEFT, leftItem) inventory.setItem(ANVIL_INPUT_LEFT, leftItem)
@ -269,7 +276,7 @@ class AnvilResultListener : Listener {
inventory.setItem(ANVIL_INPUT_RIGHT, rightItem) inventory.setItem(ANVIL_INPUT_RIGHT, rightItem)
inventory.setItem(ANVIL_OUTPUT_SLOT, null) inventory.setItem(ANVIL_OUTPUT_SLOT, null)
player.level -= repairCost
} }
// Finally, we add the item to the player // Finally, we add the item to the player
@ -313,55 +320,75 @@ class AnvilResultListener : Listener {
inventory: AnvilInventory, player: Player, inventory: AnvilInventory, player: Player,
leftItem: ItemStack, output: ItemStack, leftItem: ItemStack, output: ItemStack,
resultCopy: ItemStack, resultAmount: Int resultCopy: ItemStack, resultAmount: Int
): Int { ): AnvilCost {
if (player.gameMode == GameMode.CREATIVE) return 0 if (player.gameMode == GameMode.CREATIVE) return AnvilCost(0)
var repairCost = 0 val cost = AnvilCost()
// Get repairCost // Get repairCost
leftItem.itemMeta?.let { leftMeta -> leftItem.itemMeta?.let { leftMeta ->
val leftName = leftMeta.displayName val leftName = leftMeta.displayName
output.itemMeta?.let { output.itemMeta?.let {
// Rename cost // Rename cost
if (!leftName.contentEquals(it.displayName)) { if (!leftName.contentEquals(it.displayName)) {
repairCost += ConfigOptions.itemRenameCost cost.rename += ConfigOptions.itemRenameCost
// Color cost // Color cost
if (it.displayName.contains('§')) { if (it.displayName.contains('§')) {
repairCost += ConfigOptions.useOfColorCost cost.rename += ConfigOptions.useOfColorCost
} }
} }
} }
} }
repairCost += AnvilXpUtil.calculatePenalty(leftItem, null, resultCopy, AnvilUseType.UNIT_REPAIR) cost.workPenalty = AnvilXpUtil.calculatePenalty(leftItem, null, resultCopy, AnvilUseType.UNIT_REPAIR)
repairCost += resultAmount * ConfigOptions.unitRepairCost cost.repair = resultAmount * ConfigOptions.unitRepairCost
var sum = cost.repair
if ( if (
!ConfigOptions.doRemoveCostLimit && !ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost ConfigOptions.doCapCost
) { ) {
repairCost = min(repairCost, ConfigOptions.maxAnvilCost) val final = min(sum, ConfigOptions.maxAnvilCost)
cost.generic += (final - sum)
sum = final
} }
if ((inventory.maximumRepairCost <= repairCost) if (ConfigOptions.shouldUseMoney(player)) {
|| (player.level < repairCost) cost.isMonetary = true
) return Int.MIN_VALUE if (!EconomyManager.economy!!.has(player, cost.asMonetaryCost()))
cost.valid = false
} else {
if ((inventory.maximumRepairCost <= sum)
|| (player.level < sum)
) cost.valid = false
}
return repairCost return cost
} }
private fun getFromLoreEditXpCost( private fun getFromLoreEditXpCost(
cost: AnvilCost, cost: AnvilCost,
player: Player, player: Player,
inventory: AnvilInventory, inventory: AnvilInventory,
): Int { ): AnvilCost {
if (GameMode.CREATIVE == player.gameMode) return 0 if (GameMode.CREATIVE == player.gameMode) return AnvilCost(0)
val repairCost = cost.sum() if (ConfigOptions.shouldUseMoney(player)) {
return if ((inventory.maximumRepairCost <= repairCost) cost.isMonetary = true
|| (player.level < repairCost) if (!EconomyManager.economy!!.has(player, cost.asMonetaryCost()))
) Int.MIN_VALUE cost.valid = false
else repairCost } else {
val repairCost = cost.asXpCost()
if ((inventory.maximumRepairCost <= repairCost)
|| (player.level < repairCost)
)
cost.valid = false
}
return cost
} }
private fun handleBookLoreEdit( private fun handleBookLoreEdit(
@ -414,7 +441,7 @@ class AnvilResultListener : Listener {
val bookPage = StringBuilder() val bookPage = StringBuilder()
lore.forEach { lore.forEach {
if (bookPage.isNotEmpty()) bookPage.append('\n') if (bookPage.isNotEmpty()) bookPage.append('\n')
if(it == null) return@forEach if (it == null) return@forEach
bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it)) bookPage.append(MiniMessageUtil.plain_text_mm.serialize(it))
} }

View file

@ -29,6 +29,8 @@ object AnvilXpUtil {
class AnvilCost { class AnvilCost {
private val isAlone: Boolean private val isAlone: Boolean
var valid = true // Get set as invalid if cost can be satisfied
var isMonetary = false
var generic = 0 var generic = 0
var enchantment = 0 var enchantment = 0
@ -39,10 +41,6 @@ object AnvilXpUtil {
var workPenalty = 0 var workPenalty = 0
var recipe = 0 var recipe = 0
fun sum(): Int {
return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe
}
constructor(generic: Int) { constructor(generic: Int) {
this.generic = generic this.generic = generic
isAlone = true isAlone = true
@ -51,6 +49,24 @@ object AnvilXpUtil {
constructor() { constructor() {
isAlone = false isAlone = false
} }
fun asXpCost(): Int {
return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe
}
fun asMonetaryCost(): BigDecimal {
// multiply by per use type multipliers
return BigDecimal(generic)
.add(BigDecimal(enchantment).multiply(moneyMultiplier("enchantment")))
.add(BigDecimal(repair).multiply(moneyMultiplier("repair")))
.add(BigDecimal(rename).multiply(moneyMultiplier("rename")))
.add(BigDecimal(lore).multiply(moneyMultiplier("lore_edit")))
.add(BigDecimal(enchantment).multiply(moneyMultiplier("enchantment")))
.add(BigDecimal(illegalPenalty).multiply(moneyMultiplier("work_penalty")))
.add(BigDecimal(workPenalty).multiply(moneyMultiplier("work_penalty")))
.add(BigDecimal(recipe).multiply(moneyMultiplier("recipe")))
.multiply(moneyMultiplier("global"))
}
} }
/** /**
@ -63,10 +79,11 @@ object AnvilXpUtil {
cost: AnvilCost, cost: AnvilCost,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
if (ConfigOptions.shouldUseMoney(player)) if (ConfigOptions.shouldUseMoney(player)) {
cost.isMonetary = true
setAnvilPrice(inventory, view, player, cost) setAnvilPrice(inventory, view, player, cost)
else } else
setAnvilInvXp(inventory, view, player, cost.sum(), ignoreRules) setAnvilInvXp(inventory, view, player, cost.asXpCost(), ignoreRules)
} }
/** /**
@ -128,20 +145,6 @@ object AnvilXpUtil {
} }
} }
fun asMonetaryCost(cost: AnvilCost): BigDecimal {
// multiply by per use type multipliers
return BigDecimal(cost.generic)
.add(BigDecimal(cost.enchantment).multiply(moneyMultiplier("enchantment")))
.add(BigDecimal(cost.repair).multiply(moneyMultiplier("repair")))
.add(BigDecimal(cost.rename).multiply(moneyMultiplier("rename")))
.add(BigDecimal(cost.lore).multiply(moneyMultiplier("lore_edit")))
.add(BigDecimal(cost.enchantment).multiply(moneyMultiplier("enchantment")))
.add(BigDecimal(cost.illegalPenalty).multiply(moneyMultiplier("work_penalty")))
.add(BigDecimal(cost.workPenalty).multiply(moneyMultiplier("work_penalty")))
.add(BigDecimal(cost.recipe).multiply(moneyMultiplier("recipe")))
.multiply(moneyMultiplier("global"))
}
/** /**
* Display monetary cost needed for the work on the anvil inventory * Display monetary cost needed for the work on the anvil inventory
*/ */
@ -151,16 +154,19 @@ object AnvilXpUtil {
player: Player, player: Player,
cost: AnvilCost, cost: AnvilCost,
) { ) {
val finalCost = asMonetaryCost(cost) val finalCost = cost.asMonetaryCost()
val has = EconomyManager.economy!!.has(player, finalCost) val has = player.gameMode == GameMode.CREATIVE ||
EconomyManager.economy!!.has(player, finalCost)
val text = "Cost: " + (if(has) "§2" else "§4") + val text = "Cost: " + (if (has) "§2" else "§4") +
EconomyManager.economy!!.format(finalCost) EconomyManager.economy!!.format(finalCost)
AnvilTitleUtil.rename(view, text, AnvilTitleUtil.rename(
view, text,
player, player,
AnvilRenameDialogUtil.anvilRenameDialog, AnvilRenameDialogUtil.anvilRenameDialog,
CustomAnvil.instance) CustomAnvil.instance
)
clearAnvilXpCost(inventory, view, player) clearAnvilXpCost(inventory, view, player)
} }
@ -232,10 +238,12 @@ object AnvilXpUtil {
fun onNoResult(player: HumanEntity, view: InventoryView) { fun onNoResult(player: HumanEntity, view: InventoryView) {
if (ConfigOptions.shouldUseMoney(player)) if (ConfigOptions.shouldUseMoney(player))
AnvilTitleUtil.rename(view, "Repair & Name", AnvilTitleUtil.rename(
view, "Repair & Name",
player, player,
AnvilRenameDialogUtil.anvilRenameDialog, AnvilRenameDialogUtil.anvilRenameDialog,
CustomAnvil.instance) CustomAnvil.instance
)
} }
private fun exclusivePenaltyKey(useType: AnvilUseType): NamespacedKey { private fun exclusivePenaltyKey(useType: AnvilUseType): NamespacedKey {