mirror of
https://github.com/Auxilor/EcoQuests.git
synced 2025-12-21 16:09:16 +00:00
Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
202528681a | ||
|
|
7aa02b3a91 | ||
|
|
070d25de67 | ||
|
|
3ab99c9237 | ||
|
|
3ee10633fb | ||
|
|
49c77396ea | ||
|
|
09fb8d2109 | ||
|
|
9623f1c427 | ||
|
|
39eaef3856 | ||
|
|
bf085b4ea5 | ||
|
|
1a1433f84f | ||
|
|
571b4c05e2 | ||
|
|
58aa2fd81d | ||
|
|
335524a2da | ||
|
|
73d748d445 | ||
|
|
e0e0804cce | ||
|
|
c00d5eb7d2 | ||
|
|
f7fab37555 | ||
|
|
a93aac6b6f | ||
|
|
025a74048a | ||
|
|
9db9f542c9 | ||
|
|
75a091624c | ||
|
|
17c81ea5b8 | ||
|
|
81d4faaf0c | ||
|
|
03110e36b1 | ||
|
|
4b687e2c00 | ||
|
|
c01c86a592 | ||
|
|
438b118846 | ||
|
|
9c6cd8f467 | ||
|
|
1db9b48579 | ||
|
|
6b7380decd | ||
|
|
3ecc004a7f | ||
|
|
252163ba46 | ||
|
|
2a612e84fc | ||
|
|
c9af764714 | ||
|
|
5455db9fda | ||
|
|
3250d33f8e | ||
|
|
c0528c2c81 | ||
|
|
eecbe696a6 | ||
|
|
ba3bc524ae | ||
|
|
b98dd0c6e6 | ||
|
|
93cfb2911a | ||
|
|
d89a50b33b | ||
|
|
ebec6b0615 | ||
|
|
3ca42cb6d8 | ||
|
|
cc3e5af684 | ||
|
|
ddc2659c62 | ||
|
|
406ff65a6d | ||
|
|
e7a16550ac | ||
|
|
63b19f130e | ||
|
|
215e4556cb | ||
|
|
5eeb00c083 | ||
|
|
0a333853d8 | ||
|
|
dd454bd447 |
1
.github/CODEOWNERS
vendored
Normal file
1
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
* @WillFP
|
||||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
blank_issues_enabled: false
|
||||||
|
contact_links:
|
||||||
|
- name: Discord
|
||||||
|
url: https://discord.gg/ZcwpSsE/
|
||||||
|
about: Issues have moved to Discord, please join the server to get help!
|
||||||
11
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
11
.github/ISSUE_TEMPLATE/report-a-bug.md
vendored
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
---
|
||||||
|
name: Report a Bug
|
||||||
|
about: Report an issue with the plugin
|
||||||
|
title: ''
|
||||||
|
labels: bug
|
||||||
|
assignees: ''
|
||||||
|
---
|
||||||
|
|
||||||
|
# Please report bugs on the discord!
|
||||||
|
|
||||||
|
[Join by clicking here](https://discord.gg/ZcwpSsE/)
|
||||||
33
.github/workflows/publish-release.yml
vendored
Normal file
33
.github/workflows/publish-release.yml
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
name: Publish Packages
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
release:
|
||||||
|
types: [ created ]
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
|
||||||
|
- name: Checkout latest code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Set up JDK 17
|
||||||
|
uses: actions/setup-java@v2
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: 17
|
||||||
|
|
||||||
|
- name: Change wrapper permissions
|
||||||
|
run: chmod +x ./gradlew
|
||||||
|
|
||||||
|
- name: Publish package
|
||||||
|
uses: gradle/gradle-build-action@v2
|
||||||
|
with:
|
||||||
|
arguments: publish
|
||||||
|
env:
|
||||||
|
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
|
||||||
|
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
|
||||||
@@ -9,9 +9,23 @@ dependencies {
|
|||||||
|
|
||||||
publishing {
|
publishing {
|
||||||
publications {
|
publications {
|
||||||
register("maven", MavenPublication::class) {
|
register<MavenPublication>("maven") {
|
||||||
from(components["java"])
|
groupId = project.group.toString()
|
||||||
|
version = project.version.toString()
|
||||||
artifactId = rootProject.name
|
artifactId = rootProject.name
|
||||||
|
|
||||||
|
artifact(rootProject.tasks.shadowJar.get().archiveFile)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven {
|
||||||
|
name = "auxilor"
|
||||||
|
url = uri("https://repo.auxilor.io/repository/maven-releases/")
|
||||||
|
credentials {
|
||||||
|
username = System.getenv("MAVEN_USERNAME")
|
||||||
|
password = System.getenv("MAVEN_PASSWORD")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package com.willfp.ecoquests
|
package com.willfp.ecoquests
|
||||||
|
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.core.data.profile
|
||||||
import com.willfp.eco.core.placeholder.PlayerPlaceholder
|
import com.willfp.eco.core.placeholder.PlayerPlaceholder
|
||||||
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.placeholder.templates.SimpleInjectablePlaceholder
|
||||||
|
import com.willfp.eco.util.toNiceString
|
||||||
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.PreviousQuestsGUI
|
import com.willfp.ecoquests.gui.PreviousQuestsGUI
|
||||||
@@ -12,6 +16,7 @@ import com.willfp.ecoquests.libreforge.ConditionHasCompletedTask
|
|||||||
import com.willfp.ecoquests.libreforge.ConditionHasQuestActive
|
import com.willfp.ecoquests.libreforge.ConditionHasQuestActive
|
||||||
import com.willfp.ecoquests.libreforge.EffectGainTaskXp
|
import com.willfp.ecoquests.libreforge.EffectGainTaskXp
|
||||||
import com.willfp.ecoquests.libreforge.EffectGiveTaskXp
|
import com.willfp.ecoquests.libreforge.EffectGiveTaskXp
|
||||||
|
import com.willfp.ecoquests.libreforge.EffectQuestXpMultiplier
|
||||||
import com.willfp.ecoquests.libreforge.EffectStartQuest
|
import com.willfp.ecoquests.libreforge.EffectStartQuest
|
||||||
import com.willfp.ecoquests.libreforge.FilterQuest
|
import com.willfp.ecoquests.libreforge.FilterQuest
|
||||||
import com.willfp.ecoquests.libreforge.FilterTask
|
import com.willfp.ecoquests.libreforge.FilterTask
|
||||||
@@ -40,6 +45,7 @@ class EcoQuestsPlugin : LibreforgePlugin() {
|
|||||||
Conditions.register(ConditionHasQuestActive)
|
Conditions.register(ConditionHasQuestActive)
|
||||||
Effects.register(EffectGainTaskXp)
|
Effects.register(EffectGainTaskXp)
|
||||||
Effects.register(EffectGiveTaskXp)
|
Effects.register(EffectGiveTaskXp)
|
||||||
|
Effects.register(EffectQuestXpMultiplier)
|
||||||
Effects.register(EffectStartQuest)
|
Effects.register(EffectStartQuest)
|
||||||
Filters.register(FilterQuest)
|
Filters.register(FilterQuest)
|
||||||
Filters.register(FilterTask)
|
Filters.register(FilterTask)
|
||||||
@@ -56,9 +62,20 @@ class EcoQuestsPlugin : LibreforgePlugin() {
|
|||||||
Quests.getCompletedQuests(it).size.toString()
|
Quests.getCompletedQuests(it).size.toString()
|
||||||
}.register()
|
}.register()
|
||||||
|
|
||||||
|
PlayerPlaceholder(this, "quests_percent_completed") {
|
||||||
|
val completed = Quests.getCompletedQuests(it).size
|
||||||
|
val total = Quests.values().size
|
||||||
|
val percent = completed.toDouble() / total.toDouble() * 100.0
|
||||||
|
percent.toNiceString()
|
||||||
|
}.register()
|
||||||
|
|
||||||
PlayerPlaceholder(this, "quests_active") {
|
PlayerPlaceholder(this, "quests_active") {
|
||||||
Quests.getActiveQuests(it).size.toString()
|
Quests.getActiveQuests(it).size.toString()
|
||||||
}.register()
|
}.register()
|
||||||
|
|
||||||
|
PlayerPlaceholder(this, "recent_quest_name") {
|
||||||
|
Quests.getActiveQuests(it).minBy { quest -> quest.getTimeSinceStart(it) }.name
|
||||||
|
}.register()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun handleReload() {
|
override fun handleReload() {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ class CommandEcoQuests(plugin: EcoPlugin) : PluginCommand(
|
|||||||
init {
|
init {
|
||||||
this.addSubcommand(CommandReload(plugin))
|
this.addSubcommand(CommandReload(plugin))
|
||||||
.addSubcommand(CommandStart(plugin))
|
.addSubcommand(CommandStart(plugin))
|
||||||
|
.addSubcommand(CommandResetPlayer(plugin))
|
||||||
.addSubcommand(CommandReset(plugin))
|
.addSubcommand(CommandReset(plugin))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ package com.willfp.ecoquests.commands
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.ecoquests.gui.QuestsGUI
|
import com.willfp.ecoquests.gui.QuestsGUI
|
||||||
import com.willfp.libreforge.commands.CommandReload
|
|
||||||
import org.bukkit.command.CommandSender
|
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
class CommandQuests(plugin: EcoPlugin) : PluginCommand(
|
class CommandQuests(plugin: EcoPlugin) : PluginCommand(
|
||||||
|
|||||||
@@ -3,11 +3,8 @@ package com.willfp.ecoquests.commands
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import com.willfp.ecoquests.gui.QuestsGUI
|
|
||||||
import com.willfp.ecoquests.quests.Quests
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.libreforge.commands.CommandReload
|
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.util.StringUtil
|
import org.bukkit.util.StringUtil
|
||||||
|
|
||||||
class CommandReset(plugin: EcoPlugin) : PluginCommand(
|
class CommandReset(plugin: EcoPlugin) : PluginCommand(
|
||||||
@@ -17,15 +14,21 @@ class CommandReset(plugin: EcoPlugin) : PluginCommand(
|
|||||||
false
|
false
|
||||||
) {
|
) {
|
||||||
override fun onExecute(sender: CommandSender, args: List<String>) {
|
override fun onExecute(sender: CommandSender, args: List<String>) {
|
||||||
val player = notifyPlayerRequired(args.getOrNull(0), "invalid-player")
|
val quest = notifyNull(Quests[args.getOrNull(0)], "invalid-quest")
|
||||||
val quest = notifyNull(Quests[args.getOrNull(1)], "invalid-quest")
|
|
||||||
|
|
||||||
quest.reset(player)
|
if (!quest.isResettable) {
|
||||||
|
sender.sendMessage(
|
||||||
|
plugin.langYml.getMessage("quest-not-resettable", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
||||||
|
.replace("%quest%", quest.name)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
quest.reset()
|
||||||
|
|
||||||
sender.sendMessage(
|
sender.sendMessage(
|
||||||
plugin.langYml.getMessage("reset-quest", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
plugin.langYml.getMessage("reset-quest", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
||||||
.replace("%quest%", quest.name)
|
.replace("%quest%", quest.name)
|
||||||
.replace("%player%", player.name)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,14 +38,6 @@ class CommandReset(plugin: EcoPlugin) : PluginCommand(
|
|||||||
if (args.size == 1) {
|
if (args.size == 1) {
|
||||||
StringUtil.copyPartialMatches(
|
StringUtil.copyPartialMatches(
|
||||||
args[0],
|
args[0],
|
||||||
plugin.server.onlinePlayers.map { it.name },
|
|
||||||
completions
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (args.size == 2) {
|
|
||||||
StringUtil.copyPartialMatches(
|
|
||||||
args[1],
|
|
||||||
Quests.values().map { it.id },
|
Quests.values().map { it.id },
|
||||||
completions
|
completions
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
package com.willfp.ecoquests.commands
|
||||||
|
|
||||||
|
import com.willfp.eco.core.EcoPlugin
|
||||||
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
|
import com.willfp.eco.util.StringUtils
|
||||||
|
import com.willfp.ecoquests.quests.Quests
|
||||||
|
import org.bukkit.command.CommandSender
|
||||||
|
import org.bukkit.util.StringUtil
|
||||||
|
|
||||||
|
class CommandResetPlayer(plugin: EcoPlugin) : PluginCommand(
|
||||||
|
plugin,
|
||||||
|
"resetplayer",
|
||||||
|
"ecoquests.command.resetplayer",
|
||||||
|
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")
|
||||||
|
|
||||||
|
quest.reset(player)
|
||||||
|
|
||||||
|
sender.sendMessage(
|
||||||
|
plugin.langYml.getMessage("reset-quest-for-player", StringUtils.FormatOption.WITHOUT_PLACEHOLDERS)
|
||||||
|
.replace("%quest%", quest.name)
|
||||||
|
.replace("%player%", player.name)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun tabComplete(sender: CommandSender, args: List<String>): List<String> {
|
||||||
|
val completions = mutableListOf<String>()
|
||||||
|
|
||||||
|
if (args.size == 1) {
|
||||||
|
StringUtil.copyPartialMatches(
|
||||||
|
args[0],
|
||||||
|
plugin.server.onlinePlayers.map { it.name },
|
||||||
|
completions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size == 2) {
|
||||||
|
StringUtil.copyPartialMatches(
|
||||||
|
args[1],
|
||||||
|
Quests.values().map { it.id },
|
||||||
|
completions
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
return completions
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -3,11 +3,8 @@ package com.willfp.ecoquests.commands
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.command.impl.PluginCommand
|
import com.willfp.eco.core.command.impl.PluginCommand
|
||||||
import com.willfp.eco.util.StringUtils
|
import com.willfp.eco.util.StringUtils
|
||||||
import com.willfp.ecoquests.gui.QuestsGUI
|
|
||||||
import com.willfp.ecoquests.quests.Quests
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.libreforge.commands.CommandReload
|
|
||||||
import org.bukkit.command.CommandSender
|
import org.bukkit.command.CommandSender
|
||||||
import org.bukkit.entity.Player
|
|
||||||
import org.bukkit.util.StringUtil
|
import org.bukkit.util.StringUtil
|
||||||
|
|
||||||
class CommandStart(plugin: EcoPlugin) : PluginCommand(
|
class CommandStart(plugin: EcoPlugin) : PluginCommand(
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ class PositionedPageChanger(
|
|||||||
direction: PageChanger.Direction
|
direction: PageChanger.Direction
|
||||||
): PositionedComponent {
|
): PositionedComponent {
|
||||||
private val pageChanger = PageChanger(
|
private val pageChanger = PageChanger(
|
||||||
Items.lookup("item").item,
|
Items.lookup(config.getString("item")).item,
|
||||||
direction
|
direction
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -5,17 +5,21 @@ import com.willfp.eco.core.gui.onLeftClick
|
|||||||
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.ItemStackBuilder
|
||||||
|
import com.willfp.eco.core.items.builder.modify
|
||||||
|
import com.willfp.eco.util.formatEco
|
||||||
import com.willfp.ecoquests.gui.PreviousQuestsGUI
|
import com.willfp.ecoquests.gui.PreviousQuestsGUI
|
||||||
|
|
||||||
class QuestInfoComponent(
|
class QuestInfoComponent(
|
||||||
config: Config
|
config: Config
|
||||||
) : PositionedComponent {
|
) : PositionedComponent {
|
||||||
private val slot = slot(
|
private val baseItem = Items.lookup(config.getString("item"))
|
||||||
ItemStackBuilder(Items.lookup(config.getString("item")))
|
|
||||||
.setDisplayName(config.getFormattedString("name"))
|
private val slot = slot({ player, _ ->
|
||||||
.addLoreLines(config.getFormattedStrings("lore"))
|
baseItem.item.clone().modify {
|
||||||
.build()
|
setDisplayName(config.getString("name").formatEco(player, formatPlaceholders = true))
|
||||||
) {
|
addLoreLines(config.getStrings("lore").formatEco(player, formatPlaceholders = true))
|
||||||
|
}
|
||||||
|
}) {
|
||||||
onLeftClick { player, _, _, _ ->
|
onLeftClick { player, _, _, _ ->
|
||||||
PreviousQuestsGUI.open(player)
|
PreviousQuestsGUI.open(player)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,14 @@ import org.bukkit.entity.Player
|
|||||||
|
|
||||||
object ConditionHasCompletedTask : Condition<NoCompileData>("has_completed_task") {
|
object ConditionHasCompletedTask : Condition<NoCompileData>("has_completed_task") {
|
||||||
override val arguments = arguments {
|
override val arguments = arguments {
|
||||||
|
require("quest", "You must specify the quest ID!")
|
||||||
require("task", "You must specify the task ID!")
|
require("task", "You must specify the task ID!")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isMet(player: Player, config: Config, compileData: NoCompileData): Boolean {
|
override fun isMet(player: Player, config: Config, compileData: NoCompileData): Boolean {
|
||||||
val task = Tasks[config.getString("task")] ?: return false
|
val quest = Quests[config.getString("quest")] ?: return false
|
||||||
|
val template = Tasks[config.getString("task")] ?: return false
|
||||||
|
val task = quest.getTask(template) ?: return false
|
||||||
|
|
||||||
return task.hasCompleted(player)
|
return task.hasCompleted(player)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.willfp.ecoquests.libreforge
|
package com.willfp.ecoquests.libreforge
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.ecoquests.tasks.Tasks
|
import com.willfp.ecoquests.tasks.Tasks
|
||||||
import com.willfp.libreforge.NoCompileData
|
import com.willfp.libreforge.NoCompileData
|
||||||
import com.willfp.libreforge.arguments
|
import com.willfp.libreforge.arguments
|
||||||
@@ -17,13 +18,17 @@ object EffectGainTaskXp : Effect<NoCompileData>("gain_task_xp") {
|
|||||||
|
|
||||||
override val arguments = arguments {
|
override val arguments = arguments {
|
||||||
require("task", "You must specify the task ID!")
|
require("task", "You must specify the task ID!")
|
||||||
|
require("quest", "You must specify the quest ID!")
|
||||||
require("xp", "You must specify the amount of xp to gain!")
|
require("xp", "You must specify the amount of xp to gain!")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
||||||
val player = data.player ?: return false
|
val player = data.player ?: return false
|
||||||
|
|
||||||
val task = Tasks[config.getString("task")] ?: return false
|
val quest = Quests[config.getString("quest")] ?: return false
|
||||||
|
val template = Tasks[config.getString("task")] ?: return false
|
||||||
|
val task = quest.getTask(template) ?: return false
|
||||||
|
|
||||||
val xp = config.getDoubleFromExpression("xp", data)
|
val xp = config.getDoubleFromExpression("xp", data)
|
||||||
|
|
||||||
task.gainExperience(player, xp)
|
task.gainExperience(player, xp)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.willfp.ecoquests.libreforge
|
package com.willfp.ecoquests.libreforge
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.ecoquests.tasks.Tasks
|
import com.willfp.ecoquests.tasks.Tasks
|
||||||
import com.willfp.libreforge.NoCompileData
|
import com.willfp.libreforge.NoCompileData
|
||||||
import com.willfp.libreforge.arguments
|
import com.willfp.libreforge.arguments
|
||||||
@@ -17,13 +18,17 @@ object EffectGiveTaskXp : Effect<NoCompileData>("give_task_xp") {
|
|||||||
|
|
||||||
override val arguments = arguments {
|
override val arguments = arguments {
|
||||||
require("task", "You must specify the task ID!")
|
require("task", "You must specify the task ID!")
|
||||||
|
require("quest", "You must specify the quest ID!")
|
||||||
require("xp", "You must specify the amount of xp to give!")
|
require("xp", "You must specify the amount of xp to give!")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
override fun onTrigger(config: Config, data: TriggerData, compileData: NoCompileData): Boolean {
|
||||||
val player = data.player ?: return false
|
val player = data.player ?: return false
|
||||||
|
|
||||||
val task = Tasks[config.getString("task")] ?: return false
|
val quest = Quests[config.getString("quest")] ?: return false
|
||||||
|
val template = Tasks[config.getString("task")] ?: return false
|
||||||
|
val task = quest.getTask(template) ?: return false
|
||||||
|
|
||||||
val xp = config.getDoubleFromExpression("xp", data)
|
val xp = config.getDoubleFromExpression("xp", data)
|
||||||
|
|
||||||
task.giveExperience(player, xp)
|
task.giveExperience(player, xp)
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package com.willfp.ecoquests.libreforge
|
||||||
|
|
||||||
|
import com.willfp.ecoquests.api.event.PlayerTaskExpGainEvent
|
||||||
|
import com.willfp.ecoquests.quests.Quest
|
||||||
|
import com.willfp.ecoquests.quests.Quests
|
||||||
|
import com.willfp.libreforge.effects.templates.MultiMultiplierEffect
|
||||||
|
import org.bukkit.event.EventHandler
|
||||||
|
|
||||||
|
object EffectQuestXpMultiplier : MultiMultiplierEffect<Quest>("quest_xp_multiplier") {
|
||||||
|
override val key = "quests"
|
||||||
|
|
||||||
|
override fun getElement(key: String): Quest? {
|
||||||
|
return Quests[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getAllElements(): Collection<Quest> {
|
||||||
|
return Quests.values()
|
||||||
|
}
|
||||||
|
|
||||||
|
@EventHandler(ignoreCancelled = true)
|
||||||
|
fun handle(event: PlayerTaskExpGainEvent) {
|
||||||
|
event.amount *= getMultiplier(event.player, event.quest)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.willfp.ecoquests.libreforge
|
package com.willfp.ecoquests.libreforge
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.util.containsIgnoreCase
|
||||||
import com.willfp.ecoquests.api.event.QuestEvent
|
import com.willfp.ecoquests.api.event.QuestEvent
|
||||||
import com.willfp.libreforge.NoCompileData
|
import com.willfp.libreforge.NoCompileData
|
||||||
import com.willfp.libreforge.filters.Filter
|
import com.willfp.libreforge.filters.Filter
|
||||||
@@ -14,8 +15,6 @@ object FilterQuest : Filter<NoCompileData, Collection<String>>("quest") {
|
|||||||
override fun isMet(data: TriggerData, value: Collection<String>, compileData: NoCompileData): Boolean {
|
override fun isMet(data: TriggerData, value: Collection<String>, compileData: NoCompileData): Boolean {
|
||||||
val event = data.event as? QuestEvent ?: return true
|
val event = data.event as? QuestEvent ?: return true
|
||||||
|
|
||||||
return value.any { questID ->
|
return value.containsIgnoreCase(event.quest.id)
|
||||||
questID.equals(event.quest.id, ignoreCase = true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
package com.willfp.ecoquests.libreforge
|
package com.willfp.ecoquests.libreforge
|
||||||
|
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
|
import com.willfp.eco.util.containsIgnoreCase
|
||||||
import com.willfp.ecoquests.api.event.QuestEvent
|
import com.willfp.ecoquests.api.event.QuestEvent
|
||||||
import com.willfp.ecoquests.api.event.TaskEvent
|
import com.willfp.ecoquests.api.event.TaskEvent
|
||||||
import com.willfp.libreforge.NoCompileData
|
import com.willfp.libreforge.NoCompileData
|
||||||
@@ -15,8 +16,6 @@ object FilterTask : Filter<NoCompileData, Collection<String>>("task") {
|
|||||||
override fun isMet(data: TriggerData, value: Collection<String>, compileData: NoCompileData): Boolean {
|
override fun isMet(data: TriggerData, value: Collection<String>, compileData: NoCompileData): Boolean {
|
||||||
val event = data.event as? TaskEvent ?: return true
|
val event = data.event as? TaskEvent ?: return true
|
||||||
|
|
||||||
return value.any { taskID ->
|
return value.containsIgnoreCase(event.task.id)
|
||||||
taskID.equals(event.task.id, ignoreCase = true)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,20 +14,27 @@ import com.willfp.eco.core.placeholder.PlayerlessPlaceholder
|
|||||||
import com.willfp.eco.core.placeholder.context.placeholderContext
|
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.eco.util.lineWrap
|
||||||
import com.willfp.eco.util.toNiceString
|
import com.willfp.eco.util.toNiceString
|
||||||
import com.willfp.ecoquests.api.event.PlayerQuestCompleteEvent
|
import com.willfp.ecoquests.api.event.PlayerQuestCompleteEvent
|
||||||
import com.willfp.ecoquests.api.event.PlayerQuestStartEvent
|
import com.willfp.ecoquests.api.event.PlayerQuestStartEvent
|
||||||
import com.willfp.ecoquests.tasks.Task
|
import com.willfp.ecoquests.tasks.Task
|
||||||
|
import com.willfp.ecoquests.tasks.TaskTemplate
|
||||||
import com.willfp.ecoquests.tasks.Tasks
|
import com.willfp.ecoquests.tasks.Tasks
|
||||||
import com.willfp.ecoquests.util.formatDuration
|
import com.willfp.ecoquests.util.formatDuration
|
||||||
|
import com.willfp.ecoquests.util.randomlyPick
|
||||||
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.Bukkit
|
||||||
|
import org.bukkit.OfflinePlayer
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
|
val currentTimeMinutes: Int
|
||||||
|
get() = (System.currentTimeMillis() / 1000 / 60).toInt()
|
||||||
|
|
||||||
class Quest(
|
class Quest(
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: EcoPlugin,
|
||||||
override val id: String,
|
override val id: String,
|
||||||
@@ -37,6 +44,8 @@ class Quest(
|
|||||||
|
|
||||||
val announcesStart = config.getBool("announce-start")
|
val announcesStart = config.getBool("announce-start")
|
||||||
|
|
||||||
|
val autoStarts = config.getBool("auto-start")
|
||||||
|
|
||||||
private val guiItem = Items.lookup(config.getString("gui.item")).item
|
private val guiItem = Items.lookup(config.getString("gui.item")).item
|
||||||
|
|
||||||
val slot = slot({ player, _ ->
|
val slot = slot({ player, _ ->
|
||||||
@@ -51,6 +60,13 @@ class Quest(
|
|||||||
addLoreLines(
|
addLoreLines(
|
||||||
startConditions.getNotMetLines(player, EmptyProvidedHolder)
|
startConditions.getNotMetLines(player, EmptyProvidedHolder)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
setDisplayName(
|
||||||
|
addPlaceholdersInto(
|
||||||
|
listOf(plugin.configYml.getString("quests.icon.name")),
|
||||||
|
player
|
||||||
|
).first()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}) {
|
}) {
|
||||||
|
|
||||||
@@ -60,22 +76,62 @@ class Quest(
|
|||||||
|
|
||||||
val alwaysInGUI = config.getBool("gui.always")
|
val alwaysInGUI = config.getBool("gui.always")
|
||||||
|
|
||||||
val tasks = config.getStrings("tasks")
|
// The pool of available tasks to pick from
|
||||||
.mapNotNull { Tasks[it] }
|
private val availableTasks = config.getSubsections("tasks")
|
||||||
.map { Task(plugin, it, this) }
|
.mapNotNull {
|
||||||
|
Tasks[it.getString("task")]
|
||||||
|
?.create(this, it.getString("xp"))
|
||||||
|
}
|
||||||
|
|
||||||
private val hasStartedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
// The amount of tasks to use from the pool
|
||||||
|
val taskAmount = config.getInt("task-amount").let {
|
||||||
|
if (it < 0) {
|
||||||
|
availableTasks.size
|
||||||
|
} else {
|
||||||
|
it.coerceAtMost(availableTasks.size)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val savedTasksKey = PersistentDataKey(
|
||||||
|
plugin.createNamespacedKey("quest_${id}_tasks"),
|
||||||
|
PersistentDataKeyType.STRING_LIST,
|
||||||
|
emptyList()
|
||||||
|
)
|
||||||
|
|
||||||
|
// The tasks that are actually in use
|
||||||
|
var tasks = run {
|
||||||
|
if (isResettable) {
|
||||||
|
loadTasks() ?: availableTasks.randomlyPick(taskAmount)
|
||||||
|
} else {
|
||||||
|
availableTasks.randomlyPick(taskAmount)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
|
||||||
|
private val hasStartedKey = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("quest_${id}_has_started"),
|
plugin.createNamespacedKey("quest_${id}_has_started"),
|
||||||
PersistentDataKeyType.BOOLEAN,
|
PersistentDataKeyType.BOOLEAN,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
private val hasCompletedKey: PersistentDataKey<Boolean> = PersistentDataKey(
|
private val startedTimeKey = PersistentDataKey(
|
||||||
|
plugin.createNamespacedKey("quest_${id}_started_time"),
|
||||||
|
PersistentDataKeyType.INT,
|
||||||
|
Int.MAX_VALUE
|
||||||
|
)
|
||||||
|
|
||||||
|
private val hasCompletedKey = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("quest_${id}_has_completed"),
|
plugin.createNamespacedKey("quest_${id}_has_completed"),
|
||||||
PersistentDataKeyType.BOOLEAN,
|
PersistentDataKeyType.BOOLEAN,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val completedTimeKey = PersistentDataKey(
|
||||||
|
plugin.createNamespacedKey("quest_${id}_completed_time"),
|
||||||
|
PersistentDataKeyType.INT,
|
||||||
|
Int.MAX_VALUE
|
||||||
|
)
|
||||||
|
|
||||||
private val rewardMessages = config.getStrings("reward-messages")
|
private val rewardMessages = config.getStrings("reward-messages")
|
||||||
|
|
||||||
private val rewards = Effects.compileChain(
|
private val rewards = Effects.compileChain(
|
||||||
@@ -103,14 +159,16 @@ class Quest(
|
|||||||
|
|
||||||
private val resetTime = config.getInt("reset-time")
|
private val resetTime = config.getInt("reset-time")
|
||||||
|
|
||||||
|
val isResettable: Boolean
|
||||||
|
get() = resetTime >= 0
|
||||||
|
|
||||||
val minutesUntilReset: Int
|
val minutesUntilReset: Int
|
||||||
get() = if (resetTime < 0) {
|
get() = if (resetTime < 0) {
|
||||||
Int.MAX_VALUE
|
Int.MAX_VALUE
|
||||||
} else {
|
} else {
|
||||||
val currentTime = (System.currentTimeMillis() / 1000 / 60).toInt()
|
|
||||||
val previousTime = ServerProfile.load().read(lastResetTimeKey)
|
val previousTime = ServerProfile.load().read(lastResetTimeKey)
|
||||||
|
|
||||||
resetTime - currentTime + previousTime
|
resetTime - currentTimeMinutes + previousTime
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@@ -141,17 +199,60 @@ class Quest(
|
|||||||
PlayerlessPlaceholder(plugin, "quest_${id}_time_until_reset") {
|
PlayerlessPlaceholder(plugin, "quest_${id}_time_until_reset") {
|
||||||
formatDuration(this.minutesUntilReset)
|
formatDuration(this.minutesUntilReset)
|
||||||
}.register()
|
}.register()
|
||||||
|
|
||||||
|
PlayerPlaceholder(plugin, "quest_${id}_time_since_start") {
|
||||||
|
formatDuration(this.getTimeSinceStart(it))
|
||||||
|
}.register()
|
||||||
|
|
||||||
|
PlayerPlaceholder(plugin, "quest_${id}_time_since_completed") {
|
||||||
|
formatDuration(this.getTimeSinceCompletion(it))
|
||||||
|
}.register()
|
||||||
|
|
||||||
|
PlayerPlaceholder(plugin, "quest_${id}_time_since") {
|
||||||
|
if (hasCompleted(it)) {
|
||||||
|
plugin.langYml.getString("time-since.completed")
|
||||||
|
.replace("%time%", formatDuration(this.getTimeSinceCompletion(it)))
|
||||||
|
.formatEco(it)
|
||||||
|
} else if (hasStarted(it)) {
|
||||||
|
plugin.langYml.getString("time-since.started")
|
||||||
|
.replace("%time%", formatDuration(this.getTimeSinceStart(it)))
|
||||||
|
.formatEco(it)
|
||||||
|
} else {
|
||||||
|
plugin.langYml.getString("time-since.never")
|
||||||
|
.formatEco(it)
|
||||||
|
}
|
||||||
|
}.register()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRegister() {
|
||||||
|
for (task in tasks) {
|
||||||
|
task.bind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onRemove() {
|
||||||
|
if (isResettable) {
|
||||||
|
saveTasks()
|
||||||
|
}
|
||||||
|
|
||||||
|
for (task in tasks) {
|
||||||
|
task.unbind()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTask(template: TaskTemplate): Task? {
|
||||||
|
return tasks.firstOrNull { it.template == template }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getDescription(player: Player): List<String> {
|
fun getDescription(player: Player): List<String> {
|
||||||
return addPlaceholdersInto(listOf(config.getString("description")), player)
|
return addPlaceholdersInto(listOf(config.getString("description")), player)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasActive(player: Player): Boolean {
|
fun hasActive(player: OfflinePlayer): Boolean {
|
||||||
return hasStarted(player) && !hasCompleted(player)
|
return hasStarted(player) && !hasCompleted(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasCompleted(player: Player): Boolean {
|
fun hasCompleted(player: OfflinePlayer): Boolean {
|
||||||
return player.profile.read(hasCompletedKey)
|
return player.profile.read(hasCompletedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,14 +261,14 @@ class Quest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun shouldStart(player: Player): Boolean {
|
fun shouldStart(player: Player): Boolean {
|
||||||
return meetsStartConditions(player) && !hasStarted(player)
|
return meetsStartConditions(player) && !hasStarted(player) && autoStarts
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasStarted(player: Player): Boolean {
|
fun hasStarted(player: OfflinePlayer): Boolean {
|
||||||
return player.profile.read(hasStartedKey)
|
return player.profile.read(hasStartedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset(player: Player) {
|
fun reset(player: OfflinePlayer) {
|
||||||
player.profile.write(hasStartedKey, false)
|
player.profile.write(hasStartedKey, false)
|
||||||
player.profile.write(hasCompletedKey, false)
|
player.profile.write(hasCompletedKey, false)
|
||||||
|
|
||||||
@@ -183,10 +284,39 @@ class Quest(
|
|||||||
|
|
||||||
startEffects?.trigger(player)
|
startEffects?.trigger(player)
|
||||||
player.profile.write(hasStartedKey, true)
|
player.profile.write(hasStartedKey, true)
|
||||||
|
player.profile.write(startedTimeKey, currentTimeMinutes)
|
||||||
|
|
||||||
|
// Reset tasks to generate new xp requirements
|
||||||
|
for (task in tasks) {
|
||||||
|
task.reset(player)
|
||||||
|
}
|
||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(PlayerQuestStartEvent(player, this))
|
Bukkit.getPluginManager().callEvent(PlayerQuestStartEvent(player, this))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTimeSinceStart(player: OfflinePlayer): Int {
|
||||||
|
return currentTimeMinutes - player.profile.read(startedTimeKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTimeSinceCompletion(player: OfflinePlayer): Int {
|
||||||
|
return currentTimeMinutes - player.profile.read(completedTimeKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getTimeSincePlaceholder(player: Player): String {
|
||||||
|
return if (hasCompleted(player)) {
|
||||||
|
plugin.langYml.getString("time-since.completed")
|
||||||
|
.replace("%time%", formatDuration(this.getTimeSinceCompletion(player)))
|
||||||
|
.formatEco(player)
|
||||||
|
} else if (hasStarted(player)) {
|
||||||
|
plugin.langYml.getString("time-since.started")
|
||||||
|
.replace("%time%", formatDuration(this.getTimeSinceStart(player)))
|
||||||
|
.formatEco(player)
|
||||||
|
} else {
|
||||||
|
plugin.langYml.getString("time-since.never")
|
||||||
|
.formatEco(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun resetIfNeeded() {
|
fun resetIfNeeded() {
|
||||||
if (resetTime < 0) {
|
if (resetTime < 0) {
|
||||||
return
|
return
|
||||||
@@ -196,11 +326,69 @@ class Quest(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun reset() {
|
||||||
ServerProfile.load().write(lastResetTimeKey, (System.currentTimeMillis() / 1000 / 60).toInt())
|
ServerProfile.load().write(lastResetTimeKey, (System.currentTimeMillis() / 1000 / 60).toInt())
|
||||||
|
|
||||||
for (player in Bukkit.getOnlinePlayers()) {
|
for (player in Bukkit.getOnlinePlayers()) {
|
||||||
reset(player)
|
reset(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Offline players can be reset async
|
||||||
|
plugin.scheduler.runAsync {
|
||||||
|
for (player in Bukkit.getOfflinePlayers()) {
|
||||||
|
if (!player.isOnline) {
|
||||||
|
reset(player)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unbind old tasks
|
||||||
|
for (task in tasks) {
|
||||||
|
task.unbind()
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks = availableTasks.randomlyPick(taskAmount)
|
||||||
|
|
||||||
|
// Bind new tasks
|
||||||
|
for (task in tasks) {
|
||||||
|
task.bind()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save new tasks
|
||||||
|
saveTasks()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadTasks(): List<Task>? {
|
||||||
|
val serialized = ServerProfile.load().read(savedTasksKey)
|
||||||
|
|
||||||
|
if (serialized.isEmpty()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
val savedTasks = mutableListOf<Task>()
|
||||||
|
|
||||||
|
for (s in serialized) {
|
||||||
|
val split = s.split(":")
|
||||||
|
val taskId = split[0]
|
||||||
|
val xpExpr = split[1]
|
||||||
|
|
||||||
|
val template = Tasks[taskId] ?: continue
|
||||||
|
|
||||||
|
savedTasks += template.create(this, xpExpr)
|
||||||
|
}
|
||||||
|
|
||||||
|
return savedTasks
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun saveTasks() {
|
||||||
|
val serialized = tasks.map {
|
||||||
|
"${it.template.id}:${it.xpExpr}"
|
||||||
|
}
|
||||||
|
|
||||||
|
ServerProfile.load().write(savedTasksKey, serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun checkCompletion(player: Player): Boolean {
|
fun checkCompletion(player: Player): Boolean {
|
||||||
@@ -210,17 +398,21 @@ class Quest(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tasks.all { it.hasCompleted(player) }) {
|
if (tasks.all { it.hasCompleted(player) }) {
|
||||||
player.profile.write(hasCompletedKey, true)
|
complete(player)
|
||||||
rewards?.trigger(player)
|
|
||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(PlayerQuestCompleteEvent(player, this))
|
|
||||||
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun complete(player: Player) {
|
||||||
|
player.profile.write(hasCompletedKey, true)
|
||||||
|
player.profile.write(completedTimeKey, currentTimeMinutes)
|
||||||
|
rewards?.trigger(player)
|
||||||
|
|
||||||
|
Bukkit.getPluginManager().callEvent(PlayerQuestCompleteEvent(player, this))
|
||||||
|
}
|
||||||
|
|
||||||
private fun List<String>.addMargin(margin: Int): List<String> {
|
private fun List<String>.addMargin(margin: Int): List<String> {
|
||||||
return this.map { s -> " ".repeat(margin) + s }
|
return this.map { s -> " ".repeat(margin) + s }
|
||||||
}
|
}
|
||||||
@@ -233,6 +425,7 @@ class Quest(
|
|||||||
fun String.addPlaceholders() = this
|
fun String.addPlaceholders() = this
|
||||||
.replace("%quest%", quest.name)
|
.replace("%quest%", quest.name)
|
||||||
.replace("%time_until_reset%", formatDuration(quest.minutesUntilReset))
|
.replace("%time_until_reset%", formatDuration(quest.minutesUntilReset))
|
||||||
|
.replace("%time_since%", getTimeSincePlaceholder(player))
|
||||||
|
|
||||||
// Replace multi-line placeholders.
|
// Replace multi-line placeholders.
|
||||||
val processed = strings.flatMap { s ->
|
val processed = strings.flatMap { s ->
|
||||||
@@ -242,7 +435,7 @@ class Quest(
|
|||||||
rewardMessages
|
rewardMessages
|
||||||
.addMargin(margin)
|
.addMargin(margin)
|
||||||
} else if (s.contains("%tasks%")) {
|
} else if (s.contains("%tasks%")) {
|
||||||
tasks.flatMap { task -> task.getCompletedDescription(player) }
|
tasks.map { task -> task.getCompletedDescription(player) }
|
||||||
.addMargin(margin)
|
.addMargin(margin)
|
||||||
} else if (s.contains("%description%")) {
|
} else if (s.contains("%description%")) {
|
||||||
getDescription(player)
|
getDescription(player)
|
||||||
@@ -256,6 +449,6 @@ class Quest(
|
|||||||
placeholderContext(
|
placeholderContext(
|
||||||
player = player
|
player = player
|
||||||
)
|
)
|
||||||
)
|
).lineWrap(plugin.configYml.getInt("quests.icon.line-wrap"), true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import com.willfp.libreforge.loader.configs.ConfigCategory
|
|||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
|
|
||||||
object Quests : ConfigCategory("quest", "quests") {
|
object Quests : ConfigCategory("quest", "quests") {
|
||||||
|
override val supportsSharing = false
|
||||||
|
|
||||||
private val registry = Registry<Quest>()
|
private val registry = Registry<Quest>()
|
||||||
|
|
||||||
override fun clear(plugin: LibreforgePlugin) {
|
override fun clear(plugin: LibreforgePlugin) {
|
||||||
|
|||||||
@@ -5,7 +5,6 @@ import com.willfp.eco.core.data.keys.PersistentDataKey
|
|||||||
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
import com.willfp.eco.core.data.keys.PersistentDataKeyType
|
||||||
import com.willfp.eco.core.data.profile
|
import com.willfp.eco.core.data.profile
|
||||||
import com.willfp.eco.core.placeholder.PlayerPlaceholder
|
import com.willfp.eco.core.placeholder.PlayerPlaceholder
|
||||||
import com.willfp.eco.core.placeholder.PlayerlessPlaceholder
|
|
||||||
import com.willfp.eco.core.placeholder.context.placeholderContext
|
import com.willfp.eco.core.placeholder.context.placeholderContext
|
||||||
import com.willfp.eco.util.evaluateExpression
|
import com.willfp.eco.util.evaluateExpression
|
||||||
import com.willfp.eco.util.formatEco
|
import com.willfp.eco.util.formatEco
|
||||||
@@ -17,6 +16,7 @@ import com.willfp.ecoquests.quests.Quest
|
|||||||
import com.willfp.ecoquests.quests.Quests
|
import com.willfp.ecoquests.quests.Quests
|
||||||
import com.willfp.libreforge.counters.Accumulator
|
import com.willfp.libreforge.counters.Accumulator
|
||||||
import org.bukkit.Bukkit
|
import org.bukkit.Bukkit
|
||||||
|
import org.bukkit.OfflinePlayer
|
||||||
import org.bukkit.entity.Player
|
import org.bukkit.entity.Player
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
@@ -24,7 +24,7 @@ class Task(
|
|||||||
private val plugin: EcoPlugin,
|
private val plugin: EcoPlugin,
|
||||||
val template: TaskTemplate,
|
val template: TaskTemplate,
|
||||||
val quest: Quest,
|
val quest: Quest,
|
||||||
private val xpExpr: String
|
internal val xpExpr: String
|
||||||
) {
|
) {
|
||||||
private val xpKey = PersistentDataKey(
|
private val xpKey = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("${quest.id}_task_${template.id}_xp"),
|
plugin.createNamespacedKey("${quest.id}_task_${template.id}_xp"),
|
||||||
@@ -32,6 +32,12 @@ class Task(
|
|||||||
0.0
|
0.0
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val xpRequiredKey = PersistentDataKey(
|
||||||
|
plugin.createNamespacedKey("${quest.id}_task_${template.id}_xp_required"),
|
||||||
|
PersistentDataKeyType.DOUBLE,
|
||||||
|
0.0
|
||||||
|
)
|
||||||
|
|
||||||
private val hasCompletedKey = PersistentDataKey(
|
private val hasCompletedKey = PersistentDataKey(
|
||||||
plugin.createNamespacedKey("${quest.id}_task_${template.id}_has_completed"),
|
plugin.createNamespacedKey("${quest.id}_task_${template.id}_has_completed"),
|
||||||
PersistentDataKeyType.BOOLEAN,
|
PersistentDataKeyType.BOOLEAN,
|
||||||
@@ -80,16 +86,16 @@ class Task(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset(player: Player) {
|
fun reset(player: OfflinePlayer) {
|
||||||
player.profile.write(xpKey, 0.0)
|
player.profile.write(xpKey, 0.0)
|
||||||
player.profile.write(hasCompletedKey, false)
|
player.profile.write(hasCompletedKey, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hasCompleted(player: Player): Boolean {
|
fun hasCompleted(player: OfflinePlayer): Boolean {
|
||||||
return player.profile.read(hasCompletedKey)
|
return player.profile.read(hasCompletedKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getExperienceRequired(player: Player): Double {
|
private fun generateExperienceRequired(player: Player): Double {
|
||||||
return evaluateExpression(
|
return evaluateExpression(
|
||||||
xpExpr,
|
xpExpr,
|
||||||
placeholderContext(
|
placeholderContext(
|
||||||
@@ -98,8 +104,26 @@ class Task(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getExperience(player: Player): Double {
|
fun getExperienceRequired(player: Player): Double {
|
||||||
return min(player.profile.read(xpKey), getExperienceRequired(player))
|
val required = player.profile.read(xpRequiredKey)
|
||||||
|
|
||||||
|
return if (required <= 0) {
|
||||||
|
val newRequired = generateExperienceRequired(player)
|
||||||
|
|
||||||
|
if (newRequired <= 0) {
|
||||||
|
throw IllegalStateException("Invalid XP Required for task ${template.id} in quest ${quest.id}" +
|
||||||
|
"(Requirement was $newRequired, which is less than or equal to 0)")
|
||||||
|
}
|
||||||
|
|
||||||
|
player.profile.write(xpRequiredKey, newRequired)
|
||||||
|
newRequired
|
||||||
|
} else {
|
||||||
|
required
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getExperience(player: OfflinePlayer): Double {
|
||||||
|
return player.profile.read(xpKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -124,10 +148,11 @@ class Task(
|
|||||||
val requiredXp = getExperienceRequired(player)
|
val requiredXp = getExperienceRequired(player)
|
||||||
val newXp = player.profile.read(xpKey) + amount
|
val newXp = player.profile.read(xpKey) + amount
|
||||||
|
|
||||||
player.profile.write(xpKey, newXp)
|
player.profile.write(xpKey, min(newXp, requiredXp))
|
||||||
|
|
||||||
if (newXp >= requiredXp) {
|
if (newXp >= requiredXp) {
|
||||||
player.profile.write(hasCompletedKey, true)
|
player.profile.write(hasCompletedKey, true)
|
||||||
|
template.onComplete?.trigger(player)
|
||||||
|
|
||||||
Bukkit.getPluginManager().callEvent(PlayerTaskCompleteEvent(player, template, quest))
|
Bukkit.getPluginManager().callEvent(PlayerTaskCompleteEvent(player, template, quest))
|
||||||
|
|
||||||
@@ -145,15 +170,13 @@ class Task(
|
|||||||
.formatEco(player)
|
.formatEco(player)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getCompletedDescription(player: Player): List<String> {
|
fun getCompletedDescription(player: Player): 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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,10 @@ package com.willfp.ecoquests.tasks
|
|||||||
import com.willfp.eco.core.EcoPlugin
|
import com.willfp.eco.core.EcoPlugin
|
||||||
import com.willfp.eco.core.config.interfaces.Config
|
import com.willfp.eco.core.config.interfaces.Config
|
||||||
import com.willfp.eco.core.registry.KRegistrable
|
import com.willfp.eco.core.registry.KRegistrable
|
||||||
|
import com.willfp.ecoquests.quests.Quest
|
||||||
import com.willfp.libreforge.ViolationContext
|
import com.willfp.libreforge.ViolationContext
|
||||||
import com.willfp.libreforge.counters.Counters
|
import com.willfp.libreforge.counters.Counters
|
||||||
|
import com.willfp.libreforge.effects.Effects
|
||||||
|
|
||||||
class TaskTemplate(
|
class TaskTemplate(
|
||||||
private val plugin: EcoPlugin,
|
private val plugin: EcoPlugin,
|
||||||
@@ -14,4 +16,12 @@ class TaskTemplate(
|
|||||||
val xpGainMethods = config.getSubsections("xp-gain-methods").mapNotNull {
|
val xpGainMethods = config.getSubsections("xp-gain-methods").mapNotNull {
|
||||||
Counters.compile(it, ViolationContext(plugin, "task $id tasks"))
|
Counters.compile(it, ViolationContext(plugin, "task $id tasks"))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val onComplete = Effects.compileChain(
|
||||||
|
config.getSubsections("on-complete"),
|
||||||
|
ViolationContext(plugin, "task $id on-complete")
|
||||||
|
)
|
||||||
|
|
||||||
|
fun create(quest: Quest, xpExpr: String) =
|
||||||
|
Task(plugin, this, quest, xpExpr)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
package com.willfp.ecoquests.util
|
||||||
|
|
||||||
|
fun <T> Collection<T>.randomlyPick(amount: Int): List<T> {
|
||||||
|
val list = this.toMutableList()
|
||||||
|
val picked = mutableListOf<T>()
|
||||||
|
|
||||||
|
repeat(amount) {
|
||||||
|
val index = (0 until list.size).random()
|
||||||
|
picked.add(list[index])
|
||||||
|
list.removeAt(index)
|
||||||
|
}
|
||||||
|
|
||||||
|
return picked
|
||||||
|
}
|
||||||
@@ -3,7 +3,12 @@
|
|||||||
# by Auxilor
|
# by Auxilor
|
||||||
#
|
#
|
||||||
|
|
||||||
scan-interval: 20 # How often to scan for quest starting / completion (in ticks)
|
# Even if eco is set up to use a database, you can
|
||||||
|
# force EcoQuests to save to local storage to disable
|
||||||
|
# cross-server sync.
|
||||||
|
use-local-storage: false
|
||||||
|
|
||||||
|
scan-interval: 20 # How often to scan for quests auto-starting (in ticks)
|
||||||
|
|
||||||
gui:
|
gui:
|
||||||
title: "Quest Book"
|
title: "Quest Book"
|
||||||
@@ -34,10 +39,13 @@ gui:
|
|||||||
|
|
||||||
quest-info:
|
quest-info:
|
||||||
item: writable_book
|
item: writable_book
|
||||||
name: "&aQuest Book"
|
name: "&fQuest Book"
|
||||||
lore:
|
lore:
|
||||||
- "&eClick to view your"
|
- ""
|
||||||
- "&eprevious quests!"
|
- "&7Quests Completed: &f%ecoquests_quests_completed%"
|
||||||
|
- "&7Quests Active: &f%ecoquests_quests_active%"
|
||||||
|
- ""
|
||||||
|
- "&eClick to view past quests!"
|
||||||
|
|
||||||
location:
|
location:
|
||||||
row: 1
|
row: 1
|
||||||
@@ -130,12 +138,15 @@ completed-gui:
|
|||||||
custom-slots: [ ]
|
custom-slots: [ ]
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
line-wrap: 32
|
# The line to show when a task is completed
|
||||||
completed: "&a&l✓ &r&f%description%"
|
completed: "&a&l✔ &r&f%description%"
|
||||||
not-completed: "&c&l✘ &r&f%description%"
|
# The line to show when a task is not completed
|
||||||
|
not-completed: "&c&l❌ &r&f%description%"
|
||||||
|
|
||||||
quests:
|
quests:
|
||||||
icon:
|
icon:
|
||||||
|
name: "&e%quest%" # The name of the icon
|
||||||
|
line-wrap: 32 # Lore line-wrapping
|
||||||
lore:
|
lore:
|
||||||
- "%description%"
|
- "%description%"
|
||||||
- ""
|
- ""
|
||||||
@@ -144,6 +155,8 @@ quests:
|
|||||||
- ""
|
- ""
|
||||||
- "&fRewards:"
|
- "&fRewards:"
|
||||||
- " %rewards%"
|
- " %rewards%"
|
||||||
|
- ""
|
||||||
|
- "%time_since%"
|
||||||
|
|
||||||
complete:
|
complete:
|
||||||
message:
|
message:
|
||||||
|
|||||||
@@ -4,6 +4,6 @@ environment:
|
|||||||
|
|
||||||
options:
|
options:
|
||||||
color: "&#eacda3"
|
color: "&#eacda3"
|
||||||
resource-id: 0
|
resource-id: 4600
|
||||||
bstats-id: 0
|
bstats-id: 19455
|
||||||
uses-reflective-reload: false
|
uses-reflective-reload: false
|
||||||
@@ -10,4 +10,11 @@ messages:
|
|||||||
already-started: "&cThe player has already started this quest!"
|
already-started: "&cThe player has already started this quest!"
|
||||||
|
|
||||||
started-quest: "&fStarted the &a%quest% &fquest for &a%player%&f!"
|
started-quest: "&fStarted the &a%quest% &fquest for &a%player%&f!"
|
||||||
reset-quest: "&fReset the &a%quest% &fquest for &a%player%&f!"
|
reset-quest-for-player: "&fReset the &a%quest% &fquest for &a%player%&f!"
|
||||||
|
reset-quest: "&fReset the &a%quest% &fquest!"
|
||||||
|
quest-not-resettable: "&cThis quest is not resettable!"
|
||||||
|
|
||||||
|
time-since:
|
||||||
|
never: "&cNot started yet!"
|
||||||
|
started: "&7Started %time% ago"
|
||||||
|
completed: "&7Completed %time% ago"
|
||||||
|
|||||||
@@ -15,3 +15,38 @@ dependencies:
|
|||||||
load-after:
|
load-after:
|
||||||
- name: eco
|
- name: eco
|
||||||
bootstrap: false
|
bootstrap: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
ecoquests.*:
|
||||||
|
description: All ecoquests permissions
|
||||||
|
default: op
|
||||||
|
children:
|
||||||
|
ecoquests.command.*: true
|
||||||
|
ecoquests.command.*:
|
||||||
|
description: All commands
|
||||||
|
default: op
|
||||||
|
children:
|
||||||
|
ecoquests.command.reload: true
|
||||||
|
ecoquests.command.quests: true
|
||||||
|
ecoquests.command.start: true
|
||||||
|
ecoquests.command.reset: true
|
||||||
|
ecoquests.command.resetplayer: true
|
||||||
|
|
||||||
|
ecoquests.command.reload:
|
||||||
|
description: Allows reloading the config
|
||||||
|
default: op
|
||||||
|
ecoquests.command.ecoquests:
|
||||||
|
description: Allows the use of /ecoquests.
|
||||||
|
default: true
|
||||||
|
ecoquests.command.quests:
|
||||||
|
description: Allows the use of /quests.
|
||||||
|
default: true
|
||||||
|
ecoquests.command.start:
|
||||||
|
description: Allows using /ecoquests start.
|
||||||
|
default: op
|
||||||
|
ecoquests.command.reset:
|
||||||
|
description: Allows using /ecoquests reset.
|
||||||
|
default: op
|
||||||
|
ecoquests.command.resetplayer:
|
||||||
|
description: Allows using /ecoquests resetplayer.
|
||||||
|
default: op
|
||||||
|
|||||||
@@ -32,8 +32,9 @@ 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.start: true
|
||||||
ecoquests.command.reset: op
|
ecoquests.command.reset: true
|
||||||
|
ecoquests.command.resetplayer: true
|
||||||
|
|
||||||
ecoquests.command.reload:
|
ecoquests.command.reload:
|
||||||
description: Allows reloading the config
|
description: Allows reloading the config
|
||||||
@@ -49,4 +50,7 @@ permissions:
|
|||||||
default: op
|
default: op
|
||||||
ecoquests.command.reset:
|
ecoquests.command.reset:
|
||||||
description: Allows using /ecoquests reset.
|
description: Allows using /ecoquests reset.
|
||||||
|
default: op
|
||||||
|
ecoquests.command.resetplayer:
|
||||||
|
description: Allows using /ecoquests resetplayer.
|
||||||
default: op
|
default: op
|
||||||
@@ -1,26 +1,36 @@
|
|||||||
name: "Resettable Quest"
|
# The ID of the quest is the name of the .yml file,
|
||||||
|
# for example traveller.yml has the ID of traveller
|
||||||
|
# You can place quests anywhere in this folder,
|
||||||
|
# including in subfolders if you want to organize your quest configs
|
||||||
|
# _example.yml is not loaded.
|
||||||
|
|
||||||
description: "&fThis quest will reset in &a%time_until_reset%"
|
name: "Traveller"
|
||||||
|
|
||||||
|
description: "&7Stretch your legs! Walk around Lumoria and find new places to explore."
|
||||||
|
|
||||||
# Options for the /quests GUI
|
# Options for the /quests GUI
|
||||||
gui:
|
gui:
|
||||||
enabled: true # If the quest should be shown in the GUI
|
enabled: true # If the quest should be shown in the GUI
|
||||||
always: false # If the quest should always be in the GUI, even if it's not started
|
always: false # If the quest should always be in the GUI, even if it's not started
|
||||||
# The item to show in the GUI, read https://plugins.auxilor.io/all-plugins/the-item-lookup-system
|
# The item to show in the GUI, read https://plugins.auxilor.io/all-plugins/the-item-lookup-system
|
||||||
item: paper name:"&eExample Quest"
|
item: paper
|
||||||
|
|
||||||
# How many minutes between this quest being reset (set to -1 to disable)
|
# How many minutes between this quest being reset (set to -1 to disable)
|
||||||
# 1 Day: 1440
|
# 1 Day: 1440
|
||||||
# 1 Week: 10080
|
# 1 Week: 10080
|
||||||
# 1 Month: 43200
|
# 1 Month: 43200
|
||||||
reset-time: 10
|
reset-time: -1
|
||||||
|
|
||||||
# A list of tasks and their XP requirements to complete this quest.
|
# A list of tasks and their XP requirements to complete this quest.
|
||||||
# If the task is one action, set XP to 1.
|
# If the task is one action, set XP to 1.
|
||||||
# XP requirements can use placeholder math, for example %ecoskills_combat% * 100
|
# XP requirements can use placeholder math, for example %ecoskills_combat% * 100
|
||||||
tasks:
|
tasks:
|
||||||
- task: break_stone
|
- task: move
|
||||||
xp: 100
|
xp: 1000
|
||||||
|
|
||||||
|
# (For resettable tasks) The amount of tasks to select from the list above.
|
||||||
|
# Set to -1 to use all tasks.
|
||||||
|
task-amount: -1
|
||||||
|
|
||||||
# The messages for the %rewards% placeholder in icons, messages, etc.
|
# The messages for the %rewards% placeholder in icons, messages, etc.
|
||||||
reward-messages:
|
reward-messages:
|
||||||
@@ -40,4 +50,9 @@ start-effects: [ ]
|
|||||||
# A list of conditions required to start the quest.
|
# A list of conditions required to start the quest.
|
||||||
# The quest will be automatically started when these conditions are met.
|
# The quest will be automatically started when these conditions are met.
|
||||||
# Read https://plugins.auxilor.io/conditions/configuring-a-condition
|
# Read https://plugins.auxilor.io/conditions/configuring-a-condition
|
||||||
|
# If gui.always is true, then not-met-lines will show up on the GUI icon!
|
||||||
start-conditions: [ ]
|
start-conditions: [ ]
|
||||||
|
|
||||||
|
# If the quest should auto start when all conditions are met
|
||||||
|
# If this is set to false, the quest can only be started with /ecoquests start
|
||||||
|
auto-start: true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
name: "Resettable Quest"
|
name: "Daily Quest I"
|
||||||
|
|
||||||
description: "&fThis quest will reset in &a%time_until_reset%"
|
description: "&fThis quest will reset in &a%time_until_reset%"
|
||||||
|
|
||||||
@@ -7,13 +7,13 @@ gui:
|
|||||||
enabled: true # If the quest should be shown in the GUI
|
enabled: true # If the quest should be shown in the GUI
|
||||||
always: false # If the quest should always be in the GUI, even if it's not started
|
always: false # If the quest should always be in the GUI, even if it's not started
|
||||||
# The item to show in the GUI, read https://plugins.auxilor.io/all-plugins/the-item-lookup-system
|
# The item to show in the GUI, read https://plugins.auxilor.io/all-plugins/the-item-lookup-system
|
||||||
item: paper name:"&eExample Quest"
|
item: paper
|
||||||
|
|
||||||
# How many minutes between this quest being reset (set to -1 to disable)
|
# How many minutes between this quest being reset (set to -1 to disable)
|
||||||
# 1 Day: 1440
|
# 1 Day: 1440
|
||||||
# 1 Week: 10080
|
# 1 Week: 10080
|
||||||
# 1 Month: 43200
|
# 1 Month: 43200
|
||||||
reset-time: 10
|
reset-time: 1440
|
||||||
|
|
||||||
# A list of tasks and their XP requirements to complete this quest.
|
# A list of tasks and their XP requirements to complete this quest.
|
||||||
# If the task is one action, set XP to 1.
|
# If the task is one action, set XP to 1.
|
||||||
@@ -22,6 +22,10 @@ tasks:
|
|||||||
- task: break_stone
|
- task: break_stone
|
||||||
xp: 100
|
xp: 100
|
||||||
|
|
||||||
|
# (For resettable tasks) The amount of tasks to select from the list above.
|
||||||
|
# Set to -1 to use all tasks.
|
||||||
|
task-amount: 1
|
||||||
|
|
||||||
# The messages for the %rewards% placeholder in icons, messages, etc.
|
# The messages for the %rewards% placeholder in icons, messages, etc.
|
||||||
reward-messages:
|
reward-messages:
|
||||||
- " &8» &r&f+2 %ecoskills_defense_name%"
|
- " &8» &r&f+2 %ecoskills_defense_name%"
|
||||||
@@ -40,4 +44,7 @@ start-effects: [ ]
|
|||||||
# A list of conditions required to start the quest.
|
# A list of conditions required to start the quest.
|
||||||
# The quest will be automatically started when these conditions are met.
|
# The quest will be automatically started when these conditions are met.
|
||||||
# Read https://plugins.auxilor.io/conditions/configuring-a-condition
|
# Read https://plugins.auxilor.io/conditions/configuring-a-condition
|
||||||
|
# If gui.always is true, then not-met-lines will show up on the GUI icon!
|
||||||
start-conditions: [ ]
|
start-conditions: [ ]
|
||||||
|
|
||||||
|
auto-start: true
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
# The ID of the task is the name of the .yml file,
|
# The ID of the task is the name of the .yml file,
|
||||||
# for example break_100_stone.yml has the ID of break_100_stone
|
# for example break_100_stone.yml has the ID of break_100_stone
|
||||||
# You can place tasks anywhere in this folder,
|
# You can place tasks anywhere in this folder,
|
||||||
# including in subfolders if you want to organize your quest task
|
# including in subfolders if you want to organize your task configs
|
||||||
# _example.yml is not loaded.
|
# _example.yml is not loaded.
|
||||||
|
|
||||||
# If multiple quests have the same task, gaining task XP for one quest
|
# If multiple quests have the same task, gaining task XP for one quest
|
||||||
@@ -21,3 +21,10 @@ xp-gain-methods:
|
|||||||
filters:
|
filters:
|
||||||
blocks:
|
blocks:
|
||||||
- stone
|
- stone
|
||||||
|
|
||||||
|
# An optional list of effects to run when a player completes the task
|
||||||
|
# Read here: https://plugins.auxilor.io/effects/configuring-an-effect
|
||||||
|
on-complete:
|
||||||
|
- id: send_message
|
||||||
|
args:
|
||||||
|
message: "Task Completed!"
|
||||||
|
|||||||
4
eco-core/core-plugin/src/main/resources/tasks/move.yml
Normal file
4
eco-core/core-plugin/src/main/resources/tasks/move.yml
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
description: "&fMove distance (&a%xp%&8/&a%required-xp%&f)"
|
||||||
|
|
||||||
|
xp-gain-methods:
|
||||||
|
- trigger: move
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
#libreforge-updater
|
#libreforge-updater
|
||||||
#Wed Aug 09 14:37:41 BST 2023
|
#Fri Nov 10 13:59:29 GMT 2023
|
||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
libreforge-version=4.27.0
|
libreforge-version=4.41.0
|
||||||
version=0.3.0
|
version=1.13.0
|
||||||
|
|||||||
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0.1-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
|||||||
Reference in New Issue
Block a user