diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt index 38eeae5..b033c30 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/crate/Crate.kt @@ -129,6 +129,16 @@ class Crate( ) } + private fun hasRanOutOfRewardsAndNotify(player: Player): Boolean { + val ranOut = rewards.all { it.getWeight(player) <= 0 || it.getDisplayWeight(player) <= 0 } + + if (ranOut) { + player.sendMessage(plugin.langYml.getMessage("all-rewards-used")) + } + + return ranOut + } + private fun getRandomReward(player: Player, displayWeight: Boolean = false): Reward { var weight = 100.0 val selection = rewards.toList().shuffled() @@ -223,6 +233,10 @@ class Crate( if (!hasKeysAndNotify(player, physicalKey = true)) { return } + if (hasRanOutOfRewardsAndNotify(player)) { + return + } + if (physicalKey) { usePhysicalKey(player) @@ -234,6 +248,11 @@ class Crate( } fun open(player: Player, location: Location? = null, physicalKey: Boolean = false) { + /* Prevent server crashes */ + if (hasRanOutOfRewardsAndNotify(player)) { + return + } + val event = CrateOpenEvent(player, this, physicalKey, getRandomReward(player)) Bukkit.getPluginManager().callEvent(event) diff --git a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/reward/Reward.kt b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/reward/Reward.kt index 377cbc2..49ceb6e 100644 --- a/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/reward/Reward.kt +++ b/eco-core/core-plugin/src/main/kotlin/com/willfp/ecocrates/reward/Reward.kt @@ -2,6 +2,9 @@ package com.willfp.ecocrates.reward import com.willfp.eco.core.EcoPlugin import com.willfp.eco.core.config.interfaces.Config +import com.willfp.eco.core.data.keys.PersistentDataKey +import com.willfp.eco.core.data.keys.PersistentDataKeyType +import com.willfp.eco.core.data.profile import com.willfp.eco.core.drops.DropQueue import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.builder.ItemStackBuilder @@ -9,25 +12,55 @@ import com.willfp.eco.core.recipe.parts.EmptyTestableItem import org.bukkit.Bukkit import org.bukkit.entity.Player import org.bukkit.inventory.ItemStack +import java.util.* class Reward( private val plugin: EcoPlugin, private val config: Config ) { + val id = config.getString("id") + private val commands = config.getStrings("commands") private val items = config.getStrings("items").map { Items.lookup(it) }.filterNot { it is EmptyTestableItem } private val messages = config.getFormattedStrings("messages") + private val maxWins = config.getInt("max-wins") + + private val winsKey: PersistentDataKey = PersistentDataKey( + plugin.namespacedKeyFactory.create("${id}_wins"), + PersistentDataKeyType.INT, + 0 + ).apply { + // Only register if max wins are being limited + if (maxWins > 0) player() + } + val display: ItemStack = ItemStackBuilder(Items.lookup(config.getString("display.item"))) .addLoreLines(config.getStrings("display.lore")) .setDisplayName(config.getString("display.name")) .build() - fun getWeight(player: Player) = config.getDoubleFromExpression("weight.actual", player) + fun getWeight(player: Player): Double { + val weight = config.getDoubleFromExpression("weight.actual", player) + if (maxWins > 0) { + if (player.profile.read(winsKey) >= maxWins) { + return 0.0 + } + } + return weight + } - fun getDisplayWeight(player: Player) = config.getDoubleFromExpression("weight.display", player) + fun getDisplayWeight(player: Player): Double { + val weight = config.getDoubleFromExpression("weight.display", player) + if (maxWins > 0) { + if (player.profile.read(winsKey) >= maxWins) { + return 0.0 + } + } + return weight + } val displayRow = config.getInt("display.row") @@ -49,5 +82,21 @@ class Reward( .push() messages.forEach { player.sendMessage(plugin.langYml.prefix + it) } + + if (maxWins > 0) { + player.profile.write(winsKey, player.profile.read(winsKey) + 1) + } } -} \ No newline at end of file + + override fun equals(other: Any?): Boolean { + if (other !is Reward) { + return false + } + + return this.id == other.id + } + + override fun hashCode(): Int { + return Objects.hash(id) + } +} diff --git a/eco-core/core-plugin/src/main/resources/crates.yml b/eco-core/core-plugin/src/main/resources/crates.yml index 66d3cda..b1402d9 100644 --- a/eco-core/core-plugin/src/main/resources/crates.yml +++ b/eco-core/core-plugin/src/main/resources/crates.yml @@ -67,7 +67,8 @@ crates: pitch: 1 rewards: - - commands: [ ] + - id: diamond + commands: [ ] items: - diamond messages: @@ -75,6 +76,7 @@ crates: weight: actual: 10 display: 25 + max-wins: -1 display: name: "&bDiamond" item: diamond @@ -82,7 +84,8 @@ crates: row: 2 column: 2 - - commands: [ ] + - id: emerald + commands: [ ] items: - emerald messages: @@ -90,6 +93,7 @@ crates: weight: actual: 10 display: 50 + max-wins: -1 display: name: "&aEmerald" item: emerald @@ -97,7 +101,8 @@ crates: row: 2 column: 3 - - commands: [ ] + - id: bedrock + commands: [ ] items: - bedrock messages: @@ -105,6 +110,7 @@ crates: weight: actual: 10000000 display: 0 + max-wins: -1 display: name: "very cool demo bedrock" item: bedrock diff --git a/eco-core/core-plugin/src/main/resources/lang.yml b/eco-core/core-plugin/src/main/resources/lang.yml index 96a2389..0528e40 100644 --- a/eco-core/core-plugin/src/main/resources/lang.yml +++ b/eco-core/core-plugin/src/main/resources/lang.yml @@ -12,4 +12,5 @@ messages: gave-keys: "Gave %amount%&f %crate%&f key(s) to %user%&f!" must-target-block: "&cYou must be looking at a block!" set-block-as-crate: "Set block to be a crate!" - removed-crate: "Removed crate!" \ No newline at end of file + removed-crate: "Removed crate!" + all-rewards-used: "&cYou have already won all things in this crate!" \ No newline at end of file