9
0
mirror of https://github.com/Auxilor/EcoJobs.git synced 2025-12-20 07:29:20 +00:00

Compare commits

...

38 Commits

Author SHA1 Message Date
Will FP
ec1fe90c8c libreforge-updater 2025-03-29 14:21:51 +00:00
Will FP
7420415514 Merge pull request #33 from Exanthiax/reset-all-command
added "all" args to reset command
2025-03-29 14:18:16 +00:00
Will FP
11bce9975d Merge pull request #34 from Exanthiax/level-up-effects
added level-up-effects
2025-03-29 14:18:00 +00:00
Will FP
013d8a0068 Merge branch 'master' into level-up-effects 2025-03-29 14:17:28 +00:00
Will FP
338c1c3499 Merge pull request #35 from Exanthiax/trigger-effects
added join-effects and leave-effects
2025-03-29 14:16:40 +00:00
Exanthiax
cdcc45aef8 update all current jobs 2025-03-09 22:52:32 +00:00
Exanthiax
533d036a18 moved below placeholders 2025-02-04 23:12:04 +00:00
Exanthiax
03e99e2e1e updated ymls 2025-02-04 23:05:41 +00:00
Exanthiax
86b7ad2971 added level-up-effects
added `level-up-effects`
deprecated `level-commands` with message
2025-02-04 21:39:57 +00:00
Exanthiax
7065642d97 Update _example.yml 2025-02-04 18:04:56 +00:00
Exanthiax
e6c486bc3a added join-effects and leave-effects 2025-02-04 18:02:48 +00:00
Exanthiax
c99769a1e3 added "all" args
Within reset command, you can now use "all" as player or job.
Added new lang messages accordingly.
2025-01-31 13:38:06 +00:00
Will FP
6fc1ba72d8 libreforge-updater 2025-01-31 11:53:47 +00:00
Will FP
b08687eba2 Merge pull request #31 from Penumbrae/patch-1
Wrong usage of a filter
2025-01-31 11:41:53 +00:00
Will FP
8cd544b327 Merge pull request #32 from Exanthiax/new-xp-methods
New xp methods
2025-01-31 11:41:44 +00:00
Exanthiax
5d40c32c1e Fixed xp-required and placeholders. 2025-01-28 23:35:34 +00:00
Exanthiax
ee155ccca6 Update _example.yml 2025-01-28 20:04:22 +00:00
Exanthiax
acdb4d0f78 added xp-formula and max-level 2025-01-28 19:45:56 +00:00
Will FP
b99a72808c libreforge-updater 2025-01-25 13:49:33 +00:00
Will FP
6bd56c8d95 Fix 2025-01-25 13:48:09 +00:00
Will FP
e90f321517 libreforge-updater 2025-01-25 13:45:31 +00:00
Penumbrae
4c021781e5 Wrong usage of a filter
This job had the filter "items" to filter pickaxes, which doesn't work in this case. This essentially means that the players would be able to earn money and xp by breaking a block in any way.

Changed it to the in_mainhand condition.
2025-01-25 00:37:55 +00:00
Will FP
abfce4428f libreforge-updater 2024-11-06 18:31:32 +00:00
Will FP
d7b7f6895e libreforge-updater 2024-10-22 12:12:52 +01:00
Will FP
2a97bc2d29 libreforge-updater 2024-09-22 16:58:16 +01:00
Auxilor
af4d3058e8 libreforge-updater 2024-09-02 11:29:55 +01:00
Auxilor
802360e885 libreforge-updater 2024-08-30 17:24:55 +01:00
Auxilor
79a396f5d3 libreforge-updater 2024-08-29 12:09:03 +01:00
Auxilor
e264e49b05 libreforge-updater 2024-08-23 15:35:08 +01:00
Auxilor
d9263bcb53 libreforge-updater 2024-08-21 18:58:06 +01:00
Auxilor
4681bd63e1 libreforge-updater 2024-08-15 15:07:19 +01:00
Auxilor
998e25e7ec libreforge-updater 2024-08-03 13:41:10 +01:00
Auxilor
f1f7ec5afd libreforge-updater 2024-07-25 10:04:20 +01:00
Auxilor
875928b4c2 libreforge-updater 2024-07-21 12:19:05 +01:00
Auxilor
049cb72385 libreforge-updater 2024-07-19 20:28:24 +01:00
Auxilor
b7decc9eb8 libreforge-updater 2024-07-18 13:23:59 +01:00
Auxilor
44c59de546 libreforge-updater 2024-07-16 17:13:29 +01:00
Auxilor
fdbbf8102c libreforge-updater 2024-07-13 20:45:06 +01:00
21 changed files with 349 additions and 120 deletions

