fix and simplify xp handling

- Fix xp limit not being respected
- Fix player xp not being check causing error
This commit is contained in:
alexcrea 2026-06-19 20:29:10 +02:00
parent 9d616d2fd0
commit bc9cbe0b44
Signed by: alexcrea
GPG key ID: E346CD16413450E3
3 changed files with 40 additions and 27 deletions

View file

@ -1,6 +1,8 @@
package xyz.alexcrea.cuanvil.anvil package xyz.alexcrea.cuanvil.anvil
import io.delilaheve.util.ConfigOptions
import java.math.BigDecimal import java.math.BigDecimal
import kotlin.math.min
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
open class AnvilCost { open class AnvilCost {
@ -30,6 +32,21 @@ open class AnvilCost {
return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe return generic + enchantment + repair + rename + lore + illegalPenalty + workPenalty + recipe
} }
fun filteredXpCost(ignoreRules: Boolean = false): Int {
val original = asXpCost()
// Test repair cost limit
return if (
!ignoreRules &&
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost
) {
min(original, ConfigOptions.maxAnvilCost)
} else {
original
}
}
open fun asMonetaryCost(): BigDecimal { open fun asMonetaryCost(): BigDecimal {
// multiply by per use type multipliers // multiply by per use type multipliers
return BigDecimal(generic) return BigDecimal(generic)

View file

@ -270,13 +270,19 @@ class AnvilResultListener : Listener {
} }
private fun tryRemoveCost(player: Player, cost: AnvilCost): Boolean { private fun tryRemoveCost(player: Player, result: AnvilResult): Boolean {
if (player.gameMode == GameMode.CREATIVE) return true if (player.gameMode == GameMode.CREATIVE) return true
val cost = result.cost
if (cost.isMonetary) { if (cost.isMonetary) {
val result = EconomyManager.economy!!.remove(player, cost.asMonetaryCost()) val result = EconomyManager.economy!!.remove(player, cost.asMonetaryCost())
if (!result) return false if (!result) return false
} else { } else {
player.level -= cost.asXpCost() val xpCost = cost.filteredXpCost()
if (xpCost > AnvilXpUtil.maximumXpCost(result.ignoreXpRules)) return false
if (player.level < xpCost) return false
player.level -= xpCost
} }
return true return true
@ -308,7 +314,7 @@ class AnvilResultListener : Listener {
// If not creative middle click... // If not creative middle click...
if (event.click != ClickType.MIDDLE) { if (event.click != ClickType.MIDDLE) {
if (!tryRemoveCost(player, cost)) return false if (!tryRemoveCost(player, result)) return false
// We remove what should be removed // We remove what should be removed
if (leftItem != null) leftItem.amount -= leftRemoveCount if (leftItem != null) leftItem.amount -= leftRemoveCount

View file

@ -22,7 +22,6 @@ 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.AnvilTitleUtil
import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil import xyz.alexcrea.cuanvil.util.dialog.AnvilRenameDialogUtil
import kotlin.math.min
object AnvilXpUtil { object AnvilXpUtil {
@ -42,7 +41,15 @@ object AnvilXpUtil {
cost.isMonetary = true cost.isMonetary = true
setAnvilPrice(inventory, view, player, cost) setAnvilPrice(inventory, view, player, cost)
} else } else
setAnvilInvXp(inventory, view, player, cost.asXpCost(), ignoreRules) setAnvilInvXp(inventory, view, player, cost.filteredXpCost(ignoreRules), ignoreRules)
}
fun maximumXpCost(ignoreRules: Boolean = false): Int {
return if (ConfigOptions.doRemoveCostLimit || ignoreRules) {
Int.MAX_VALUE
} else {
ConfigOptions.maxAnvilCost + 1
}
} }
/** /**
@ -55,28 +62,11 @@ object AnvilXpUtil {
anvilCost: Int, anvilCost: Int,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
val maximumRepairCost = maximumXpCost(ignoreRules)
// Test repair cost limit
val finalAnvilCost = if (
!ignoreRules &&
!ConfigOptions.doRemoveCostLimit &&
ConfigOptions.doCapCost
) {
min(anvilCost, ConfigOptions.maxAnvilCost)
} else {
anvilCost
}
val maximumRepairCost =
if (ConfigOptions.doRemoveCostLimit || ignoreRules) {
Int.MAX_VALUE
} else {
ConfigOptions.maxAnvilCost + 1
}
// Try first just in case another plugin, or the test need this // Try first just in case another plugin, or the test need this
inventory.maximumRepairCost = maximumRepairCost inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there // TODO for 2.x.x use anvil view & set directly there
/* Because Minecraft likes to have the final say in the repair cost displayed /* Because Minecraft likes to have the final say in the repair cost displayed
@ -87,15 +77,15 @@ object AnvilXpUtil {
) { ) {
// retry after a tick // retry after a tick
inventory.maximumRepairCost = maximumRepairCost inventory.maximumRepairCost = maximumRepairCost
inventory.repairCost = finalAnvilCost inventory.repairCost = anvilCost
// TODO for 2.x.x use anvil view & set directly there // TODO for 2.x.x use anvil view & set directly there
if (player !is Player) return@scheduleOnEntity if (player !is Player) return@scheduleOnEntity
if (player.gameMode != GameMode.CREATIVE) { if (player.gameMode != GameMode.CREATIVE) {
val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) && val bypassToExpensive = (ConfigOptions.doReplaceTooExpensive) &&
(finalAnvilCost >= 40) && (anvilCost >= 40) &&
finalAnvilCost < inventory.maximumRepairCost anvilCost < inventory.maximumRepairCost
DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive) DependencyManager.packetManager.setInstantBuild(player, bypassToExpensive)
} }