shop-reborn/src/main/kotlin/pw.hamzantal.shopreborn/ClickListeners.kt

330 lines
11 KiB
Kotlin

package pw.hamzantal.shopreborn
import hazae41.minecraft.kutils.bukkit.execute
import hazae41.minecraft.kutils.bukkit.msg
import org.bukkit.Bukkit
import org.bukkit.OfflinePlayer
import org.bukkit.entity.Player
import org.bukkit.event.inventory.ClickType.*
import org.bukkit.event.inventory.InventoryClickEvent
import org.bukkit.event.inventory.InventoryCloseEvent
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import kotlin.math.max
import kotlin.math.min
enum class PurchaseType { BUY, SELL }
class PurchaseEvent(
val inv: Inventory,
val item: ItemStack,
val shop: ShopConfig,
val p: Player,
val block: ShopConfig.Item,
val type: PurchaseType
)
val purchases = mutableListOf<PurchaseEvent>()
fun closeListener(e: InventoryCloseEvent) {
val purchase = purchases.firstOrNull { it.inv == e.inventory } ?: return
purchases -= purchase
}
fun baseListener(e: InventoryClickEvent) {
if (e.inventory == GlobalConfig.main.inventory) {
mainClick(e)
return
}
val purchase = purchases.firstOrNull { it.inv == e.inventory }
if (purchase != null) clickInventory(e, purchase)
val shop = GlobalConfig.shops.firstOrNull { it.inventories.contains(e.inventory) } ?: return
shopClick(e, shop)
}
fun mainClick(e: InventoryClickEvent) {
e.isCancelled = true
if (e.rawSlot > e.inventory.size) return
val main = GlobalConfig.main
val p = e.whoClicked as Player
val block = main.blocks.firstOrNull { it.slot == e.slot } ?: return
block.commands.forEach {
if (it.contains("%PLAYER%")) Bukkit.getConsoleSender().execute(it.replace("%PLAYER%", p.name))
else p.performCommand(it)
}
}
fun shopClick(e: InventoryClickEvent, shop: ShopConfig) {
e.isCancelled = true
if (e.rawSlot > e.inventory.size) return
val main = GlobalConfig.main
val p = e.whoClicked as Player
//Check Menu Buttons
if (e.currentItem == main.buttons.menu) {
p.openInventory(main.inventory)
return
}
if (e.currentItem == main.buttons.forward) {
val current = shop.inventories.indexOf(e.inventory)
if (current + 1 == shop.inventories.size) return
p.openInventory(shop.inventories[current + 1])
return
}
if (e.currentItem == main.buttons.previous) {
val current = shop.inventories.indexOf(e.inventory)
if (current == 0) return
p.openInventory(shop.inventories[current - 1])
}
//Buy / Sell Item
val block = shop.blocks.firstOrNull { it.item == e.currentItem } ?: return
if (block is ShopConfig.Command) {
val item = block.item
val cost = block.buy
if (cost < 0) {
block.commands.forEach {
if (it.contains("%PLAYER%"))
Bukkit.getConsoleSender().execute(it.replace("%PLAYER%", p.name))
else p.chat(it)
}
return
}
val name = if (item.itemMeta.hasDisplayName()) item.itemMeta.displayName else item.type.prettyName()
val op = Bukkit.getOfflinePlayer(p.uniqueId)
val balance = econ.getBalance(op)
if (cost > balance) {
p.msg(GlobalConfig.messages.buyNotEnough)
return
}
val r = econ.withdrawPlayer(op, cost)
if (r.transactionSuccess()) {
block.commands.forEach {
if (it.contains("%PLAYER%"))
Bukkit.getConsoleSender().execute(it.replace("%PLAYER%", p.name))
else p.chat(it)
}
p.msg(
GlobalConfig.messages.commandSuccess
.replace("%NAME%", name)
.replace("%COST%", cost.withCurrency())
)
} else {
p.msg(GlobalConfig.messages.purchaseError.replace("%MSG%", r.errorMessage))
}
}
if (block is ShopConfig.Item) {
when (e.click) {
LEFT -> buy(e, p, shop, block)
RIGHT -> sell(e, p, shop, block)
MIDDLE, SHIFT_LEFT -> {
val raw = block.raw
val howMany = p containing raw
val single = block.sell / block.item.amount
val op = Bukkit.getOfflinePlayer(p.uniqueId)
executeSell(raw, howMany, single, p, op)
}
else -> return
}
}
}
fun clickInventory(e: InventoryClickEvent, pe: PurchaseEvent) {
e.isCancelled = true
val block = pe.block
val origin = block.item
val p = pe.p
val singleCost =
if (pe.type == PurchaseType.BUY) pe.block.buy / origin.amount
else pe.block.sell / origin.amount
val lore =
if (pe.type == PurchaseType.BUY) GlobalConfig.messages.buyLore
else GlobalConfig.messages.sellLore
val op = Bukkit.getOfflinePlayer(p.uniqueId)
if (!econ.hasAccount(op))
econ.createPlayerAccount(op)
when (e.currentItem) {
PurchaseItems.set1 -> {
pe.item.amount = 1
pe.item.setLore(lore.mixPlaceholder(price = singleCost))
}
PurchaseItems.sub10 -> {
val now = max(1, pe.item.amount - 10)
pe.item.amount = now
pe.item.setLore(lore.mixPlaceholder(price = singleCost * now))
}
PurchaseItems.sub1 -> {
val now = max(1, pe.item.amount - 1)
pe.item.amount = now
pe.item.setLore(lore.mixPlaceholder(price = singleCost * now))
}
PurchaseItems.add1 -> {
val now = min(64, pe.item.amount + 1)
pe.item.amount = now
pe.item.setLore(lore.mixPlaceholder(price = singleCost * now))
}
PurchaseItems.add10 -> {
val now = min(64, pe.item.amount + 10)
pe.item.amount = now
pe.item.setLore(lore.mixPlaceholder(price = singleCost * now))
}
PurchaseItems.set64 -> {
pe.item.amount = 64
pe.item.setLore(lore.mixPlaceholder(price = singleCost * 64))
}
PurchaseItems.cancel -> {
pe.p.openInventory(pe.shop.inventory)
purchases -= pe
}
PurchaseItems.sellAll -> {
val howMany = p containing block.raw
executeSell(block.raw, howMany, singleCost, p, op)
}
}
pe.inv.setItem(22, pe.item)
if (e.currentItem == PurchaseItems.sellConfirm && pe.type == PurchaseType.SELL) {
val howMany = pe.item.amount
executeSell(block.raw, howMany, singleCost, p, op)
}
if (e.currentItem == PurchaseItems.buyConfirm && pe.type == PurchaseType.BUY) {
val item = block.raw.clone()
val name = if (item.itemMeta.hasDisplayName()) item.itemMeta.displayName else item.type.prettyName()
val balance = econ.getBalance(op)
val amount = pe.item.amount
val cost = singleCost * amount
if (cost > balance) {
p.msg(GlobalConfig.messages.buyNotEnough)
return
}
if (p.inventory.firstEmpty() == -1) {
p.msg(GlobalConfig.messages.buyInvFull)
return
}
val r = econ.withdrawPlayer(op, cost)
if (r.transactionSuccess()) {
p.inventory.addItem(item.apply { this.amount = amount })
p.msg(
GlobalConfig.messages.buySuccess
.replace("%AMOUNT%", amount.toString())
.replace("%NAME%", name)
.replace("%COST%", cost.withCurrency())
)
return
}
p.msg(GlobalConfig.messages.purchaseError.replace("%MSG%", r.errorMessage))
}
}
fun executeSell(item: ItemStack, howMany: Int, singleCost: Double, p: Player, op: OfflinePlayer) {
val name = if (item.itemMeta.hasDisplayName()) item.itemMeta.displayName else item.type.prettyName()
if (howMany <= 0 || p containing item < howMany) {
p.msg(GlobalConfig.messages.sellNotEnough.replace("%NAME%", name))
return
}
if (singleCost < 0) {
p.msg(GlobalConfig.messages.sellUnavailable)
return
}
val total = singleCost * howMany
val r = econ.depositPlayer(op, total)
if (r.transactionSuccess()) {
p.inventory.removeItem(item.clone().apply { amount = howMany })
p.msg(
GlobalConfig.messages.sellSuccess
.replace("%AMOUNT%", howMany.toString())
.replace("%NAME%", name)
.replace("%COST%", total.withCurrency())
)
return
}
p.msg(GlobalConfig.messages.purchaseError.replace("%MSG%", r.errorMessage))
}
val base = Array<ItemStack?>(54) { null }.apply {
set(18, PurchaseItems.set1)
set(19, PurchaseItems.sub10)
set(20, PurchaseItems.sub1)
set(24, PurchaseItems.add1)
set(25, PurchaseItems.add10)
set(26, PurchaseItems.set64)
}
fun buy(e: InventoryClickEvent, p: Player, shop: ShopConfig, block: ShopConfig.Item) {
val item = e.currentItem.clone()
if (block.buy < 0) {
p.msg(GlobalConfig.messages.buyUnavailable)
return
}
val name = if (item.itemMeta.hasDisplayName()) item.itemMeta.displayName else item.type.prettyName()
val inv = Bukkit.createInventory(
null,
54,
GlobalConfig.messages.buyShopTitle.replace("%NAME%", name).c
).apply {
contents = base.clone()
val buyLore = GlobalConfig.messages.buyLore.mixPlaceholder(price = block.buy)
setItem(22, item.setLore(buyLore))
setItem(39, PurchaseItems.buyConfirm)
setItem(41, PurchaseItems.cancel)
}
p.openInventory(inv)
purchases.add(PurchaseEvent(inv, item, shop, p, block, PurchaseType.BUY))
}
fun sell(e: InventoryClickEvent, p: Player, shop: ShopConfig, block: ShopConfig.Item) {
val item = e.currentItem.clone()
if (block.sell == -1.0) {
p.msg(GlobalConfig.messages.sellUnavailable)
return
}
val name = if (item.itemMeta.hasDisplayName()) item.itemMeta.displayName else item.type.prettyName()
val inv = Bukkit.createInventory(
null,
54,
GlobalConfig.messages.sellShopTitle.replace("%NAME%", name).c
).apply {
contents = base.clone()
val sellLore = GlobalConfig.messages.sellLore.mixPlaceholder(price = block.sell)
val possibleSellAll = p containing block.raw
val cost = block.sell / item.amount * possibleSellAll
val sellAllLore = GlobalConfig.messages.sellAllLore.mixPlaceholder(possibleSellAll, cost)
setItem(22, item.setLore(sellLore))
setItem(39, PurchaseItems.sellConfirm)
setItem(40, PurchaseItems.sellAll.setLore(sellAllLore))
setItem(41, PurchaseItems.cancel)
}
p.openInventory(inv)
purchases.add(PurchaseEvent(inv, item, shop, p, block, PurchaseType.SELL))
}