diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/ShopItem.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/ShopItem.kt index a2a4663..23f9880 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/ShopItem.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/ShopItem.kt @@ -99,7 +99,9 @@ class ShopItem( val sellMenu = SellMenu(this, plugin) - private val limit = config.getIntOrNull("buy.limit") ?: Int.MAX_VALUE + val limit = config.getIntOrNull("buy.limit") ?: Int.MAX_VALUE + + val globalLimit = config.getIntOrNull("buy.global-limit") ?: Int.MAX_VALUE private val maxAtOnce = config.getIntOrNull("buy.max-at-once") ?: Int.MAX_VALUE @@ -191,8 +193,18 @@ class ShopItem( } /** Get the max amount of times this player can buy this item again. */ - fun getBuysLeft(player: Player): Int { - return limit - player.profile.read(timesBoughtKey) + fun getBuysLeft(player: OfflinePlayer): Int { + return limit - getTotalBuys(player) + } + + /** Get the total amount of times a player has bought this item. */ + fun getTotalBuys(player: OfflinePlayer): Int { + return player.profile.read(timesBoughtKey) + } + + /** Get the total amount of times a server has bought this item. */ + fun getTotalGlobalBuys(): Int { + return Bukkit.getServer().profile.read(timesBoughtKey) } /** If a [player] is allowed to purchase this item. */ @@ -206,6 +218,10 @@ class ShopItem( return BuyStatus.BOUGHT_TOO_MANY } + if (Bukkit.getServer().profile.read(timesBoughtKey) + amount > globalLimit) { + return BuyStatus.GLOBAL_BOUGHT_TOO_MANY + } + if (!player.hasPermission("ecoshop.buy.$id")) { return BuyStatus.NO_PERMISSION } @@ -269,7 +285,8 @@ class ShopItem( } } - player.profile.write(timesBoughtKey, player.profile.read(timesBoughtKey) + 1) + player.profile.write(timesBoughtKey, getTotalBuys(player) + 1) + Bukkit.getServer().profile.write(timesBoughtKey, getTotalGlobalBuys() + 1) if (shop?.isBroadcasting == true) { shop.broadcastPurchase(player, this, amount) @@ -440,6 +457,8 @@ class ShopItem( } fun resetTimesBought(player: OfflinePlayer) { + val totalBuysForPlayer = getTotalBuys(player) + Bukkit.getServer().profile.write(timesBoughtKey, getTotalGlobalBuys() - totalBuysForPlayer) player.profile.write(timesBoughtKey, 0) } diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/Status.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/Status.kt index 2decfe9..f22816c 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/Status.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/Status.kt @@ -4,6 +4,7 @@ package com.willfp.ecoshop.shop enum class BuyStatus { CANNOT_BUY, BOUGHT_TOO_MANY, + GLOBAL_BOUGHT_TOO_MANY, NO_PERMISSION, MISSING_REQUIREMENTS, CANNOT_AFFORD, diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/gui/ShopItemSlot.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/gui/ShopItemSlot.kt index 88ddb39..1a9c847 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/gui/ShopItemSlot.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecoshop/shop/gui/ShopItemSlot.kt @@ -19,6 +19,7 @@ import com.willfp.ecoshop.shop.configKey import com.willfp.ecoshop.shop.getDisplay import com.willfp.ecoshop.shop.parentShop import org.bukkit.entity.Player +import org.bukkit.inventory.ItemStack fun Collection.replaceIn(token: String, replacement: Any?) = this.map { it.replace(token, replacement.toNiceString()) } @@ -27,90 +28,7 @@ class ShopItemSlot( item: ShopItem, plugin: EcoPlugin ) : CustomSlot() { - private val slot = slot({ player, _ -> - item.displayItem.modify { - if (item.isBuyable) { - addLoreLines( - /* - Big ugly tree. - This code sucks and I should probably refactor it. - */ - when (val status = item.getBuyStatus(player, 1, BuyType.NORMAL)) { - BuyStatus.MISSING_REQUIREMENTS, - BuyStatus.NO_PERMISSION, - -> plugin.langYml.getStrings("lore.${status.configKey}") - - else -> when (item.getBuysLeft(player)) { - 0 -> plugin.langYml.getStrings("cant-buy-again") - - 1 -> if (item.hasAltBuy) plugin.langYml.getStrings("dual-buy-price") - .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") - .replaceIn("%alt_price%", item.altBuyPrice?.getDisplay(player) ?: "") - else plugin.langYml.getStrings("one-buy-price") - .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") - - else -> if (item.hasAltBuy) plugin.langYml.getStrings("dual-buy-price") - .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") - .replaceIn("%alt_price%", item.altBuyPrice?.getDisplay(player) ?: "") - else plugin.langYml.getStrings("buy-price") - .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") - } - } - ) - } - - if (item.isSellable) { - addLoreLines( - plugin.langYml.getStrings("sell-price") - .replaceIn("%price%", item.sellPrice?.getDisplay(player) ?: "") - ) - } - - addLoreLines( - item.bottomLore.formatEco(player) - ) - - if (item.isBuyable) { - addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.buy").formatEco(player)) - } - - if (item.isShowingQuickBuySell) { - if (item.isBuyable && item.getMaxBuysAtOnce(player) > item.buyAmount) { - if (item.hasAltBuy) { - addLoreLines( - plugin.langYml.getStrings("quick-buy-alt-present") - .replaceIn("%price%", item.buyPrice.getDisplay(player, item.buyAmount)) - .replaceIn("%amount%", item.buyAmount.toString()) - ) - addLoreLines( - plugin.langYml.getStrings("quick-buy-alt") - .replaceIn("%price%", item.altBuyPrice.getDisplay(player, item.buyAmount)) - .replaceIn("%amount%", item.buyAmount.toString()) - ) - } else { - addLoreLines( - plugin.langYml.getStrings("quick-buy") - .replaceIn("%amount%", item.buyAmount.toString()) - ) - } - } - } - - if (item.isSellable) { - addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.sell").formatEco(player)) - } - - if (item.isShowingQuickBuySell) { - if (item.isSellable) { - addLoreLines( - plugin.langYml.getStrings("quick-sell") - ) - } - } - - addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.always").formatEco(player)) - } - }) { + private val slot = slot(extractItemStack(item, plugin)) { fun handleMainBuyClick(player: Player, menu: Menu, buyType: BuyType) { val status = item.getBuyStatus(player, 1, buyType) @@ -213,7 +131,107 @@ class ShopItemSlot( } } + private fun extractItemStack(item: ShopItem, plugin: EcoPlugin): (Player, Menu) -> ItemStack { + return { player: Player, _: Menu -> + val playerBuysLeft = item.getBuysLeft(player) + val zeroBuysLeftMessage = plugin.langYml.getStrings("cant-buy-again") + val fallbackPriceMessage = if (playerBuysLeft == 1) { + "one-buy-price" + } else { + "buy-price" + } + val altBuyMessage = plugin.langYml.getStrings("dual-buy-price") + .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") + .replaceIn("%alt_price%", item.altBuyPrice?.getDisplay(player) ?: "") + val status = item.getBuyStatus(player, 1, BuyType.NORMAL) + val itemStack = item.displayItem.modify { + if (item.isBuyable) { + addLoreLines( + if (status == BuyStatus.MISSING_REQUIREMENTS || status == BuyStatus.NO_PERMISSION) { + plugin.langYml.getStrings("lore.${status.configKey}") + } else { + if (playerBuysLeft == 0) { + zeroBuysLeftMessage + } else { + if (item.hasAltBuy) { + altBuyMessage + } else { + plugin.langYml.getStrings(fallbackPriceMessage) + .replaceIn("%price%", item.buyPrice?.getDisplay(player) ?: "") + } + } + } + ) + } + + if (item.isSellable) { + addLoreLines( + plugin.langYml.getStrings("sell-price") + .replaceIn("%price%", item.sellPrice?.getDisplay(player) ?: "") + ) + } + + if (item.isShowingQuickBuySell) { + if (item.isBuyable && item.getMaxBuysAtOnce(player) > item.buyAmount) { + if (item.hasAltBuy) { + addLoreLines( + plugin.langYml.getStrings("quick-buy-alt-present") + .replaceIn("%price%", item.buyPrice.getDisplay(player, item.buyAmount)) + .replaceIn("%amount%", item.buyAmount.toString()) + ) + addLoreLines( + plugin.langYml.getStrings("quick-buy-alt") + .replaceIn("%price%", item.altBuyPrice.getDisplay(player, item.buyAmount)) + .replaceIn("%amount%", item.buyAmount.toString()) + ) + } else { + addLoreLines( + plugin.langYml.getStrings("quick-buy") + .replaceIn("%amount%", item.buyAmount.toString()) + ) + } + } + + if (item.isSellable) { + addLoreLines( + plugin.langYml.getStrings("quick-sell") + ) + + addLoreLines( + plugin.configYml.getStrings("shop-items.global-bottom-lore.sell").formatEco(player) + ) + } + } + + addLoreLines( + item.bottomLore.formatEco(player) + ) + + if (item.isBuyable) { + addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.buy").formatEco(player)) + } + + if (item.isSellable) { + addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.sell").formatEco(player)) + } + + addLoreLines(plugin.configYml.getStrings("shop-items.global-bottom-lore.always").formatEco(player)) + } + + val meta = itemStack.itemMeta + val lore = (meta?.lore ?: emptyList()) + .replaceIn("%playerbuys%", item.getTotalBuys(player)) + .replaceIn("%playerlimit%", item.limit) + .replaceIn("%globalbuys%", item.getTotalGlobalBuys()) + .replaceIn("%globallimit%", item.globalLimit) + meta?.lore = lore + itemStack.itemMeta = meta + itemStack + } + } + init { init(slot) } + } diff --git a/eco-core/core-plugin/src/main/resources/lang.yml b/eco-core/core-plugin/src/main/resources/lang.yml index 19d95e8..b6dd9ec 100644 --- a/eco-core/core-plugin/src/main/resources/lang.yml +++ b/eco-core/core-plugin/src/main/resources/lang.yml @@ -24,6 +24,7 @@ messages: no-permission: "&cYou don't have permission to buy this item!" missing-requirements: "&cYou can't buy this item!" cannot-afford: "&cYou need &a%price%&r&c to buy this!" + global-bought-too-many: "&cThe server has no more stock!" bought-item: "&fYou bought %item%&r&f for %price%&r&f!" bought-item-multiple: "&fYou bought %amount%x&r %item%&r&f for %price%&r&f!"