From fb09c7a9060e2a3920a1968933c6228391a66e67 Mon Sep 17 00:00:00 2001 From: taah Date: Sat, 18 Jun 2022 01:19:24 -0700 Subject: [PATCH] add checks in order to make sure negative coins don't occur add configurable price use persistent data containers to keep track of items --- src/main/java/dev/plex/ShopModule.kt | 2 +- .../java/dev/plex/commands/ShopCommand.kt | 1 + .../java/dev/plex/listener/ShopListener.kt | 8 ++- src/main/java/dev/plex/shop/ShopMenu.kt | 25 +++++++-- .../java/dev/plex/shop/item/AbstractItem.kt | 51 ++++++++++++++++++- .../dev/plex/shop/item/impl/FireballItem.kt | 14 ++++- src/main/resources/data/config.yml | 3 ++ 7 files changed, 97 insertions(+), 7 deletions(-) diff --git a/src/main/java/dev/plex/ShopModule.kt b/src/main/java/dev/plex/ShopModule.kt index 1ea35a8..f10a213 100644 --- a/src/main/java/dev/plex/ShopModule.kt +++ b/src/main/java/dev/plex/ShopModule.kt @@ -30,7 +30,7 @@ class ShopModule : PlexModule() { } override fun enable() { - ShopMenu.registerItem(18, FireballItem( + ShopMenu.registerItem(22, FireballItem( ItemBuilder(Material.FIRE_CHARGE).displayName(SafeMiniMessage.mmDeserialize("Fireball")).build(), getConfig().getDouble("shop.prices.fireball", 0.0) )) diff --git a/src/main/java/dev/plex/commands/ShopCommand.kt b/src/main/java/dev/plex/commands/ShopCommand.kt index fb2f255..cd7ffb9 100644 --- a/src/main/java/dev/plex/commands/ShopCommand.kt +++ b/src/main/java/dev/plex/commands/ShopCommand.kt @@ -1,5 +1,6 @@ package dev.plex.commands +import dev.plex.ShopModule import dev.plex.cache.DataUtils import dev.plex.command.PlexCommand import dev.plex.command.annotation.CommandParameters diff --git a/src/main/java/dev/plex/listener/ShopListener.kt b/src/main/java/dev/plex/listener/ShopListener.kt index 21bcbc3..4e4c34b 100644 --- a/src/main/java/dev/plex/listener/ShopListener.kt +++ b/src/main/java/dev/plex/listener/ShopListener.kt @@ -1,5 +1,7 @@ package dev.plex.listener +import dev.plex.cache.DataUtils +import dev.plex.shop.ShopMenu import dev.plex.util.minimessage.SafeMiniMessage import net.kyori.adventure.text.Component import org.bukkit.event.EventHandler @@ -17,7 +19,11 @@ class ShopListener : PlexListener() return } event.isCancelled = true - + if (!ShopMenu.ITEMS.containsKey(event.slot)) + { + return + } + ShopMenu.ITEMS[event.slot]!!.purchase(DataUtils.getPlayer(event.whoClicked.uniqueId)) } } \ No newline at end of file diff --git a/src/main/java/dev/plex/shop/ShopMenu.kt b/src/main/java/dev/plex/shop/ShopMenu.kt index c51bfca..88838b1 100644 --- a/src/main/java/dev/plex/shop/ShopMenu.kt +++ b/src/main/java/dev/plex/shop/ShopMenu.kt @@ -1,14 +1,23 @@ package dev.plex.shop +import com.google.common.collect.Lists import com.google.common.collect.Maps +import dev.plex.Plex +import dev.plex.ShopModule import dev.plex.player.PlexPlayer import dev.plex.shop.item.AbstractItem import dev.plex.util.item.ItemBuilder import dev.plex.util.minimessage.SafeMiniMessage +import net.kyori.adventure.text.Component +import net.kyori.adventure.text.minimessage.MiniMessage import org.bukkit.Bukkit import org.bukkit.Material +import org.bukkit.NamespacedKey import org.bukkit.entity.Player import org.bukkit.inventory.Inventory +import org.bukkit.inventory.meta.ItemMeta +import org.bukkit.persistence.PersistentDataContainer +import org.bukkit.persistence.PersistentDataType /** * @author Taah @@ -23,17 +32,26 @@ class ShopMenu val ITEMS: HashMap = Maps.newHashMap() fun registerItem(index: Int, item: AbstractItem) { - ITEMS.put(index, item); + val meta: ItemMeta = item.item.itemMeta + val dataContainer: PersistentDataContainer = meta.persistentDataContainer + dataContainer.set(item.itemTag, PersistentDataType.STRING, item.itemTag.key) + val lore = meta.lore() ?: Lists.newArrayList() + lore.add(Component.empty()) + lore.add(MiniMessage.miniMessage().deserialize("Price: ${item.cost}")) + meta.lore(lore) + item.item.itemMeta = meta + ITEMS[index] = item; + ShopModule.get().registerListener(item) } fun open(plexPlayer: PlexPlayer) { val player: Player? = plexPlayer.player - val inventory: Inventory = constructInventory() + val inventory: Inventory = constructInventory(plexPlayer) player?.openInventory(inventory) } - private fun constructInventory(): Inventory + private fun constructInventory(plexPlayer: PlexPlayer): Inventory { val inventory: Inventory = Bukkit.createInventory(null, 54, SafeMiniMessage.mmDeserialize("Shop")) ITEMS.forEach { (t, u) -> inventory.setItem(t, u.item) } @@ -44,6 +62,7 @@ class ShopMenu inventory.setItem(i, ItemBuilder(Material.GRAY_STAINED_GLASS_PANE).displayName(SafeMiniMessage.mmDeserialize(" ")).build()) } } + inventory.setItem(53, ItemBuilder(Material.SUNFLOWER).displayName(SafeMiniMessage.mmDeserialize("${plexPlayer.coins} Coins")).build()) return inventory } } diff --git a/src/main/java/dev/plex/shop/item/AbstractItem.kt b/src/main/java/dev/plex/shop/item/AbstractItem.kt index ec01386..93c000b 100644 --- a/src/main/java/dev/plex/shop/item/AbstractItem.kt +++ b/src/main/java/dev/plex/shop/item/AbstractItem.kt @@ -1,18 +1,67 @@ package dev.plex.shop.item import dev.plex.cache.DataUtils +import dev.plex.listener.PlexListener import dev.plex.player.PlexPlayer +import dev.plex.util.PlexLog +import dev.plex.util.minimessage.SafeMiniMessage +import org.bukkit.Material +import org.bukkit.NamespacedKey +import org.bukkit.event.EventHandler +import org.bukkit.event.player.PlayerInteractEvent +import org.bukkit.inventory.EquipmentSlot import org.bukkit.inventory.ItemStack +import org.bukkit.inventory.meta.ItemMeta +import org.bukkit.persistence.PersistentDataContainer import java.util.concurrent.CompletableFuture -abstract class AbstractItem(val item: ItemStack, private val cost: Double) +abstract class AbstractItem(val item: ItemStack, val cost: Double, val itemTag: NamespacedKey) : PlexListener() { fun purchase(player: PlexPlayer) { + if (player.coins < this.cost) { + player.player?.sendMessage(SafeMiniMessage.mmDeserialize("You need ${this.cost - player.coins} more coins to purchase this!")) + return + } + if (player.player?.inventory!!.filter { it?.type != Material.AIR }.size == 53) + { + player.player?.sendMessage(SafeMiniMessage.mmDeserialize("Your inventory is currently full!")) + return + } player.coins.minus(this.cost); player.player?.inventory?.addItem(this.item); CompletableFuture.runAsync { DataUtils.update(player); } } + + abstract fun interact(event: PlayerInteractEvent) + + @EventHandler + fun onInteract(event: PlayerInteractEvent) + { + if (event.hand != EquipmentSlot.HAND) + { + return + } + + if (event.item == null) + { + return + } + + if (!event.item!!.hasItemMeta()) + { + return + } + + val meta: ItemMeta = event.item!!.itemMeta + val dataContainer: PersistentDataContainer = meta.persistentDataContainer + if (!dataContainer.has(itemTag)) + { + return + } + + interact(event) + } } diff --git a/src/main/java/dev/plex/shop/item/impl/FireballItem.kt b/src/main/java/dev/plex/shop/item/impl/FireballItem.kt index 4015e4e..c13a569 100644 --- a/src/main/java/dev/plex/shop/item/impl/FireballItem.kt +++ b/src/main/java/dev/plex/shop/item/impl/FireballItem.kt @@ -1,8 +1,20 @@ package dev.plex.shop.item.impl +import dev.plex.Plex import dev.plex.shop.item.AbstractItem +import org.bukkit.NamespacedKey +import org.bukkit.entity.Fireball +import org.bukkit.event.player.PlayerInteractEvent import org.bukkit.inventory.ItemStack -class FireballItem(item: ItemStack, cost: Double) : AbstractItem(item, cost) +class FireballItem(item: ItemStack, cost: Double) : AbstractItem(item, cost, ITEM_TAG) { + companion object { + val ITEM_TAG: NamespacedKey = NamespacedKey(Plex.get(), "fireball_item") + } + + override fun interact(event: PlayerInteractEvent) + { + event.player.launchProjectile(Fireball::class.java) + } } \ No newline at end of file diff --git a/src/main/resources/data/config.yml b/src/main/resources/data/config.yml index e69de29..e9ba01e 100644 --- a/src/main/resources/data/config.yml +++ b/src/main/resources/data/config.yml @@ -0,0 +1,3 @@ +shop: + prices: + fireball: 16 \ No newline at end of file