View File

@@ -1,9 +1,11 @@
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
plugins { plugins {
java java
`java-library` `java-library`
`maven-publish` `maven-publish`
kotlin("jvm") version "1.9.20" kotlin("jvm") version "2.1.0"
id("io.github.goooler.shadow") version "8.1.7" id("com.gradleup.shadow") version "8.3.0"
id("com.willfp.libreforge-gradle-plugin") version "1.0.0" id("com.willfp.libreforge-gradle-plugin") version "1.0.0"
} }
@@ -25,7 +27,7 @@ allprojects {
apply(plugin = "java") apply(plugin = "java")
apply(plugin = "kotlin") apply(plugin = "kotlin")
apply(plugin = "maven-publish") apply(plugin = "maven-publish")
apply(plugin = "io.github.goooler.shadow") apply(plugin = "com.gradleup.shadow")
repositories { repositories {
mavenLocal() mavenLocal()
@@ -37,9 +39,9 @@ allprojects {
} }
dependencies { dependencies {
compileOnly("com.willfp:eco:6.55.0") compileOnly("com.willfp:eco:6.56.0")
compileOnly("org.jetbrains:annotations:23.0.0") compileOnly("org.jetbrains:annotations:23.0.0")
compileOnly("org.jetbrains.kotlin:kotlin-stdlib:1.9.20") compileOnly("org.jetbrains.kotlin:kotlin-stdlib:2.1.0")
} }
java { java {
@@ -54,8 +56,8 @@ allprojects {
} }
compileKotlin { compileKotlin {
kotlinOptions { compilerOptions {
jvmTarget = "17" jvmTarget.set(JvmTarget.JVM_17)
} }
} }

View File

@@ -140,7 +140,7 @@ fun OfflinePlayer.resetJob(job: Job) {
/** /**
* Get the experience required to advance to the next level. * Get the experience required to advance to the next level.
*/ */
fun OfflinePlayer.getJobXPRequired(job: Job) = job.getExpForLevel(this.getJobLevel(job) + 1) fun OfflinePlayer.getJobXPRequired(job: Job) = job.getFormattedExpForLevel(this.getJobLevel(job) + 1)
/** /**
* Get progress to next level between 0 and 1, where 0 is none and 1 is complete. * Get progress to next level between 0 and 1, where 0 is none and 1 is complete.

View File

@@ -10,6 +10,7 @@ import com.willfp.ecojobs.api.resetJob
import com.willfp.ecojobs.jobs.Jobs import com.willfp.ecojobs.jobs.Jobs
import org.bukkit.Bukkit import org.bukkit.Bukkit
import org.bukkit.command.CommandSender import org.bukkit.command.CommandSender
import org.bukkit.util.StringUtil
class CommandReset(plugin: EcoPlugin) : Subcommand(plugin, "reset", "ecojobs.command.reset", false) { class CommandReset(plugin: EcoPlugin) : Subcommand(plugin, "reset", "ecojobs.command.reset", false) {
override fun onExecute(sender: CommandSender, args: List<String>) { override fun onExecute(sender: CommandSender, args: List<String>) {
@@ -24,16 +25,68 @@ class CommandReset(plugin: EcoPlugin) : Subcommand(plugin, "reset", "ecojobs.com
} }
val playerName = args[0] val playerName = args[0]
val jobName = args[1]
// Reset all jobs for all players
if (playerName.equals("all", ignoreCase = true) && jobName.equals("all", ignoreCase = true)) {
Bukkit.getOnlinePlayers().forEach { player ->
Jobs.values().forEach { job ->
if (player.hasJob(job)) {
player.forceLeaveJob(job)
player.resetJob(job)
}
}
}
sender.sendMessage(plugin.langYml.getMessage("reset-all-players-all-jobs"))
return
}
// Reset a specific job for all players
if (playerName.equals("all", ignoreCase = true)) {
val job = Jobs.getByID(jobName)
if (job == null) {
sender.sendMessage(plugin.langYml.getMessage("invalid-job"))
return
}
Bukkit.getOnlinePlayers().forEach { player ->
if (player.hasJob(job)) {
player.forceLeaveJob(job)
player.resetJob(job)
}
}
sender.sendMessage(
plugin.langYml.getMessage("reset-all-players")
.replace("%job%", job.name)
)
return
}
// Reset all jobs for a specific player
val player = Bukkit.getPlayer(playerName) val player = Bukkit.getPlayer(playerName)
if (player == null) { if (player == null) {
sender.sendMessage(plugin.langYml.getMessage("invalid-player")) sender.sendMessage(plugin.langYml.getMessage("invalid-player"))
return return
} }
val job = Jobs.getByID(args[1]) if (jobName.equals("all", ignoreCase = true)) {
Jobs.values().forEach { job ->
if (player.hasJob(job)) {
player.forceLeaveJob(job)
player.resetJob(job)
}
}
sender.sendMessage(
plugin.langYml.getMessage("reset-all-jobs")
.replace("%player%", player.savedDisplayName)
)
return
}
// Reset a specific job for a specific player
val job = Jobs.getByID(jobName)
if (job == null) { if (job == null) {
sender.sendMessage(plugin.langYml.getMessage("invalid-job")) sender.sendMessage(plugin.langYml.getMessage("invalid-job"))
return return
@@ -55,12 +108,23 @@ class CommandReset(plugin: EcoPlugin) : Subcommand(plugin, "reset", "ecojobs.com
} }
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> { override fun tabComplete(sender: CommandSender, args: List<String>): List<String> {
val completions = mutableListOf<String>()
if (args.size == 1) { if (args.size == 1) {
return Bukkit.getOnlinePlayers().map { it.name } StringUtil.copyPartialMatches(
args[0],
listOf("all") union Bukkit.getOnlinePlayers().map { player -> player.name },
completions
)
return completions
} }
if (args.size == 2) { if (args.size == 2) {
return Jobs.values().map { it.id } StringUtil.copyPartialMatches(
args[1],
listOf("all") union Jobs.values().map { it.id },
completions
)
return completions
} }
return emptyList() return emptyList()

View File

@@ -9,10 +9,12 @@ import com.willfp.eco.core.items.builder.ItemStackBuilder
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.context.placeholderContext
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
@@ -24,20 +26,21 @@ import com.willfp.ecojobs.api.getJobXP
import com.willfp.ecojobs.api.getJobXPRequired import com.willfp.ecojobs.api.getJobXPRequired
import com.willfp.ecojobs.api.hasJobActive import com.willfp.ecojobs.api.hasJobActive
import com.willfp.ecojobs.api.jobLimit import com.willfp.ecojobs.api.jobLimit
import com.willfp.ecojobs.util.LevelInjectable
import com.willfp.libreforge.ViolationContext import com.willfp.libreforge.ViolationContext
import com.willfp.libreforge.conditions.ConditionList import com.willfp.libreforge.conditions.ConditionList
import com.willfp.libreforge.conditions.Conditions import com.willfp.libreforge.conditions.Conditions
import com.willfp.libreforge.counters.Counters import com.willfp.libreforge.counters.Counters
import com.willfp.libreforge.effects.EffectList import com.willfp.libreforge.effects.EffectList
import com.willfp.libreforge.effects.Effects import com.willfp.libreforge.effects.Effects
import com.willfp.libreforge.effects.executors.impl.NormalExecutorFactory
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 +52,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 +77,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 +114,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 ->
@@ -122,24 +134,7 @@ class Job(
ViolationContext(plugin, "Job $id") ViolationContext(plugin, "Job $id")
) )
for (string in config.getStrings("level-commands")) { manageLevelCommands(config)
val split = string.split(":")
if (split.size == 1) {
for (level in 1..maxLevel) {
val commands = levelCommands[level] ?: mutableListOf()
commands.add(string)
levelCommands[level] = commands
}
} else {
val level = split[0].toInt()
val command = string.removePrefix("$level:")
val commands = levelCommands[level] ?: mutableListOf()
commands.add(command)
levelCommands[level] = commands
}
}
PlayerPlaceholder( PlayerPlaceholder(
plugin, "${id}_percentage_progress" plugin, "${id}_percentage_progress"
@@ -190,6 +185,49 @@ class Job(
}.register() }.register()
} }
@Deprecated("Use level-up-effects instead")
private fun manageLevelCommands(config: Config) {
if (config.getStrings("level-commands").isNotEmpty()) {
plugin.logger.warning("$id job: The `level-commands` key is deprecated and will be removed in future versions. Switch to `level-up-effects` instead. Refer to the wiki for more info.")
}
for (string in config.getStrings("level-commands")) {
val split = string.split(":")
if (split.size == 1) {
for (level in 1..maxLevel) {
val commands = levelCommands[level] ?: mutableListOf()
commands.add(string)
levelCommands[level] = commands
}
} else {
val level = split[0].toInt()
val command = string.removePrefix("$level:")
val commands = levelCommands[level] ?: mutableListOf()
commands.add(command)
levelCommands[level] = commands
}
}
}
val levelUpEffects = Effects.compileChain(
config.getSubsections("level-up-effects"),
NormalExecutorFactory.create(),
ViolationContext(plugin, "Job $id level-up-effects")
)
val joinEffects = Effects.compileChain(
config.getSubsections("join-effects"),
NormalExecutorFactory.create(),
ViolationContext(plugin, "Job $id join-effects")
)
val leaveEffects = Effects.compileChain(
config.getSubsections("leave-effects"),
NormalExecutorFactory.create(),
ViolationContext(plugin, "Job $id leave-effects")
)
override fun onRegister() { override fun onRegister() {
jobXpGains.forEach { it.bind(JobXPAccumulator(this)) } jobXpGains.forEach { it.bind(JobXPAccumulator(this)) }
} }
@@ -275,13 +313,8 @@ class Job(
val withPlaceholders = lore.map { val withPlaceholders = lore.map {
it.replace("%percentage_progress%", (player.getJobProgress(this) * 100).toNiceString()) it.replace("%percentage_progress%", (player.getJobProgress(this) * 100).toNiceString())
.replace("%current_xp%", player.getJobXP(this).toNiceString()) .replace("%current_xp%", player.getJobXP(this).toNiceString())
.replace("%required_xp%", this.getExpForLevel(player.getJobLevel(this) + 1).let { req -> .replace("%required_xp%", this.getFormattedExpForLevel(player.getJobLevel(this) + 1))
if (req == Int.MAX_VALUE) { .replace("%description%", this.description).replace("%job%", this.name)
plugin.langYml.getFormattedString("infinity")
} else {
req.toNiceString()
}
}).replace("%description%", this.description).replace("%job%", this.name)
.replace("%level%", (forceLevel ?: player.getJobLevel(this)).toString()) .replace("%level%", (forceLevel ?: player.getJobLevel(this)).toString())
.replace("%level_numeral%", NumberUtils.toNumeral(forceLevel ?: player.getJobLevel(this))) .replace("%level_numeral%", NumberUtils.toNumeral(forceLevel ?: player.getJobLevel(this)))
.replace("%join_price%", this.joinPrice.getDisplay(player)) .replace("%join_price%", this.joinPrice.getDisplay(player))
@@ -347,14 +380,36 @@ class Job(
}.build() }.build()
} }
fun getExpForLevel(level: Int): Int { /**
if (level < 1 || level > maxLevel) { * Get the XP required to reach the next level, if currently at [level].
return Int.MAX_VALUE */
fun getExpForLevel(level: Int): Double {
if (xpFormula != null) {
return evaluateExpression(
xpFormula,
placeholderContext(
injectable = LevelInjectable(level)
)
)
} }
return levelXpRequirements[level - 1] if (levelXpRequirements != null) {
return levelXpRequirements.getOrNull(level) ?: Double.POSITIVE_INFINITY
} }
return Double.POSITIVE_INFINITY
}
fun getFormattedExpForLevel(level: Int): String {
val required = getExpForLevel(level)
return if (required.isInfinite()) {
plugin.langYml.getFormattedString("infinity")
} else {
required.toNiceString()
}
}
@Deprecated("Use level-up-effects instead")
fun executeLevelCommands(player: Player, level: Int) { fun executeLevelCommands(player: Player, level: Int) {
val commands = levelCommands[level] ?: emptyList() val commands = levelCommands[level] ?: emptyList()
@@ -409,43 +464,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

@@ -2,6 +2,7 @@ package com.willfp.ecojobs.jobs
import com.willfp.ecojobs.EcoJobsPlugin import com.willfp.ecojobs.EcoJobsPlugin
import com.willfp.ecojobs.api.event.PlayerJobLevelUpEvent import com.willfp.ecojobs.api.event.PlayerJobLevelUpEvent
import com.willfp.libreforge.toDispatcher
import org.bukkit.Sound import org.bukkit.Sound
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority import org.bukkit.event.EventPriority
@@ -16,6 +17,7 @@ class JobLevelListener(
val player = event.player val player = event.player
val level = event.level val level = event.level
job.levelUpEffects?.trigger(player.toDispatcher())
job.executeLevelCommands(player, level) job.executeLevelCommands(player, level)
if (this.plugin.configYml.getBool("level-up.sound.enabled")) { if (this.plugin.configYml.getBool("level-up.sound.enabled")) {

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
}

View File

@@ -2,6 +2,7 @@ package com.willfp.ecojobs.jobs
import com.willfp.ecojobs.api.event.PlayerJobJoinEvent import com.willfp.ecojobs.api.event.PlayerJobJoinEvent
import com.willfp.ecojobs.api.event.PlayerJobLeaveEvent import com.willfp.ecojobs.api.event.PlayerJobLeaveEvent
import com.willfp.libreforge.toDispatcher
import org.bukkit.entity.Player import org.bukkit.entity.Player
import org.bukkit.event.EventHandler import org.bukkit.event.EventHandler
import org.bukkit.event.EventPriority import org.bukkit.event.EventPriority
@@ -23,6 +24,7 @@ object PriceHandler : Listener {
} }
price.pay(player) price.pay(player)
job.joinEffects?.trigger(player.toDispatcher())
} }
@EventHandler( @EventHandler(
@@ -40,5 +42,6 @@ object PriceHandler : Listener {
} }
price.pay(player) price.pay(player)
job.leaveEffects?.trigger(player.toDispatcher())
} }
} }

