9
0
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:
Auxilor
2023-08-08 20:13:55 +01:00
parent 051eb37dd6
commit 1d3326a5f6
20 changed files with 347 additions and 29 deletions

View File

@@ -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),

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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
}
}
}

View File

@@ -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>) {

View File

@@ -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)
}
}

View File

@@ -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(

View File

@@ -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
}

View File

@@ -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
} }

View File

@@ -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
)
)
}
} }

View File

@@ -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)
}
}

View File

@@ -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) }
}
} }

View File

@@ -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)

View File

@@ -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

View File

@@ -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!"

View File

@@ -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
@@ -41,4 +42,7 @@ permissions:
default: true default: true
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

View File

@@ -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: [ ]

View File

@@ -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: [ ]

View File

@@ -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:

View File

@@ -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: