diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/InstructionTask.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/InstructionTask.kt index cda592a76a..94bf2b0ee1 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/InstructionTask.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/client/instruction/InstructionTask.kt @@ -61,31 +61,5 @@ class InstructionTask( companion object { const val MAX_INSTRUCTIONS = 20 - - fun Flow.test() { - - flow> { - coroutineScope { - val upstreamChannel = buffer(10).produceIn(this) - upstreamChannel.tryReceive().getOrNull() - } - } - } - - @JvmStatic - fun main(args: Array): Unit = runBlocking { - - val channel = Channel(5) - - for (i in 0 until 4) { - channel.send(i) - } - launch { - for (i in 0 until 5) { - val it = channel.tryReceive().getOrNull() ?: break - println(it) - } - } - } } } \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/client/ui/event/Command.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/client/ui/event/Command.kt index c61c8ff0a5..7404da63c6 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/client/ui/event/Command.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/client/ui/event/Command.kt @@ -1,5 +1,7 @@ package world.gregs.voidps.engine.client.ui.event +import world.gregs.voidps.engine.client.ui.chat.Colours +import world.gregs.voidps.engine.client.ui.chat.toTag import world.gregs.voidps.engine.entity.character.Character import world.gregs.voidps.engine.entity.character.mode.interact.Interaction import world.gregs.voidps.engine.entity.character.player.Player @@ -21,23 +23,61 @@ data class Command( 2 -> character["rights", "none"] else -> null } + + companion object { + var count = 0 + val adminCommands = mutableListOf() + val modCommands = mutableListOf() + } } -fun adminCommand(vararg commands: String, block: suspend Command.() -> Unit) { +fun adminCommand(command: String, description: String = "", aliases: List = emptyList(), block: suspend Command.() -> Unit) { + if (description.isNotBlank()) { + Command.adminCommands.add("${Colours.BLUE.toTag()}${command}") + } + val index = command.indexOfFirst { it == '(' || it == '[' } + val commandName = (if (index != -1) command.substring(0, index) else command).trim() val handler: suspend Command.(Player) -> Unit = { block.invoke(this) } - for (command in commands) { - Events.handle("command", command, "admin", handler = handler) + Events.handle("command", commandName, "admin", handler = handler) + for (alias in aliases) { + if (description.isNotBlank()) { + Command.adminCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}") + } + Events.handle("command", alias, "admin", handler = handler) + } + + if (description.isNotBlank()) { + Command.adminCommands.add(description) + Command.adminCommands.add("") } } -fun modCommand(vararg commands: String, block: suspend Command.() -> Unit) { +fun modCommand(command: String, description: String = "", aliases: List = emptyList(), block: suspend Command.() -> Unit) { + if (description.isNotBlank()) { + Command.modCommands.add("${Colours.BLUE.toTag()}${command}") + Command.adminCommands.add("${Colours.BLUE.toTag()}${command}") + } + val index = command.indexOfFirst { it == '(' || it == '[' } + val commandName = (if (index != -1) command.substring(0, index) else command).trim() val handler: suspend Command.(Player) -> Unit = { block.invoke(this) } - for (command in commands) { - Events.handle("command", command, "mod", handler = handler) - Events.handle("command", command, "admin", handler = handler) + Events.handle("command", commandName, "mod", handler = handler) + Events.handle("command", commandName, "admin", handler = handler) + for (alias in aliases) { + if (description.isNotBlank()) { + Command.modCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}") + Command.adminCommands.add("${Colours.BLUE.toTag()}${command.replace(commandName, alias)}") + } + Events.handle("command", alias, "mod", handler = handler) + Events.handle("command", alias, "admin", handler = handler) + } + if (description.isNotBlank()) { + Command.modCommands.add(description) + Command.adminCommands.add(description) + Command.modCommands.add("") + Command.adminCommands.add("") } } \ No newline at end of file diff --git a/engine/src/main/kotlin/world/gregs/voidps/engine/event/Events.kt b/engine/src/main/kotlin/world/gregs/voidps/engine/event/Events.kt index 43ef7419cd..c51c104827 100644 --- a/engine/src/main/kotlin/world/gregs/voidps/engine/event/Events.kt +++ b/engine/src/main/kotlin/world/gregs/voidps/engine/event/Events.kt @@ -65,12 +65,7 @@ class Events( } } runBlocking { - for (handler in handlers) { - if (event is CancellableEvent && event.cancelled) { - break - } - handler.invoke(event, dispatcher) - } + handleEvent(handlers, event, dispatcher) } return true } @@ -85,14 +80,22 @@ class Events( all?.invoke(dispatcher, event) } scope.launch(errorHandler) { - for (handler in handlers) { - if (event is CancellableEvent && event.cancelled) { - break - } + handleEvent(handlers, event, dispatcher) + } + return true + } + + private suspend fun handleEvent(handlers: Set Unit>, event: Event, dispatcher: EventDispatcher) { + for (handler in handlers) { + if (event is CancellableEvent && event.cancelled) { + break + } + try { handler.invoke(event, dispatcher) + } catch (e: Exception) { + logger.warn(e) { "Error in event handler $dispatcher $event $handler" } } } - return true } fun contains(dispatcher: EventDispatcher, event: Event): Boolean { diff --git a/engine/src/test/kotlin/world/gregs/voidps/engine/event/EventsTest.kt b/engine/src/test/kotlin/world/gregs/voidps/engine/event/EventsTest.kt index adfb024c6a..e937fb994d 100644 --- a/engine/src/test/kotlin/world/gregs/voidps/engine/event/EventsTest.kt +++ b/engine/src/test/kotlin/world/gregs/voidps/engine/event/EventsTest.kt @@ -3,6 +3,7 @@ package world.gregs.voidps.engine.event import org.junit.jupiter.api.Assertions.assertEquals import org.junit.jupiter.api.Assertions.assertNull import kotlin.test.Test +import org.junit.jupiter.api.Assertions.assertTrue class EventsTest { @@ -19,6 +20,19 @@ class EventsTest { assertEquals(setOf(handler), result) } + @Test + fun `Exceptions thrown in handlers are handled`() { + val trie = Events() + val handler: suspend Event.(EventDispatcher) -> Unit = { + throw IllegalStateException("tantrum") + } + trie.insert(arrayOf("param1"), handler) + + val result = trie.emit(entity, event("param1")) + + assertTrue(result) + } + @Test fun `Exact match non string values`() { val trie = Events() diff --git a/game/src/main/kotlin/world/gregs/voidps/bot/BotSpawns.kts b/game/src/main/kotlin/world/gregs/voidps/bot/BotSpawns.kts index c71ec14573..9910cab147 100644 --- a/game/src/main/kotlin/world/gregs/voidps/bot/BotSpawns.kts +++ b/game/src/main/kotlin/world/gregs/voidps/bot/BotSpawns.kts @@ -3,6 +3,7 @@ package world.gregs.voidps.bot import kotlinx.coroutines.* import world.gregs.voidps.engine.Contexts import world.gregs.voidps.engine.client.PlayerAccountLoader +import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.data.AccountManager import world.gregs.voidps.engine.data.Settings @@ -70,7 +71,7 @@ worldTimerTick("bot_spawn") { spawn() } -adminCommand("bots") { +adminCommand("bots (count)", "spawn (count) number of bots") { val count = content.toIntOrNull() ?: 1 GlobalScope.launch { repeat(count) { @@ -86,7 +87,7 @@ adminCommand("bots") { } } -adminCommand("clear_bots") { +adminCommand("clear_bots [count]", "clear all or some amount of bots") { val count = content.toIntOrNull() ?: MAX_PLAYERS World.queue("bot_${counter}") { val manager = get() @@ -96,15 +97,17 @@ adminCommand("clear_bots") { } } -adminCommand("bot") { +adminCommand("bot", "toggle yourself on/off as a bot player") { if (player.isBot) { player.clear("bot") + player.message("Bot disabled.") } else { val bot = player.initBot() if (content.isNotBlank()) { player["task_bot"] = content } bot.emit(StartBot) + player.message("Bot enabled.") } } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/achievement/TaskSystem.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/achievement/TaskSystem.kts index 6791fdbb56..04c656e3c4 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/achievement/TaskSystem.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/achievement/TaskSystem.kts @@ -2,7 +2,6 @@ package world.gregs.voidps.world.activity.achievement import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.chat.plural -import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.event.interfaceOpen import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.open @@ -218,12 +217,4 @@ interfaceOption("Hint", "hint_*", "task_system") { player["world_map_marker_1"] = tile player["world_map_marker_text_1"] = "" player.open("world_map") -} - -adminCommand("tasks", "achievements") { - for (struct in structDefinitions.definitions) { - if (struct.stringId.endsWith("_task")) { - player[struct.stringId] = true - } - } } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/bank/BankOpen.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/bank/BankOpen.kts index 8ffc99ed30..21da922c90 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/bank/BankOpen.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/bank/BankOpen.kts @@ -11,7 +11,7 @@ import world.gregs.voidps.engine.entity.obj.objectOperate import world.gregs.voidps.engine.inv.sendInventory import world.gregs.voidps.world.activity.bank.Bank.tabs -adminCommand("bank") { +adminCommand("bank", "open your bank anywhere") { player.open("bank") } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts index 5b46d09301..0ba268e411 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/dnd/shootingstar/ShootingStar.kts @@ -71,7 +71,7 @@ settingsReload { } } -adminCommand("star") { +adminCommand("star [minutes]", "start a new shooting star event in [minutes]") { cleanseEvent(true) val minutes = content.toIntOrNull() if (minutes != null) { diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/BookPages.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/BookPages.kts index 2ce5486199..2273ebffe0 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/BookPages.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/BookPages.kts @@ -1,5 +1,6 @@ package world.gregs.voidps.world.activity.quest +import world.gregs.voidps.engine.client.ui.Interfaces import world.gregs.voidps.engine.client.ui.close import world.gregs.voidps.engine.client.ui.dialogue.continueDialogue import world.gregs.voidps.engine.client.ui.event.interfaceRefresh @@ -44,17 +45,20 @@ continueDialogue("book_long", "turn_page_left") { player -> fun refreshBook(player: Player, book: String) { val name: String = player["book"] ?: return - val pageNumber: Int = player["book_page"] ?: return - player.interfaces.apply { - sendText(book, "title", books.title(name)) - sendText(book, "page_number_left", (pageNumber + 1).toString()) - sendText(book, "page_number_right", (pageNumber + 2).toString()) - val pages = books.get(name) - sendVisibility(book, "turn_page_left", pageNumber > 0) - sendVisibility(book, "turn_page_right", pageNumber < pages.lastIndex) - val page = pages.getOrNull(pageNumber)?.lines() - for (i in 0 until if (book == "book_long") 30 else 21) { - sendText(book, "line${i + 1}", page?.getOrNull(i) ?: "") - } + val page: Int = player["book_page"] ?: return + val pages = books.get(name) + player.interfaces.display(book, books.title(book), page, pages) +} + +fun Interfaces.display(book: String, title: String, pageNumber: Int, pages: List) { + sendText(book, "title", title) + sendText(book, "page_number_left", (pageNumber + 1).toString()) + sendText(book, "page_number_right", (pageNumber + 2).toString()) + sendVisibility(book, "turn_page_left", pageNumber > 0) + sendVisibility(book, "turn_page_right", pageNumber < pages.lastIndex) + val lines = pages.getOrNull(pageNumber)?.lines() + for (i in 0 until if (book == "book_long") 30 else 21) { + println("Send line${i + 1} ${lines?.getOrNull(i)}") + sendText(book, "line${i + 1}", lines?.getOrNull(i) ?: "") } } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quest.kt b/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quest.kt index cc07ec2374..b31380d621 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quest.kt +++ b/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quest.kt @@ -5,6 +5,19 @@ import world.gregs.voidps.engine.client.ui.open import world.gregs.voidps.engine.entity.character.player.Player import world.gregs.voidps.engine.entity.item.Item +val quests = listOf( + "unstable_foundations", + "cooks_assistant", + "demon_slayer", + "dorics_quest", + "gunnars_ground", + "the_restless_ghost", + "rune_mysteries", + "the_knights_sword", + // mini-quests + "enter_the_abyss", +) + fun Player.quest(name: String): String = this[name, "unstarted"] fun Player.questComplete(name: String): Boolean = quest(name) == "completed" diff --git a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quests.kts b/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quests.kts deleted file mode 100644 index 150ccaa871..0000000000 --- a/game/src/main/kotlin/world/gregs/voidps/world/activity/quest/Quests.kts +++ /dev/null @@ -1,24 +0,0 @@ -package world.gregs.voidps.world.activity.quest - -import world.gregs.voidps.engine.client.ui.event.adminCommand - -val quests = listOf( - "unstable_foundations", - "cooks_assistant", - "demon_slayer", - "dorics_quest", - "gunnars_ground", - "the_restless_ghost", - "rune_mysteries", - "the_knights_sword", - // mini-quests - "enter_the_abyss", -) - -adminCommand("quests") { - for (quest in quests) { - player[quest] = "completed" - } - player["quest_points"] = 7 - player.refreshQuestJournal() -} \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/admin/AdminCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/admin/AdminCommands.kts index 9f8fb5aecb..4300368d4c 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/admin/AdminCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/admin/AdminCommands.kts @@ -10,13 +10,13 @@ import kotlinx.coroutines.launch import net.pearx.kasechange.toSentenceCase import net.pearx.kasechange.toSnakeCase import world.gregs.voidps.bot.navigation.graph.NavigationGraph +import world.gregs.voidps.cache.Definition +import world.gregs.voidps.cache.definition.Extra import world.gregs.voidps.engine.client.clearCamera import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.client.ui.chat.toDigitGroupString -import world.gregs.voidps.engine.client.ui.chat.toSIInt -import world.gregs.voidps.engine.client.ui.chat.toSILong -import world.gregs.voidps.engine.client.ui.chat.toSIPrefix +import world.gregs.voidps.engine.client.ui.chat.* import world.gregs.voidps.engine.client.ui.close +import world.gregs.voidps.engine.client.ui.event.Command import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.event.modCommand import world.gregs.voidps.engine.client.ui.open @@ -54,6 +54,8 @@ import world.gregs.voidps.network.login.protocol.encode.playSoundEffect import world.gregs.voidps.type.Direction import world.gregs.voidps.type.Region import world.gregs.voidps.world.activity.quest.Books +import world.gregs.voidps.world.activity.quest.quests +import world.gregs.voidps.world.activity.quest.refreshQuestJournal import world.gregs.voidps.world.interact.entity.npc.shop.OpenShop import world.gregs.voidps.world.interact.entity.obj.Teleports import world.gregs.voidps.world.interact.entity.player.combat.prayer.PrayerConfigs @@ -65,6 +67,7 @@ import world.gregs.voidps.world.interact.entity.player.effect.skull import world.gregs.voidps.world.interact.entity.player.effect.unskull import world.gregs.voidps.world.interact.entity.player.energy.MAX_RUN_ENERGY import world.gregs.voidps.world.interact.entity.player.music.MusicTracks +import world.gregs.voidps.world.interact.entity.player.music.MusicUnlock import world.gregs.voidps.world.interact.entity.sound.playJingle import world.gregs.voidps.world.interact.entity.sound.playMidi import world.gregs.voidps.world.interact.entity.sound.playSound @@ -77,7 +80,10 @@ import kotlin.system.measureTimeMillis val areas: AreaDefinitions by inject() val players: Players by inject() -adminCommand("tele", "tp") { +Command.adminCommands.add("${Colours.PURPLE.toTag()}====== Admin Commands ======") +Command.adminCommands.add("") + +adminCommand("tele (x) (y) [level]", "teleport to given coordinates or area name", listOf("tp")) { if (content.contains(",")) { val params = content.split(",") val level = params[0].toInt() @@ -88,26 +94,31 @@ adminCommand("tele", "tp") { val parts = content.split(" ") val int = parts[0].toIntOrNull() when { - int == null -> player.tele(areas[content]) + int == null -> when (content.lowercase()) { + "draynor" -> player.tele(3086, 3248) + "varrock" -> player.tele(3212, 3429) + "lumbridge" -> player.tele(3222, 3219) + else -> player.tele(areas[content]) + } parts.size == 1 -> player.tele(Region(int).tile.add(32, 32)) else -> player.tele(int, parts[1].toInt(), if (parts.size > 2) parts[2].toInt() else 0) } } } -adminCommand("teleto") { +adminCommand("teleto (player-name)", "teleport to another player") { val target = players.firstOrNull { it.name.equals(content, true) } if (target != null) { player.tele(target.tile) } } -adminCommand("teletome") { +adminCommand("teletome (player-name)", "teleport another player to you") { val other = players.get(content) ?: return@adminCommand other.tele(player.tile) } -adminCommand("npc") { +adminCommand("npc (npc-id)", "spawn an npc") { val id = content.toIntOrNull() val defs: NPCDefinitions = get() val definition = if (id != null) defs.getOrNull(id) else defs.getOrNull(content) @@ -128,7 +139,7 @@ adminCommand("npc") { npc?.start("movement_delay", -1) } -modCommand("save") { +modCommand("save", "save all players") { val account: SaveQueue = get() players.forEach(account::save) } @@ -146,7 +157,7 @@ worldSpawn { } } -adminCommand("items") { +adminCommand("items (item-id) [item-id] [item-id]...", "spawn multiple items at once") { val parts = content.split(" ") for (i in parts.indices) { val id = definitions.get(alternativeNames.getOrDefault(parts[i], parts[i])).stringId @@ -154,7 +165,7 @@ adminCommand("items") { } } -adminCommand("item") { +adminCommand("item (item-id) [item-amount]", "spawn an item by int or string id e.g. 'item pure_ess 2'") { val parts = content.split(" ") val definition = definitions.get(alternativeNames.getOrDefault(parts[0], parts[0])) val id = definition.stringId @@ -181,7 +192,7 @@ adminCommand("item") { } } -adminCommand("give") { +adminCommand("give (item-id) [amount] (player-name)", "spawn item in another players inventory") { val parts = content.split(" ") val id = definitions.get(parts.first()).stringId val amount = parts[1] @@ -194,26 +205,38 @@ adminCommand("give") { } } -modCommand("find") { +modCommand("find (item name)", "search the id of an item", aliases = listOf("search")) { val search = content.lowercase() - var found = false - repeat(definitions.size) { id -> - val def = definitions.getOrNull(id) ?: return@repeat - if (def.name.lowercase().contains(search)) { - player.message("[${def.name.lowercase()}] - id: $id", ChatType.Console) - found = true + var found = 0 + player.message("===== Items =====", ChatType.Console) + found += search(player, get(), search) { it.name } + player.message("===== Objects =====", ChatType.Console) + found += search(player, get(), search) { it.name } + player.message("===== NPCs =====", ChatType.Console) + found += search(player, get(), search) { it.name } + player.message("$found results found for '$search'", ChatType.Console) +} + +val utf8Regex = "[^\\x20-\\x7e]".toRegex() + +fun search(player: Player, definitions: DefinitionsDecoder, search: String, getName: (T) -> String): Int where T : Definition, T : Extra { + var found = 0 + for (id in definitions.definitions.indices) { + val def = definitions.getOrNull(id) ?: continue + val name = getName(def) + if (name.lowercase().contains(search)) { + player.message("[${name.lowercase().replace(utf8Regex, "")}] - id: $id${if (def.stringId.isNotBlank()) " (${def.stringId})" else ""}", ChatType.Console) + found++ } } - if (!found) { - player.message("No results found for '$search'", ChatType.Console) - } + return found } -modCommand("clear") { +modCommand("clear", "delete all items in the players inventory") { player.inventory.clear() } -adminCommand("master") { +adminCommand("master", "set all skills to 99") { for (skill in Skill.all) { player.experience.set(skill, 14000000.0) player.levels.restore(skill, 1000) @@ -223,7 +246,45 @@ adminCommand("master") { } } -adminCommand("setlevel") { +adminCommand("unlock [activity-type]", "unlock everything or of a type (music, tasks, emotes, quests)") { + val type = content + if (type == "" || type == "music" || type == "songs" || type == "music tracks" || type == "music_tracks") { + get().get("music_track_names").map?.keys?.forEach { key -> + MusicUnlock.unlockTrack(player, key) + } + player.message("All songs unlocked.") + } + if (type == "" || type == "tasks" || type == "achievements") { + for (struct in get().definitions) { + if (struct.stringId.endsWith("_task")) { + player[struct.stringId] = true + } + } + player.message("All tasks completed.") + } + if (type == "" || type == "emotes") { + val defs = get() + for (compId in 26..52) { + if (compId == 39) { + continue + } + val component = defs.getComponent("emotes", compId) ?: continue + player["unlocked_emote_${component.stringId}"] = true + } + player["unlocked_emote_lost_tribe"] = true + player.message("All emotes unlocked.") + } + if (type == "" || type == "quests") { + for (quest in quests) { + player[quest] = "completed" + } + player["quest_points"] = player["quest_points_total", 1] + player.refreshQuestJournal() + player.message("All quests unlocked.") + } +} + +adminCommand("setlevel (skill-name) (level)", "set any skill to a specific level") { val split = content.split(" ") val skill = Skill.valueOf(split[0].toSentenceCase()) val level = split[1].toInt() @@ -244,7 +305,7 @@ adminCommand("setlevel") { } } -adminCommand("reset") { +adminCommand("reset", "rest all skills to level 1") { for ((index, skill) in Skill.all.withIndex()) { player.experience.set(skill, Experience.defaultExperience[index]) player.levels.set(skill, Levels.defaultLevels[index]) @@ -254,58 +315,58 @@ adminCommand("reset") { player.clearCamera() } -modCommand("hide") { +modCommand("hide", "toggle invisibility to other players") { player.appearance.hidden = !player.appearance.hidden player.flagAppearance() } -adminCommand("skull") { +adminCommand("skull", "apply a skull to the player") { player.skull() } -adminCommand("unskull") { +adminCommand("unskull", "remove a skull") { player.unskull() } -adminCommand("rest") { +adminCommand("rest", "set run energy to full") { player["energy"] = MAX_RUN_ENERGY } -adminCommand("spec") { +adminCommand("spec", "set special attack energy to full") { player.specialAttackEnergy = MAX_SPECIAL_ATTACK } -adminCommand("curse", "curses") { +adminCommand("curse", "toggle curse prayers", listOf("curses")) { player[PRAYERS] = if (player.isCurses()) "normal" else "curses" } -adminCommand("ancient", "ancients") { +adminCommand("ancient", "toggle ancient spellbook", listOf("ancients")) { player.open("ancient_spellbook") } -adminCommand("lunar", "lunars") { +adminCommand("lunar", "toggle lunar spellbook", listOf("lunars")) { player.open("lunar_spellbook") } -adminCommand("regular", "regulars", "modern", "moderns") { +adminCommand("regular", "toggle modern spellbook", listOf("regulars", "modern", "moderns")) { player.open("modern_spellbook") } -adminCommand("dung", "dungs", "dungeoneering", "dungeoneerings") { +adminCommand("dung", "toggle dungeoneering spellbook", listOf("dungs", "dungeoneering", "dungeoneerings")) { player.open("dungeoneering_spellbook") } -adminCommand("pray") { +adminCommand("pray", "restore full prayer points") { player.levels.clear(Skill.Prayer) } -adminCommand("restore") { +adminCommand("restore", "restore all skills") { Skill.entries.forEach { player.levels.clear(it) } } -adminCommand("sound") { +adminCommand("sound (sound-id)", "play a sound by int or string id") { val id = content.toIntOrNull() if (id == null) { player.playSound(content.toSnakeCase()) @@ -314,7 +375,7 @@ adminCommand("sound") { } } -adminCommand("midi") { +adminCommand("midi (midi-id)", "play a midi effect by int or string id") { val id = content.toIntOrNull() if (id == null) { player.playMidi(content.toSnakeCase()) @@ -323,7 +384,7 @@ adminCommand("midi") { } } -adminCommand("jingle") { +adminCommand("jingle (jingle-id)", "play a jingle sound by int or string id") { val id = content.toIntOrNull() if (id == null) { player.playJingle(content.toSnakeCase()) @@ -332,16 +393,35 @@ adminCommand("jingle") { } } -adminCommand("song", "track") { - player.playTrack(content.toInt()) +val enums: EnumDefinitions by inject() + +adminCommand("song (song-id)", "play a song by int id", listOf("track")) { + val names = enums.get("music_track_names").map!! + var id = content.toIntOrNull() + if (id == null) { + val search = content.replace(" ", "_") + for ((key, value) in names) { + if ((value as String).toSnakeCase() == search) { + id = key + break + } + } + if (id != null) { + player.playTrack(id) + } else { + player.message("Song not found with id '${search}'.") + } + } else { + player.playTrack(content.toInt()) + } } -modCommand("pos", "mypos") { +modCommand("pos", "print out players current coordinates", listOf("mypos")) { player.message("${player.tile} Zone(${player.tile.zone.id}) ${player.tile.region}") println(player.tile) } -adminCommand("reload") { +adminCommand("reload (config-name)", "reload any type of content or file e.g. npcs, object defs, or settings") { when (content) { "book", "books" -> get().load() "stairs", "tele", "teles", "teleports" -> get().load() @@ -386,11 +466,11 @@ adminCommand("reload") { } } -adminCommand("shop") { +adminCommand("shop (shop-id)", "open a shop by id") { player.emit(OpenShop(content)) } -adminCommand("debug") { +adminCommand("debug", "toggle debug mode and printing logs") { val target = if (content.isNotEmpty()) { players.get(content) } else { @@ -416,7 +496,7 @@ class InventoryDelegate( } } -modCommand("chance") { +modCommand("chance (drop-table-id)", "get the chances for all items of a drop table") { val table = tables.get(content) ?: tables.get("${content}_drop_table") if (table == null) { player.message("No drop table found for '$content'") @@ -442,7 +522,7 @@ fun sendChances(player: Player, table: DropTable) { } } -modCommand("sim") { +modCommand("sim (drop-table-name) (drop-count)", "simulate any amount of drops from a drop-table/boss") { val parts = content.split(" ") val name = parts.first() val count = parts.last().toSIInt() diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/admin/ObjectCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/admin/ObjectCommands.kts index 328eb588dc..dd5935f333 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/admin/ObjectCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/admin/ObjectCommands.kts @@ -6,7 +6,7 @@ import world.gregs.voidps.engine.inject val objects: GameObjects by inject() -adminCommand("get") { +adminCommand("get", "get all objects under the player") { objects[player.tile].forEach { println(it) } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/DebugCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/DebugCommands.kts index 8861bd428b..93e03f383f 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/DebugCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/DebugCommands.kts @@ -7,6 +7,9 @@ import world.gregs.voidps.bot.path.EdgeTraversal import world.gregs.voidps.bot.path.NodeTargetStrategy import world.gregs.voidps.engine.GameLoop import world.gregs.voidps.engine.client.* +import world.gregs.voidps.engine.client.ui.chat.Colours +import world.gregs.voidps.engine.client.ui.chat.toTag +import world.gregs.voidps.engine.client.ui.event.Command import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.event.modCommand import world.gregs.voidps.engine.client.ui.open @@ -15,7 +18,10 @@ import world.gregs.voidps.engine.data.definition.PatrolDefinitions import world.gregs.voidps.engine.entity.character.mode.Patrol import world.gregs.voidps.engine.entity.character.move.tele import world.gregs.voidps.engine.entity.character.npc.NPCs +import world.gregs.voidps.engine.entity.character.player.Players import world.gregs.voidps.engine.entity.character.player.chat.ChatType +import world.gregs.voidps.engine.entity.character.player.isAdmin +import world.gregs.voidps.engine.entity.item.floor.FloorItems import world.gregs.voidps.engine.entity.obj.GameObjects import world.gregs.voidps.engine.get import world.gregs.voidps.engine.inject @@ -30,6 +36,7 @@ import world.gregs.voidps.network.login.protocol.encode.npcDialogueHead import world.gregs.voidps.network.login.protocol.encode.playerDialogueHead import world.gregs.voidps.type.Tile import world.gregs.voidps.type.Zone +import world.gregs.voidps.world.activity.quest.* import world.gregs.voidps.world.interact.dialogue.sendLines import world.gregs.voidps.world.interact.dialogue.type.npc import world.gregs.voidps.world.interact.dialogue.type.startQuest @@ -48,17 +55,31 @@ modCommand("test") { } } -modCommand("patrol") { +modCommand("commands", aliases = listOf("help")) { + val commands = if (player.isAdmin()) Command.adminCommands else Command.modCommands + val list = listOf( + "Commands list with descriptions and usage instructions in the format:", + "${Colours.BLUE.toTag()}command_name (required-variable) [optional-variable]", + "command description", + "" + ) + player.sendQuestJournal("Commands List", list + commands) +} + +Command.adminCommands.add("${Colours.PURPLE.toTag()}====== Testing Commands ======") +Command.adminCommands.add("") + +adminCommand("patrol (patrol-id)", "walk along a patrol route") { val patrol = get().get(content) player.tele(patrol.waypoints.first().first) player.mode = Patrol(player, patrol.waypoints) } -modCommand("reset_cam") { +modCommand("reset_cam", "reset camera to normal") { player.client?.clearCamera() } -adminCommand("move_to") { +adminCommand("move_to (x) (y) (height) (c-speed) (v-speed)", "move camera to look at coordinates") { val test = content.split(" ") val viewport = player.viewport!! val result = viewport.lastLoadZone.safeMinus(viewport.zoneRadius, viewport.zoneRadius) @@ -67,7 +88,7 @@ adminCommand("move_to") { player.moveCamera(local, test[2].toInt(), test[3].toInt(), test[4].toInt()) } -adminCommand("look_at") { +adminCommand("look_at (x) (y) (height) (c-speed) (v-speed)", "turn camera to look at coordinates") { val test = content.split(" ") val viewport = player.viewport!! val result = viewport.lastLoadZone.safeMinus(viewport.zoneRadius, viewport.zoneRadius) @@ -76,12 +97,12 @@ adminCommand("look_at") { player.turnCamera(local, test[2].toInt(), test[3].toInt(), test[4].toInt()) } -adminCommand("shake") { +adminCommand("shake (intensity) (type) (cycle) (movement) (speed)", "shake camera") { val test = content.split(" ") player.shakeCamera(test[0].toInt(), test[1].toInt(), test[2].toInt(), test[3].toInt(), test[4].toInt()) } -modCommand("timers") { +modCommand("timers", "list all players active timers") { player.message("=== Timers ===", ChatType.Console) for (timer in player.timers.queue) { player.message("${timer.name}: ${timer.nextTick - GameLoop.tick}", ChatType.Console) @@ -92,7 +113,7 @@ modCommand("timers") { } } -modCommand("variables", "vars") { +modCommand("variables", "list all players variables", listOf("vars")) { player.message("=== Variables ===", ChatType.Console) for ((variable, value) in (player.variables as PlayerVariables).temp) { if (content.isNotBlank() && !variable.contains(content, ignoreCase = true)) { @@ -143,7 +164,7 @@ adminCommand("pf_bench") { println("Invalid path: ${timeInvalid}ms") } -adminCommand("expr") { +adminCommand("expr (animation-id)", "display dialogue head with an animation expression by id") { val id = content.toIntOrNull() if (id != null) { val npc = id < 1000 @@ -162,7 +183,7 @@ adminCommand("expr") { } } -adminCommand("showcol") { +adminCommand("showcol", "show nearby collision") { val area = player.tile.toCuboid(10) val collisions: Collisions = get() for (tile in area) { @@ -172,7 +193,7 @@ adminCommand("showcol") { } } -adminCommand("path") { +adminCommand("path", "show calculated walk paths") { player.softTimers.toggle("show_path") } @@ -253,7 +274,7 @@ adminCommand("sendItems") { player.sendInventoryItems(90, 28, ags, true) } -adminCommand("obj") { +adminCommand("obj (object-id) [object-type] [object-rotation]", "spawn an object") { if (content.isNotBlank()) { val parts = content.split(" ") val id = parts.getOrNull(0) @@ -271,6 +292,47 @@ adminCommand("obj") { } } + +adminCommand("under [type]", "display entity types underneath the player") { + val type = content + if (type == "" || type == "obj" || type == "objs" || type == "objects") { + val objs = get()[player.tile] + if (objs.isNotEmpty()) { + player.message("--- Objects ---", ChatType.Console) + for (obj in objs) { + player.message(obj.toString(), ChatType.Console) + } + } + } + if (type == "" || type == "players") { + val players = get()[player.tile].filterNot { it == player } + if (players.isNotEmpty()) { + player.message("--- Players ---", ChatType.Console) + for (other in players) { + player.message(other.toString(), ChatType.Console) + } + } + } + if (type == "" || type == "npcs") { + val npcs = get()[player.tile] + if (npcs.isNotEmpty()) { + player.message("--- NPCs ---", ChatType.Console) + for (npc in npcs) { + player.message(npc.toString(), ChatType.Console) + } + } + } + if (type == "" || type == "items" || type == "floor items" || type == "floor_items") { + val items = get()[player.tile] + if (items.isNotEmpty()) { + player.message("--- Floor Items ---", ChatType.Console) + for (item in items) { + player.message(item.toString(), ChatType.Console) + } + } + } +} + adminCommand("tree") { val parts = content.split(" ") val tree = parts[0] diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/InterfaceCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/InterfaceCommands.kts index dde1eae800..82f1d55d9d 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/InterfaceCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/InterfaceCommands.kts @@ -4,6 +4,9 @@ import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.sendInterfaceSettings import world.gregs.voidps.engine.client.sendInventoryItems import world.gregs.voidps.engine.client.sendScript +import world.gregs.voidps.engine.client.ui.chat.Colours +import world.gregs.voidps.engine.client.ui.chat.toTag +import world.gregs.voidps.engine.client.ui.event.Command import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.menu.InterfaceOptionSettings.getHash import world.gregs.voidps.engine.data.definition.InterfaceDefinitions @@ -16,7 +19,10 @@ import world.gregs.voidps.network.login.protocol.encode.* val definitions: InterfaceDefinitions by inject() -adminCommand("inter") { +Command.adminCommands.add("${Colours.PURPLE.toTag()}====== Interface Commands ======") +Command.adminCommands.add("") + +adminCommand("inter (interface-id)", "open an interface with int or string id") { val id = content.toIntOrNull() if (id == null) { val name = content @@ -44,34 +50,34 @@ fun closeInterface(player: Player): Boolean { return player.interfaces.close(id) } -adminCommand("show") { +adminCommand("show (interface-id) (interface-component-id) (visibility)", "set the visibility of an interface component") { val parts = content.split(" ") player.client?.interfaceVisibility(parts[0].toInt(), parts[1].toInt(), !parts[2].toBoolean()) } -adminCommand("colour") { +adminCommand("colour (interface-id) (interface-component-id) (red) (green) (blue)", "set colour of interface component") { val parts = content.split(" ") player.client?.colourInterface(parts[0].toInt(), parts[1].toInt(), parts[2].toInt(), parts[3].toInt(), parts[4].toInt()) } -adminCommand("sendItem") { +adminCommand("sendItem (interface) (interface-component) (item-id) [item-amount]", "send an item to an interface component") { val parts = content.split(" ") player.interfaces.sendItem(parts[0], parts[1], parts[2].toInt(), parts.getOrNull(3)?.toInt() ?: 1) } -adminCommand("sendText") { +adminCommand("sendText (interface) (interface-component) (text...)", "send any text to an interface component") { val parts = content.split(" ") player.interfaces.sendText(parts[0], parts[1], content.removePrefix("${parts[0]} ${parts[1]} ")) } -adminCommand("setting") { +adminCommand("setting (interface) (component-id) (from-slot) (to-slot) (settings...)", "send settings to an interface component") { val parts = content.split(" ") val remainder = parts.subList(4, parts.size).map { it.toIntOrNull() }.requireNoNulls().toIntArray() player.message("Settings sent ${remainder.toList()}", ChatType.Console) player.sendInterfaceSettings(parts[0].toInt(), parts[1].toInt(), parts[2].toInt(), parts[3].toInt(), getHash(*remainder)) } -adminCommand("script") { +adminCommand("script (script-id) [params...]", "run a client script with any number of parameters") { val parts = content.split(" ") val remainder = parts.subList(1, parts.size).map { if (it == "true") 1 else if (it == "false") 0 else it.toIntOrNull() ?: it } val id = parts[0].toIntOrNull() @@ -91,12 +97,12 @@ adminCommand("sendItems") { } } -adminCommand("var") { +adminCommand("var (variable-name) (variable-value)", "set a variable") { val parts = content.split(" ") player[parts.first()] = parts.last().toBooleanStrictOrNull() ?: parts.last().toIntOrNull() ?: parts.last() } -adminCommand("varp") { +adminCommand("varp (varp-id) (int-value)", "send a player-variable value to the client by string or int id") { val parts = content.split(" ") val intId = parts.first().toIntOrNull() if (intId == null) { @@ -112,7 +118,7 @@ adminCommand("varp") { } } -adminCommand("varbit") { +adminCommand("varbit (varbit-id) (int-value)", "send a variable-bit value to the client by string or int id") { val parts = content.split(" ") val intId = parts.first().toIntOrNull() if (intId == null) { @@ -128,7 +134,7 @@ adminCommand("varbit") { } } -adminCommand("varc") { +adminCommand("varc (varc-id) (int-value)", "send a client-variable value to the client by string or int id") { val parts = content.split(" ") val intId = parts.first().toIntOrNull() if (intId == null) { @@ -138,7 +144,7 @@ adminCommand("varc") { } } -adminCommand("varcstr") { +adminCommand("varcstr (varcstr-id) (string-value)", "send a variable-client-string value to the client") { val parts = content.split(" ") val intId = parts.first().toIntOrNull() val string = content.removePrefix("${parts.first()} ") diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/NPCUpdatingCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/NPCUpdatingCommands.kts index 7cad567188..388bb0eac9 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/NPCUpdatingCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/NPCUpdatingCommands.kts @@ -12,13 +12,13 @@ import world.gregs.voidps.world.interact.entity.effect.transform val npcs: NPCs by inject() -adminCommand("npckill") { +adminCommand("npckill", "kill all npcs") { npcs.forEach { npc -> npcs.remove(npc) } } -modCommand("npcs") { +modCommand("npcs", "get total npc count") { player.message("NPCs: ${npcs.size}") } diff --git a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts index b0950d8a86..fcabc62804 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/command/debug/PlayerUpdatingCommands.kts @@ -3,6 +3,7 @@ package world.gregs.voidps.world.command.debug import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.launch +import net.pearx.kasechange.toScreamingSnakeCase import world.gregs.voidps.engine.client.message import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.event.modCommand @@ -19,7 +20,7 @@ import world.gregs.voidps.world.interact.entity.proj.shoot val players: Players by inject() -adminCommand("kill") { +adminCommand("kill", "remove all bots") { players.forEach { bot -> if (bot.name.startsWith("Bot")) { players.remove(bot) @@ -35,42 +36,36 @@ adminCommand("kill") { } } -modCommand("players") { +modCommand("players", "get the total and local player counts") { player.message("Players: ${players.size}, ${player.viewport?.players?.localCount}") } -adminCommand("under") { - players[player.tile].forEach { - println("$it - ${players[it.tile]}") - } -} - -adminCommand("anim") { +adminCommand("anim (anim-id)", "perform animation by int or string id (-1 to clear)") { when (content) { "-1", "" -> player.clearAnimation() else -> player.setAnimation(content, override = true)// 863 } } -adminCommand("emote") { +adminCommand("emote (emote-id)", "perform render emote by int or string id (-1 to clear)") { when (content) { "-1", "" -> player.renderEmote = "human_stand" else -> player.renderEmote = content } } -adminCommand("gfx") { +adminCommand("gfx (gfx-id)", "perform graphic effect by int or string id (-1 to clear)") { when (content) { "-1", "" -> player.clearGraphic() else -> player.setGraphic(content)// 93 } } -adminCommand("proj") { +adminCommand("proj (gfx-id)", "shoot projectile by int or string id (-1 to clear)") { player.shoot(content, player.tile.add(0, 5), delay = 0, flightTime = 400) } -adminCommand("tfm", "transform") { +adminCommand("tfm", "transform to npc with int or string id (-1 to clear)", listOf("transform")) { player.transform(content) } @@ -78,7 +73,7 @@ adminCommand("overlay") { player.colourOverlay(-2108002746, 10, 100) } -adminCommand("chat") { +adminCommand("chat (message)", "force a chat message over players head") { player.forceChat = content } @@ -86,7 +81,7 @@ adminCommand("move") { player.setExactMovement(Delta(0, -2), 120, startDelay = 60, direction = Direction.SOUTH) } -adminCommand("hit") { +adminCommand("hit [amount]", "damage player by an amount") { player.damage(content.toIntOrNull() ?: 10) } @@ -94,7 +89,7 @@ adminCommand("time") { player.setTimeBar(true, 0, 60, 1) } -adminCommand("watch") { +adminCommand("watch (player-name)", "watch another player") { val bot = players.get(content) if (bot != null) { player.watch(bot) @@ -107,33 +102,38 @@ adminCommand("shoot") { player.shoot("15", player.tile.addY(10)) } -adminCommand("face") { - val parts = content.split(" ") - player.turn(parts[0].toInt(), parts[1].toInt()) +adminCommand("face (delta-x) (delta-y)", "turn player to face a direction or delta coordinate") { + if (content.contains(" ")) { + val parts = content.split(" ") + player.turn(parts[0].toInt(), parts[1].toInt()) + } else { + val direction = Direction.valueOf(content.toScreamingSnakeCase()) + player.turn(direction.delta) + } } -adminCommand("zone", "chunk") { +adminCommand("zone", aliases = listOf("chunk")) { val zones: DynamicZones = get() zones.copy(player.tile.zone, player.tile.zone, rotation = 2) } -adminCommand("clear_zone") { +adminCommand("clear_zone", "clear the dynamic flag from current zone") { val zones: DynamicZones = get() zones.clear(player.tile.zone) } -adminCommand("skill") { +adminCommand("skill (level)", "set the current displayed skill level") { player.skillLevel = content.toInt() } -adminCommand("cmb") { +adminCommand("cmb (level)", "set the current displayed combat level") { player.combatLevel = content.toInt() } -adminCommand("tgl") { +adminCommand("tgl", "toggle skill level display") { player.toggleSkillLevel() } -adminCommand("sum") { +adminCommand("sum (level)", "set the current summoning combat level") { player.summoningCombatLevel = content.toInt() } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/community/Rights.kts b/game/src/main/kotlin/world/gregs/voidps/world/community/Rights.kts index 5f2aadbfd3..ec62c0805e 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/community/Rights.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/community/Rights.kts @@ -18,7 +18,7 @@ playerSpawn { player -> } } -adminCommand("rights") { +adminCommand("rights (player-name) (rights-name)", "set the rights for another player ${PlayerRights.entries.joinToString(",", "(", ")")}") { val right = content.split(" ").last() val rights: PlayerRights try { diff --git a/game/src/main/kotlin/world/gregs/voidps/world/community/friend/NameChange.kts b/game/src/main/kotlin/world/gregs/voidps/world/community/friend/NameChange.kts index 8b4a02eb3a..92b0a9b9ea 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/community/friend/NameChange.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/community/friend/NameChange.kts @@ -19,7 +19,7 @@ import java.util.concurrent.TimeUnit val players: Players by inject() -modCommand("rename") { +modCommand("rename", "rename your accounts display name (login stays the same)") { val remaining = player.remaining("rename_delay", epochSeconds()).toLong() if (remaining > 0 && !player.isAdmin()) { player.message("You've already changed your name this month.") diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/combat/CombatDebug.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/combat/CombatDebug.kts index 64ca85dc8e..3a8dc52772 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/combat/CombatDebug.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/combat/CombatDebug.kts @@ -13,7 +13,7 @@ import world.gregs.voidps.world.interact.entity.combat.hit.Hit val npcDefinitions: NPCDefinitions by inject() -modCommand("maxhit") { +modCommand("maxhit [npc-id] [spell-id]", "calculate your max hit against an npc") { val debug = player["debug", false] player["debug"] = false val parts = content.split(" ") diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/display/tab/Emotes.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/display/tab/Emotes.kts index b215e2a31a..ecf59a47fd 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/display/tab/Emotes.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/display/tab/Emotes.kts @@ -2,7 +2,6 @@ package world.gregs.voidps.world.interact.entity.player.display.tab import net.pearx.kasechange.toSnakeCase import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.event.interfaceOpen import world.gregs.voidps.engine.client.ui.event.interfaceRefresh import world.gregs.voidps.engine.client.ui.interfaceOption @@ -232,15 +231,4 @@ suspend fun CharacterContext.playDungeoneeringMasterCapeEmote(player: Player) { player.playAnimation("emote_dung_master_sword") player.transform("") -} - -adminCommand("emotes") { - for (compId in unlockableRange) { - if (compId == 39) { - continue - } - val component = definitions.getComponent("emotes", compId) ?: continue - player["unlocked_emote_${component.stringId}"] = true - } - player["unlocked_emote_lost_tribe"] = true } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/music/Music.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/music/Music.kts index c1b35e1b9c..d838c3fde8 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/music/Music.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/music/Music.kts @@ -2,7 +2,6 @@ package world.gregs.voidps.world.interact.entity.player.music import world.gregs.voidps.bot.isBot import world.gregs.voidps.engine.client.message -import world.gregs.voidps.engine.client.ui.event.adminCommand import world.gregs.voidps.engine.client.ui.interfaceOption import world.gregs.voidps.engine.client.ui.playTrack import world.gregs.voidps.engine.data.definition.DefinitionsDecoder.Companion.toIdentifier @@ -81,13 +80,4 @@ fun autoPlay(player: Player, track: MusicTracks.Track) { if (!player["playing_song", false]) { player.playTrack(index) } -} - -/** - * Unlocks all music tracks - */ -adminCommand("unlock") { - enums.get("music_track_names").map?.keys?.forEach { key -> - MusicUnlock.unlockTrack(player, key) - } } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Disease.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Disease.kts index 755f4ddd97..9cc26a0d68 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Disease.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Disease.kts @@ -69,10 +69,11 @@ fun damage(character: Character) { character.directHit(source, damage, "disease") } -adminCommand("disease") { - if (player.diseased) { +adminCommand("disease [damage]", "toggle hitting player with disease") { + val damage = content.toIntOrNull() ?: 100 + if (player.diseased || damage < 0) { player.cureDisease() } else { - player.disease(player, content.toIntOrNull() ?: 100) + player.disease(player, damage) } } \ No newline at end of file diff --git a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Poison.kts b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Poison.kts index ed61347b8c..b0788b3012 100644 --- a/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Poison.kts +++ b/game/src/main/kotlin/world/gregs/voidps/world/interact/entity/player/toxin/Poison.kts @@ -87,10 +87,11 @@ characterCombatAttack { source -> } } -adminCommand("poison") { - if (player.poisoned) { +adminCommand("poison [damage]", "toggle hitting player with poison") { + val damage = content.toIntOrNull() ?: 100 + if (player.poisoned || damage < 0) { player.curePoison() } else { - player.poison(player, content.toIntOrNull() ?: 100) + player.poison(player, damage) } } \ No newline at end of file