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 import org.bukkit.inventory.InventoryView
// TODO yet another cleanup to do on legacy removal branch // TODO yet another cleanup to do on legacy removal branch
object RenameAnvilUtil { object AnvilTitleUtil {
fun rename(view: InventoryView, name: String) { fun rename(view: InventoryView, name: String) {
view.title = name view.title = name

View file

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

View file

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

View file

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

View file

@ -6,7 +6,7 @@ import org.bukkit.entity.Player
import org.bukkit.plugin.Plugin import org.bukkit.plugin.Plugin
import java.math.BigDecimal import java.math.BigDecimal
class UnlockedEconomyManager: EconomyManager { class UnlockedEconomyManager : EconomyManager {
val plugin: String val plugin: String
val economy: Economy? val economy: Economy?
@ -42,23 +42,27 @@ class UnlockedEconomyManager: EconomyManager {
} }
override fun has(player: Player, money: BigDecimal): Boolean { 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.uniqueId,
player.world.name, player.world.name,
currency(), currency(),
money) money
)
} }
override fun remove(player: Player, money: BigDecimal): Boolean { 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.uniqueId,
player.world.name, player.world.name,
currency(), currency(),
money) money
)
.transactionSuccess() .transactionSuccess()
} }

View file

@ -19,13 +19,13 @@ class VaultEconomyManager : EconomyManager {
} }
override fun has(player: Player, money: BigDecimal): Boolean { 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()) return economy!!.has(player, money.toDouble())
} }
override fun remove(player: Player, money: BigDecimal): Boolean { 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() 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.DisenchantClickListener
import com.jankominek.disenchantment.listeners.ShatterClickListener import com.jankominek.disenchantment.listeners.ShatterClickListener
import io.delilaheve.CustomAnvil import io.delilaheve.CustomAnvil
import org.bukkit.entity.HumanEntity import org.bukkit.entity.Player
import org.bukkit.event.Listener import org.bukkit.event.Listener
import org.bukkit.event.inventory.InventoryClickEvent import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
@ -51,7 +51,7 @@ class DisenchantmentDependency {
InventoryClickEvent.getHandlerList().unregister(listener) InventoryClickEvent.getHandlerList().unregister(listener)
} }
fun testPrepareAnvil(event: PrepareAnvilEvent, player: HumanEntity): Boolean { fun testPrepareAnvil(event: PrepareAnvilEvent, player: Player): Boolean {
val previousResult = event.result val previousResult = event.result
event.result = null event.result = null

View file

@ -1,7 +1,7 @@
package xyz.alexcrea.cuanvil.dependency.plugins package xyz.alexcrea.cuanvil.dependency.plugins
import io.delilaheve.CustomAnvil 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.InventoryClickEvent
import org.bukkit.event.inventory.PrepareAnvilEvent import org.bukkit.event.inventory.PrepareAnvilEvent
import org.bukkit.inventory.AnvilInventory 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 val previousResult = event.result
event.result = null event.result = null

View file

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

View file

@ -2,9 +2,12 @@ package xyz.alexcrea.cuanvil.util
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
import net.kyori.adventure.text.Component
import net.kyori.adventure.text.format.TextColor
import org.bukkit.GameMode import org.bukkit.GameMode
import org.bukkit.NamespacedKey import org.bukkit.NamespacedKey
import org.bukkit.entity.HumanEntity import org.bukkit.entity.HumanEntity
@ -16,7 +19,9 @@ import org.bukkit.inventory.meta.Repairable
import org.bukkit.persistence.PersistentDataType import org.bukkit.persistence.PersistentDataType
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.group.ConflictType import xyz.alexcrea.cuanvil.group.ConflictType
import java.math.BigDecimal
import kotlin.math.min import kotlin.math.min
object AnvilXpUtil { object AnvilXpUtil {
@ -43,6 +48,7 @@ object AnvilXpUtil {
this.generic = generic this.generic = generic
isAlone = true isAlone = true
} }
constructor() { constructor() {
isAlone = false isAlone = false
} }
@ -54,12 +60,14 @@ object AnvilXpUtil {
fun setAnvilInvCost( fun setAnvilInvCost(
inventory: AnvilInventory, inventory: AnvilInventory,
view: InventoryView, view: InventoryView,
player: HumanEntity, player: Player,
cost: AnvilCost, cost: AnvilCost,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
// TODO check require money or xp cost & display appropriately if (ConfigOptions.shouldUseMoney)
setAnvilInvXp(inventory, view, player, cost.sum(), ignoreRules) setAnvilPrice(inventory, view, player, cost)
else
setAnvilInvXp(inventory, view, player, cost.sum(), ignoreRules)
} }
/** /**
@ -72,7 +80,7 @@ object AnvilXpUtil {
anvilCost: Int, anvilCost: Int,
ignoreRules: Boolean = false ignoreRules: Boolean = false
) { ) {
// Test repair cost limit // Test repair cost limit
val finalAnvilCost = if ( val finalAnvilCost = if (
!ignoreRules && !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 * Function to calculate work penalty of anvil work
* Also change result work penalty if right item is not null * Also change result work penalty if right item is not null