View File

@@ -0,0 +1,27 @@
package com.willfp.ecojobs.util
import com.willfp.eco.core.placeholder.InjectablePlaceholder
import com.willfp.eco.core.placeholder.PlaceholderInjectable
import com.willfp.eco.core.placeholder.StaticPlaceholder
class LevelInjectable(
level: Int
) : PlaceholderInjectable {
private val placeholders = listOf(
StaticPlaceholder(
"level"
) { level.toString() }
)
override fun getPlaceholderInjections(): List<InjectablePlaceholder> {
return placeholders
}
override fun addInjectablePlaceholder(p0: Iterable<InjectablePlaceholder>) {
return
}
override fun clearInjectedPlaceholders() {
return
}
}

View File

@@ -27,6 +27,13 @@ join-price:
# Reference with %join_lore% # Reference with %join_lore%
join-lore: [] join-lore: []
# A list of effects to run when the player joins the job.
# Read https://plugins.auxilor.io/effects/configuring-an-effect
join-effects:
- id: broadcast
args:
message: "&8» &a%player% &8joined the &6Miner &8job!"
# The price to leave this job (set to 0 to disable) # The price to leave this job (set to 0 to disable)
# Read here for more: https://plugins.auxilor.io/all-plugins/prices # Read here for more: https://plugins.auxilor.io/all-plugins/prices
leave-price: leave-price:
@@ -39,7 +46,22 @@ leave-price:
leave-lore: leave-lore:
- " &8» This will cost %leave_price%" - " &8» This will cost %leave_price%"
# The xp requirements for each job level - add new levels by adding more to this list # A list of effects to run when the player leaves the job.
# Read https://plugins.auxilor.io/effects/configuring-an-effect
leave-effects:
- id: send_message
args:
message: "&8» &8You left the &6Miner &8job!"
# There are two ways to specify level XP requirements:
# 1. A formula to calculate for infinite levels
# 2. A list of XP requirements for each level
# Formula
# xp-formula: (2 ^ %level%) * 25
# max-level: 100 # The max level of the job
# List
level-xp-requirements: level-xp-requirements:
- 100 - 100
- 120 - 120
@@ -133,10 +155,13 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks mined" - "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks mined"
# Commands to be sent on levelup, can be formatted two ways: # Effects to run when the skill levels up
# level:command (e.g. 10:eco give %player% 1000), which would execute that command for level 10 # %level% is the level the skill leveled up to.
# command (e.g. eco give %player% 5000), which would execute that command for all levels # If you want to restrict this to certain levels, you can use
level-commands: [ ] # require: %level% = 20, or require: %level% < 50, etc.
# If you want a reward to run every x levels, you can use
# every: 1, or every: 12, etc
level-up-effects: [ ]
# The effects for the job, has %level% as a placeholder # The effects for the job, has %level% as a placeholder
effects: effects:

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -95,7 +99,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each bee you breed" - "&8» &8Earn &a$%money%&8 for each bee you breed"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -94,7 +98,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks placed" - "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks placed"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -92,7 +96,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each enchanted item" - "&8» &8Earn &a$%money%&8 for each enchanted item"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -107,7 +111,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each crop farmed" - "&8» &8Earn &a$%money%&8 for each crop farmed"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -92,7 +96,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each fish caught" - "&8» &8Earn &a$%money%&8 for each fish caught"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -104,7 +108,7 @@ level-up-messages:
1: 1:
- "&8» &7Earn &a$%money%&7 for each log chopped." - "&8» &7Earn &a$%money%&7 for each log chopped."
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -74,8 +78,10 @@ level-xp-requirements:
xp-gain-methods: xp-gain-methods:
- trigger: mine_block - trigger: mine_block
multiplier: 0.5 multiplier: 0.5
conditions: [ ] filters: [ ]
filters: conditions:
- id: in_mainhand
args:
items: items:
- "*wooden_pickaxe" - "*wooden_pickaxe"
- "*stone_pickaxe" - "*stone_pickaxe"
@@ -102,14 +108,16 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks mined" - "&8» &8Earn &a$%money%&8 for each &a%blocks%&8 blocks mined"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money
args: args:
every: "ceil(10 - %level% / 10)" every: "ceil(10 - %level% / 10)"
amount: "0.4 * %level%" amount: "0.4 * %level%"
filters: conditions:
- id: in_mainhand
args:
items: items:
- "*wooden_pickaxe" - "*wooden_pickaxe"
- "*stone_pickaxe" - "*stone_pickaxe"

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -95,7 +99,7 @@ level-up-messages:
- "&8» &8Earn &a$%money%&8 per heart of health that" - "&8» &8Earn &a$%money%&8 per heart of health that"
- " &8mobs you kill have" - " &8mobs you kill have"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -10,6 +10,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -17,6 +19,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -92,7 +96,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each smelted item" - "&8» &8Earn &a$%money%&8 for each smelted item"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -18,6 +18,8 @@ join-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
join-effects: []
join-lore: [] join-lore: []
leave-price: leave-price:
@@ -25,6 +27,8 @@ leave-price:
type: coins type: coins
display: "&a$%value%" display: "&a$%value%"
leave-effects: []
leave-lore: leave-lore:
- "" - ""
@@ -133,7 +137,7 @@ level-up-messages:
1: 1:
- "&8» &8Earn &a$%money%&8 for each tool crafted" - "&8» &8Earn &a$%money%&8 for each tool crafted"
level-commands: [ ] level-up-effects: [ ]
effects: effects:
- id: give_money - id: give_money

