330 lines
11 KiB
Kotlin
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))
|
|
} |