diff --git a/build.gradle.kts b/build.gradle.kts index 11c0323..f901bfe 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -42,7 +42,7 @@ dependencies { // MC Libraries implementation("de.miraculixx:mc-commons:1.0.1") implementation("de.miraculixx:kpaper-light:1.2.1") - implementation("dev.jorel:commandapi-bukkit-shade-mojang-mapped:9.4.0") + library("dev.jorel:commandapi-bukkit-shade-mojang-mapped:9.4.0") library("dev.jorel:commandapi-bukkit-kotlin:9.4.0") // Internal APIs @@ -68,10 +68,9 @@ tasks { shadowJar { dependencies { include { - it.moduleGroup == "de.miraculixx" || it.moduleGroup == "dev.jorel" + it.moduleGroup == "de.miraculixx" } } - relocate("dev.jorel.commandapi", "de.miraculixx.mchallenge.commandapi") } } @@ -92,9 +91,6 @@ bukkit { load = BukkitPluginDescription.PluginLoadOrder.STARTUP depend = listOf() softDepend = listOf("MTimer", "MWeb") - commands.create("mobhunt") - commands.create("itemhunt") - commands.create("deathhunt") libraries = listOf( "io.ktor:ktor-client-core-jvm:2.3.7", "io.ktor:ktor-client-cio-jvm:2.3.7" diff --git a/data/challenges.json b/data/challenges.json index 5493856..9f65ee7 100644 --- a/data/challenges.json +++ b/data/challenges.json @@ -1,4 +1,14 @@ [ + { + "key": "DEATH_HUNT", + "version": 105, + "block": "totem_of_undying", + "tags": [ + "FUN", + "FORCE" + ], + "new": true + }, { "key": "RHYTHM_CRAFT", "version": -1, @@ -32,8 +42,7 @@ "wrongDamage", "randomOrder", "visual" - ], - "new": true + ] }, { "key": "WORLD_DECAY", @@ -45,8 +54,7 @@ "settings": [ "delay", "steps" - ], - "new": true + ] }, { "key": "CHUNK_SYNC", @@ -57,8 +65,7 @@ ], "settings": [ "env" - ], - "new": true + ] }, { "key": "LOW_VISION", diff --git a/data/language/mchallenge/en.yml b/data/language/mchallenge/en.yml index f3d7b7a..5726441 100644 --- a/data/language/mchallenge/en.yml +++ b/data/language/mchallenge/en.yml @@ -70,7 +70,7 @@ command: notLoggedIn: "Connect your MUtils Account to unlock Premium Features" updateRule: "The rule was updated to " noRule: "Please select a valid rule to change!" - registered: "Added command /. Use to interact with the Challenge" + registered: "Challenge Command: /" #-----------------------------------------# @@ -95,12 +95,15 @@ event: noDoubleKill: " killed the same mob twice in a row!" hitOrder: " was not allowed do damage a mob" crushedAnvils: " was hit by an anvil!" - mobHunt: + mob_hunt: collect: " found !" success: "Congratulations! You found all mobs" - itemHunt: + item_hunt: collect: " collected !" success: "Congratulations! You found all items" + death_hunt: + collect: " died to !" + success: "Congratulations! You died to all deaths" itemDecay: time: "Decay in" paused: "Paused display (selected)" @@ -406,6 +409,9 @@ items: HP_DRAIN: n: "Health Drainer" l: "Every few minutes your max health will be
reduced by a given percentage.
Better be quick!" + DEATH_HUNT: + n: "Death Hunt" + l: "Die to all given deaths in a specific order
to finish!
Use /deathhunt to modify" chS: FLY: power: diff --git a/gradle.properties b/gradle.properties index 06f4d79..346f16f 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,7 +1,7 @@ kotlin.code.style=official # Project Settings - set name in settings.gradle.kts -version=115 +version=116 group=de.miraculixx name=MChallenge description=MUtils Challenges - Play various Challenges that can modify the game slightly to completely against or in coop with your friends! diff --git a/src/main/kotlin/de/miraculixx/mchallenge/MChallenge.kt b/src/main/kotlin/de/miraculixx/mchallenge/MChallenge.kt index c85673b..b81c50a 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/MChallenge.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/MChallenge.kt @@ -94,6 +94,7 @@ class MChallenge : KPaper() { ConfigManager.addConfigurable(BackpackCommand()) // Load configuration + prefix = cmp("MChallenge", cHighlight) + _prefixSeparator ConfigManager.addConfigurable(ChallengeManager) val settings = ConfigManager.settings debug = settings.debug @@ -120,7 +121,7 @@ class MChallenge : KPaper() { Spectator.loadData() // Connect Bridge - bridgeAPI = MUtilsBridge(MUtilsPlatform.PAPER, MUtilsModule.CHALLENGES, server.version, server.port, debug) + bridgeAPI = MUtilsBridge(MUtilsPlatform.PAPER, MUtilsModule.CHALLENGES, server.minecraftVersion, server.port, debug) val version = bridgeAPI.versionCheck(description.version.toIntOrNull() ?: 0, File("plugins/update")) //bridgeAPI.modrinthUpdate(File("plugins/update")) // TODO Prompt with click to update diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/ChallengeCommand.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/CommandChallenge.kt similarity index 93% rename from src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/ChallengeCommand.kt rename to src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/CommandChallenge.kt index a2afb41..755f961 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/ChallengeCommand.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/CommandChallenge.kt @@ -4,7 +4,7 @@ import de.miraculixx.mchallenge.utils.Command import de.miraculixx.mchallenge.utils.bc import de.miraculixx.mcommons.text.prefix -interface ChallengeCommand { +interface CommandChallenge { val command: Command fun registerCommand() { diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/HuntChallenge.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/HuntChallenge.kt new file mode 100644 index 0000000..a258b45 --- /dev/null +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/challenges/interfaces/HuntChallenge.kt @@ -0,0 +1,120 @@ +package de.miraculixx.mchallenge.modules.challenges.interfaces + +import de.miraculixx.kpaper.event.listen +import de.miraculixx.kpaper.event.register +import de.miraculixx.kpaper.event.unregister +import de.miraculixx.kpaper.extensions.broadcast +import de.miraculixx.kpaper.extensions.onlinePlayers +import de.miraculixx.mchallenge.MChallenge +import de.miraculixx.mchallenge.modules.ChallengeManager +import de.miraculixx.mchallenge.utils.Command +import de.miraculixx.mchallenge.utils.command +import de.miraculixx.mchallenge.utils.config.loadConfig +import de.miraculixx.mchallenge.utils.config.saveConfig +import de.miraculixx.mchallenge.utils.serializer.Serializer +import de.miraculixx.mcommons.serializer.miniMessage +import de.miraculixx.mcommons.text.cmp +import de.miraculixx.mcommons.text.prefix +import dev.jorel.commandapi.kotlindsl.anyExecutor +import dev.jorel.commandapi.kotlindsl.literalArgument +import kotlinx.serialization.Serializable +import net.kyori.adventure.audience.Audience +import net.kyori.adventure.bossbar.BossBar +import net.kyori.adventure.key.Key +import net.kyori.adventure.sound.Sound +import org.bukkit.event.player.PlayerJoinEvent +import java.io.File + +abstract class HuntChallenge(name: String, val key: String) : CommandChallenge { + abstract val remainingEntries: MutableList + abstract val allEntries: List + abstract val typeName: String + abstract var currentTarget: T? + abstract val maxEntries: Int + abstract val serializer: Serializer + + private val dataFile = File("${MChallenge.configFolder.path}/data/$key.json") + private val bar = BossBar.bossBar(cmp("Waiting for server..."), 0f, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS) + + override val command: Command = command(name) { + literalArgument("skip") { + anyExecutor { sender, _ -> + nextEntry(sender.name, sender) + } + } + literalArgument("reset") { + anyExecutor { _, _ -> + remainingEntries.clear() + remainingEntries.addAll(allEntries) + calcBar() + } + } + } + + abstract fun getTranslationKey(): String? + + fun nextEntry(playerName: String, audience: Audience) { + broadcast(prefix, "event.$key.collect", listOf(playerName, getTranslationKey()?.let { "" } ?: "")) + audience.playSound(Sound.sound(Key.key("entity.chicken.egg"), Sound.Source.MASTER, 1f, 1.2f)) + currentTarget = if (remainingEntries.isEmpty()) { + broadcast(prefix, "event.$key.success") + ChallengeManager.stopChallenges() + null + } else remainingEntries.random() + remainingEntries.remove(currentTarget) + calcBar() + } + + private fun calcBar() { + val collectedAmount = maxEntries - remainingEntries.size + val target = getTranslationKey()?.let { "" } ?: "Finished" + bar.name(miniMessage.deserialize("$typeName: $target ($collectedAmount/$maxEntries)")) + } + + + // + // Common Events + // + private val onJoin = listen { + it.player.showBossBar(bar) + } + + + // + // Challenge Lifecycle + // + fun startHunt() { + registerCommand() + val preData = dataFile.loadConfig(HuntData()) + val preTarget = preData.currentTarget + currentTarget = if (preTarget == null) { + remainingEntries.addAll(allEntries) + remainingEntries.random() + } else { + remainingEntries.addAll(preData.remainingEntries.map { serializer.toObject(it) }) + serializer.toObject(preTarget) + } + + remainingEntries.remove(currentTarget) + calcBar() + onlinePlayers.forEach { it.showBossBar(bar) } + onJoin.register() + } + + fun stopHunt() { + unregisterCommand() + dataFile.saveConfig(HuntData(currentTarget?.let { serializer.toString(it) }, remainingEntries.map { serializer.toString(it) })) + onlinePlayers.forEach { it.hideBossBar(bar) } + onJoin.unregister() + } + + + // + // Data Holder + // + @Serializable + data class HuntData( + val currentTarget: String? = null, + val remainingEntries: List = emptyList() + ) +} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHunt.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHunt.kt index 2137308..19114de 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHunt.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHunt.kt @@ -8,50 +8,29 @@ import de.miraculixx.kpaper.event.register import de.miraculixx.kpaper.event.unregister import de.miraculixx.kpaper.extensions.broadcast import de.miraculixx.kpaper.extensions.onlinePlayers -import de.miraculixx.kpaper.items.getLivingMobs -import de.miraculixx.mchallenge.MChallenge -import de.miraculixx.mchallenge.PluginManager -import de.miraculixx.mchallenge.commands.ModuleCommand -import de.miraculixx.mchallenge.modules.ChallengeManager -import de.miraculixx.mchallenge.modules.mods.force.huntMob.HuntObject -import de.miraculixx.mchallenge.utils.config.loadConfig -import de.miraculixx.mchallenge.utils.config.saveConfig -import de.miraculixx.mcommons.serializer.miniMessage -import de.miraculixx.mcommons.text.cMark -import de.miraculixx.mcommons.text.cmp -import de.miraculixx.mcommons.text.prefix +import de.miraculixx.mchallenge.modules.challenges.interfaces.HuntChallenge +import de.miraculixx.mchallenge.utils.serializer.Serializer +import de.miraculixx.mcommons.extensions.enumOf +import de.miraculixx.mcommons.text.cHighlight import io.papermc.paper.event.entity.TameableDeathMessageEvent -import kotlinx.serialization.Serializable import net.kyori.adventure.audience.Audience -import net.kyori.adventure.bossbar.BossBar -import net.kyori.adventure.key.Key -import net.kyori.adventure.sound.Sound import net.kyori.adventure.text.TranslatableComponent -import net.minecraft.util.GsonHelper import org.bukkit.EntityEffect -import org.bukkit.Material -import org.bukkit.Statistic import org.bukkit.entity.EntityType -import org.bukkit.entity.LivingEntity -import org.bukkit.entity.Player -import org.bukkit.entity.Projectile -import org.bukkit.event.entity.EntityDamageByEntityEvent -import org.bukkit.event.entity.EntityDeathEvent import org.bukkit.event.entity.PlayerDeathEvent -import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.potion.PotionEffect import org.bukkit.potion.PotionEffectType -import org.json.simple.JSONObject -import java.io.File -class DeathHunt : Challenge, HuntObject { - private val dataFile = File("${MChallenge.configFolder.path}/data/death_hunt.json") - val allDeathKeys: List = extractValidKeys() - private var currentTarget: String? = null - override val maxEntries = allDeathKeys.size - override val remainingEntries = mutableListOf() - override val blacklist = mutableListOf() - override val bar = BossBar.bossBar(cmp("Waiting for server..."), 0f, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS) +class DeathHunt : Challenge, HuntChallenge("deathhunt", "death_hunt") { + override val typeName = "Death" + override val allEntries = extractValidKeys() + override val maxEntries = allEntries.size + override val remainingEntries: MutableList = mutableListOf() + override var currentTarget: String? = null + override val serializer: Serializer = object: Serializer { + override fun toString(data: String) = data + override fun toObject(data: String) = data + } override fun register() { onDeath.register() @@ -90,39 +69,16 @@ class DeathHunt : Challenge, HuntObject { broadcast(message) } - override fun start(): Boolean { - val preData = dataFile.loadConfig(DeathHuntData()) - val preTarget = preData.target - currentTarget = if (preTarget == null) { - remainingEntries.addAll(allDeathKeys) - remainingEntries.random() - } else { - remainingEntries.addAll(preData.remainingDeaths) - preTarget - } - remainingEntries.remove(currentTarget) - calcBar(getCurrentEntryName()) - onlinePlayers.forEach { it.showBossBar(bar) } - val cmdClass = DeathHuntCommand(this) - val cmdInstance = PluginManager.getCommand("deathhunt") ?: return false - cmdInstance.setExecutor(cmdClass) - cmdInstance.tabCompleter = cmdClass - onJoin.register() + startHunt() return true } override fun stop() { - dataFile.saveConfig(DeathHuntData(currentTarget, remainingEntries)) - onlinePlayers.forEach { it.hideBossBar(bar) } - ModuleCommand("mobhunt") - onJoin.unregister() + stopHunt() } - private val onJoin = listen(register = false) { - bar.addViewer(it.player) - it.player.getStatistic(Statistic.ANIMALS_BRED) - } + override fun getTranslationKey() = currentTarget?.let { "Player/Pet':'Something'>" } private fun extractValidKeys(): List { val rawJson = javaClass.getResourceAsStream("/data/deathKeys.json")?.readBytes()?.decodeToString() ?: "{}" @@ -138,34 +94,4 @@ class DeathHunt : Challenge, HuntObject { "death.attack.genericKill" ) } - - - - override fun nextEntry(playerName: String, audience: Audience) { - broadcast(prefix, "event.deathHunt.collect", listOf(playerName, currentTarget?.let { "" } ?: "")) - audience.playSound(Sound.sound(Key.key("entity.chicken.egg"), Sound.Source.MASTER, 1f, 1.2f)) - val size = remainingEntries.size - currentTarget = if (size == 0) { - broadcast(prefix,"event.deathHunt.success") - ChallengeManager.stopChallenges() - null - } else remainingEntries.random() - remainingEntries.remove(currentTarget) - calcBar(getCurrentEntryName()) - } - - override fun getCurrentEntryName() = currentTarget - - override fun calcBar(entryName: String?) { - val collectedAmount = maxEntries - remainingEntries.size - val target = entryName?.let { "':'${cMark}Entity'>" } ?: "Finished" - bar.name(miniMessage.deserialize("$target ($collectedAmount/$maxEntries)")) - } - - @Serializable - private data class DeathHuntData( - val target: String? = null, - val remainingDeaths: List = emptyList(), - val blacklist: List = emptyList() - ) } \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHuntCommand.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHuntCommand.kt deleted file mode 100644 index 0731fc6..0000000 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntDeath/DeathHuntCommand.kt +++ /dev/null @@ -1,21 +0,0 @@ -package de.miraculixx.mchallenge.modules.mods.force.huntDeath - -import de.miraculixx.mchallenge.modules.mods.force.huntMob.HuntCommand -import org.bukkit.command.Command -import org.bukkit.command.CommandSender -import org.bukkit.command.TabExecutor - -class DeathHuntCommand(private val data: DeathHunt) : TabExecutor, HuntCommand { - override val typeList = data.allDeathKeys - override val typeNameList = typeList - override fun onTabComplete(sender: CommandSender, command: Command, label: String, args: Array?): MutableList { - return getTabComplete(args, data.blacklist) - } - - override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { - data.handleCommand(sender, sender.name, args) - return true - } - - override fun getType(input: String?) = input -} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHunt.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHunt.kt index d6400d5..54cef7a 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHunt.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHunt.kt @@ -4,37 +4,25 @@ import de.miraculixx.challenge.api.modules.challenges.Challenge import de.miraculixx.kpaper.event.listen import de.miraculixx.kpaper.event.register import de.miraculixx.kpaper.event.unregister -import de.miraculixx.kpaper.extensions.broadcast -import de.miraculixx.kpaper.extensions.onlinePlayers import de.miraculixx.kpaper.items.getMaterials -import de.miraculixx.mchallenge.MChallenge -import de.miraculixx.mchallenge.PluginManager -import de.miraculixx.mchallenge.commands.ModuleCommand -import de.miraculixx.mchallenge.modules.ChallengeManager -import de.miraculixx.mchallenge.modules.mods.force.huntMob.HuntObject -import de.miraculixx.mchallenge.utils.config.loadConfig -import de.miraculixx.mchallenge.utils.config.saveConfig -import de.miraculixx.mcommons.text.cmp -import de.miraculixx.mcommons.text.prefix -import kotlinx.serialization.Serializable -import net.kyori.adventure.audience.Audience -import net.kyori.adventure.bossbar.BossBar -import net.kyori.adventure.key.Key -import net.kyori.adventure.sound.Sound +import de.miraculixx.mchallenge.modules.challenges.interfaces.HuntChallenge +import de.miraculixx.mchallenge.utils.serializer.Serializer +import de.miraculixx.mcommons.extensions.enumOf import org.bukkit.Material import org.bukkit.entity.Player import org.bukkit.event.entity.EntityPickupItemEvent import org.bukkit.event.inventory.InventoryCloseEvent -import org.bukkit.event.player.PlayerJoinEvent -import java.io.File -class ItemHunt : Challenge, HuntObject { - private val dataFile = File("${MChallenge.configFolder.path}/data/item_hunt.json") - private var currentItem: Material? = null - override val maxEntries = getMaterials(true).size +class ItemHunt : Challenge, HuntChallenge("itemhunt", "item_hunt") { + override val typeName = "Item" + override val allEntries = getMaterials(true) + override val maxEntries = allEntries.size override val remainingEntries = mutableListOf() - override val blacklist = mutableListOf() - override val bar = BossBar.bossBar(cmp("Waiting for server..."), 0f, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS) + override var currentTarget: Material? = null + override val serializer = object : Serializer { + override fun toString(data: Material) = data.name + override fun toObject(data: String) = enumOf(data) ?: Material.STONE + } override fun register() { onCollect.register() @@ -47,73 +35,29 @@ class ItemHunt : Challenge, HuntObject { } override fun start(): Boolean { - val content = dataFile.loadConfig(ItemHuntData()) - blacklist.addAll(content.blacklist) - if (content.remaining.isEmpty()) remainingEntries.addAll(getMaterials(true)) - else remainingEntries.addAll(content.remaining) - remainingEntries.removeAll(blacklist) - if (content.target != null) currentItem = content.target - else { - currentItem = remainingEntries.random() - remainingEntries.remove(currentItem) - } - onlinePlayers.forEach { it.showBossBar(bar) } - calcBar(getCurrentEntryName()) - val cmdClass = ItemHuntCommand(this) - val cmdInstance = PluginManager.getCommand("itemhunt") ?: return false - cmdInstance.setExecutor(cmdClass) - cmdInstance.tabCompleter = cmdClass - onJoin.register() + startHunt() return true } override fun stop() { - if (!dataFile.exists()) dataFile.parentFile.mkdirs() - dataFile.saveConfig(ItemHuntData(currentItem, remainingEntries)) - onlinePlayers.forEach { it.hideBossBar(bar) } - ModuleCommand("itemhunt") - onJoin.unregister() + stopHunt() } private val onCollect = listen(register = false) { val entity = it.entity if (entity !is Player) return@listen - if (currentItem == it.item.itemStack.type) collectItem(entity) + if (currentTarget == it.item.itemStack.type) collectItem(entity) } private val onInvClose = listen(register = false) { val player = it.player if (player !is Player) return@listen - it.inventory.forEach { item -> if (item?.type == currentItem) collectItem(player) } - } - - private val onJoin = listen(register = false) { - bar.addViewer(it.player) + it.inventory.forEach { item -> if (item?.type == currentTarget) collectItem(player) } } private fun collectItem(player: Player) { nextEntry(player.name, player) } - override fun nextEntry(playerName: String, audience: Audience) { - broadcast(prefix, "event.itemHunt.collect", listOf(playerName, "")) - audience.playSound(Sound.sound(Key.key("entity.chicken.egg"), Sound.Source.MASTER, 1f, 1.2f)) - val size = remainingEntries.size - currentItem = if (size == 0) { - broadcast(prefix, "event.itemHunt.success", listOf(maxEntries.toString())) - ChallengeManager.stopChallenges() - null - } else remainingEntries.random() - remainingEntries.remove(currentItem) - calcBar(getCurrentEntryName()) - } - - override fun getCurrentEntryName() = currentItem?.key.toString() - - @Serializable - private data class ItemHuntData( - val target: Material? = null, - val remaining: List = emptyList(), - val blacklist: List = emptyList() - ) + override fun getTranslationKey() = currentTarget?.translationKey()?.let { "" } } \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHuntCommand.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHuntCommand.kt deleted file mode 100644 index be14717..0000000 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntItems/ItemHuntCommand.kt +++ /dev/null @@ -1,24 +0,0 @@ -package de.miraculixx.mchallenge.modules.mods.force.huntItems - -import de.miraculixx.kpaper.items.getMaterials -import de.miraculixx.mchallenge.modules.mods.force.huntMob.HuntCommand -import de.miraculixx.mcommons.extensions.enumOf -import org.bukkit.Material -import org.bukkit.command.Command -import org.bukkit.command.CommandSender -import org.bukkit.command.TabExecutor - -class ItemHuntCommand(private val data: ItemHunt) : TabExecutor, HuntCommand { - override val typeList = getMaterials(true) - override val typeNameList = getMaterials(true).map { it.name } - override fun onTabComplete(sender: CommandSender, command: Command, label: String, args: Array?): MutableList { - return getTabComplete(args, data.blacklist.map { it.name }) - } - - override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { - data.handleCommand(sender, sender.name, args) - return true - } - - override fun getType(input: String?) = enumOf(input) -} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntCommand.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntCommand.kt deleted file mode 100644 index 56cd234..0000000 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntCommand.kt +++ /dev/null @@ -1,53 +0,0 @@ -package de.miraculixx.mchallenge.modules.mods.force.huntMob - -import de.miraculixx.mcommons.text.cError -import de.miraculixx.mcommons.text.cmp -import de.miraculixx.mcommons.text.plus -import de.miraculixx.mcommons.text.prefix -import net.kyori.adventure.audience.Audience - -interface HuntCommand { - val typeNameList: List - val typeList: List - fun getTabComplete(args: Array?, blacklist: List): MutableList { - return when (args?.size ?: 0) { - 0, 1 -> listOf("skip", "reset") - 2 -> if (args?.getOrNull(0) == "blacklist") { - listOf("add", "remove") - } else emptyList() - - 3 -> when (args?.getOrNull(1)) { - "add" -> typeNameList - "remove" -> blacklist - else -> emptyList() - } - - else -> emptyList() - }.filter { it.contains(args?.lastOrNull() ?: "") }.toMutableList() - } - - fun HuntObject.handleCommand(sender: Audience, senderName: String, args: Array?) { - when (args?.getOrNull(0)?.lowercase()) { - "skip" -> nextEntry(senderName, sender) - "reset" -> reset(typeList) - "blacklist" -> { - val arg3 = args.getOrNull(2) - val type = getType(arg3) - if (type == null) { - sender.sendMessage(prefix + cmp("Please enter a valid type!", cError)) - return - } - - when (args.getOrNull(1)?.lowercase()) { - "add" -> addBlacklist(type) - "remove" -> removeBlacklist(type) - else -> sender.sendMessage(prefix + cmp("Invalid command structure", cError)) - } - } - - else -> sender.sendMessage(prefix + cmp("Invalid command structure", cError)) - } - } - - fun getType(input: String?): T? -} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntObject.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntObject.kt deleted file mode 100644 index c54d252..0000000 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/HuntObject.kt +++ /dev/null @@ -1,40 +0,0 @@ -package de.miraculixx.mchallenge.modules.mods.force.huntMob - -import de.miraculixx.mcommons.serializer.miniMessage -import net.kyori.adventure.audience.Audience -import net.kyori.adventure.bossbar.BossBar - -interface HuntObject { - val bar: BossBar - val maxEntries: Int - val remainingEntries: MutableList - val blacklist: MutableList - - fun addBlacklist(entry: T) { - blacklist.add(entry) - remainingEntries.remove(entry) - calcBar(getCurrentEntryName()) - } - - fun removeBlacklist(entry: T) { - if (blacklist.remove(entry)) - remainingEntries.add(entry) - } - - fun reset(allEntries: List) { - remainingEntries.clear() - remainingEntries.addAll(allEntries) - remainingEntries.removeAll(blacklist) - calcBar(getCurrentEntryName()) - } - - fun getCurrentEntryName(): String? - - fun nextEntry(playerName: String, audience: Audience) - - fun calcBar(entryName: String?) { - val collectedAmount = maxEntries - remainingEntries.size - val target = entryName?.let { "" } ?: "Finished" - bar.name(miniMessage.deserialize("Item: $target ($collectedAmount/$maxEntries)")) - } -} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHunt.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHunt.kt index 1836803..eb073d9 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHunt.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHunt.kt @@ -4,78 +4,46 @@ import de.miraculixx.challenge.api.modules.challenges.Challenge import de.miraculixx.kpaper.event.listen import de.miraculixx.kpaper.event.register import de.miraculixx.kpaper.event.unregister -import de.miraculixx.kpaper.extensions.broadcast -import de.miraculixx.kpaper.extensions.onlinePlayers import de.miraculixx.kpaper.items.getLivingMobs -import de.miraculixx.mchallenge.MChallenge -import de.miraculixx.mchallenge.PluginManager -import de.miraculixx.mchallenge.commands.ModuleCommand -import de.miraculixx.mchallenge.modules.ChallengeManager -import de.miraculixx.mchallenge.utils.config.loadConfig -import de.miraculixx.mchallenge.utils.config.saveConfig -import de.miraculixx.mcommons.text.cmp -import de.miraculixx.mcommons.text.prefix -import kotlinx.serialization.Serializable -import net.kyori.adventure.audience.Audience -import net.kyori.adventure.bossbar.BossBar -import net.kyori.adventure.key.Key -import net.kyori.adventure.sound.Sound -import org.bukkit.Material +import de.miraculixx.mchallenge.modules.challenges.interfaces.HuntChallenge +import de.miraculixx.mchallenge.utils.serializer.Serializer +import de.miraculixx.mcommons.extensions.enumOf import org.bukkit.entity.EntityType import org.bukkit.entity.LivingEntity import org.bukkit.entity.Player import org.bukkit.entity.Projectile import org.bukkit.event.entity.EntityDamageByEntityEvent -import org.bukkit.event.player.PlayerJoinEvent -import java.io.File -class MobHunt : Challenge, HuntObject { - private val dataFile = File("${MChallenge.configFolder.path}/data/mob_hunt.json") - private var currentTarget: EntityType? = null - override val maxEntries = getLivingMobs(true).size +class MobHunt : Challenge, HuntChallenge("mobhunt", "mob_hunt") { + override val typeName = "Mob" + override var currentTarget: EntityType? = null + override val allEntries = getLivingMobs(true) + override val maxEntries = allEntries.size override val remainingEntries = mutableListOf() - override val blacklist = mutableListOf() - override val bar = BossBar.bossBar(cmp("Waiting for server..."), 0f, BossBar.Color.BLUE, BossBar.Overlay.PROGRESS) + override val serializer: Serializer = object: Serializer { + override fun toString(data: EntityType) = data.name + override fun toObject(data: String) = enumOf(data) ?: EntityType.ZOMBIE + } override fun register() { onKill.register() } override fun unregister() { + stop() onKill.unregister() } override fun start(): Boolean { - val preData = dataFile.loadConfig(MobHuntData()) - val preTarget = preData.target - currentTarget = if (preTarget == null) { - remainingEntries.addAll(getLivingMobs(true)) - remainingEntries.random() - } else { - remainingEntries.addAll(preData.remainingMobs) - preTarget - } - remainingEntries.remove(currentTarget) - calcBar(getCurrentEntryName()) - onlinePlayers.forEach { it.showBossBar(bar) } - val cmdClass = MobHuntCommand(this) - val cmdInstance = PluginManager.getCommand("mobhunt") ?: return false - cmdInstance.setExecutor(cmdClass) - cmdInstance.tabCompleter = cmdClass - onJoin.register() + startHunt() return true } override fun stop() { - dataFile.saveConfig(MobHuntData(currentTarget, remainingEntries)) - onlinePlayers.forEach { it.hideBossBar(bar) } - ModuleCommand("mobhunt") - onJoin.unregister() + stopHunt() } - private val onJoin = listen(register = false) { - bar.addViewer(it.player) - } + override fun getTranslationKey() = currentTarget?.translationKey()?.let { "" } private val onKill = listen(register = false) { val target = it.entity @@ -92,26 +60,4 @@ class MobHunt : Challenge, HuntObject { nextEntry(player.name, player) } - - override fun nextEntry(playerName: String, audience: Audience) { - broadcast(prefix, "event.mobHunt.collect", listOf(playerName, currentTarget?.let { "" } ?: "")) - audience.playSound(Sound.sound(Key.key("entity.chicken.egg"), Sound.Source.MASTER, 1f, 1.2f)) - val size = remainingEntries.size - currentTarget = if (size == 0) { - broadcast(prefix,"event.mobHunt.success") - ChallengeManager.stopChallenges() - null - } else remainingEntries.random() - remainingEntries.remove(currentTarget) - calcBar(getCurrentEntryName()) - } - - override fun getCurrentEntryName() = currentTarget?.name - - @Serializable - private data class MobHuntData( - val target: EntityType? = null, - val remainingMobs: List = emptyList(), - val blacklist: List = emptyList() - ) } \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHuntCommand.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHuntCommand.kt deleted file mode 100644 index 7563149..0000000 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/force/huntMob/MobHuntCommand.kt +++ /dev/null @@ -1,23 +0,0 @@ -package de.miraculixx.mchallenge.modules.mods.force.huntMob - -import de.miraculixx.kpaper.items.getLivingMobs -import de.miraculixx.mcommons.extensions.enumOf -import org.bukkit.command.Command -import org.bukkit.command.CommandSender -import org.bukkit.command.TabExecutor -import org.bukkit.entity.EntityType - -class MobHuntCommand(private val data: MobHunt) : TabExecutor, HuntCommand { - override val typeList = getLivingMobs(true) - override val typeNameList = getLivingMobs(true).map { it.name } - override fun onTabComplete(sender: CommandSender, command: Command, label: String, args: Array?): MutableList { - return getTabComplete(args, data.blacklist.map { it.name }) - } - - override fun onCommand(sender: CommandSender, command: Command, label: String, args: Array?): Boolean { - data.handleCommand(sender, sender.name, args) - return true - } - - override fun getType(input: String?) = enumOf(input) -} \ No newline at end of file diff --git a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/multiplayer/blockAsync/BlockAsync.kt b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/multiplayer/blockAsync/BlockAsync.kt index ef353dc..fa94d3f 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/multiplayer/blockAsync/BlockAsync.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/modules/mods/multiplayer/blockAsync/BlockAsync.kt @@ -12,7 +12,7 @@ import de.miraculixx.mchallenge.PluginManager import de.miraculixx.mchallenge.modules.challenges.Challenges import de.miraculixx.mchallenge.modules.challenges.challenges import de.miraculixx.mchallenge.modules.challenges.getSetting -import de.miraculixx.mchallenge.modules.challenges.interfaces.ChallengeCommand +import de.miraculixx.mchallenge.modules.challenges.interfaces.CommandChallenge import de.miraculixx.mchallenge.utils.bc import de.miraculixx.mchallenge.utils.command import de.miraculixx.mcommons.namespace @@ -35,7 +35,7 @@ import org.bukkit.inventory.ItemStack import org.bukkit.persistence.PersistentDataType -class BlockAsync : Challenge, ChallengeCommand { +class BlockAsync : Challenge, CommandChallenge { private val blockList = HashMap>() //Location ist der fake Block - Player der Spieler, welcher den Block abgebaut hat private val hidePlayers: Boolean diff --git a/src/main/kotlin/de/miraculixx/mchallenge/utils/CommandExtensions.kt b/src/main/kotlin/de/miraculixx/mchallenge/utils/CommandExtensions.kt index e38d458..e84f222 100644 --- a/src/main/kotlin/de/miraculixx/mchallenge/utils/CommandExtensions.kt +++ b/src/main/kotlin/de/miraculixx/mchallenge/utils/CommandExtensions.kt @@ -3,7 +3,7 @@ package de.miraculixx.mchallenge.utils import dev.jorel.commandapi.CommandAPI import dev.jorel.commandapi.CommandTree -fun command(name: String, tree: CommandTree.() -> Unit = {}) = Command(name, tree) +fun command(name: String, tree: CommandTree.() -> Unit = {}) = Command(name, tree, false) class Command( val name: String, diff --git a/src/main/kotlin/de/miraculixx/mchallenge/utils/serializer/Serializer.kt b/src/main/kotlin/de/miraculixx/mchallenge/utils/serializer/Serializer.kt new file mode 100644 index 0000000..78d3d56 --- /dev/null +++ b/src/main/kotlin/de/miraculixx/mchallenge/utils/serializer/Serializer.kt @@ -0,0 +1,6 @@ +package de.miraculixx.mchallenge.utils.serializer + +interface Serializer { + fun toString(data: T): String + fun toObject(data: String): T +} \ No newline at end of file