9
0
mirror of https://github.com/Auxilor/EcoJobs.git synced 2025-12-21 16:09:18 +00:00

added xp-formula and max-level

This commit is contained in:
Exanthiax
2025-01-28 19:45:56 +00:00
parent b99a72808c
commit acdb4d0f78
2 changed files with 74 additions and 45 deletions

View File

@@ -6,13 +6,16 @@ import com.willfp.eco.core.data.keys.PersistentDataKey
import com.willfp.eco.core.data.keys.PersistentDataKeyType import com.willfp.eco.core.data.keys.PersistentDataKeyType
import com.willfp.eco.core.items.Items import com.willfp.eco.core.items.Items
import com.willfp.eco.core.items.builder.ItemStackBuilder import com.willfp.eco.core.items.builder.ItemStackBuilder
import com.willfp.eco.core.placeholder.InjectablePlaceholder
import com.willfp.eco.core.placeholder.PlayerPlaceholder import com.willfp.eco.core.placeholder.PlayerPlaceholder
import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder import com.willfp.eco.core.placeholder.PlayerStaticPlaceholder
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder import com.willfp.eco.core.placeholder.PlayerlessPlaceholder
import com.willfp.eco.core.placeholder.StaticPlaceholder
import com.willfp.eco.core.price.ConfiguredPrice import com.willfp.eco.core.price.ConfiguredPrice
import com.willfp.eco.core.price.impl.PriceEconomy import com.willfp.eco.core.price.impl.PriceEconomy
import com.willfp.eco.core.registry.Registrable import com.willfp.eco.core.registry.Registrable
import com.willfp.eco.util.NumberUtils import com.willfp.eco.util.NumberUtils
import com.willfp.eco.util.NumberUtils.evaluateExpression
import com.willfp.eco.util.formatEco import com.willfp.eco.util.formatEco
import com.willfp.eco.util.toNiceString import com.willfp.eco.util.toNiceString
import com.willfp.ecojobs.EcoJobsPlugin import com.willfp.ecojobs.EcoJobsPlugin
@@ -32,12 +35,11 @@ import com.willfp.libreforge.effects.EffectList
import com.willfp.libreforge.effects.Effects import com.willfp.libreforge.effects.Effects
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.OfflinePlayer import org.bukkit.OfflinePlayer
import org.bukkit.configuration.InvalidConfigurationException
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack import org.bukkit.inventory.ItemStack
import java.time.Duration import java.time.Duration
import java.util.Objects import java.util.Objects
import java.util.concurrent.TimeUnit
import kotlin.math.max
class Job( class Job(
val id: String, val id: String,
@@ -49,8 +51,11 @@ class Job(
.build<Int, LeaderboardCacheEntry?>() .build<Int, LeaderboardCacheEntry?>()
val name = config.getFormattedString("name") val name = config.getFormattedString("name")
val description = config.getFormattedString("description") val description = config.getFormattedString("description")
val isUnlockedByDefault = config.getBool("unlocked-by-default") val isUnlockedByDefault = config.getBool("unlocked-by-default")
val resetsOnQuit = config.getBool("reset-on-quit") val resetsOnQuit = config.getBool("reset-on-quit")
val joinPrice = ConfiguredPrice.create(config.getSubsection("join-price")) ?: ConfiguredPrice( val joinPrice = ConfiguredPrice.create(config.getSubsection("join-price")) ?: ConfiguredPrice(
@@ -71,9 +76,11 @@ class Job(
EcoJobsPlugin.instance.namespacedKeyFactory.create("${id}_xp"), PersistentDataKeyType.DOUBLE, 0.0 EcoJobsPlugin.instance.namespacedKeyFactory.create("${id}_xp"), PersistentDataKeyType.DOUBLE, 0.0
) )
private val levelXpRequirements = listOf(0) + config.getInts("level-xp-requirements") private val xpFormula = config.getStringOrNull("xp-formula")
val maxLevel = levelXpRequirements.size private val levelXpRequirements = config.getDoublesOrNull("level-xp-requirements")
val maxLevel = config.getIntOrNull("max-level") ?: levelXpRequirements?.size ?: Int.MAX_VALUE
val levelGUI = JobLevelGUI(plugin, this) val levelGUI = JobLevelGUI(plugin, this)
@@ -106,6 +113,10 @@ class Job(
} }
init { init {
if (xpFormula == null && levelXpRequirements == null) {
throw InvalidConfigurationException("Skill $id has no requirements or xp formula")
}
config.injectPlaceholders(PlayerStaticPlaceholder( config.injectPlaceholders(PlayerStaticPlaceholder(
"level" "level"
) { p -> ) { p ->
@@ -352,9 +363,23 @@ class Job(
return Int.MAX_VALUE return Int.MAX_VALUE
} }
return levelXpRequirements[level - 1] // Use levelXpRequirements if it exists and covers the level
if (levelXpRequirements != null && levelXpRequirements.size >= level) {
return levelXpRequirements[level - 1].toInt()
}
// Fallback to using the xpFormula if it exists
if (xpFormula != null) {
return evaluateExpression(
xpFormula.replace("%level%", level.toString())
).toInt()
}
// Default fallback if neither configuration is usable
return Int.MAX_VALUE
} }
fun executeLevelCommands(player: Player, level: Int) { fun executeLevelCommands(player: Player, level: Int) {
val commands = levelCommands[level] ?: emptyList() val commands = levelCommands[level] ?: emptyList()
@@ -409,43 +434,3 @@ private fun Collection<LevelPlaceholder>.format(string: String, level: Int): Str
fun OfflinePlayer.getJobLevelObject(job: Job): JobLevel = job.getLevel(this.getJobLevel(job)) fun OfflinePlayer.getJobLevelObject(job: Job): JobLevel = job.getLevel(this.getJobLevel(job))
private val expMultiplierCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build<Player, Double> {
it.cacheJobExperienceMultiplier()
}
val Player.jobExperienceMultiplier: Double
get() = expMultiplierCache.get(this)
private fun Player.cacheJobExperienceMultiplier(): Double {
if (this.hasPermission("ecojobs.xpmultiplier.quadruple")) {
return 4.0
}
if (this.hasPermission("ecojobs.xpmultiplier.triple")) {
return 3.0
}
if (this.hasPermission("ecojobs.xpmultiplier.double")) {
return 2.0
}
if (this.hasPermission("ecojobs.xpmultiplier.50percent")) {
return 1.5
}
return 1 + getNumericalPermission("ecojobs.xpmultiplier", 0.0) / 100
}
fun Player.getNumericalPermission(permission: String, default: Double): Double {
var highest: Double? = null
for (permissionAttachmentInfo in this.effectivePermissions) {
val perm = permissionAttachmentInfo.permission
if (perm.startsWith(permission)) {
val found = perm.substring(perm.lastIndexOf(".") + 1).toDoubleOrNull() ?: continue
highest = max(highest ?: Double.MIN_VALUE, found)
}
}
return highest ?: default
}

View File

@@ -1,9 +1,12 @@
package com.willfp.ecojobs.jobs package com.willfp.ecojobs.jobs
import com.github.benmanes.caffeine.cache.Caffeine
import com.willfp.ecojobs.api.giveJobExperience import com.willfp.ecojobs.api.giveJobExperience
import com.willfp.ecojobs.api.hasJobActive import com.willfp.ecojobs.api.hasJobActive
import com.willfp.libreforge.counters.Accumulator import com.willfp.libreforge.counters.Accumulator
import org.bukkit.entity.Player import org.bukkit.entity.Player
import java.util.concurrent.TimeUnit
import kotlin.math.max
class JobXPAccumulator( class JobXPAccumulator(
private val job: Job private val job: Job
@@ -16,3 +19,44 @@ class JobXPAccumulator(
player.giveJobExperience(job, count) player.giveJobExperience(job, count)
} }
} }
private val expMultiplierCache = Caffeine.newBuilder().expireAfterWrite(10, TimeUnit.SECONDS).build<Player, Double> {
it.cacheJobExperienceMultiplier()
}
val Player.jobExperienceMultiplier: Double
get() = expMultiplierCache.get(this)
private fun Player.cacheJobExperienceMultiplier(): Double {
if (this.hasPermission("ecojobs.xpmultiplier.quadruple")) {
return 4.0
}
if (this.hasPermission("ecojobs.xpmultiplier.triple")) {
return 3.0
}
if (this.hasPermission("ecojobs.xpmultiplier.double")) {
return 2.0
}
if (this.hasPermission("ecojobs.xpmultiplier.50percent")) {
return 1.5
}
return 1 + getNumericalPermission("ecojobs.xpmultiplier", 0.0) / 100
}
fun Player.getNumericalPermission(permission: String, default: Double): Double {
var highest: Double? = null
for (permissionAttachmentInfo in this.effectivePermissions) {
val perm = permissionAttachmentInfo.permission
if (perm.startsWith(permission)) {
val found = perm.substring(perm.lastIndexOf(".") + 1).toDoubleOrNull() ?: continue
highest = max(highest ?: Double.MIN_VALUE, found)
}
}
return highest ?: default
}