Experimental advancements GUI

This commit is contained in:
NotAlexNoyle committed 2026-05-21 10:03:11 -04:00
1 parent 969321a78f
commit dd09597a52
13 files changed
+158 -45

No files matched your search

+4 -1
View File
@@ -3,4 +3,7 @@
url = https://github.com/true-og/DiamondBank-OG
[submodule "libs/Utilities-OG"]
path = libs/Utilities-OG
url = https://github.com/true-og/Utilities-OG
url = https://github.com/true-og/Utilities-OG
[submodule "libs/GxUI-OG"]
path = libs/GxUI-OG
url = https://github.com/true-og/GxUI-OG
+1
View File
@@ -83,6 +83,7 @@ dependencies {
compileOnlyApi(project(":libs:DiamondBank-OG")) {
attributes { attribute(kotlinAttribute, true) }
} // Import TrueOG network DiamondBank-OG Kotlin API (from source).
implementation(project(":libs:GxUI-OG")) // Shade TrueOG Network GxUI-OG advancement menu API into this plugin.
}
/* ---------------------- Reproducible jars ---------------------------- */
Submodule
+1
Submodule libs/GxUI-OG added at 24b385d3f7.
@@ -10,44 +10,56 @@ import org.bukkit.entity.Player
class ClaimQuest : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
QuestsOG.plugin.logger.info("/claimquest invoked by ${sender.name}")
if (sender !is Player) {
sender.sendMessage("ERROR: You can only execute this command as a player.")
return true
}
val nextQuest = HomesProgression.getNextQuest(sender)
QuestsOG.plugin.logger.info("/claimquest nextQuest=${nextQuest?.javaClass?.simpleName}")
if (nextQuest == null) {
UtilitiesOG.trueogMessage(sender, "<green>You have completed all available quests.<reset>")
return true
}
QuestsOG.scope.launch {
val isEligible = nextQuest.isEligible(sender)
if (isEligible == null) {
UtilitiesOG.trueogMessage(
sender,
"<red>Something went wrong while checking your quest eligibility. Contact an administrator.<reset>",
)
return@launch
}
if (isEligible) {
val successful = nextQuest.consumeQuestItems(sender)
if (!successful) {
UtilitiesOG.trueogMessage(sender, "<red>Something wrong while trying to consume the quest items.")
try {
QuestsOG.plugin.logger.info("/claimquest coroutine entered for ${sender.name}")
val isEligible = nextQuest.isEligible(sender)
QuestsOG.plugin.logger.info("/claimquest isEligible=$isEligible")
if (isEligible == null) {
UtilitiesOG.trueogMessage(
sender,
"<red>Something went wrong while checking your quest eligibility. Contact an administrator.<reset>",
)
return@launch
}
nextQuest.reward(sender)
val homeCount = HomesProgression.getHomeCount(nextQuest)
val questName = nextQuest::class.simpleName
UtilitiesOG.logToConsole("[Quests-OG]", "${sender.name} claimed quest $questName")
UtilitiesOG.trueogMessage(
sender,
"<green>Claimed quest! You now have <yellow>$homeCount<green> homes.<reset>",
)
return@launch
} else {
UtilitiesOG.trueogMessage(sender, "<red>You must meet all the quest's requirements first.<reset>")
if (isEligible) {
val successful = nextQuest.consumeQuestItems(sender)
if (!successful) {
UtilitiesOG.trueogMessage(
sender,
"<red>Something wrong while trying to consume the quest items.",
)
return@launch
}
nextQuest.reward(sender)
val homeCount = HomesProgression.getHomeCount(nextQuest)
val questName = nextQuest::class.simpleName
UtilitiesOG.logToConsole("[Quests-OG]", "${sender.name} claimed quest $questName")
UtilitiesOG.trueogMessage(
sender,
"<green>Claimed quest! You now have <yellow>$homeCount<green> homes.<reset>",
)
return@launch
} else {
UtilitiesOG.trueogMessage(sender, "<red>You must meet all the quest's requirements first.<reset>")
}
} catch (t: Throwable) {
QuestsOG.plugin.logger.severe("/claimquest failed: ${t.message}")
t.printStackTrace()
}
}
return true
@@ -0,0 +1,62 @@
package net.trueog.questsOG
import kotlinx.coroutines.launch
import net.trueog.gxui.advancements.AdvancementMenu
import net.trueog.gxui.advancements.AdvancementState
import net.trueog.questsOG.progression.HomesProgression
import net.trueog.questsOG.quests.Quest
import org.bukkit.command.Command
import org.bukkit.command.CommandExecutor
import org.bukkit.command.CommandSender
import org.bukkit.entity.Player
class QuestGuiCommand : CommandExecutor {
override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array<out String>?): Boolean {
QuestsOG.plugin.logger.info("/questgui invoked by ${sender.name}")
if (sender !is Player) {
sender.sendMessage("ERROR: You can only execute this command as a player.")
return true
}
QuestsOG.scope.launch {
try {
QuestsOG.plugin.logger.info("/questgui coroutine entered for ${sender.name}")
val nextQuest = HomesProgression.getNextQuest(sender)
QuestsOG.plugin.logger.info("/questgui nextQuest=${nextQuest?.javaClass?.simpleName}")
val builder = AdvancementMenu.builder(QuestsOG.plugin, sender, "&6Home Quests")
HomesProgression.quests.forEach { quest ->
builder.add(questName(quest), stateFor(quest, nextQuest))
quest.getRequirements(sender)?.forEach { requirement ->
when (requirement) {
is ProgressRequirement ->
builder.progress(requirement.name, requirement.current, requirement.target)
is BooleanRequirement -> builder.bool(requirement.name, requirement.met)
}
}
if (quest == nextQuest) builder.footer("&7Use &e/claimquest &7when ready.")
}
QuestsOG.plugin.logger.info("/questgui dispatching builder.open on main thread")
MainThreadBlock.runOnMainThread { builder.open(args) }
QuestsOG.plugin.logger.info("/questgui done")
} catch (t: Throwable) {
QuestsOG.plugin.logger.severe("/questgui failed: ${t.message}")
t.printStackTrace()
}
}
return true
}
private fun questName(quest: Quest): String = "Home ${HomesProgression.getHomeCount(quest)} Quest"
private fun stateFor(quest: Quest, nextQuest: Quest?): AdvancementState =
when {
nextQuest == null -> AdvancementState.COMPLETE
quest == nextQuest -> AdvancementState.IN_PROGRESS
HomesProgression.quests.indexOf(quest) < HomesProgression.quests.indexOf(nextQuest) ->
AdvancementState.COMPLETE
else -> AdvancementState.LOCKED
}
}
@@ -6,19 +6,19 @@ import net.kyori.adventure.text.minimessage.MiniMessage
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags
import net.luckperms.api.LuckPerms
import net.trueog.diamondbankog.api.DiamondBankAPIKotlin
import net.trueog.diamondbankog.api.DiamondBankAPIJava
import org.bukkit.Bukkit
import org.bukkit.plugin.Plugin
import org.bukkit.plugin.java.JavaPlugin
class QuestsOG : JavaPlugin() {
companion object {
val scope = CoroutineScope(Dispatchers.Default + SupervisorJob())
lateinit var scope: CoroutineScope
lateinit var plugin: QuestsOG
lateinit var config: Config
lateinit var redis: Redis
lateinit var diamondBankAPI: DiamondBankAPIKotlin
lateinit var diamondBankAPI: DiamondBankAPIJava
lateinit var luckPerms: LuckPerms
lateinit var duels: Duels
lateinit var mobHeads: Plugin
@@ -32,6 +32,11 @@ class QuestsOG : JavaPlugin() {
override fun onEnable() {
plugin = this
val exceptionHandler = CoroutineExceptionHandler { _, throwable ->
logger.severe("Uncaught coroutine exception: ${throwable.message}")
throwable.printStackTrace()
}
scope = CoroutineScope(Dispatchers.Default + SupervisorJob() + exceptionHandler)
Companion.config =
Config.create()
@@ -47,7 +52,7 @@ class QuestsOG : JavaPlugin() {
return
}
val diamondBankAPIProvider = server.servicesManager.getRegistration(DiamondBankAPIKotlin::class.java)
val diamondBankAPIProvider = server.servicesManager.getRegistration(DiamondBankAPIJava::class.java)
if (diamondBankAPIProvider == null) {
logger.severe("DiamondBank-OG API is null")
Bukkit.getPluginManager().disablePlugin(this)
@@ -81,6 +86,7 @@ class QuestsOG : JavaPlugin() {
this.server.pluginManager.registerEvents(Events(), this)
getCommand("claimquest")?.setExecutor(ClaimQuest())
getCommand("questgui")?.setExecutor(QuestGuiCommand())
}
override fun onDisable() {
@@ -1,6 +1,7 @@
package net.trueog.questsOG.quests
import net.luckperms.api.node.types.PermissionNode
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.questsOG.BooleanRequirement
import net.trueog.questsOG.MainThreadBlock.runOnMainThread
import net.trueog.questsOG.ProgressRequirement
@@ -54,7 +55,9 @@ class HomesFive : Quest {
private suspend fun fetchRequirements(player: Player): Requirements? {
val totalShards =
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId).getOrElse {
try {
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId)
} catch (e: DiamondBankException) {
return null
}
@@ -138,14 +141,16 @@ class HomesFive : Quest {
override suspend fun consumeQuestItems(player: Player): Boolean {
val requiredShards = 2500L * 9
val withdrawResult =
try {
QuestsOG.diamondBankAPI.consumeFromPlayer(
player.uniqueId,
requiredShards,
"Home five quest claimed by ${player.name} (${player.uniqueId})",
"Quests-OG /claimquest",
)
if (withdrawResult.isFailure) return false
} catch (e: DiamondBankException) {
return false
}
runOnMainThread { player.level -= 200 }
@@ -1,6 +1,7 @@
package net.trueog.questsOG.quests
import net.luckperms.api.node.types.PermissionNode
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.questsOG.BooleanRequirement
import net.trueog.questsOG.MainThreadBlock.runOnMainThread
import net.trueog.questsOG.ProgressRequirement
@@ -33,7 +34,9 @@ class HomesFour : Quest {
private suspend fun fetchRequirements(player: Player): Requirements? {
val totalShards =
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId).getOrElse {
try {
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId)
} catch (e: DiamondBankException) {
return null
}
@@ -107,14 +110,16 @@ class HomesFour : Quest {
override suspend fun consumeQuestItems(player: Player): Boolean {
val requiredShards = 1000L * 9
val withdrawResult =
try {
QuestsOG.diamondBankAPI.consumeFromPlayer(
player.uniqueId,
requiredShards,
"Home four quest claimed by ${player.name} (${player.uniqueId})",
"Quests-OG /claimquest",
)
if (withdrawResult.isFailure) return false
} catch (e: DiamondBankException) {
return false
}
runOnMainThread { player.level -= 150 }
@@ -1,6 +1,7 @@
package net.trueog.questsOG.quests
import net.luckperms.api.node.types.PermissionNode
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.questsOG.MainThreadBlock.runOnMainThread
import net.trueog.questsOG.ProgressRequirement
import net.trueog.questsOG.QuestsOG
@@ -46,7 +47,9 @@ class HomesSix : Quest {
private suspend fun fetchRequirements(player: Player): Requirements? {
val totalShards =
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId).getOrElse {
try {
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId)
} catch (e: DiamondBankException) {
return null
}
@@ -116,14 +119,16 @@ class HomesSix : Quest {
override suspend fun consumeQuestItems(player: Player): Boolean {
val requiredShards = 5000L * 9
val withdrawResult =
try {
QuestsOG.diamondBankAPI.consumeFromPlayer(
player.uniqueId,
requiredShards,
"Home six quest claimed by ${player.name} (${player.uniqueId})",
"Quests-OG /claimquest",
)
if (withdrawResult.isFailure) return false
} catch (e: DiamondBankException) {
return false
}
return runOnMainThread {
player.level -= 250
@@ -1,6 +1,7 @@
package net.trueog.questsOG.quests
import net.luckperms.api.node.types.PermissionNode
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.questsOG.BooleanRequirement
import net.trueog.questsOG.MainThreadBlock.runOnMainThread
import net.trueog.questsOG.ProgressRequirement
@@ -27,7 +28,9 @@ class HomesThree : Quest {
private suspend fun fetchRequirements(player: Player): Requirements? {
val totalShards =
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId).getOrElse {
try {
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId)
} catch (e: DiamondBankException) {
return null
}
@@ -85,14 +88,16 @@ class HomesThree : Quest {
override suspend fun consumeQuestItems(player: Player): Boolean {
val requiredShards = 250L * 9
val withdrawResult =
try {
QuestsOG.diamondBankAPI.consumeFromPlayer(
player.uniqueId,
requiredShards,
"Home three quest claimed by ${player.name} (${player.uniqueId})",
"Quests-OG /claimquest",
)
if (withdrawResult.isFailure) return false
} catch (e: DiamondBankException) {
return false
}
runOnMainThread { player.level -= 100 }
@@ -1,6 +1,7 @@
package net.trueog.questsOG.quests
import net.luckperms.api.node.types.PermissionNode
import net.trueog.diamondbankog.DiamondBankException
import net.trueog.questsOG.MainThreadBlock.runOnMainThread
import net.trueog.questsOG.ProgressRequirement
import net.trueog.questsOG.QuestsOG
@@ -19,7 +20,9 @@ class HomesTwo : Quest {
private suspend fun fetchRequirements(player: Player): Requirements? {
val totalShards =
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId).getOrElse {
try {
QuestsOG.diamondBankAPI.getTotalShards(player.uniqueId)
} catch (e: DiamondBankException) {
return null
}
@@ -74,14 +77,16 @@ class HomesTwo : Quest {
override suspend fun consumeQuestItems(player: Player): Boolean {
val requiredShards = 100L * 9
val withdrawResult =
try {
QuestsOG.diamondBankAPI.consumeFromPlayer(
player.uniqueId,
requiredShards,
"Home two quest claimed by ${player.name} (${player.uniqueId})",
"Quests-OG /claimquest",
)
if (withdrawResult.isFailure) return false
} catch (e: DiamondBankException) {
return false
}
runOnMainThread { player.level -= 100 }
+3
View File
@@ -10,3 +10,6 @@ commands:
claimquest:
description: Claims a quest, duh
usage: /claimquest
questgui:
description: Open the homes quest menu. Optional page argument (e.g. /questgui 2).
usage: /questgui [page]