monetary cost display

This commit is contained in:
alexcrea 2026-05-25 18:05:29 +02:00
parent ac9f492125
commit 1b3447d041
Signed by: alexcrea
GPG key ID: E346CD16413450E3
10 changed files with 97 additions and 29 deletions

View file

@ -3,7 +3,7 @@ package xyz.alexcrea.cuanvil.util
import org.bukkit.inventory.InventoryView
// TODO yet another cleanup to do on legacy removal branch
object RenameAnvilUtil {
object AnvilTitleUtil {
fun rename(view: InventoryView, name: String) {
view.title = name

View file

@ -91,7 +91,7 @@ object ConfigOptions {
const val VERBOSE_DEBUG_LOGGING = "debug_log_verbose"
// Minimum versions
val MINIMUM_MONETARY_COST_VER = Version(21, 0, 0)
val MINIMUM_MONETARY_COST_VER = Version(1, 21, 0)
// ----------------------
// Default config values

View file

@ -7,6 +7,7 @@ import org.bukkit.Bukkit
import org.bukkit.ChatColor
import org.bukkit.command.CommandSender
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
@ -199,7 +200,7 @@ object DependencyManager {
}
// Return true if should bypass (either by a dependency or error)
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
fun tryEventPreAnvilBypass(event: PrepareAnvilEvent, player: Player): Boolean {
try {
return unsafeTryEventPreAnvilBypass(event, player)
} catch (e: Exception) {
@ -208,7 +209,7 @@ object DependencyManager {
}
}
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
private fun unsafeTryEventPreAnvilBypass(event: PrepareAnvilEvent, player: Player): Boolean {
// Run the event
val bypassEvent = CAPreAnvilBypassEvent(event)
Bukkit.getPluginManager().callEvent(bypassEvent)

View file

@ -12,10 +12,10 @@ interface EconomyManager {
fun setupEconomy(plugin: Plugin) {
if (plugin.server.pluginManager.getPlugin("Vault") == null)
return
if(UnlockedEconomyManager.unlockedAvailable())
if (UnlockedEconomyManager.unlockedAvailable())
economy = UnlockedEconomyManager(plugin)
if(economy == null || !economy!!.initialized())
if (economy == null || !economy!!.initialized())
economy = VaultEconomyManager(plugin)
}

View file

@ -6,7 +6,7 @@ import org.bukkit.entity.Player
import org.bukkit.plugin.Plugin
import java.math.BigDecimal
class UnlockedEconomyManager: EconomyManager {
class UnlockedEconomyManager : EconomyManager {
val plugin: String
val economy: Economy?
@ -42,23 +42,27 @@ class UnlockedEconomyManager: EconomyManager {
}
override fun has(player: Player, money: BigDecimal): Boolean {
if(money.signum() <= 0) return true
if (money.signum() <= 0) return true
return economy!!.has(plugin,
return economy!!.has(
plugin,
player.uniqueId,
player.world.name,
currency(),
money)
money
)
}
override fun remove(player: Player, money: BigDecimal): Boolean {
if(money.signum() <= 0) return true
if (money.signum() <= 0) return true
return economy!!.withdraw(plugin,
return economy!!.withdraw(
plugin,
player.uniqueId,
player.world.name,
currency(),
money)
money
)
.transactionSuccess()
}

View file

@ -19,13 +19,13 @@ class VaultEconomyManager : EconomyManager {
}
override fun has(player: Player, money: BigDecimal): Boolean {
if(money.signum() <= 0) return true
if (money.signum() <= 0) return true
return economy!!.has(player, money.toDouble())
}
override fun remove(player: Player, money: BigDecimal): Boolean {
if(money.signum() <= 0) return true
if (money.signum() <= 0) return true
return economy!!.withdrawPlayer(player, money.toDouble()).transactionSuccess()
}

View file

@ -8,7 +8,7 @@ import com.jankominek.disenchantment.events.ShatterEvent
import com.jankominek.disenchantment.listeners.DisenchantClickListener
import com.jankominek.disenchantment.listeners.ShatterClickListener
import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
@ -51,7 +51,7 @@ class DisenchantmentDependency {
InventoryClickEvent.getHandlerList().unregister(listener)
}
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
fun testPrepareAnvil(event: PrepareAnvilEvent, player: Player): Boolean {
val previousResult = event.result
event.result = null

View file

@ -1,7 +1,7 @@
package xyz.alexcrea.cuanvil.dependency.plugins
import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity
import org.bukkit.entity.Player
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory
@ -46,7 +46,7 @@ class HavenBagsDependency {
}
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean {
fun testPrepareAnvil(event: PrepareAnvilEvent, player: Player): Boolean {
val previousResult = event.result
event.result = null

View file

@ -13,6 +13,7 @@ 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.event.EventHandler
import org.bukkit.event.EventPriority
import org.bukkit.event.Listener
@ -54,7 +55,8 @@ class PrepareAnvilListener : Listener {
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
fun anvilCombineCheck(event: PrepareAnvilEvent) {
// Should find player
val player: HumanEntity = InventoryViewUtil.getInstance().getPlayer(event.view)
val player = InventoryViewUtil.getInstance().getPlayer(event.view)
if(player !is Player) return
val inventory = event.inventory
// Test if custom anvil is bypassed before immutability test
@ -183,7 +185,7 @@ class PrepareAnvilListener : Listener {
// return true if a custom recipe exist with these ingredients
private fun testCustomRecipe(
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: HumanEntity,
player: Player,
first: ItemStack, second: ItemStack?
): Boolean {
val recipe = CustomRecipeUtil.getCustomRecipe(first, second)
@ -209,7 +211,7 @@ class PrepareAnvilListener : Listener {
private fun doRenaming(
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: HumanEntity, first: ItemStack
player: Player, first: ItemStack
) {
val resultItem = DependencyManager.cloneItem(event, first)
val cost = AnvilCost()
@ -274,7 +276,7 @@ class PrepareAnvilListener : Listener {
private fun doMerge(
event: PrepareAnvilEvent, inventory: AnvilInventory,
player: HumanEntity,
player: Player,
first: ItemStack, second: ItemStack
) {
val newEnchants = first.findEnchantments()
@ -327,7 +329,7 @@ class PrepareAnvilListener : Listener {
// return true if there is a valid unit repair with these ingredients
private fun testUnitRepair(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
event: PrepareAnvilEvent, inventory: AnvilInventory, player: Player,
first: ItemStack, second: ItemStack
): Boolean {
val unitRepairAmount = first.getRepair(second) ?: return false
@ -356,7 +358,7 @@ class PrepareAnvilListener : Listener {
}
private fun testLoreEdit(
event: PrepareAnvilEvent, inventory: AnvilInventory, player: HumanEntity,
event: PrepareAnvilEvent, inventory: AnvilInventory, player: Player,
first: ItemStack, second: ItemStack
): Boolean {
val type = second.type

View file

@ -2,9 +2,12 @@ package xyz.alexcrea.cuanvil.util
import io.delilaheve.CustomAnvil
import io.delilaheve.util.ConfigOptions
import io.delilaheve.util.ConfigOptions.getMonetaryMultiplier as moneyMultiplier
import io.delilaheve.util.EnchantmentUtil.enchantmentName
import io.delilaheve.util.ItemUtil.findEnchantments
import io.delilaheve.util.ItemUtil.isEnchantedBook
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.TextColor
import org.bukkit.GameMode
import org.bukkit.NamespacedKey
import org.bukkit.entity.HumanEntity
@ -16,7 +19,9 @@ import org.bukkit.inventory.meta.Repairable
import org.bukkit.persistence.PersistentDataType
import xyz.alexcrea.cuanvil.config.ConfigHolder
import xyz.alexcrea.cuanvil.dependency.DependencyManager
import xyz.alexcrea.cuanvil.dependency.economy.EconomyManager
import xyz.alexcrea.cuanvil.group.ConflictType
import java.math.BigDecimal
import kotlin.math.min
object AnvilXpUtil {
@ -43,6 +48,7 @@ object AnvilXpUtil {
this.generic = generic
isAlone = true
}
constructor() {
isAlone = false
}
@ -54,12 +60,14 @@ object AnvilXpUtil {
fun setAnvilInvCost(
inventory: AnvilInventory,
view: InventoryView,
player: HumanEntity,
player: Player,
cost: AnvilCost,
ignoreRules: Boolean = false
) {
// TODO check require money or xp cost & display appropriately
setAnvilInvXp(inventory, view, player, cost.sum(), ignoreRules)
if (ConfigOptions.shouldUseMoney)
setAnvilPrice(inventory, view, player, cost)
else
setAnvilInvXp(inventory, view, player, cost.sum(), ignoreRules)
}
/**
@ -72,7 +80,7 @@ object AnvilXpUtil {
anvilCost: Int,
ignoreRules: Boolean = false
) {
// Test repair cost limit
val finalAnvilCost = if (
!ignoreRules &&
@ -121,6 +129,59 @@ 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
*/
private fun setAnvilPrice(
inventory: AnvilInventory,
view: InventoryView,
player: Player,
cost: AnvilCost,
) {
val finalCost = asMonetaryCost(cost)
val has = EconomyManager.economy!!.has(player, finalCost)
val text = "Cost: " + (if(has) "§2" else "§4") +
EconomyManager.economy!!.format(finalCost)
AnvilTitleUtil.rename(view, text)
clearAnvilXpCost(inventory, view, player)
}
private fun clearAnvilXpCost(
inventory: AnvilInventory,
view: InventoryView,
player: HumanEntity,
) {
// TODO for 2.x.x use anvil view & set directly there
inventory.repairCost = 0
// retry after a tick
DependencyManager.scheduler.scheduleOnEntity(
CustomAnvil.instance, player
) {
inventory.repairCost = 0
if (player !is Player) return@scheduleOnEntity
player.updateInventory()
}
}
/**
* Function to calculate work penalty of anvil work
* Also change result work penalty if right item is not null