mirror of
https://github.com/Auxilor/EcoQuests.git
synced 2025-12-21 07:59:14 +00:00
Improved GUI, fixed bugs, added API events, added quest complete display
This commit is contained in:
@@ -1,16 +1,24 @@
|
|||||||
package com.willfp.ecoquests
|
package com.willfp.ecoquests
|
||||||
|
|
||||||
|
import com.sun.tools.javac.jvm.ByteCodes.ret
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.ecoquests.commands.CommandEcoQuests
|
import com.willfp.ecoquests.commands.CommandEcoQuests
|
||||||
import com.willfp.ecoquests.commands.CommandQuests
|
import com.willfp.ecoquests.commands.CommandQuests
|
||||||
|
import com.willfp.ecoquests.gui.QuestsGUI
|
||||||
|
import com.willfp.ecoquests.quests.QuestCompleteDisplay
|
||||||
import com.willfp.ecoquests.quests.Quests
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.ecoquests.tasks.Tasks
|
import com.willfp.ecoquests.tasks.Tasks
|
||||||
import com.willfp.libreforge.loader.LibreforgePlugin
|
import com.willfp.libreforge.loader.LibreforgePlugin
|
||||||
import com.willfp.libreforge.loader.configs.ConfigCategory
|
import com.willfp.libreforge.loader.configs.ConfigCategory
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
|
||||||
|
|
||||||
class EcoQuestsPlugin : LibreforgePlugin() {
|
class EcoQuestsPlugin : LibreforgePlugin() {
|
||||||
|
override fun handleReload() {
|
||||||
|
QuestsGUI.reload(this)
|
||||||
|
}
|
||||||
|
|
||||||
override fun createTasks() {
|
override fun createTasks() {
|
||||||
val scanInterval = this.configYml.getInt("scan-interval").toLong()
|
val scanInterval = this.configYml.getInt("scan-interval").toLong()
|
||||||
this.scheduler.runTimer(scanInterval, scanInterval) {
|
this.scheduler.runTimer(scanInterval, scanInterval) {
|
||||||
@@ -24,6 +32,12 @@ class EcoQuestsPlugin : LibreforgePlugin() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun loadListeners(): List<Listener> {
|
||||||
|
return listOf(
|
||||||
|
QuestCompleteDisplay(this)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
override fun loadPluginCommands(): List<PluginCommand> {
|
override fun loadPluginCommands(): List<PluginCommand> {
|
||||||
return listOf(
|
return listOf(
|
||||||
CommandEcoQuests(this),
|
CommandEcoQuests(this),
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.ecoquests.api.event
|
||||||
|
|
||||||
|
import com.willfp.ecoquests.quests.Quest
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.event.player.PlayerEvent
|
||||||
|
|
||||||
|
class PlayerCompleteQuestEvent(
|
||||||
|
who: Player,
|
||||||
|
val quest: Quest
|
||||||
|
): PlayerEvent(who) {
|
||||||
|
override fun getHandlers(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val HANDLERS = HandlerList()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getHandlerList(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.ecoquests.api.event
|
||||||
|
|
||||||
|
import com.willfp.ecoquests.tasks.Task
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.event.player.PlayerEvent
|
||||||
|
|
||||||
|
class PlayerCompleteTaskEvent(
|
||||||
|
who: Player,
|
||||||
|
val task: Task
|
||||||
|
): PlayerEvent(who) {
|
||||||
|
override fun getHandlers(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val HANDLERS = HandlerList()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getHandlerList(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.ecoquests.api.event
|
||||||
|
|
||||||
|
import com.willfp.ecoquests.quests.Quest
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
import org.bukkit.event.HandlerList
|
||||||
|
import org.bukkit.event.player.PlayerEvent
|
||||||
|
|
||||||
|
class PlayerStartQuestEvent(
|
||||||
|
who: Player,
|
||||||
|
val quest: Quest
|
||||||
|
): PlayerEvent(who) {
|
||||||
|
override fun getHandlers(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val HANDLERS = HandlerList()
|
||||||
|
|
||||||
|
@JvmStatic
|
||||||
|
fun getHandlerList(): HandlerList {
|
||||||
|
return HANDLERS
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ class CommandEcoQuests(plugin: EcoPlugin) : PluginCommand(
|
|||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
this.addSubcommand(CommandReload(plugin))
|
this.addSubcommand(CommandReload(plugin))
|
||||||
|
.addSubcommand(CommandStart(plugin))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onExecute(sender: CommandSender, args: List<String>) {
|
override fun onExecute(sender: CommandSender, args: List<String>) {
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package com.willfp.ecoquests.commands
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.ecoquests.gui.QuestsGUI
|
||||||
|
import com.willfp.ecoquests.quests.Quests
|
||||||
|
import com.willfp.libreforge.commands.CommandReload
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
class CommandStart(plugin: EcoPlugin) : PluginCommand(
|
||||||
|
plugin,
|
||||||
|
"start",
|
||||||
|
"ecoquests.command.start",
|
||||||
|
false
|
||||||
|
) {
|
||||||
|
override fun onExecute(sender: CommandSender, args: List<String>) {
|
||||||
|
val player = notifyPlayerRequired(args.getOrNull(0), "invalid-player")
|
||||||
|
val quest = notifyNull(Quests[args.getOrNull(1)], "invalid-quest")
|
||||||
|
|
||||||
|
if (quest.hasStarted(player) || quest.hasCompleted(player)) {
|
||||||
|
sender.sendMessage(plugin.langYml.getMessage("already-started"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
quest.start(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -9,6 +9,7 @@ import com.willfp.eco.core.gui.slot.FillerMask
|
|||||||
import com.willfp.eco.core.gui.slot.MaskItems
|
import com.willfp.eco.core.gui.slot.MaskItems
|
||||||
import com.willfp.eco.core.items.Items
|
import com.willfp.eco.core.items.Items
|
||||||
import com.willfp.ecoquests.gui.components.CloseButton
|
import com.willfp.ecoquests.gui.components.CloseButton
|
||||||
|
import com.willfp.ecoquests.gui.components.GUIInfoComponent
|
||||||
import com.willfp.ecoquests.gui.components.PositionedPageChanger
|
import com.willfp.ecoquests.gui.components.PositionedPageChanger
|
||||||
import com.willfp.ecoquests.gui.components.QuestAreaComponent
|
import com.willfp.ecoquests.gui.components.QuestAreaComponent
|
||||||
import com.willfp.ecoquests.gui.components.addComponent
|
import com.willfp.ecoquests.gui.components.addComponent
|
||||||
@@ -18,9 +19,13 @@ object QuestsGUI {
|
|||||||
private lateinit var menu: Menu
|
private lateinit var menu: Menu
|
||||||
|
|
||||||
fun reload(plugin: EcoPlugin) {
|
fun reload(plugin: EcoPlugin) {
|
||||||
|
val questAreaComponent = QuestAreaComponent(plugin.configYml.getSubsection("gui.quest-area"))
|
||||||
|
|
||||||
menu = menu(plugin.configYml.getInt("gui.rows")) {
|
menu = menu(plugin.configYml.getInt("gui.rows")) {
|
||||||
title = plugin.configYml.getFormattedString("gui.title")
|
title = plugin.configYml.getFormattedString("gui.title")
|
||||||
|
|
||||||
|
maxPages { questAreaComponent.getPages(it) }
|
||||||
|
|
||||||
setMask(
|
setMask(
|
||||||
FillerMask(
|
FillerMask(
|
||||||
MaskItems.fromItemNames(plugin.configYml.getStrings("gui.mask.materials")),
|
MaskItems.fromItemNames(plugin.configYml.getStrings("gui.mask.materials")),
|
||||||
@@ -28,19 +33,21 @@ object QuestsGUI {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
addComponent(GUIInfoComponent(plugin.configYml.getSubsection("gui.gui-info")))
|
||||||
|
|
||||||
addComponent(CloseButton(plugin.configYml.getSubsection("gui.close")))
|
addComponent(CloseButton(plugin.configYml.getSubsection("gui.close")))
|
||||||
|
|
||||||
addComponent(PositionedPageChanger(
|
addComponent(PositionedPageChanger(
|
||||||
plugin.configYml.getSubsection("gui.prev-page.item"),
|
plugin.configYml.getSubsection("gui.prev-page"),
|
||||||
PageChanger.Direction.BACKWARDS)
|
PageChanger.Direction.BACKWARDS)
|
||||||
)
|
)
|
||||||
|
|
||||||
addComponent(PositionedPageChanger(
|
addComponent(PositionedPageChanger(
|
||||||
plugin.configYml.getSubsection("gui.next-page.item"),
|
plugin.configYml.getSubsection("gui.next-page"),
|
||||||
PageChanger.Direction.FORWARDS)
|
PageChanger.Direction.FORWARDS)
|
||||||
)
|
)
|
||||||
|
|
||||||
addComponent(QuestAreaComponent(plugin.configYml.getSubsection("gui.quest-area")))
|
addComponent(questAreaComponent)
|
||||||
|
|
||||||
for (config in plugin.configYml.getSubsections("gui.custom-slots")) {
|
for (config in plugin.configYml.getSubsections("gui.custom-slots")) {
|
||||||
setSlot(
|
setSlot(
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.ecoquests.gui.components
|
||||||
|
|
||||||
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.core.gui.slot
|
||||||
|
import com.willfp.eco.core.items.Items
|
||||||
|
import com.willfp.eco.core.items.builder.ItemStackBuilder
|
||||||
|
|
||||||
|
class GUIInfoComponent(
|
||||||
|
config: Config
|
||||||
|
) : PositionedComponent {
|
||||||
|
private val slot = slot(
|
||||||
|
ItemStackBuilder(Items.lookup(config.getString("item")))
|
||||||
|
.setDisplayName(config.getFormattedString("name"))
|
||||||
|
.addLoreLines(config.getFormattedStrings("lore"))
|
||||||
|
.build()
|
||||||
|
) {
|
||||||
|
onLeftClick { event, _ -> event.whoClicked.closeInventory() }
|
||||||
|
}
|
||||||
|
|
||||||
|
override val row: Int = config.getInt("location.row")
|
||||||
|
override val column: Int = config.getInt("location.column")
|
||||||
|
|
||||||
|
override fun getSlotAt(row: Int, column: Int) = slot
|
||||||
|
}
|
||||||
@@ -16,11 +16,18 @@ class QuestAreaComponent(
|
|||||||
override val rowSize = config.getInt("bottom-right.row") - row + 1
|
override val rowSize = config.getInt("bottom-right.row") - row + 1
|
||||||
override val columnSize = config.getInt("bottom-right.column") - column + 1
|
override val columnSize = config.getInt("bottom-right.column") - column + 1
|
||||||
|
|
||||||
override fun getSlotAt(row: Int, column: Int, player: Player, menu: Menu): Slot? {
|
private val pageSize = rowSize * columnSize
|
||||||
val index = MenuUtils.rowColumnToSlot(row, column, columnSize)
|
|
||||||
|
|
||||||
return Quests.values()
|
fun getPages(player: Player): Int {
|
||||||
.filter { it.hasStarted(player) }
|
return Quests.getCurrentlyActiveQuests(player).size.floorDiv(pageSize) + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getSlotAt(row: Int, column: Int, player: Player, menu: Menu): Slot? {
|
||||||
|
val page = menu.getPage(player)
|
||||||
|
|
||||||
|
val index = MenuUtils.rowColumnToSlot(row, column, columnSize) + ((page - 1) * pageSize)
|
||||||
|
|
||||||
|
return Quests.getCurrentlyActiveQuests(player)
|
||||||
.getOrNull(index)
|
.getOrNull(index)
|
||||||
?.slot
|
?.slot
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,18 +7,20 @@ import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
|||||||
import com.willfp.eco.core.data.profile
|
import com.willfp.eco.core.data.profile
|
||||||
import com.willfp.eco.core.gui.slot
|
import com.willfp.eco.core.gui.slot
|
||||||
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.modify
|
import com.willfp.eco.core.items.builder.modify
|
||||||
|
import com.willfp.eco.core.placeholder.context.placeholderContext
|
||||||
import com.willfp.eco.core.registry.KRegistrable
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
import com.willfp.eco.util.formatEco
|
import com.willfp.eco.util.formatEco
|
||||||
|
import com.willfp.ecoquests.api.event.PlayerCompleteQuestEvent
|
||||||
|
import com.willfp.ecoquests.api.event.PlayerStartQuestEvent
|
||||||
import com.willfp.ecoquests.tasks.Tasks
|
import com.willfp.ecoquests.tasks.Tasks
|
||||||
import com.willfp.libreforge.EmptyProvidedHolder
|
import com.willfp.libreforge.EmptyProvidedHolder
|
||||||
import com.willfp.libreforge.ViolationContext
|
import com.willfp.libreforge.ViolationContext
|
||||||
import com.willfp.libreforge.conditions.Conditions
|
import com.willfp.libreforge.conditions.Conditions
|
||||||
import com.willfp.libreforge.effects.Effects
|
import com.willfp.libreforge.effects.Effects
|
||||||
import com.willfp.libreforge.effects.executors.impl.NormalExecutorFactory
|
import com.willfp.libreforge.effects.executors.impl.NormalExecutorFactory
|
||||||
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import org.bukkit.inventory.ItemStack
|
|
||||||
|
|
||||||
class Quest(
|
class Quest(
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: EcoPlugin,
|
||||||
@@ -34,7 +36,7 @@ class Quest(
|
|||||||
addLoreLines(
|
addLoreLines(
|
||||||
plugin.configYml.getStrings("gui.quest-area.quest-icon.lore")
|
plugin.configYml.getStrings("gui.quest-area.quest-icon.lore")
|
||||||
.flatMap {
|
.flatMap {
|
||||||
if (it == "%tasks%") tasks.map { task -> task.getCompletedDescription(player) }
|
if (it == "%tasks%") tasks.flatMap { task -> task.getCompletedDescription(player) }
|
||||||
else listOf(it)
|
else listOf(it)
|
||||||
}.formatEco(player)
|
}.formatEco(player)
|
||||||
)
|
)
|
||||||
@@ -45,18 +47,20 @@ class Quest(
|
|||||||
|
|
||||||
val tasks = config.getStrings("tasks").mapNotNull { Tasks[it] }
|
val tasks = config.getStrings("tasks").mapNotNull { Tasks[it] }
|
||||||
|
|
||||||
val hasStartedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
private val hasStartedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("quest_${id}_has_started"),
|
plugin.createNamespacedKey("quest_${id}_has_started"),
|
||||||
PersistentDataKeyType.BOOLEAN,
|
PersistentDataKeyType.BOOLEAN,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
val hasCompletedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
private val hasCompletedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("quest_${id}_has_completed"),
|
plugin.createNamespacedKey("quest_${id}_has_completed"),
|
||||||
PersistentDataKeyType.BOOLEAN,
|
PersistentDataKeyType.BOOLEAN,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val rewardMessages = config.getStrings("reward-message")
|
||||||
|
|
||||||
val rewards = Effects.compileChain(
|
val rewards = Effects.compileChain(
|
||||||
config.getSubsections("rewards"),
|
config.getSubsections("rewards"),
|
||||||
NormalExecutorFactory.create(),
|
NormalExecutorFactory.create(),
|
||||||
@@ -74,6 +78,10 @@ class Quest(
|
|||||||
ViolationContext(plugin, "quest $id start-conditions")
|
ViolationContext(plugin, "quest $id start-conditions")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
fun hasCompleted(player: Player): Boolean {
|
||||||
|
return player.profile.read(hasCompletedKey)
|
||||||
|
}
|
||||||
|
|
||||||
fun shouldStart(player: Player): Boolean {
|
fun shouldStart(player: Player): Boolean {
|
||||||
return startConditions.areMet(player, EmptyProvidedHolder)
|
return startConditions.areMet(player, EmptyProvidedHolder)
|
||||||
&& !hasStarted(player)
|
&& !hasStarted(player)
|
||||||
@@ -90,6 +98,8 @@ class Quest(
|
|||||||
|
|
||||||
startEffects?.trigger(player)
|
startEffects?.trigger(player)
|
||||||
player.profile.write(hasStartedKey, true)
|
player.profile.write(hasStartedKey, true)
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(PlayerStartQuestEvent(player, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkCompletion(player: Player): Boolean {
|
fun checkCompletion(player: Player): Boolean {
|
||||||
@@ -102,9 +112,45 @@ class Quest(
|
|||||||
player.profile.write(hasCompletedKey, true)
|
player.profile.write(hasCompletedKey, true)
|
||||||
rewards?.trigger(player)
|
rewards?.trigger(player)
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(PlayerCompleteQuestEvent(player, this))
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun List<String>.addMargin(margin: Int): List<String> {
|
||||||
|
return this.map { s -> " ".repeat(margin) + s }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun addPlaceholdersInto(
|
||||||
|
strings: List<String>,
|
||||||
|
player: Player
|
||||||
|
): List<String> {
|
||||||
|
val quest = this // I just hate the @ notation kotlin uses
|
||||||
|
fun String.addPlaceholders() = this
|
||||||
|
.replace("%quest%", quest.name)
|
||||||
|
|
||||||
|
// Replace placeholders in the strings with their actual values.
|
||||||
|
val withPlaceholders = strings.map { it.addPlaceholders() }
|
||||||
|
|
||||||
|
// Replace multi-line placeholders.
|
||||||
|
val processed = withPlaceholders.flatMap { s ->
|
||||||
|
val margin = s.length - s.trimStart().length
|
||||||
|
|
||||||
|
if (s.contains("%rewards%")) {
|
||||||
|
rewardMessages
|
||||||
|
.addMargin(margin)
|
||||||
|
} else {
|
||||||
|
listOf(s)
|
||||||
|
}
|
||||||
|
}.map { it.addPlaceholders() }
|
||||||
|
|
||||||
|
return processed.formatEco(
|
||||||
|
placeholderContext(
|
||||||
|
player = player
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
package com.willfp.ecoquests.quests
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.sound.PlayableSound
|
||||||
|
import com.willfp.eco.util.toComponent
|
||||||
|
import com.willfp.ecoquests.api.event.PlayerCompleteQuestEvent
|
||||||
|
import net.kyori.adventure.title.Title
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
import org.bukkit.event.Listener
|
||||||
|
import java.time.Duration
|
||||||
|
|
||||||
|
class QuestCompleteDisplay(
|
||||||
|
private val plugin: EcoPlugin
|
||||||
|
) : Listener {
|
||||||
|
private val sound = if (plugin.configYml.getBool("quests.complete.sound.enabled")) {
|
||||||
|
PlayableSound.create(
|
||||||
|
plugin.configYml.getSubsection("quests.complete.sound")
|
||||||
|
)
|
||||||
|
} else null
|
||||||
|
|
||||||
|
@EventHandler
|
||||||
|
fun handle(event: PlayerCompleteQuestEvent) {
|
||||||
|
val player = event.player
|
||||||
|
val quest = event.quest
|
||||||
|
|
||||||
|
if (plugin.configYml.getBool("quests.complete.message.enabled")) {
|
||||||
|
val rawMessage = plugin.configYml.getStrings("quests.complete.message.message")
|
||||||
|
|
||||||
|
val formatted = quest.addPlaceholdersInto(
|
||||||
|
rawMessage,
|
||||||
|
player
|
||||||
|
)
|
||||||
|
|
||||||
|
formatted.forEach { player.sendMessage(it) }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (plugin.configYml.getBool("quests.complete.title.enabled")) {
|
||||||
|
val rawTitle = plugin.configYml.getString("quests.complete.title.title")
|
||||||
|
val rawSubtitle = plugin.configYml.getString("quests.complete.title.subtitle")
|
||||||
|
|
||||||
|
val formatted = quest.addPlaceholdersInto(
|
||||||
|
listOf(rawTitle, rawSubtitle),
|
||||||
|
player
|
||||||
|
)
|
||||||
|
|
||||||
|
player.showTitle(
|
||||||
|
Title.title(
|
||||||
|
formatted[0].toComponent(),
|
||||||
|
formatted[1].toComponent(),
|
||||||
|
Title.Times.times(
|
||||||
|
Duration.ofMillis((plugin.configYml.getDouble("quests.complete.title.fade-in") * 1000).toLong()),
|
||||||
|
Duration.ofMillis((plugin.configYml.getDouble("quests.complete.title.stay") * 1000).toLong()),
|
||||||
|
Duration.ofMillis((plugin.configYml.getDouble("quests.complete.title.fade-out") * 1000).toLong())
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
sound?.playTo(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import com.willfp.eco.core.config.interfaces.Config
|
|||||||
import com.willfp.eco.core.registry.Registry
|
import com.willfp.eco.core.registry.Registry
|
||||||
import com.willfp.libreforge.loader.LibreforgePlugin
|
import com.willfp.libreforge.loader.LibreforgePlugin
|
||||||
import com.willfp.libreforge.loader.configs.ConfigCategory
|
import com.willfp.libreforge.loader.configs.ConfigCategory
|
||||||
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
object Quests : ConfigCategory("quest", "quests") {
|
object Quests : ConfigCategory("quest", "quests") {
|
||||||
private val registry = Registry<Quest>()
|
private val registry = Registry<Quest>()
|
||||||
@@ -19,5 +20,11 @@ object Quests : ConfigCategory("quest", "quests") {
|
|||||||
operator fun get(id: String?) = registry[id ?: ""]
|
operator fun get(id: String?) = registry[id ?: ""]
|
||||||
|
|
||||||
fun values(): Collection<Quest> = registry.values()
|
fun values(): Collection<Quest> = registry.values()
|
||||||
|
|
||||||
|
fun getCurrentlyActiveQuests(player: Player): List<Quest> {
|
||||||
|
return values()
|
||||||
|
.filter { it.hasStarted(player) }
|
||||||
|
.filterNot { it.hasCompleted(player) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,15 +7,14 @@ import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
|||||||
import com.willfp.eco.core.data.profile
|
import com.willfp.eco.core.data.profile
|
||||||
import com.willfp.eco.core.registry.KRegistrable
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
import com.willfp.eco.util.formatEco
|
import com.willfp.eco.util.formatEco
|
||||||
|
import com.willfp.eco.util.lineWrap
|
||||||
import com.willfp.eco.util.toNiceString
|
import com.willfp.eco.util.toNiceString
|
||||||
|
import com.willfp.ecoquests.api.event.PlayerCompleteTaskEvent
|
||||||
import com.willfp.ecoquests.quests.Quests
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.libreforge.BlankHolder.conditions
|
|
||||||
import com.willfp.libreforge.EmptyProvidedHolder
|
|
||||||
import com.willfp.libreforge.ViolationContext
|
import com.willfp.libreforge.ViolationContext
|
||||||
import com.willfp.libreforge.conditions.Conditions
|
|
||||||
import com.willfp.libreforge.counters.Accumulator
|
import com.willfp.libreforge.counters.Accumulator
|
||||||
import com.willfp.libreforge.counters.Counters
|
import com.willfp.libreforge.counters.Counters
|
||||||
import org.bukkit.OfflinePlayer
|
import org.bukkit.Bukkit
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class Task(
|
class Task(
|
||||||
@@ -35,7 +34,7 @@ class Task(
|
|||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
private val tasks = config.getSubsections("tasks").mapNotNull {
|
private val xpGainMethods = config.getSubsections("xp-gain-methods").mapNotNull {
|
||||||
Counters.compile(it, ViolationContext(plugin, "task $id tasks"))
|
Counters.compile(it, ViolationContext(plugin, "task $id tasks"))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,14 +45,14 @@ class Task(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onRegister() {
|
override fun onRegister() {
|
||||||
for (task in tasks) {
|
for (counter in xpGainMethods) {
|
||||||
task.bind(accumulator)
|
counter.bind(accumulator)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onRemove() {
|
override fun onRemove() {
|
||||||
for (task in tasks) {
|
for (counter in xpGainMethods) {
|
||||||
task.unbind()
|
counter.unbind()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -64,13 +63,15 @@ class Task(
|
|||||||
.formatEco(player)
|
.formatEco(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCompletedDescription(player: Player): String {
|
fun getCompletedDescription(player: Player): List<String> {
|
||||||
return if (hasCompleted(player)) {
|
return if (hasCompleted(player)) {
|
||||||
plugin.configYml.getString("tasks.completed")
|
plugin.configYml.getString("tasks.completed")
|
||||||
.replace("%description%", getDescription(player))
|
.replace("%description%", getDescription(player))
|
||||||
|
.lineWrap(plugin.configYml.getInt("tasks.line-wrap"), true)
|
||||||
} else {
|
} else {
|
||||||
plugin.configYml.getString("tasks.not-completed")
|
plugin.configYml.getString("tasks.not-completed")
|
||||||
.replace("%description%", getDescription(player))
|
.replace("%description%", getDescription(player))
|
||||||
|
.lineWrap(plugin.configYml.getInt("tasks.line-wrap"), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,6 +96,8 @@ class Task(
|
|||||||
if (newXp >= requiredXp) {
|
if (newXp >= requiredXp) {
|
||||||
player.profile.write(hasCompletedKey, true)
|
player.profile.write(hasCompletedKey, true)
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(PlayerCompleteTaskEvent(player, this))
|
||||||
|
|
||||||
// Then check if any quests are now completed
|
// Then check if any quests are now completed
|
||||||
for (quest in Quests.values()) {
|
for (quest in Quests.values()) {
|
||||||
quest.checkCompletion(player)
|
quest.checkCompletion(player)
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ gui:
|
|||||||
- "111111111"
|
- "111111111"
|
||||||
|
|
||||||
gui-info:
|
gui-info:
|
||||||
item: writable_book name:"&aQuest Book"
|
item: writable_book
|
||||||
|
name: "&aQuest Book"
|
||||||
lore:
|
lore:
|
||||||
- "&7View your active quests,"
|
- "&7View your active quests,"
|
||||||
- "&7progress, and rewards."
|
- "&7progress, and rewards."
|
||||||
@@ -78,5 +79,37 @@ gui:
|
|||||||
custom-slots: [ ]
|
custom-slots: [ ]
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
|
line-wrap: 32
|
||||||
completed: " &a&l✓ &r&f%description%"
|
completed: " &a&l✓ &r&f%description%"
|
||||||
not-completed: " &c&l✘ &r&f%description%"
|
not-completed: " &c&l✘ &r&f%description%"
|
||||||
|
|
||||||
|
quests:
|
||||||
|
complete:
|
||||||
|
message:
|
||||||
|
enabled: true
|
||||||
|
message:
|
||||||
|
- "&f"
|
||||||
|
- " &#eacda3&lQUEST COMPLETE: &f%quest%"
|
||||||
|
- "&f"
|
||||||
|
- " &#eacda3&lREWARDS:"
|
||||||
|
- "%rewards%"
|
||||||
|
- "&f"
|
||||||
|
title:
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# Durations are in seconds
|
||||||
|
fade-in: 0.5
|
||||||
|
stay: 2
|
||||||
|
fade-out: 0.5
|
||||||
|
|
||||||
|
title: "&#eacda3&lQuest Complete!"
|
||||||
|
subtitle: "&f%quest%"
|
||||||
|
sound:
|
||||||
|
# If a sound should be played
|
||||||
|
enabled: true
|
||||||
|
# The sound that should be played
|
||||||
|
sound: ui_toast_challange_complete
|
||||||
|
# Pitch between 0.5 and 2
|
||||||
|
pitch: 1.5
|
||||||
|
# The volume
|
||||||
|
volume: 1.0
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
messages:
|
messages:
|
||||||
prefix: "&#eacda3&lEcoQuests &f» "
|
prefix: "&#eacda3&lEcoQuests &8» &f"
|
||||||
no-permission: "&cYou don't have permission to do this!"
|
no-permission: "&cYou don't have permission to do this!"
|
||||||
not-player: "&cThis command must be run by a player"
|
not-player: "&cThis command must be run by a player"
|
||||||
invalid-command: "&cUnknown subcommand!"
|
invalid-command: "&cUnknown subcommand!"
|
||||||
reloaded: "Reloaded!"
|
reloaded: "Reloaded!"
|
||||||
|
|
||||||
|
invalid-player: "&cInvalid player!"
|
||||||
|
invalid-quest: "&cInvalid quest!"
|
||||||
|
already-started: "&cThe player has already started this quest!"
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ permissions:
|
|||||||
children:
|
children:
|
||||||
ecoquests.command.reload: true
|
ecoquests.command.reload: true
|
||||||
ecoquests.command.quests: true
|
ecoquests.command.quests: true
|
||||||
|
ecoquests.command.start: op
|
||||||
|
|
||||||
ecoquests.command.reload:
|
ecoquests.command.reload:
|
||||||
description: Allows reloading the config
|
description: Allows reloading the config
|
||||||
@@ -42,3 +43,6 @@ permissions:
|
|||||||
ecoquests.command.quests:
|
ecoquests.command.quests:
|
||||||
description: Allows the use of /quests.
|
description: Allows the use of /quests.
|
||||||
default: true
|
default: true
|
||||||
|
ecoquests.command.start:
|
||||||
|
description: Allows using /ecoquests start.
|
||||||
|
default: op
|
||||||
@@ -7,6 +7,9 @@ gui:
|
|||||||
tasks:
|
tasks:
|
||||||
- break_100_stone
|
- break_100_stone
|
||||||
|
|
||||||
|
reward-messages:
|
||||||
|
- " &8» &r&f+2 %ecoskills_defense_name%"
|
||||||
|
|
||||||
# A list of effects to run when the quest is completed.
|
# A list of effects to run when the quest is completed.
|
||||||
# Read https://plugins.auxilor.io/effects/configuring-an-effect
|
# Read https://plugins.auxilor.io/effects/configuring-an-effect
|
||||||
rewards: [ ]
|
rewards: [ ]
|
||||||
|
|||||||
@@ -7,6 +7,9 @@ gui:
|
|||||||
tasks:
|
tasks:
|
||||||
- break_100_stone
|
- break_100_stone
|
||||||
|
|
||||||
|
reward-messages:
|
||||||
|
- " &8» &r&f+2 %ecoskills_defense_name%"
|
||||||
|
|
||||||
# A list of effects to run when the quest is completed.
|
# A list of effects to run when the quest is completed.
|
||||||
# Read https://plugins.auxilor.io/effects/configuring-an-effect
|
# Read https://plugins.auxilor.io/effects/configuring-an-effect
|
||||||
rewards: [ ]
|
rewards: [ ]
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ description: "&fBreak stone blocks (&a%xp%&8/&a%required-xp%&f)"
|
|||||||
# If the task is just one action, set this to 1.
|
# If the task is just one action, set this to 1.
|
||||||
required-xp: 100
|
required-xp: 100
|
||||||
|
|
||||||
# A task takes a trigger, a multiplier, conditions, and filters.
|
# An XP gain method takes a trigger, a multiplier, conditions, and filters.
|
||||||
# The multiplier takes the value produced by the trigger and multiplies it
|
# The multiplier takes the value produced by the trigger and multiplies it
|
||||||
# by some value to calculate the experience that should be given.
|
# by some value to calculate the experience that should be given.
|
||||||
tasks:
|
xp-gain-methods:
|
||||||
- trigger: mine_block
|
- trigger: mine_block
|
||||||
multiplier: 1
|
multiplier: 1
|
||||||
filters:
|
filters:
|
||||||
|
|||||||
@@ -7,10 +7,10 @@ description: "&fBreak stone blocks (&a%xp%&8/&a%required-xp%&f)"
|
|||||||
# If the task is just one action, set this to 1.
|
# If the task is just one action, set this to 1.
|
||||||
required-xp: 100
|
required-xp: 100
|
||||||
|
|
||||||
# A task takes a trigger, a multiplier, conditions, and filters.
|
# An XP gain method takes a trigger, a multiplier, conditions, and filters.
|
||||||
# The multiplier takes the value produced by the trigger and multiplies it
|
# The multiplier takes the value produced by the trigger and multiplies it
|
||||||
# by some value to calculate the experience that should be given.
|
# by some value to calculate the experience that should be given.
|
||||||
tasks:
|
xp-gain-methods:
|
||||||
- trigger: mine_block
|
- trigger: mine_block
|
||||||
multiplier: 1
|
multiplier: 1
|
||||||
filters:
|
filters:
|
||||||
|
|||||||
Reference in New Issue
Block a user