diff --git a/plugin/src/main/kotlin/me/gabytm/minecraft/arcanevouchers/actions/tags/ChanceTag.kt b/plugin/src/main/kotlin/me/gabytm/minecraft/arcanevouchers/actions/tags/ChanceTag.kt index d89e8ec..f50f9e3 100644 --- a/plugin/src/main/kotlin/me/gabytm/minecraft/arcanevouchers/actions/tags/ChanceTag.kt +++ b/plugin/src/main/kotlin/me/gabytm/minecraft/arcanevouchers/actions/tags/ChanceTag.kt @@ -1,10 +1,11 @@ package me.gabytm.minecraft.arcanevouchers.actions.tags +import me.gabytm.minecraft.arcanevouchers.functions.debug import me.gabytm.util.actions.actions.Context import me.gabytm.util.actions.components.Component import me.gabytm.util.actions.placeholders.PlaceholderManager import org.bukkit.entity.Player -import java.util.* +import java.util.concurrent.ThreadLocalRandom class ChanceTag(stringValue: String, placeholderManager: PlaceholderManager) : Component( stringValue, @@ -13,6 +14,7 @@ class ChanceTag(stringValue: String, placeholderManager: PlaceholderManager) : C private val elements: Set> private val default: String + private val limitChanceToMax: Boolean init { // Example: {50=COAL,25=DIAMOND,25=EMERALD,default=STONE} @@ -31,25 +33,33 @@ class ChanceTag(stringValue: String, placeholderManager: PlaceholderManager) : C "" } + limitChanceToMax = default == "#limit-max-chance" + elements = pairs.toSet() } override fun parse(player: Player, context: Context): String { // Map all elements into Pair val set = elements.map { - val chance = placeholderManager.replace(player, it.first, context).toDoubleOrNull() + val chance = placeholderManager.replace(player, it.first, context).toFloatOrNull() ?: throw IllegalArgumentException("(chance tag) '${it.first}' is not a number") chance to placeholderManager.replace(player, it.second, context) } - val chance = RANDOM.nextDouble(101.0) // Generate random chance between 0 and 100 - val valid = set.filter { chance <= it.first } // Filter the elements + val chance = if (limitChanceToMax) { + ThreadLocalRandom.current().nextFloat() * set.maxOf { it.first } // Variable max chance + } else { + ThreadLocalRandom.current().nextFloat() * 100.00001f // Generate random chance between 0 and 100 + } + val possible = set.filter { chance <= it.first } + debug(player, "(chance tag) elements = $elements, set = $set") + debug(player, "(chance tag) chance = $chance, possible = $possible") - return if (valid.isEmpty()) { + return if (possible.isEmpty()) { default - } else if (valid.size == 1) { - valid.first().second + } else if (possible.size == 1) { + possible.first().second } else { - valid.elementAt(RANDOM.nextInt(valid.size)).second + possible.elementAt(ThreadLocalRandom.current().nextInt(possible.size)).second } } @@ -57,7 +67,6 @@ class ChanceTag(stringValue: String, placeholderManager: PlaceholderManager) : C companion object { private const val ID: String = "chance" - private val RANDOM = SplittableRandom() }