View File

@@ -8,6 +8,9 @@ messages:
needs-player: "&cYou must specify a player!" needs-player: "&cYou must specify a player!"
gave-xp: "&fYou have given &a%xp% &fXP to %player%&f's %job%&f!" gave-xp: "&fYou have given &a%xp% &fXP to %player%&f's %job%&f!"
reset-xp: "&fYou have reset %player%&f's %job%&f XP!" reset-xp: "&fYou have reset %player%&f's %job%&f XP!"
reset-all-players: "&fYou have reset all players' %job%&f XP!"
reset-all-jobs: "&fYou have reset %player%&f's XP for all jobs!"
reset-all-players-all-jobs: "&fYou have reset all players' XP for all jobs!"
needs-job: "&cYou must specify a job!" needs-job: "&cYou must specify a job!"
need-amount: "&cYou must specify a amount!" need-amount: "&cYou must specify a amount!"
invalid-player: "&cInvalid player!" invalid-player: "&cInvalid player!"

View File

@@ -1,5 +1,5 @@
#libreforge-updater #libreforge-updater
#Mon Jul 08 15:58:17 BST 2024 #Sat Mar 29 14:21:51 GMT 2025
kotlin.code.style=official kotlin.code.style=official
libreforge-version=4.65.0 libreforge-version=4.75.0
version=3.63.0 version=3.73.0