From c86a5f70a63d035e219396ee8850f7a1536d215c Mon Sep 17 00:00:00 2001 From: Joshua Goins Date: Sat, 12 Jul 2025 18:33:52 -0400 Subject: [PATCH] Add command, actor control to unlock instanced content --- USAGE.md | 1 + resources/scripts/commands/Commands.lua | 2 ++ resources/scripts/commands/debug/UnlockContent.lua | 8 ++++++++ src/ipc/zone/actor_control.rs | 9 +++++++++ src/world/connection.rs | 9 +++++++++ src/world/lua.rs | 9 +++++++++ 6 files changed, 38 insertions(+) create mode 100644 resources/scripts/commands/debug/UnlockContent.lua diff --git a/USAGE.md b/USAGE.md index fcfab62..7c51f1f 100644 --- a/USAGE.md +++ b/USAGE.md @@ -118,6 +118,7 @@ These special debug commands start with `!` and are custom to Kawari. * `!item `: Gives you an item matching by name. * `!inspect`: Prints info about the player. * `!completeallquests`: Completes every quest in the game, useful for accessing stuff gated behind quest completion. +* `!unlockcontent `: Unlocks the specified instanced content. ### GM commands diff --git a/resources/scripts/commands/Commands.lua b/resources/scripts/commands/Commands.lua index 29cb64a..552f87d 100644 --- a/resources/scripts/commands/Commands.lua +++ b/resources/scripts/commands/Commands.lua @@ -45,4 +45,6 @@ registerCommand("ost", DBG_DIR.."OnScreenTest.lua") registerCommand("permtest", DBG_DIR.."PermissionTest.lua") registerCommand("setpos", DBG_DIR.."SetPos.lua") registerCommand("unlock", DBG_DIR.."Unlock.lua") +registerCommand("unlockcontent", DBG_DIR.."UnlockContent.lua") registerCommand("completeallquests", DBG_DIR.."CompleteAllQuests.lua") + diff --git a/resources/scripts/commands/debug/UnlockContent.lua b/resources/scripts/commands/debug/UnlockContent.lua new file mode 100644 index 0000000..c5abd00 --- /dev/null +++ b/resources/scripts/commands/debug/UnlockContent.lua @@ -0,0 +1,8 @@ +required_rank = GM_RANK_DEBUG +command_sender = "[unlockcontent] " + +function onCommand(args, player) + local id = args[1] + player:unlock_content(id) + printf(player, "Content %s unlocked!", id) +end diff --git a/src/ipc/zone/actor_control.rs b/src/ipc/zone/actor_control.rs index 1e89d20..6ebbf93 100644 --- a/src/ipc/zone/actor_control.rs +++ b/src/ipc/zone/actor_control.rs @@ -119,6 +119,15 @@ pub enum ActorControlCategory { #[brw(pad_before = 2)] // padding unk1: u32, }, + #[brw(magic = 0x83u16)] + UnlockInstanceContent { + #[brw(pad_before = 2)] // padding + /// Index into InstanceContent Excel sheet + id: u32, + #[br(map = read_bool_from::)] + #[bw(map = write_bool_as::)] + unlocked: bool, + }, Unknown { category: u16, #[brw(pad_before = 2)] // padding diff --git a/src/world/connection.rs b/src/world/connection.rs index 6951209..7a4778d 100644 --- a/src/world/connection.rs +++ b/src/world/connection.rs @@ -821,6 +821,15 @@ impl ZoneConnection { self.player_data.completed_quests = vec![0xFF; COMPLETED_QUEST_BITMASK_SIZE]; self.send_quest_information().await; } + Task::UnlockContent { id } => { + self.actor_control_self(ActorControlSelf { + category: ActorControlCategory::UnlockInstanceContent { + id: *id as u32, + unlocked: true, + }, + }) + .await; + } } } player.queued_tasks.clear(); diff --git a/src/world/lua.rs b/src/world/lua.rs index 4c19768..db597ce 100644 --- a/src/world/lua.rs +++ b/src/world/lua.rs @@ -37,6 +37,7 @@ pub enum Task { UnlockOrchestrion { id: u16, on: bool }, AddItem { id: u32 }, CompleteAllQuests {}, + UnlockContent { id: u16 }, } #[derive(Default, Clone)] @@ -269,6 +270,10 @@ impl LuaPlayer { fn complete_all_quests(&mut self) { self.queued_tasks.push(Task::CompleteAllQuests {}); } + + fn unlock_content(&mut self, id: u16) { + self.queued_tasks.push(Task::UnlockContent { id }); + } } impl UserData for LuaPlayer { @@ -400,6 +405,10 @@ impl UserData for LuaPlayer { this.complete_all_quests(); Ok(()) }); + methods.add_method_mut("unlock_content", |_, this, id: u16| { + this.unlock_content(id); + Ok(()) + }); } fn add_fields>(fields: &mut F) {