From 1f7aa984b02db3f8c3104b1e21ed6a598b306746 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 23 Jan 2026 15:23:55 -0600 Subject: [PATCH 001/114] chore(ui): move interface key to ui --- src/glue/CGlueMgr.cpp | 22 ++-------------------- src/ui/Key.cpp | 20 ++++++++++++++++++++ src/ui/Key.hpp | 8 ++++++++ 3 files changed, 30 insertions(+), 20 deletions(-) create mode 100644 src/ui/Key.cpp create mode 100644 src/ui/Key.hpp diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index 6591a9e..27049df 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -25,6 +25,7 @@ #include "ui/FrameScript.hpp" #include "ui/FrameXML.hpp" #include "ui/Interface.hpp" +#include "ui/Key.hpp" #include "ui/ScriptFunctions.hpp" #include "ui/game/CGVideoOptions.hpp" #include "ui/simple/CSimpleModelFFX.hpp" @@ -36,25 +37,6 @@ #include #include -unsigned char InterfaceKey[256] = { - 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, - 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, - 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, - 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, - 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, - 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, - 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, - 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, - 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, - 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, - 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, - 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, - 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, - 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, - 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, - 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 -}; - int32_t CGlueMgr::m_acceptedEULA = 1; // TODO int32_t CGlueMgr::m_acceptedTerminationWithoutNotice; int32_t CGlueMgr::m_acceptedTOS = 1; // TODO @@ -1015,7 +997,7 @@ void CGlueMgr::Resume() { MD5Init(&md5); - switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", 0, InterfaceKey, digest1)) { + switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", nullptr, InterfaceKey, digest1)) { case 0: status.Add(STATUS_WARNING, "GlueXML missing signature"); ClientPostClose(9); diff --git a/src/ui/Key.cpp b/src/ui/Key.cpp new file mode 100644 index 0000000..738ba04 --- /dev/null +++ b/src/ui/Key.cpp @@ -0,0 +1,20 @@ +#include "ui/Key.hpp" + +uint8_t InterfaceKey[256] = { + 0xC3, 0x5B, 0x50, 0x84, 0xB9, 0x3E, 0x32, 0x42, 0x8C, 0xD0, 0xC7, 0x48, 0xFA, 0x0E, 0x5D, 0x54, + 0x5A, 0xA3, 0x0E, 0x14, 0xBA, 0x9E, 0x0D, 0xB9, 0x5D, 0x8B, 0xEE, 0xB6, 0x84, 0x93, 0x45, 0x75, + 0xFF, 0x31, 0xFE, 0x2F, 0x64, 0x3F, 0x3D, 0x6D, 0x07, 0xD9, 0x44, 0x9B, 0x40, 0x85, 0x59, 0x34, + 0x4E, 0x10, 0xE1, 0xE7, 0x43, 0x69, 0xEF, 0x7C, 0x16, 0xFC, 0xB4, 0xED, 0x1B, 0x95, 0x28, 0xA8, + 0x23, 0x76, 0x51, 0x31, 0x57, 0x30, 0x2B, 0x79, 0x08, 0x50, 0x10, 0x1C, 0x4A, 0x1A, 0x2C, 0xC8, + 0x8B, 0x8F, 0x05, 0x2D, 0x22, 0x3D, 0xDB, 0x5A, 0x24, 0x7A, 0x0F, 0x13, 0x50, 0x37, 0x8F, 0x5A, + 0xCC, 0x9E, 0x04, 0x44, 0x0E, 0x87, 0x01, 0xD4, 0xA3, 0x15, 0x94, 0x16, 0x34, 0xC6, 0xC2, 0xC3, + 0xFB, 0x49, 0xFE, 0xE1, 0xF9, 0xDA, 0x8C, 0x50, 0x3C, 0xBE, 0x2C, 0xBB, 0x57, 0xED, 0x46, 0xB9, + 0xAD, 0x8B, 0xC6, 0xDF, 0x0E, 0xD6, 0x0F, 0xBE, 0x80, 0xB3, 0x8B, 0x1E, 0x77, 0xCF, 0xAD, 0x22, + 0xCF, 0xB7, 0x4B, 0xCF, 0xFB, 0xF0, 0x6B, 0x11, 0x45, 0x2D, 0x7A, 0x81, 0x18, 0xF2, 0x92, 0x7E, + 0x98, 0x56, 0x5D, 0x5E, 0x69, 0x72, 0x0A, 0x0D, 0x03, 0x0A, 0x85, 0xA2, 0x85, 0x9C, 0xCB, 0xFB, + 0x56, 0x6E, 0x8F, 0x44, 0xBB, 0x8F, 0x02, 0x22, 0x68, 0x63, 0x97, 0xBC, 0x85, 0xBA, 0xA8, 0xF7, + 0xB5, 0x40, 0x68, 0x3C, 0x77, 0x86, 0x6F, 0x4B, 0xD7, 0x88, 0xCA, 0x8A, 0xD7, 0xCE, 0x36, 0xF0, + 0x45, 0x6E, 0xD5, 0x64, 0x79, 0x0F, 0x17, 0xFC, 0x64, 0xDD, 0x10, 0x6F, 0xF3, 0xF5, 0xE0, 0xA6, + 0xC3, 0xFB, 0x1B, 0x8C, 0x29, 0xEF, 0x8E, 0xE5, 0x34, 0xCB, 0xD1, 0x2A, 0xCE, 0x79, 0xC3, 0x9A, + 0x0D, 0x36, 0xEA, 0x01, 0xE0, 0xAA, 0x91, 0x20, 0x54, 0xF0, 0x72, 0xD8, 0x1E, 0xC7, 0x89, 0xD2 +}; diff --git a/src/ui/Key.hpp b/src/ui/Key.hpp new file mode 100644 index 0000000..7aef2bc --- /dev/null +++ b/src/ui/Key.hpp @@ -0,0 +1,8 @@ +#ifndef UI_KEY_HPP +#define UI_KEY_HPP + +#include + +extern uint8_t InterfaceKey[256]; + +#endif From bdf0bd27a119693e752872aab6c112e6b88d218b Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 23 Jan 2026 21:17:43 -0600 Subject: [PATCH 002/114] feat(ui): initialize game UI in ClientInitializeGame --- src/client/Client.cpp | 5 ++ src/ui/Game.hpp | 6 +++ src/ui/game/CGGameUI.cpp | 94 ++++++++++++++++++++++++++++++++++++ src/ui/game/CGGameUI.hpp | 17 +++++++ src/ui/game/CGWorldFrame.cpp | 22 +++++++++ src/ui/game/CGWorldFrame.hpp | 19 ++++++++ 6 files changed, 163 insertions(+) create mode 100644 src/ui/Game.hpp create mode 100644 src/ui/game/CGGameUI.cpp create mode 100644 src/ui/game/CGGameUI.hpp create mode 100644 src/ui/game/CGWorldFrame.cpp create mode 100644 src/ui/game/CGWorldFrame.hpp diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 4e2722f..a193f64 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -18,6 +18,7 @@ #include "sound/Interface.hpp" #include "ui/FrameScript.hpp" #include "ui/FrameXML.hpp" +#include "ui/Game.hpp" #include "util/Random.hpp" #include "world/World.hpp" #include @@ -85,6 +86,10 @@ void ClientInitializeGame(uint32_t mapId, C3Vector position) { // TODO + CGGameUI::InitializeGame(); + + // TODO + EventRegister(EVENT_ID_IDLE, ClientIdle); // TODO diff --git a/src/ui/Game.hpp b/src/ui/Game.hpp new file mode 100644 index 0000000..6f5e712 --- /dev/null +++ b/src/ui/Game.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_HPP +#define UI_GAME_HPP + +#include "ui/game/CGGameUI.hpp" + +#endif diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp new file mode 100644 index 0000000..0f1ff34 --- /dev/null +++ b/src/ui/game/CGGameUI.cpp @@ -0,0 +1,94 @@ +#include "ui/game/CGGameUI.hpp" +#include "client/Client.hpp" +#include "ui/FrameXML.hpp" +#include "ui/Key.hpp" +#include "ui/game/CGWorldFrame.hpp" +#include "ui/simple/CSimpleTop.hpp" +#include "util/CStatus.hpp" +#include + +CSimpleTop* CGGameUI::s_simpleTop; + +void CGGameUI::Initialize() { + // TODO + + CGGameUI::s_simpleTop = STORM_NEW(CSimpleTop); + + // TODO + + CGGameUI::RegisterFrameFactories(); + + // TODO + + CStatus status; + + // TODO + + MD5_CTX md5; + uint8_t digest1[16]; + uint8_t digest2[16]; + + MD5Init(&md5); + + switch (FrameXML_CheckSignature("Interface\\FrameXML\\FrameXML.toc", "Interface\\FrameXML\\Bindings.xml", InterfaceKey, digest1)) { + case 0: { + status.Add(STATUS_WARNING, "FrameXML missing signature"); + ClientPostClose(10); + + return; + } + + case 1: { + status.Add(STATUS_WARNING, "FrameXML has corrupt signature"); + ClientPostClose(10); + + return; + } + + case 2: { + status.Add(STATUS_WARNING, "FrameXML is modified or corrupt"); + ClientPostClose(10); + + return; + } + + case 3: { + // Success + break; + } + + default: { + ClientPostClose(10); + + return; + } + } + + // TODO file count and progress bar logic + + FrameXML_FreeHashNodes(); + + FrameXML_CreateFrames("Interface\\FrameXML\\FrameXML.toc", nullptr, &md5, &status); + + // TODO CGUIBindings::s_bindings->Load("Interface\\FrameXML\\Bindings.xml", &md5, &status); + + MD5Final(digest2, &md5); + + // TODO digest validation + + // TODO +} + +void CGGameUI::InitializeGame() { + // TODO + + CGGameUI::Initialize(); + + // TODO +} + +void CGGameUI::RegisterFrameFactories() { + FrameXML_RegisterFactory("WorldFrame", &CGWorldFrame::Create, true); + + // TODO register remaining factories +} diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp new file mode 100644 index 0000000..17b86f1 --- /dev/null +++ b/src/ui/game/CGGameUI.hpp @@ -0,0 +1,17 @@ +#ifndef UI_GAME_C_G_GAME_UI_HPP +#define UI_GAME_C_G_GAME_UI_HPP + +class CSimpleTop; + +class CGGameUI { + public: + // Static variables + static CSimpleTop* s_simpleTop; + + // Static functions + static void Initialize(); + static void InitializeGame(); + static void RegisterFrameFactories(); +}; + +#endif diff --git a/src/ui/game/CGWorldFrame.cpp b/src/ui/game/CGWorldFrame.cpp new file mode 100644 index 0000000..db9a49e --- /dev/null +++ b/src/ui/game/CGWorldFrame.cpp @@ -0,0 +1,22 @@ +#include "ui/game/CGWorldFrame.hpp" +#include + +CSimpleFrame* CGWorldFrame::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGWorldFrame)(parent); +} + +CGWorldFrame::CGWorldFrame(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO + + CGWorldFrame::s_currentWorldFrame = this; + + // TODO + + this->EnableEvent(SIMPLE_EVENT_KEY, -1); + this->EnableEvent(SIMPLE_EVENT_MOUSE, -1); + this->EnableEvent(SIMPLE_EVENT_MOUSEWHEEL, -1); + + // TODO +} diff --git a/src/ui/game/CGWorldFrame.hpp b/src/ui/game/CGWorldFrame.hpp new file mode 100644 index 0000000..ce95231 --- /dev/null +++ b/src/ui/game/CGWorldFrame.hpp @@ -0,0 +1,19 @@ +#ifndef UI_GAME_C_G_WORLD_FRAME_HPP +#define UI_GAME_C_G_WORLD_FRAME_HPP + +#include "ui/simple/CSimpleFrame.hpp" +#include + +class CGWorldFrame : public CSimpleFrame { + public: + // Static variables + CGWorldFrame* s_currentWorldFrame; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + + // Member functions + CGWorldFrame(CSimpleFrame* parent); +}; + +#endif From 8d1316b163d28f9476d87b32bdf3dbd472ef4d32 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sat, 24 Jan 2026 20:58:04 -0600 Subject: [PATCH 003/114] chore: normalize signature checking logic between GlueXML and FrameXML --- src/glue/CGlueMgr.cpp | 56 +++++++++++++++++++++------------------- src/ui/game/CGGameUI.cpp | 16 ++++++------ 2 files changed, 37 insertions(+), 35 deletions(-) diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index 27049df..90fae26 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -987,51 +987,53 @@ void CGlueMgr::Resume() { DeleteInterfaceFiles(); - MD5_CTX md5; - unsigned char digest1[16]; - unsigned char digest2[16]; - - int32_t v8; - unsigned char* v9; - unsigned char* v10; - - MD5Init(&md5); + uint8_t digest1[16]; switch (FrameXML_CheckSignature("Interface\\GlueXML\\GlueXML.toc", nullptr, InterfaceKey, digest1)) { - case 0: + case 0: { status.Add(STATUS_WARNING, "GlueXML missing signature"); ClientPostClose(9); - return; - case 1: + return; + } + + case 1: { status.Add(STATUS_WARNING, "GlueXML has corrupt signature"); ClientPostClose(9); - return; - case 2: + return; + } + + case 2: { status.Add(STATUS_WARNING, "GlueXML is modified or corrupt"); ClientPostClose(9); + return; + } - case 3: - FrameXML_FreeHashNodes(); - FrameXML_CreateFrames("Interface\\GlueXML\\GlueXML.toc", 0, &md5, &status); - - MD5Final(digest2, &md5); - - v8 = 16; - v9 = digest2; - v10 = digest1; - + case 3: { + // Success break; + } - default: + default: { ClientPostClose(9); + return; + } } - // TODO - // - some kind of digest validation? + MD5_CTX md5; + MD5Init(&md5); + + FrameXML_FreeHashNodes(); + + FrameXML_CreateFrames("Interface\\GlueXML\\GlueXML.toc", nullptr, &md5, &status); + + uint8_t digest2[16]; + MD5Final(digest2, &md5); + + // TODO digest validation FrameScript_SignalEvent(22, nullptr); diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 0f1ff34..2411bc7 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -24,32 +24,28 @@ void CGGameUI::Initialize() { // TODO - MD5_CTX md5; uint8_t digest1[16]; - uint8_t digest2[16]; - - MD5Init(&md5); switch (FrameXML_CheckSignature("Interface\\FrameXML\\FrameXML.toc", "Interface\\FrameXML\\Bindings.xml", InterfaceKey, digest1)) { case 0: { status.Add(STATUS_WARNING, "FrameXML missing signature"); ClientPostClose(10); - return; + break; } case 1: { status.Add(STATUS_WARNING, "FrameXML has corrupt signature"); ClientPostClose(10); - return; + break; } case 2: { status.Add(STATUS_WARNING, "FrameXML is modified or corrupt"); ClientPostClose(10); - return; + break; } case 3: { @@ -60,10 +56,13 @@ void CGGameUI::Initialize() { default: { ClientPostClose(10); - return; + break; } } + MD5_CTX md5; + MD5Init(&md5); + // TODO file count and progress bar logic FrameXML_FreeHashNodes(); @@ -72,6 +71,7 @@ void CGGameUI::Initialize() { // TODO CGUIBindings::s_bindings->Load("Interface\\FrameXML\\Bindings.xml", &md5, &status); + uint8_t digest2[16]; MD5Final(digest2, &md5); // TODO digest validation From 1589466076e9b579764f3c20babc75979a9ed54c Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sat, 24 Jan 2026 22:48:09 -0600 Subject: [PATCH 004/114] feat(ui): add proper ScriptIx dtor --- src/ui/FrameScript_Object.cpp | 12 ++++++------ src/ui/FrameScript_Object.hpp | 3 ++- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/ui/FrameScript_Object.cpp b/src/ui/FrameScript_Object.cpp index d63daae..15b19a6 100644 --- a/src/ui/FrameScript_Object.cpp +++ b/src/ui/FrameScript_Object.cpp @@ -5,6 +5,12 @@ int32_t FrameScript_Object::s_objectTypes = 0; +FrameScript_Object::ScriptIx::~ScriptIx() { + if (this->luaRef) { + luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->luaRef); + } +} + int32_t FrameScript_Object::CreateScriptMetaTable(lua_State* L, void (*a2)(lua_State* L)) { lua_createtable(L, 0, 0); lua_pushstring(L, "__index"); @@ -24,12 +30,6 @@ void FrameScript_Object::FillScriptMethodTable(lua_State *L, FrameScript_Method } } -FrameScript_Object::~FrameScript_Object() { - if (this->m_onEvent.luaRef) { - luaL_unref(FrameScript_GetContext(), LUA_REGISTRYINDEX, this->m_onEvent.luaRef); - } -} - const char* FrameScript_Object::GetDisplayName() { const char* name = this->GetName(); return name ? name : ""; diff --git a/src/ui/FrameScript_Object.hpp b/src/ui/FrameScript_Object.hpp index c8edad2..e80049e 100644 --- a/src/ui/FrameScript_Object.hpp +++ b/src/ui/FrameScript_Object.hpp @@ -14,6 +14,7 @@ class FrameScript_Object { struct ScriptIx { int32_t luaRef = 0; const char* unk = nullptr; + ~ScriptIx(); }; class ScriptFunction { @@ -34,7 +35,7 @@ class FrameScript_Object { ScriptIx m_onEvent; // Virtual member functions - virtual ~FrameScript_Object(); + virtual ~FrameScript_Object() = default; virtual char* GetName() = 0; virtual int32_t GetScriptMetaTable() = 0; virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); From 23be35bed231f78be5239a6b998e281f86b6e19e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 12:45:10 -0600 Subject: [PATCH 005/114] feat(ui): delete strata in CSimpleTop dtor --- src/ui/simple/CSimpleTop.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/ui/simple/CSimpleTop.cpp b/src/ui/simple/CSimpleTop.cpp index fa9903c..61a4a8f 100644 --- a/src/ui/simple/CSimpleTop.cpp +++ b/src/ui/simple/CSimpleTop.cpp @@ -400,6 +400,13 @@ CSimpleTop::CSimpleTop() : CLayoutFrame() { CSimpleTop::~CSimpleTop() { // TODO + for (auto& strata : this->m_strata) { + delete strata; + strata = nullptr; + } + + // TODO + this->DisableEvents(); HandleClose(this->m_screenLayer); From 4e9ea8f5a1be43260c913bdbc6c156b3765ae93b Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 13:40:19 -0600 Subject: [PATCH 006/114] feat(ui): delete frames in CSimpleTop dtor --- src/ui/simple/CSimpleTop.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/simple/CSimpleTop.cpp b/src/ui/simple/CSimpleTop.cpp index 61a4a8f..4283997 100644 --- a/src/ui/simple/CSimpleTop.cpp +++ b/src/ui/simple/CSimpleTop.cpp @@ -400,6 +400,11 @@ CSimpleTop::CSimpleTop() : CLayoutFrame() { CSimpleTop::~CSimpleTop() { // TODO + while (auto frame = this->m_frames.Head()) { + this->m_frames.UnlinkNode(frame); + delete frame; + } + for (auto& strata : this->m_strata) { delete strata; strata = nullptr; From cded0d86e7b97ba80937cb6c71ca744141e3821c Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 14:37:15 -0600 Subject: [PATCH 007/114] feat(ui): clear top pointer in CSimpleFrame dtor --- src/ui/simple/CSimpleFrame.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 500772a..7630899 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -69,6 +69,7 @@ CSimpleFrame::~CSimpleFrame() { this->m_intAC = 3; this->m_top->UnregisterFrame(this); + this->m_top = nullptr; // TODO } From daba2a1ffd899f480fbf0f0b771ad840efb8f1a3 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 14:40:28 -0600 Subject: [PATCH 008/114] feat(ui): delete title region in CSimpleFrame dtor --- src/ui/simple/CSimpleFrame.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 7630899..9cf321d 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -64,13 +64,15 @@ CSimpleFrame::CSimpleFrame(CSimpleFrame* parent) : CScriptRegion() { } CSimpleFrame::~CSimpleFrame() { - // TODO - this->m_intAC = 3; this->m_top->UnregisterFrame(this); this->m_top = nullptr; + if (this->m_titleRegion) { + delete this->m_titleRegion; + } + // TODO } From c2eedc1d473de6acfea9f9544cc278023dc2d990 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 14:50:16 -0600 Subject: [PATCH 009/114] feat(ui): clean up draw layers and batches in CSimpleFrame dtor --- src/ui/simple/CSimpleFrame.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 9cf321d..83bbd59 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -73,6 +73,14 @@ CSimpleFrame::~CSimpleFrame() { delete this->m_titleRegion; } + for (int32_t layer = 0; layer < NUM_SIMPLEFRAME_DRAWLAYERS; layer++) { + this->m_drawlayers[layer].UnlinkAll(); + + if (this->m_batch[layer]) { + delete this->m_batch[layer]; + } + } + // TODO } From f1b8f495b668cffddbf5739bb19490f554f893ba Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 15:05:10 -0600 Subject: [PATCH 010/114] feat(ui): delete regions in CSimpleFrame dtor --- src/ui/simple/CSimpleFrame.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 83bbd59..cc176e7 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -81,6 +81,11 @@ CSimpleFrame::~CSimpleFrame() { } } + while (auto region = this->m_regions.Head()) { + this->m_regions.UnlinkNode(region); + delete region; + } + // TODO } From caf628145db7311baef3d599a19f14abbdf33581 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 25 Jan 2026 22:37:37 -0600 Subject: [PATCH 011/114] feat(ui): add ScriptEventsRegisterFunctions --- src/ui/game/CGGameUI.cpp | 13 + src/ui/game/ScriptEvents.cpp | 861 +++++++++++++++++++++++++++++++++++ src/ui/game/ScriptEvents.hpp | 6 + 3 files changed, 880 insertions(+) create mode 100644 src/ui/game/ScriptEvents.cpp create mode 100644 src/ui/game/ScriptEvents.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 2411bc7..4e6277a 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -3,12 +3,21 @@ #include "ui/FrameXML.hpp" #include "ui/Key.hpp" #include "ui/game/CGWorldFrame.hpp" +#include "ui/game/ScriptEvents.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" #include CSimpleTop* CGGameUI::s_simpleTop; +void LoadScriptFunctions() { + // TODO + + ScriptEventsRegisterFunctions(); + + // TODO +} + void CGGameUI::Initialize() { // TODO @@ -16,6 +25,10 @@ void CGGameUI::Initialize() { // TODO + LoadScriptFunctions(); + + // TODO + CGGameUI::RegisterFrameFactories(); // TODO diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp new file mode 100644 index 0000000..33419f3 --- /dev/null +++ b/src/ui/game/ScriptEvents.cpp @@ -0,0 +1,861 @@ +#include "ui/game/ScriptEvents.hpp" +#include "ui/FrameScript.hpp" +#include "ui/ScriptFunctions.hpp" +#include "ui/ScriptFunctionsShared.hpp" +#include "util/Unimplemented.hpp" + +int32_t Script_UnitExists(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsVisible(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPlayer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsInMyGuild(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsCorpse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPartyLeader(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitGroupRolesAssigned(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsRaidOfficer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInParty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPlayerOrPetInParty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInRaid(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPlayerOrPetInRaid(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPlayerControlled(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsAFK(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsDND(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPVP(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPVPSanctuary(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPVPFreeForAll(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitFactionGroup(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitReaction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsEnemy(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCanCooperate(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCanAssist(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCanAttack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsCharmed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsPossessed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PlayerCanTeleport(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitClassification(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitSelectionColor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitGUID(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPVPName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitXP(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitXPMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitHealth(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitHealthMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitMana(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitManaMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPower(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPowerMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPowerType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitOnTaxi(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsFeignDeath(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsDead(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsGhost(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsDeadOrGhost(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsConnected(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitAffectingCombat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitSex(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitLevel(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMoney(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetHonorCurrency(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetArenaCurrency(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitRace(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitClass(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitClassBase(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitResistance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitStat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitAttackBothHands(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitDamage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitRangedDamage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitRangedAttack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitAttackSpeed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitAttackPower(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitRangedAttackPower(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitDefense(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitArmor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCharacterPoints(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitBuff(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitDebuff(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitAura(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsTapped(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsTappedByPlayer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsTappedByAllThreatList(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsTrivial(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitHasRelicSlot(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetPortraitTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasFullControl(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetComboPoints(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsInGuild(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsGuildLeader(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsArenaTeamCaptain(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsInArenaTeam(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsResting(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCombatRating(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCombatRatingBonus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMaxCombatRatingBonus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetDodgeChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBlockChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetShieldBlock(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetParryChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCritChanceFromAgility(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSpellCritChanceFromIntellect(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCritChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRangedCritChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSpellCritChance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSpellBonusDamage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSpellBonusHealing(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPetSpellBonusDamage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSpellPenetration(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetArmorPenetration(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAttackPowerForStat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCreatureType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCreatureFamily(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetResSicknessDuration(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPSessionStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPYesterdayStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPLifetimeStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitPVPRank(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPRankInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPRankProgress(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitCastingInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitChannelInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsLoggedIn(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsFlyableArea(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsIndoors(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsOutdoors(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsOutOfBounds(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsFalling(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsSwimming(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsFlying(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsMounted(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsStealthed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsSameServer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitHealthModifier(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitMaxHealthModifier(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitPowerModifier(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitHealthRegenRateFromSpirit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitManaRegenRateFromSpirit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetManaRegen(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPowerRegen(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRuneCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRuneCount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRuneType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReportPlayerIsPVPAFK(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PlayerIsPVPInactive(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetExpertise(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetExpertisePercent(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInBattleground(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInRange(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitSpeed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetUnitPitch(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInVehicle(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitUsingVehicle(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitControllingVehicle(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitInVehicleControlSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitHasVehicleUI(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitTargetsVehicleInRaidUI(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitVehicleSkin(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitVehicleSeatCount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitVehicleSeatInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitSwitchToVehicleSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanSwitchVehicleSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetVehicleUIIndicator(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetVehicleUIIndicatorSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitThreatSituation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitDetailedThreatSituation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UnitIsControlling(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EjectPassengerFromSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanEjectPassengerFromSeat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RespondInstanceLock(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPlayerFacing(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPlayerInfoByGUID(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemStatDelta(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsXPUserDisabled(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_FillLocalizedClassList(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +static FrameScript_Method s_UnitFunctions[] = { + { "UnitExists", &Script_UnitExists }, + { "UnitIsVisible", &Script_UnitIsVisible }, + { "UnitIsUnit", &Script_UnitIsUnit }, + { "UnitIsPlayer", &Script_UnitIsPlayer }, + { "UnitIsInMyGuild", &Script_UnitIsInMyGuild }, + { "UnitIsCorpse", &Script_UnitIsCorpse }, + { "UnitIsPartyLeader", &Script_UnitIsPartyLeader }, + { "UnitGroupRolesAssigned", &Script_UnitGroupRolesAssigned }, + { "UnitIsRaidOfficer", &Script_UnitIsRaidOfficer }, + { "UnitInParty", &Script_UnitInParty }, + { "UnitPlayerOrPetInParty", &Script_UnitPlayerOrPetInParty }, + { "UnitInRaid", &Script_UnitInRaid }, + { "UnitPlayerOrPetInRaid", &Script_UnitPlayerOrPetInRaid }, + { "UnitPlayerControlled", &Script_UnitPlayerControlled }, + { "UnitIsAFK", &Script_UnitIsAFK }, + { "UnitIsDND", &Script_UnitIsDND }, + { "UnitIsPVP", &Script_UnitIsPVP }, + { "UnitIsPVPSanctuary", &Script_UnitIsPVPSanctuary }, + { "UnitIsPVPFreeForAll", &Script_UnitIsPVPFreeForAll }, + { "UnitFactionGroup", &Script_UnitFactionGroup }, + { "UnitReaction", &Script_UnitReaction }, + { "UnitIsEnemy", &Script_UnitIsEnemy }, + { "UnitIsFriend", &Script_UnitIsFriend }, + { "UnitCanCooperate", &Script_UnitCanCooperate }, + { "UnitCanAssist", &Script_UnitCanAssist }, + { "UnitCanAttack", &Script_UnitCanAttack }, + { "UnitIsCharmed", &Script_UnitIsCharmed }, + { "UnitIsPossessed", &Script_UnitIsPossessed }, + { "PlayerCanTeleport", &Script_PlayerCanTeleport }, + { "UnitClassification", &Script_UnitClassification }, + { "UnitSelectionColor", &Script_UnitSelectionColor }, + { "UnitGUID", &Script_UnitGUID }, + { "UnitName", &Script_UnitName }, + { "UnitPVPName", &Script_UnitPVPName }, + { "UnitXP", &Script_UnitXP }, + { "UnitXPMax", &Script_UnitXPMax }, + { "UnitHealth", &Script_UnitHealth }, + { "UnitHealthMax", &Script_UnitHealthMax }, + { "UnitMana", &Script_UnitMana }, + { "UnitManaMax", &Script_UnitManaMax }, + { "UnitPower", &Script_UnitPower }, + { "UnitPowerMax", &Script_UnitPowerMax }, + { "UnitPowerType", &Script_UnitPowerType }, + { "UnitOnTaxi", &Script_UnitOnTaxi }, + { "UnitIsFeignDeath", &Script_UnitIsFeignDeath }, + { "UnitIsDead", &Script_UnitIsDead }, + { "UnitIsGhost", &Script_UnitIsGhost }, + { "UnitIsDeadOrGhost", &Script_UnitIsDeadOrGhost }, + { "UnitIsConnected", &Script_UnitIsConnected }, + { "UnitAffectingCombat", &Script_UnitAffectingCombat }, + { "UnitSex", &Script_UnitSex }, + { "UnitLevel", &Script_UnitLevel }, + { "GetMoney", &Script_GetMoney }, + { "GetHonorCurrency", &Script_GetHonorCurrency }, + { "GetArenaCurrency", &Script_GetArenaCurrency }, + { "UnitRace", &Script_UnitRace }, + { "UnitClass", &Script_UnitClass }, + { "UnitClassBase", &Script_UnitClassBase }, + { "UnitResistance", &Script_UnitResistance }, + { "UnitStat", &Script_UnitStat }, + { "UnitAttackBothHands", &Script_UnitAttackBothHands }, + { "UnitDamage", &Script_UnitDamage }, + { "UnitRangedDamage", &Script_UnitRangedDamage }, + { "UnitRangedAttack", &Script_UnitRangedAttack }, + { "UnitAttackSpeed", &Script_UnitAttackSpeed }, + { "UnitAttackPower", &Script_UnitAttackPower }, + { "UnitRangedAttackPower", &Script_UnitRangedAttackPower }, + { "UnitDefense", &Script_UnitDefense }, + { "UnitArmor", &Script_UnitArmor }, + { "UnitCharacterPoints", &Script_UnitCharacterPoints }, + { "UnitBuff", &Script_UnitBuff }, + { "UnitDebuff", &Script_UnitDebuff }, + { "UnitAura", &Script_UnitAura }, + { "UnitIsTapped", &Script_UnitIsTapped }, + { "UnitIsTappedByPlayer", &Script_UnitIsTappedByPlayer }, + { "UnitIsTappedByAllThreatList", &Script_UnitIsTappedByAllThreatList }, + { "UnitIsTrivial", &Script_UnitIsTrivial }, + { "UnitHasRelicSlot", &Script_UnitHasRelicSlot }, + { "SetPortraitTexture", &Script_SetPortraitTexture }, + { "HasFullControl", &Script_HasFullControl }, + { "GetComboPoints", &Script_GetComboPoints }, + { "IsInGuild", &Script_IsInGuild }, + { "IsGuildLeader", &Script_IsGuildLeader }, + { "IsArenaTeamCaptain", &Script_IsArenaTeamCaptain }, + { "IsInArenaTeam", &Script_IsInArenaTeam }, + { "IsResting", &Script_IsResting }, + { "GetCombatRating", &Script_GetCombatRating }, + { "GetCombatRatingBonus", &Script_GetCombatRatingBonus }, + { "GetMaxCombatRatingBonus", &Script_GetMaxCombatRatingBonus }, + { "GetDodgeChance", &Script_GetDodgeChance }, + { "GetBlockChance", &Script_GetBlockChance }, + { "GetShieldBlock", &Script_GetShieldBlock }, + { "GetParryChance", &Script_GetParryChance }, + { "GetCritChanceFromAgility", &Script_GetCritChanceFromAgility }, + { "GetSpellCritChanceFromIntellect", &Script_GetSpellCritChanceFromIntellect }, + { "GetCritChance", &Script_GetCritChance }, + { "GetRangedCritChance", &Script_GetRangedCritChance }, + { "GetSpellCritChance", &Script_GetSpellCritChance }, + { "GetSpellBonusDamage", &Script_GetSpellBonusDamage }, + { "GetSpellBonusHealing", &Script_GetSpellBonusHealing }, + { "GetPetSpellBonusDamage", &Script_GetPetSpellBonusDamage }, + { "GetSpellPenetration", &Script_GetSpellPenetration }, + { "GetArmorPenetration", &Script_GetArmorPenetration }, + { "GetAttackPowerForStat", &Script_GetAttackPowerForStat }, + { "UnitCreatureType", &Script_UnitCreatureType }, + { "UnitCreatureFamily", &Script_UnitCreatureFamily }, + { "GetResSicknessDuration", &Script_GetResSicknessDuration }, + { "GetPVPSessionStats", &Script_GetPVPSessionStats }, + { "GetPVPYesterdayStats", &Script_GetPVPYesterdayStats }, + { "GetPVPLifetimeStats", &Script_GetPVPLifetimeStats }, + { "UnitPVPRank", &Script_UnitPVPRank }, + { "GetPVPRankInfo", &Script_GetPVPRankInfo }, + { "GetPVPRankProgress", &Script_GetPVPRankProgress }, + { "UnitCastingInfo", &Script_UnitCastingInfo }, + { "UnitChannelInfo", &Script_UnitChannelInfo }, + { "IsLoggedIn", &Script_IsLoggedIn }, + { "IsFlyableArea", &Script_IsFlyableArea }, + { "IsIndoors", &Script_IsIndoors }, + { "IsOutdoors", &Script_IsOutdoors }, + { "IsOutOfBounds", &Script_IsOutOfBounds }, + { "IsFalling", &Script_IsFalling }, + { "IsSwimming", &Script_IsSwimming }, + { "IsFlying", &Script_IsFlying }, + { "IsMounted", &Script_IsMounted }, + { "IsStealthed", &Script_IsStealthed }, + { "UnitIsSameServer", &Script_UnitIsSameServer }, + { "GetUnitHealthModifier", &Script_GetUnitHealthModifier }, + { "GetUnitMaxHealthModifier", &Script_GetUnitMaxHealthModifier }, + { "GetUnitPowerModifier", &Script_GetUnitPowerModifier }, + { "GetUnitHealthRegenRateFromSpirit", &Script_GetUnitHealthRegenRateFromSpirit }, + { "GetUnitManaRegenRateFromSpirit", &Script_GetUnitManaRegenRateFromSpirit }, + { "GetManaRegen", &Script_GetManaRegen }, + { "GetPowerRegen", &Script_GetPowerRegen }, + { "GetRuneCooldown", &Script_GetRuneCooldown }, + { "GetRuneCount", &Script_GetRuneCount }, + { "GetRuneType", &Script_GetRuneType }, + { "ReportPlayerIsPVPAFK", &Script_ReportPlayerIsPVPAFK }, + { "PlayerIsPVPInactive", &Script_PlayerIsPVPInactive }, + { "GetExpertise", &Script_GetExpertise }, + { "GetExpertisePercent", &Script_GetExpertisePercent }, + { "UnitInBattleground", &Script_UnitInBattleground }, + { "UnitInRange", &Script_UnitInRange }, + { "GetUnitSpeed", &Script_GetUnitSpeed }, + { "GetUnitPitch", &Script_GetUnitPitch }, + { "UnitInVehicle", &Script_UnitInVehicle }, + { "UnitUsingVehicle", &Script_UnitUsingVehicle }, + { "UnitControllingVehicle", &Script_UnitControllingVehicle }, + { "UnitInVehicleControlSeat", &Script_UnitInVehicleControlSeat }, + { "UnitHasVehicleUI", &Script_UnitHasVehicleUI }, + { "UnitTargetsVehicleInRaidUI", &Script_UnitTargetsVehicleInRaidUI }, + { "UnitVehicleSkin", &Script_UnitVehicleSkin }, + { "UnitVehicleSeatCount", &Script_UnitVehicleSeatCount }, + { "UnitVehicleSeatInfo", &Script_UnitVehicleSeatInfo }, + { "UnitSwitchToVehicleSeat", &Script_UnitSwitchToVehicleSeat }, + { "CanSwitchVehicleSeat", &Script_CanSwitchVehicleSeat }, + { "GetVehicleUIIndicator", &Script_GetVehicleUIIndicator }, + { "GetVehicleUIIndicatorSeat", &Script_GetVehicleUIIndicatorSeat }, + { "UnitThreatSituation", &Script_UnitThreatSituation }, + { "UnitDetailedThreatSituation", &Script_UnitDetailedThreatSituation }, + { "UnitIsControlling", &Script_UnitIsControlling }, + { "EjectPassengerFromSeat", &Script_EjectPassengerFromSeat }, + { "CanEjectPassengerFromSeat", &Script_CanEjectPassengerFromSeat }, + { "RespondInstanceLock", &Script_RespondInstanceLock }, + { "GetPlayerFacing", &Script_GetPlayerFacing }, + { "GetPlayerInfoByGUID", &Script_GetPlayerInfoByGUID }, + { "GetItemStats", &Script_GetItemStats }, + { "GetItemStatDelta", &Script_GetItemStatDelta }, + { "IsXPUserDisabled", &Script_IsXPUserDisabled }, + { "FillLocalizedClassList", &Script_FillLocalizedClassList }, +}; + +void ScriptEventsRegisterFunctions() { + SystemRegisterFunctions(); + + for (auto& func : s_UnitFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/ScriptEvents.hpp b/src/ui/game/ScriptEvents.hpp new file mode 100644 index 0000000..8240bc3 --- /dev/null +++ b/src/ui/game/ScriptEvents.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_SCRIPT_EVENTS_HPP +#define UI_GAME_SCRIPT_EVENTS_HPP + +void ScriptEventsRegisterFunctions(); + +#endif From cbbf491620b52954eecfd13b5b438ad5b092598d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 12:24:17 -0600 Subject: [PATCH 012/114] chore(ui): clean up SystemRegisterFunctions --- src/glue/CGlueMgr.cpp | 1 + src/ui/ScriptFunctions.cpp | 9 --------- src/ui/ScriptFunctions.hpp | 4 ---- src/ui/ScriptFunctionsSystem.cpp | 14 +++++++++++--- src/ui/ScriptFunctionsSystem.hpp | 6 ++++++ src/ui/game/ScriptEvents.cpp | 3 +-- 6 files changed, 19 insertions(+), 18 deletions(-) create mode 100644 src/ui/ScriptFunctionsSystem.hpp diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index 90fae26..fa46eed 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -27,6 +27,7 @@ #include "ui/Interface.hpp" #include "ui/Key.hpp" #include "ui/ScriptFunctions.hpp" +#include "ui/ScriptFunctionsSystem.hpp" #include "ui/game/CGVideoOptions.hpp" #include "ui/simple/CSimpleModelFFX.hpp" #include "ui/simple/CSimpleTop.hpp" diff --git a/src/ui/ScriptFunctions.cpp b/src/ui/ScriptFunctions.cpp index 977956f..e1a7943 100644 --- a/src/ui/ScriptFunctions.cpp +++ b/src/ui/ScriptFunctions.cpp @@ -54,12 +54,3 @@ void RegisterSimpleFrameScriptMethods() { // CSimpleColorSelect::CreateScriptMetaTable(); // CSimpleMovieFrame::CreateScriptMetaTable(); } - -void SystemRegisterFunctions() { - for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_SYSTEM; ++i) { - FrameScript_RegisterFunction( - FrameScript::s_ScriptFunctions_System[i].name, - FrameScript::s_ScriptFunctions_System[i].method - ); - } -} diff --git a/src/ui/ScriptFunctions.hpp b/src/ui/ScriptFunctions.hpp index bfbce2b..fc0853e 100644 --- a/src/ui/ScriptFunctions.hpp +++ b/src/ui/ScriptFunctions.hpp @@ -7,15 +7,11 @@ struct lua_State; #define NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME 7 -#define NUM_SCRIPT_FUNCTIONS_SYSTEM 7 namespace FrameScript { extern FrameScript_Method s_ScriptFunctions_SimpleFrame[NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME]; - extern FrameScript_Method s_ScriptFunctions_System[NUM_SCRIPT_FUNCTIONS_SYSTEM]; } void RegisterSimpleFrameScriptMethods(); -void SystemRegisterFunctions(); - #endif diff --git a/src/ui/ScriptFunctionsSystem.cpp b/src/ui/ScriptFunctionsSystem.cpp index f0fa93e..a1f04e4 100644 --- a/src/ui/ScriptFunctionsSystem.cpp +++ b/src/ui/ScriptFunctionsSystem.cpp @@ -1,4 +1,4 @@ -#include "ui/ScriptFunctions.hpp" +#include "ui/FrameScript.hpp" #include "ui/ScriptFunctionsShared.hpp" #include "ui/Types.hpp" #include "util/Lua.hpp" @@ -22,10 +22,12 @@ int32_t Script_ConsoleExec(lua_State* L) { } int32_t Script_AccessDenied(lua_State* L) { - return luaL_error(L, "Access Denied"); + luaL_error(L, "Access Denied"); + + return 0; } -FrameScript_Method FrameScript::s_ScriptFunctions_System[NUM_SCRIPT_FUNCTIONS_SYSTEM] = { +static FrameScript_Method s_SystemFunctions[] = { { "GetTime", &Script_GetTime }, { "GetGameTime", &Script_GetGameTime }, { "ConsoleExec", &Script_ConsoleExec }, @@ -34,3 +36,9 @@ FrameScript_Method FrameScript::s_ScriptFunctions_System[NUM_SCRIPT_FUNCTIONS_SY { "AppendToFile", &Script_AccessDenied }, { "GetAccountExpansionLevel", &Script_GetAccountExpansionLevel } }; + +void SystemRegisterFunctions() { + for (auto& func : s_SystemFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/ScriptFunctionsSystem.hpp b/src/ui/ScriptFunctionsSystem.hpp new file mode 100644 index 0000000..15fd17d --- /dev/null +++ b/src/ui/ScriptFunctionsSystem.hpp @@ -0,0 +1,6 @@ +#ifndef UI_SCRIPT_FUNCTIONS_SYSTEM_HPP +#define UI_SCRIPT_FUNCTIONS_SYSTEM_HPP + +void SystemRegisterFunctions(); + +#endif diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index 33419f3..258413b 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -1,7 +1,6 @@ #include "ui/game/ScriptEvents.hpp" #include "ui/FrameScript.hpp" -#include "ui/ScriptFunctions.hpp" -#include "ui/ScriptFunctionsShared.hpp" +#include "ui/ScriptFunctionsSystem.hpp" #include "util/Unimplemented.hpp" int32_t Script_UnitExists(lua_State* L) { From dc071210cabf494c8ae22583a0cc298ae79e07e4 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 15:54:06 -0600 Subject: [PATCH 013/114] chore(ui): clean up RegisterSimpleFrameScriptMethods --- src/glue/CGlueMgr.cpp | 2 +- src/ui/ScriptFunctions.cpp | 56 ------------------- src/ui/ScriptFunctions.hpp | 17 ------ src/ui/ScriptFunctionsShared.cpp | 2 +- .../ScriptMethods.cpp} | 56 ++++++++++++++++++- src/ui/simple/ScriptMethods.hpp | 6 ++ 6 files changed, 61 insertions(+), 78 deletions(-) delete mode 100644 src/ui/ScriptFunctions.cpp delete mode 100644 src/ui/ScriptFunctions.hpp rename src/ui/{ScriptFunctionsSimpleFrame.cpp => simple/ScriptMethods.cpp} (68%) create mode 100644 src/ui/simple/ScriptMethods.hpp diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index fa46eed..e19ad25 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -26,11 +26,11 @@ #include "ui/FrameXML.hpp" #include "ui/Interface.hpp" #include "ui/Key.hpp" -#include "ui/ScriptFunctions.hpp" #include "ui/ScriptFunctionsSystem.hpp" #include "ui/game/CGVideoOptions.hpp" #include "ui/simple/CSimpleModelFFX.hpp" #include "ui/simple/CSimpleTop.hpp" +#include "ui/simple/ScriptMethods.hpp" #include "util/Filesystem.hpp" #include "util/Locale.hpp" #include "util/Log.hpp" diff --git a/src/ui/ScriptFunctions.cpp b/src/ui/ScriptFunctions.cpp deleted file mode 100644 index e1a7943..0000000 --- a/src/ui/ScriptFunctions.cpp +++ /dev/null @@ -1,56 +0,0 @@ -#include "ui/ScriptFunctions.hpp" -#include "ui/FrameScript.hpp" -#include "ui/simple/CSimpleButton.hpp" -#include "ui/simple/CSimpleCheckbox.hpp" -#include "ui/simple/CSimpleEditBox.hpp" -#include "ui/simple/CSimpleFont.hpp" -#include "ui/simple/CSimpleFontString.hpp" -#include "ui/simple/CSimpleFrame.hpp" -#include "ui/simple/CSimpleHTML.hpp" -#include "ui/simple/CSimpleModel.hpp" -#include "ui/simple/CSimpleModelFFX.hpp" -#include "ui/simple/CSimpleScrollFrame.hpp" -#include "ui/simple/CSimpleSlider.hpp" -#include "ui/simple/CSimpleTexture.hpp" - -void RegisterSimpleFrameScriptMethods() { - for (int32_t i = 0; i < NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME; ++i) { - FrameScript_RegisterFunction( - FrameScript::s_ScriptFunctions_SimpleFrame[i].name, - FrameScript::s_ScriptFunctions_SimpleFrame[i].method - ); - } - - // TODO - // CSimpleAnim::CreateScriptMetaTable(); - // CSimpleTranslationAnim::CreateScriptMetaTable(); - // CSimpleRotationAnim::CreateScriptMetaTable(); - // CSimpleScaleAnim::CreateScriptMetaTable(); - // CSimpleControlPoint::CreateScriptMetaTable(); - // CSimplePathAnim::CreateScriptMetaTable(); - // CSimpleAlphaAnim::CreateScriptMetaTable(); - // CSimpleAnimGroup::CreateScriptMetaTable(); - - CSimpleFont::CreateScriptMetaTable(); - CSimpleTexture::CreateScriptMetaTable(); - CSimpleFontString::CreateScriptMetaTable(); - CSimpleFrame::CreateScriptMetaTable(); - CSimpleButton::CreateScriptMetaTable(); - CSimpleCheckbox::CreateScriptMetaTable(); - CSimpleEditBox::CreateScriptMetaTable(); - CSimpleHTML::CreateScriptMetaTable(); - - // TODO - // CSimpleMessageFrame::CreateScriptMetaTable(); - // CSimpleMessageScrollFrame::CreateScriptMetaTable(); - - CSimpleModel::CreateScriptMetaTable(); - CSimpleModelFFX::CreateScriptMetaTable(); - CSimpleScrollFrame::CreateScriptMetaTable(); - CSimpleSlider::CreateScriptMetaTable(); - - // TODO - // CSimpleStatusBar::CreateScriptMetaTable(); - // CSimpleColorSelect::CreateScriptMetaTable(); - // CSimpleMovieFrame::CreateScriptMetaTable(); -} diff --git a/src/ui/ScriptFunctions.hpp b/src/ui/ScriptFunctions.hpp deleted file mode 100644 index fc0853e..0000000 --- a/src/ui/ScriptFunctions.hpp +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef UI_SCRIPT_FUNCTIONS_HPP -#define UI_SCRIPT_FUNCTIONS_HPP - -#include "ui/Types.hpp" -#include - -struct lua_State; - -#define NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME 7 - -namespace FrameScript { - extern FrameScript_Method s_ScriptFunctions_SimpleFrame[NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME]; -} - -void RegisterSimpleFrameScriptMethods(); - -#endif diff --git a/src/ui/ScriptFunctionsShared.cpp b/src/ui/ScriptFunctionsShared.cpp index 96a9700..5ffb059 100644 --- a/src/ui/ScriptFunctionsShared.cpp +++ b/src/ui/ScriptFunctionsShared.cpp @@ -1,4 +1,4 @@ -#include "ui/ScriptFunctions.hpp" +#include "ui/ScriptFunctionsShared.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" #include diff --git a/src/ui/ScriptFunctionsSimpleFrame.cpp b/src/ui/simple/ScriptMethods.cpp similarity index 68% rename from src/ui/ScriptFunctionsSimpleFrame.cpp rename to src/ui/simple/ScriptMethods.cpp index cf2e6c4..c27b5d7 100644 --- a/src/ui/ScriptFunctionsSimpleFrame.cpp +++ b/src/ui/simple/ScriptMethods.cpp @@ -1,13 +1,24 @@ +#include "ui/simple/ScriptMethods.hpp" #include "ui/FrameXML.hpp" -#include "ui/ScriptFunctions.hpp" #include "ui/Types.hpp" +#include "ui/simple/CSimpleButton.hpp" +#include "ui/simple/CSimpleCheckbox.hpp" +#include "ui/simple/CSimpleEditBox.hpp" +#include "ui/simple/CSimpleFont.hpp" +#include "ui/simple/CSimpleFontString.hpp" #include "ui/simple/CSimpleFrame.hpp" +#include "ui/simple/CSimpleHTML.hpp" +#include "ui/simple/CSimpleModel.hpp" +#include "ui/simple/CSimpleModelFFX.hpp" +#include "ui/simple/CSimpleScrollFrame.hpp" +#include "ui/simple/CSimpleSlider.hpp" +#include "ui/simple/CSimpleTexture.hpp" #include "util/CStatus.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" #include -#include #include +#include int32_t Script_GetText(lua_State* L) { WHOA_UNIMPLEMENTED(0); @@ -137,7 +148,7 @@ int32_t Script_GetCurrentKeyBoardFocus(lua_State* L) { WHOA_UNIMPLEMENTED(0); } -FrameScript_Method FrameScript::s_ScriptFunctions_SimpleFrame[NUM_SCRIPT_FUNCTIONS_SIMPLE_FRAME] = { +static FrameScript_Method s_ScriptFunctions[] = { { "GetText", &Script_GetText }, { "GetNumFrames", &Script_GetNumFrames }, { "EnumerateFrames", &Script_EnumerateFrames }, @@ -146,3 +157,42 @@ FrameScript_Method FrameScript::s_ScriptFunctions_SimpleFrame[NUM_SCRIPT_FUNCTIO { "GetFramesRegisteredForEvent", &Script_GetFramesRegisteredForEvent }, { "GetCurrentKeyBoardFocus", &Script_GetCurrentKeyBoardFocus }, }; + +void RegisterSimpleFrameScriptMethods() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } + + // TODO + // CSimpleAnim::CreateScriptMetaTable(); + // CSimpleTranslationAnim::CreateScriptMetaTable(); + // CSimpleRotationAnim::CreateScriptMetaTable(); + // CSimpleScaleAnim::CreateScriptMetaTable(); + // CSimpleControlPoint::CreateScriptMetaTable(); + // CSimplePathAnim::CreateScriptMetaTable(); + // CSimpleAlphaAnim::CreateScriptMetaTable(); + // CSimpleAnimGroup::CreateScriptMetaTable(); + + CSimpleFont::CreateScriptMetaTable(); + CSimpleTexture::CreateScriptMetaTable(); + CSimpleFontString::CreateScriptMetaTable(); + CSimpleFrame::CreateScriptMetaTable(); + CSimpleButton::CreateScriptMetaTable(); + CSimpleCheckbox::CreateScriptMetaTable(); + CSimpleEditBox::CreateScriptMetaTable(); + CSimpleHTML::CreateScriptMetaTable(); + + // TODO + // CSimpleMessageFrame::CreateScriptMetaTable(); + // CSimpleMessageScrollFrame::CreateScriptMetaTable(); + + CSimpleModel::CreateScriptMetaTable(); + CSimpleModelFFX::CreateScriptMetaTable(); + CSimpleScrollFrame::CreateScriptMetaTable(); + CSimpleSlider::CreateScriptMetaTable(); + + // TODO + // CSimpleStatusBar::CreateScriptMetaTable(); + // CSimpleColorSelect::CreateScriptMetaTable(); + // CSimpleMovieFrame::CreateScriptMetaTable(); +} diff --git a/src/ui/simple/ScriptMethods.hpp b/src/ui/simple/ScriptMethods.hpp new file mode 100644 index 0000000..5d1e0e5 --- /dev/null +++ b/src/ui/simple/ScriptMethods.hpp @@ -0,0 +1,6 @@ +#ifndef UI_SIMPLE_SCRIPT_METHODS_HPP +#define UI_SIMPLE_SCRIPT_METHODS_HPP + +void RegisterSimpleFrameScriptMethods(); + +#endif From 6dd15ed2cf39162db052430f030ed191a441909c Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 16:35:15 -0600 Subject: [PATCH 014/114] feat(ui): add FrameScript_UnregisterFunction --- src/ui/FrameScript.cpp | 9 +++++++++ src/ui/FrameScript.hpp | 2 ++ 2 files changed, 11 insertions(+) diff --git a/src/ui/FrameScript.cpp b/src/ui/FrameScript.cpp index 0bdc56d..2945dcc 100644 --- a/src/ui/FrameScript.cpp +++ b/src/ui/FrameScript.cpp @@ -1047,6 +1047,15 @@ const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32 return buffer; } +void FrameScript_UnregisterFunction(char const* name) { + auto L = FrameScript::s_context; + + lua_pushnil(L); + lua_pushstring(L, name); + lua_insert(L, -2); + lua_rawset(L, LUA_GLOBALSINDEX); +} + void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event) { if (event->pendingSignalCount) { auto node = event->unregisterListeners.Head(); diff --git a/src/ui/FrameScript.hpp b/src/ui/FrameScript.hpp index 8685e26..c84f30a 100644 --- a/src/ui/FrameScript.hpp +++ b/src/ui/FrameScript.hpp @@ -99,6 +99,8 @@ void FrameScript_SignalEvent(uint32_t index, const char* format, ...); const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32_t bufferLen); +void FrameScript_UnregisterFunction(char const* name); + void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event); void ScriptEventsInitialize(); From c0ec4aed44f9fa64be607bcb039b36313ef33391 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 16:36:15 -0600 Subject: [PATCH 015/114] chore(ui): tweak style --- src/ui/FrameScript.cpp | 2 +- src/ui/FrameScript.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ui/FrameScript.cpp b/src/ui/FrameScript.cpp index 2945dcc..4ab2053 100644 --- a/src/ui/FrameScript.cpp +++ b/src/ui/FrameScript.cpp @@ -1047,7 +1047,7 @@ const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32 return buffer; } -void FrameScript_UnregisterFunction(char const* name) { +void FrameScript_UnregisterFunction(const char* name) { auto L = FrameScript::s_context; lua_pushnil(L); diff --git a/src/ui/FrameScript.hpp b/src/ui/FrameScript.hpp index c84f30a..e2e4c83 100644 --- a/src/ui/FrameScript.hpp +++ b/src/ui/FrameScript.hpp @@ -99,7 +99,7 @@ void FrameScript_SignalEvent(uint32_t index, const char* format, ...); const char* FrameScript_Sprintf(lua_State* L, int32_t idx, char buffer[], uint32_t bufferLen); -void FrameScript_UnregisterFunction(char const* name); +void FrameScript_UnregisterFunction(const char* name); void FrameScript_UnregisterScriptEvent(FrameScript_Object* object, FrameScript_EventObject* event); From 95a8f4287f4576069303459ed195638a3616e419 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 16:37:50 -0600 Subject: [PATCH 016/114] feat(ui): add SystemUnregisterFunctions --- src/ui/ScriptFunctionsSystem.cpp | 6 ++++++ src/ui/ScriptFunctionsSystem.hpp | 2 ++ 2 files changed, 8 insertions(+) diff --git a/src/ui/ScriptFunctionsSystem.cpp b/src/ui/ScriptFunctionsSystem.cpp index a1f04e4..72c13dd 100644 --- a/src/ui/ScriptFunctionsSystem.cpp +++ b/src/ui/ScriptFunctionsSystem.cpp @@ -42,3 +42,9 @@ void SystemRegisterFunctions() { FrameScript_RegisterFunction(func.name, func.method); } } + +void SystemUnregisterFunctions() { + for (auto& func : s_SystemFunctions) { + FrameScript_UnregisterFunction(func.name); + } +} diff --git a/src/ui/ScriptFunctionsSystem.hpp b/src/ui/ScriptFunctionsSystem.hpp index 15fd17d..67581e6 100644 --- a/src/ui/ScriptFunctionsSystem.hpp +++ b/src/ui/ScriptFunctionsSystem.hpp @@ -3,4 +3,6 @@ void SystemRegisterFunctions(); +void SystemUnregisterFunctions(); + #endif From a168c6fd41a06a6b80e3788f478fc20e7c4847cc Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 16:41:13 -0600 Subject: [PATCH 017/114] feat(glue): unregister system functions in CGlueMgr::Suspend --- src/glue/CGlueMgr.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/glue/CGlueMgr.cpp b/src/glue/CGlueMgr.cpp index e19ad25..6a21ac4 100644 --- a/src/glue/CGlueMgr.cpp +++ b/src/glue/CGlueMgr.cpp @@ -1187,6 +1187,10 @@ void CGlueMgr::Suspend() { // TODO + SystemUnregisterFunctions(); + + // TODO + FrameXML_FreeHashNodes(); // TODO From 61b05eb3664b1c8427aba8f1f05b3dabf987c08d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 26 Jan 2026 21:11:36 -0600 Subject: [PATCH 018/114] feat(ui): add GMTicketInfoRegisterScriptFunctions --- src/ui/game/CGGameUI.cpp | 5 ++ src/ui/game/GMTicketInfoScript.cpp | 87 ++++++++++++++++++++++++++++++ src/ui/game/GMTicketInfoScript.hpp | 6 +++ 3 files changed, 98 insertions(+) create mode 100644 src/ui/game/GMTicketInfoScript.cpp create mode 100644 src/ui/game/GMTicketInfoScript.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 4e6277a..852e9e4 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -3,6 +3,7 @@ #include "ui/FrameXML.hpp" #include "ui/Key.hpp" #include "ui/game/CGWorldFrame.hpp" +#include "ui/game/GMTicketInfoScript.hpp" #include "ui/game/ScriptEvents.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" @@ -16,6 +17,10 @@ void LoadScriptFunctions() { ScriptEventsRegisterFunctions(); // TODO + + GMTicketInfoRegisterScriptFunctions(); + + // TODO } void CGGameUI::Initialize() { diff --git a/src/ui/game/GMTicketInfoScript.cpp b/src/ui/game/GMTicketInfoScript.cpp new file mode 100644 index 0000000..302a150 --- /dev/null +++ b/src/ui/game/GMTicketInfoScript.cpp @@ -0,0 +1,87 @@ +#include "ui/game/GMTicketInfoScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +int32_t Script_GetGMTicket(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_NewGMTicket(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UpdateGMTicket(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeleteGMTicket(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMResponseNeedMoreHelp(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMResponseResolve(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetGMStatus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveyQuestion(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveyNumAnswers(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveyAnswer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveyAnswerSubmit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveyCommentSubmit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMSurveySubmit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMReportLag(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RegisterStaticConstants(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "GetGMTicket", &Script_GetGMTicket }, + { "NewGMTicket", &Script_NewGMTicket }, + { "UpdateGMTicket", &Script_UpdateGMTicket }, + { "DeleteGMTicket", &Script_DeleteGMTicket }, + { "GMResponseNeedMoreHelp", &Script_GMResponseNeedMoreHelp }, + { "GMResponseResolve", &Script_GMResponseResolve }, + { "GetGMStatus", &Script_GetGMStatus }, + { "GMSurveyQuestion", &Script_GMSurveyQuestion }, + { "GMSurveyNumAnswers", &Script_GMSurveyNumAnswers }, + { "GMSurveyAnswer", &Script_GMSurveyAnswer }, + { "GMSurveyAnswerSubmit", &Script_GMSurveyAnswerSubmit }, + { "GMSurveyCommentSubmit", &Script_GMSurveyCommentSubmit }, + { "GMSurveySubmit", &Script_GMSurveySubmit }, + { "GMReportLag", &Script_GMReportLag }, + { "RegisterStaticConstants", &Script_RegisterStaticConstants }, +}; + +void GMTicketInfoRegisterScriptFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/GMTicketInfoScript.hpp b/src/ui/game/GMTicketInfoScript.hpp new file mode 100644 index 0000000..1a0c64f --- /dev/null +++ b/src/ui/game/GMTicketInfoScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_GM_TICKET_INFO_SCRIPT_HPP +#define UI_GAME_GM_TICKET_INFO_SCRIPT_HPP + +void GMTicketInfoRegisterScriptFunctions(); + +#endif From bc1d7cbd663ff628703b306fb67a296999015fe2 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 05:28:39 -0600 Subject: [PATCH 019/114] feat(ui): add GameScriptRegisterFunctions --- src/glue/GlueScript.cpp | 30 - src/ui/ScriptFunctionsShared.cpp | 30 + src/ui/ScriptFunctionsShared.hpp | 6 + src/ui/game/CGGameUI.cpp | 5 + src/ui/game/GameScript.cpp | 1554 ++++++++++++++++++++++++++++++ src/ui/game/GameScript.hpp | 6 + 6 files changed, 1601 insertions(+), 30 deletions(-) create mode 100644 src/ui/game/GameScript.cpp create mode 100644 src/ui/game/GameScript.hpp diff --git a/src/glue/GlueScript.cpp b/src/glue/GlueScript.cpp index 1730888..1e8cd23 100644 --- a/src/glue/GlueScript.cpp +++ b/src/glue/GlueScript.cpp @@ -522,36 +522,6 @@ int32_t Script_IsScanDLLFinished(lua_State* L) { return 1; } -int32_t Script_IsWindowsClient(lua_State* L) { -#if defined(WHOA_SYSTEM_WIN) - lua_pushnumber(L, 1.0); -#else - lua_pushnil(L); -#endif - - return 1; -} - -int32_t Script_IsMacClient(lua_State* L) { -#if defined(WHOA_SYSTEM_MAC) - lua_pushnumber(L, 1.0); -#else - lua_pushnil(L); -#endif - - return 1; -} - -int32_t Script_IsLinuxClient(lua_State* L) { -#if defined(WHOA_SYSTEM_LINUX) - lua_pushnumber(L, 1.0); -#else - lua_pushnil(L); -#endif - - return 1; -} - int32_t Script_SetRealmSplitState(lua_State* L) { WHOA_UNIMPLEMENTED(0); } diff --git a/src/ui/ScriptFunctionsShared.cpp b/src/ui/ScriptFunctionsShared.cpp index 5ffb059..c6e1289 100644 --- a/src/ui/ScriptFunctionsShared.cpp +++ b/src/ui/ScriptFunctionsShared.cpp @@ -6,3 +6,33 @@ int32_t Script_GetAccountExpansionLevel(lua_State* L) { WHOA_UNIMPLEMENTED(0); } + +int32_t Script_IsLinuxClient(lua_State* L) { +#if defined(WHOA_SYSTEM_LINUX) + lua_pushnumber(L, 1.0); +#else + lua_pushnil(L); +#endif + + return 1; +} + +int32_t Script_IsMacClient(lua_State* L) { +#if defined(WHOA_SYSTEM_MAC) + lua_pushnumber(L, 1.0); +#else + lua_pushnil(L); +#endif + + return 1; +} + +int32_t Script_IsWindowsClient(lua_State* L) { +#if defined(WHOA_SYSTEM_WIN) + lua_pushnumber(L, 1.0); +#else + lua_pushnil(L); +#endif + + return 1; +} diff --git a/src/ui/ScriptFunctionsShared.hpp b/src/ui/ScriptFunctionsShared.hpp index 04e196b..1c80788 100644 --- a/src/ui/ScriptFunctionsShared.hpp +++ b/src/ui/ScriptFunctionsShared.hpp @@ -6,4 +6,10 @@ int32_t Script_GetAccountExpansionLevel(lua_State* L); +int32_t Script_IsLinuxClient(lua_State* L); + +int32_t Script_IsMacClient(lua_State* L); + +int32_t Script_IsWindowsClient(lua_State* L); + #endif diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 852e9e4..0f527fd 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -4,6 +4,7 @@ #include "ui/Key.hpp" #include "ui/game/CGWorldFrame.hpp" #include "ui/game/GMTicketInfoScript.hpp" +#include "ui/game/GameScript.hpp" #include "ui/game/ScriptEvents.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" @@ -14,6 +15,10 @@ CSimpleTop* CGGameUI::s_simpleTop; void LoadScriptFunctions() { // TODO + GameScriptRegisterFunctions(); + + // TODO + ScriptEventsRegisterFunctions(); // TODO diff --git a/src/ui/game/GameScript.cpp b/src/ui/game/GameScript.cpp new file mode 100644 index 0000000..bc194d8 --- /dev/null +++ b/src/ui/game/GameScript.cpp @@ -0,0 +1,1554 @@ +#include "ui/game/GameScript.hpp" +#include "ui/FrameScript.hpp" +#include "ui/ScriptFunctionsShared.hpp" +#include "util/Unimplemented.hpp" + +namespace { +int32_t Script_FrameXML_Debug(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBuildInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReloadUI(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RegisterForSave(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RegisterForSavePerCharacter(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetLayoutMode(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsModifierKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsLeftShiftKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsRightShiftKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsShiftKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsLeftControlKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsRightControlKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsControlKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsLeftAltKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsRightAltKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsAltKeyDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsMouseButtonDown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMouseButtonName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMouseButtonClicked(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetConsoleKey(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Screenshot(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetFramerate(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePerformanceDisplay(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePerformancePause(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePerformanceValues(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResetPerformanceValues(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetDebugStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsDebugBuild(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RegisterCVar(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetCVar(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVar(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarBool(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarDefault(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarMin(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarAbsoluteMin(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCVarAbsoluteMax(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetWaterDetail(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetWaterDetail(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetFarclip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetFarclip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTexLodBias(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetTexLodBias(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBaseMip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBaseMip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ToggleTris(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePortals(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ToggleCollision(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ToggleCollisionDisplay(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePlayerBounds(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Stuck(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Logout(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Quit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetCursor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResetCursor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ClearCursor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CursorHasItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CursorHasSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CursorHasMacro(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CursorHasMoney(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCursorInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EquipCursorItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeleteCursorItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EquipPendingItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CancelPendingEquip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearest(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestEnemy(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestEnemyPlayer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestFriendPlayer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestPartyMember(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetNearestRaidMember(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetDirectionEnemy(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetDirectionFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetDirectionFinished(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetLastTarget(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetLastEnemy(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetLastFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AttackTarget(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AssistUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_FocusUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_FollowUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_InteractUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ClearTarget(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ClearFocus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AutoEquipCursorItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ToggleSheath(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetZoneText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRealZoneText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSubZoneText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMinimapZoneText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_InitiateTrade(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanInspect(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_NotifyInspect(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_InviteUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UninviteUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RequestTimePlayed(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RepopMe(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptResurrect(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineResurrect(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResurrectGetOfferer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResurrectHasSickness(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResurrectHasTimer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BeginTrade(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CancelTrade(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptGroup(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineGroup(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptGuild(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineGuild(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptArenaTeam(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineArenaTeam(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CancelLogout(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ForceLogout(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ForceQuit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCursorMoney(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DropCursorMoney(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PickupPlayerMoney(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasSoulstone(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UseSoulstone(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasKey(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildInvite(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildUninvite(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildPromote(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildDemote(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildSetLeader(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildSetMOTD(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildLeave(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildDisband(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GuildInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ArenaTeamInviteByName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ArenaTeamLeave(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ArenaTeamUninviteByName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ArenaTeamSetLeaderByName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ArenaTeamDisband(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetScreenWidth(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetScreenHeight(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetDamageBonusStat(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetReleaseTimeRemaining(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCorpseRecoveryDelay(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInstanceBootTimeRemaining(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInstanceLockTimeRemaining(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInstanceLockTimeRemainingEncounter(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSummonConfirmTimeLeft(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSummonConfirmSummoner(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSummonConfirmAreaName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ConfirmSummon(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CancelSummon(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCursorPosition(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNetStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SitStandOrDescendStart(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_StopCinematic(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RunScript(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CheckInteractDistance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RandomRoll(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_OpeningCinematic(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_InCinematic(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptXPLoss(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CheckSpiritHealerDist(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CheckTalentMasterDist(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CheckBinderDist(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RetrieveCorpse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BindEnchant(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReplaceEnchant(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReplaceTradeEnchant(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_NotWhileDeadError(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRestState(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetXPExhaustion(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTimeToWellRested(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GMRequestPlayerInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCoinIcon(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCoinText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCoinTextureString(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsSubZonePVPPOI(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetZonePVPInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TogglePVP(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetPVP(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPDesired(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetPVPTimer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsPVPTimerRunning(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ConfirmBindOnUse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetPortraitToTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetLocale(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetGMTicketCategories(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DropItemOnUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RestartGx(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RestoreVideoResolutionDefaults(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RestoreVideoEffectsDefaults(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RestoreVideoStereoDefaults(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBindLocation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ConfirmTalentWipe(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ConfirmBinder(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ShowingHelm(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ShowingCloak(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ShowHelm(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ShowCloak(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetEuropeanNumbers(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAreaSpiritHealerTime(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptAreaSpiritHeal(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CancelAreaSpiritHeal(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMouseFocus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRealmName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemQualityColor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemGem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetExtendedItemInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemIcon(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemFamily(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemCount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PickupItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsCurrentItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsUsableItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsHelpfulItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsHarmfulItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsConsumableItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsEquippableItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsEquippedItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsEquippedItemType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsDressableItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ItemHasRange(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsItemInRange(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumAddOns(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAddOnInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAddOnMetadata(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UpdateAddOnMemoryUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAddOnMemoryUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetScriptCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UpdateAddOnCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAddOnCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetFunctionCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetFrameCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetEventCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResetCPUUsage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAddOnDependencies(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EnableAddOn(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EnableAllAddOns(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DisableAddOn(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DisableAllAddOns(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResetDisabledAddOns(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsAddOnLoadOnDemand(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsAddOnLoaded(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_LoadAddOn(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PartialPlayTime(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_NoPlayTime(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBillingTimeRested(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanShowResetInstances(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ResetInstances(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsInInstance(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInstanceDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInstanceInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetDungeonDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetDungeonDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRaidDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetRaidDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReportBug(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ReportSuggestion(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMirrorTimerInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMirrorTimerProgress(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumTitles(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCurrentTitle(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetCurrentTitle(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsTitleKnown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTitleName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UseItemByName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EquipItemByName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetExistingLocales(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_InCombatLockdown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_StartAttack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_StopAttack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetTaxiBenchmarkMode(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTaxiBenchmarkMode(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Dismount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_VoicePushToTalkStart(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_VoicePushToTalkStop(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetUIVisibility(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsReferAFriendLinked(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanGrantLevel(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GrantLevel(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanSummonFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SummonFriend(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSummonFriendCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTotemInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetTotemTimeLeft(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TargetTotem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DestroyTotem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumDeclensionSets(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptLevelGrant(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DeclineLevelGrant(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UploadSettings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_DownloadSettings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMovieResolution(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GameMovieFinished(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsDesaturateSupported(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetThreatStatusColor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsThreatWarningEnabled(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ConsoleAddMessage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetItemUniqueness(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EndRefund(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_EndBoundTradeable(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanMapChangeDifficulty(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetExpansionLevel(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetAllowLowLevelRaid(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetAllowLowLevelRaid(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "FrameXML_Debug", &Script_FrameXML_Debug }, + { "GetBuildInfo", &Script_GetBuildInfo }, + { "ReloadUI", &Script_ReloadUI }, + { "RegisterForSave", &Script_RegisterForSave }, + { "RegisterForSavePerCharacter", &Script_RegisterForSavePerCharacter }, + { "SetLayoutMode", &Script_SetLayoutMode }, + { "IsModifierKeyDown", &Script_IsModifierKeyDown }, + { "IsLeftShiftKeyDown", &Script_IsLeftShiftKeyDown }, + { "IsRightShiftKeyDown", &Script_IsRightShiftKeyDown }, + { "IsShiftKeyDown", &Script_IsShiftKeyDown }, + { "IsLeftControlKeyDown", &Script_IsLeftControlKeyDown }, + { "IsRightControlKeyDown", &Script_IsRightControlKeyDown }, + { "IsControlKeyDown", &Script_IsControlKeyDown }, + { "IsLeftAltKeyDown", &Script_IsLeftAltKeyDown }, + { "IsRightAltKeyDown", &Script_IsRightAltKeyDown }, + { "IsAltKeyDown", &Script_IsAltKeyDown }, + { "IsMouseButtonDown", &Script_IsMouseButtonDown }, + { "GetMouseButtonName", &Script_GetMouseButtonName }, + { "GetMouseButtonClicked", &Script_GetMouseButtonClicked }, + { "SetConsoleKey", &Script_SetConsoleKey }, + { "Screenshot", &Script_Screenshot }, + { "GetFramerate", &Script_GetFramerate }, + { "TogglePerformanceDisplay", &Script_TogglePerformanceDisplay }, + { "TogglePerformancePause", &Script_TogglePerformancePause }, + { "TogglePerformanceValues", &Script_TogglePerformanceValues }, + { "ResetPerformanceValues", &Script_ResetPerformanceValues }, + { "GetDebugStats", &Script_GetDebugStats }, + { "IsDebugBuild", &Script_IsDebugBuild }, + { "RegisterCVar", &Script_RegisterCVar }, + { "GetCVarInfo", &Script_GetCVarInfo }, + { "SetCVar", &Script_SetCVar }, + { "GetCVar", &Script_GetCVar }, + { "GetCVarBool", &Script_GetCVarBool }, + { "GetCVarDefault", &Script_GetCVarDefault }, + { "GetCVarMin", &Script_GetCVarMin }, + { "GetCVarMax", &Script_GetCVarMax }, + { "GetCVarAbsoluteMin", &Script_GetCVarAbsoluteMin }, + { "GetCVarAbsoluteMax", &Script_GetCVarAbsoluteMax }, + { "GetWaterDetail", &Script_GetWaterDetail }, + { "SetWaterDetail", &Script_SetWaterDetail }, + { "GetFarclip", &Script_GetFarclip }, + { "SetFarclip", &Script_SetFarclip }, + { "GetTexLodBias", &Script_GetTexLodBias }, + { "SetTexLodBias", &Script_SetTexLodBias }, + { "SetBaseMip", &Script_SetBaseMip }, + { "GetBaseMip", &Script_GetBaseMip }, + { "ToggleTris", &Script_ToggleTris }, + { "TogglePortals", &Script_TogglePortals }, + { "ToggleCollision", &Script_ToggleCollision }, + { "ToggleCollisionDisplay", &Script_ToggleCollisionDisplay }, + { "TogglePlayerBounds", &Script_TogglePlayerBounds }, + { "Stuck", &Script_Stuck }, + { "Logout", &Script_Logout }, + { "Quit", &Script_Quit }, + { "SetCursor", &Script_SetCursor }, + { "ResetCursor", &Script_ResetCursor }, + { "ClearCursor", &Script_ClearCursor }, + { "CursorHasItem", &Script_CursorHasItem }, + { "CursorHasSpell", &Script_CursorHasSpell }, + { "CursorHasMacro", &Script_CursorHasMacro }, + { "CursorHasMoney", &Script_CursorHasMoney }, + { "GetCursorInfo", &Script_GetCursorInfo }, + { "EquipCursorItem", &Script_EquipCursorItem }, + { "DeleteCursorItem", &Script_DeleteCursorItem }, + { "EquipPendingItem", &Script_EquipPendingItem }, + { "CancelPendingEquip", &Script_CancelPendingEquip }, + { "TargetUnit", &Script_TargetUnit }, + { "TargetNearest", &Script_TargetNearest }, + { "TargetNearestEnemy", &Script_TargetNearestEnemy }, + { "TargetNearestEnemyPlayer", &Script_TargetNearestEnemyPlayer }, + { "TargetNearestFriend", &Script_TargetNearestFriend }, + { "TargetNearestFriendPlayer", &Script_TargetNearestFriendPlayer }, + { "TargetNearestPartyMember", &Script_TargetNearestPartyMember }, + { "TargetNearestRaidMember", &Script_TargetNearestRaidMember }, + { "TargetDirectionEnemy", &Script_TargetDirectionEnemy }, + { "TargetDirectionFriend", &Script_TargetDirectionFriend }, + { "TargetDirectionFinished", &Script_TargetDirectionFinished }, + { "TargetLastTarget", &Script_TargetLastTarget }, + { "TargetLastEnemy", &Script_TargetLastEnemy }, + { "TargetLastFriend", &Script_TargetLastFriend }, + { "AttackTarget", &Script_AttackTarget }, + { "AssistUnit", &Script_AssistUnit }, + { "FocusUnit", &Script_FocusUnit }, + { "FollowUnit", &Script_FollowUnit }, + { "InteractUnit", &Script_InteractUnit }, + { "ClearTarget", &Script_ClearTarget }, + { "ClearFocus", &Script_ClearFocus }, + { "AutoEquipCursorItem", &Script_AutoEquipCursorItem }, + { "ToggleSheath", &Script_ToggleSheath }, + { "GetZoneText", &Script_GetZoneText }, + { "GetRealZoneText", &Script_GetRealZoneText }, + { "GetSubZoneText", &Script_GetSubZoneText }, + { "GetMinimapZoneText", &Script_GetMinimapZoneText }, + { "InitiateTrade", &Script_InitiateTrade }, + { "CanInspect", &Script_CanInspect }, + { "NotifyInspect", &Script_NotifyInspect }, + { "InviteUnit", &Script_InviteUnit }, + { "UninviteUnit", &Script_UninviteUnit }, + { "RequestTimePlayed", &Script_RequestTimePlayed }, + { "RepopMe", &Script_RepopMe }, + { "AcceptResurrect", &Script_AcceptResurrect }, + { "DeclineResurrect", &Script_DeclineResurrect }, + { "ResurrectGetOfferer", &Script_ResurrectGetOfferer }, + { "ResurrectHasSickness", &Script_ResurrectHasSickness }, + { "ResurrectHasTimer", &Script_ResurrectHasTimer }, + { "BeginTrade", &Script_BeginTrade }, + { "CancelTrade", &Script_CancelTrade }, + { "AcceptGroup", &Script_AcceptGroup }, + { "DeclineGroup", &Script_DeclineGroup }, + { "AcceptGuild", &Script_AcceptGuild }, + { "DeclineGuild", &Script_DeclineGuild }, + { "AcceptArenaTeam", &Script_AcceptArenaTeam }, + { "DeclineArenaTeam", &Script_DeclineArenaTeam }, + { "CancelLogout", &Script_CancelLogout }, + { "ForceLogout", &Script_ForceLogout }, + { "ForceQuit", &Script_ForceQuit }, + { "GetCursorMoney", &Script_GetCursorMoney }, + { "DropCursorMoney", &Script_DropCursorMoney }, + { "PickupPlayerMoney", &Script_PickupPlayerMoney }, + { "HasSoulstone", &Script_HasSoulstone }, + { "UseSoulstone", &Script_UseSoulstone }, + { "HasKey", &Script_HasKey }, + { "GuildInvite", &Script_GuildInvite }, + { "GuildUninvite", &Script_GuildUninvite }, + { "GuildPromote", &Script_GuildPromote }, + { "GuildDemote", &Script_GuildDemote }, + { "GuildSetLeader", &Script_GuildSetLeader }, + { "GuildSetMOTD", &Script_GuildSetMOTD }, + { "GuildLeave", &Script_GuildLeave }, + { "GuildDisband", &Script_GuildDisband }, + { "GuildInfo", &Script_GuildInfo }, + { "ArenaTeamInviteByName", &Script_ArenaTeamInviteByName }, + { "ArenaTeamLeave", &Script_ArenaTeamLeave }, + { "ArenaTeamUninviteByName", &Script_ArenaTeamUninviteByName }, + { "ArenaTeamSetLeaderByName", &Script_ArenaTeamSetLeaderByName }, + { "ArenaTeamDisband", &Script_ArenaTeamDisband }, + { "GetScreenWidth", &Script_GetScreenWidth }, + { "GetScreenHeight", &Script_GetScreenHeight }, + { "GetDamageBonusStat", &Script_GetDamageBonusStat }, + { "GetReleaseTimeRemaining", &Script_GetReleaseTimeRemaining }, + { "GetCorpseRecoveryDelay", &Script_GetCorpseRecoveryDelay }, + { "GetInstanceBootTimeRemaining", &Script_GetInstanceBootTimeRemaining }, + { "GetInstanceLockTimeRemaining", &Script_GetInstanceLockTimeRemaining }, + { "GetInstanceLockTimeRemainingEncounter", &Script_GetInstanceLockTimeRemainingEncounter }, + { "GetSummonConfirmTimeLeft", &Script_GetSummonConfirmTimeLeft }, + { "GetSummonConfirmSummoner", &Script_GetSummonConfirmSummoner }, + { "GetSummonConfirmAreaName", &Script_GetSummonConfirmAreaName }, + { "ConfirmSummon", &Script_ConfirmSummon }, + { "CancelSummon", &Script_CancelSummon }, + { "GetCursorPosition", &Script_GetCursorPosition }, + { "GetNetStats", &Script_GetNetStats }, + { "SitStandOrDescendStart", &Script_SitStandOrDescendStart }, + { "StopCinematic", &Script_StopCinematic }, + { "RunScript", &Script_RunScript }, + { "CheckInteractDistance", &Script_CheckInteractDistance }, + { "RandomRoll", &Script_RandomRoll }, + { "OpeningCinematic", &Script_OpeningCinematic }, + { "InCinematic", &Script_InCinematic }, + { "IsWindowsClient", &Script_IsWindowsClient }, + { "IsMacClient", &Script_IsMacClient }, + { "IsLinuxClient", &Script_IsLinuxClient }, + { "AcceptXPLoss", &Script_AcceptXPLoss }, + { "CheckSpiritHealerDist", &Script_CheckSpiritHealerDist }, + { "CheckTalentMasterDist", &Script_CheckTalentMasterDist }, + { "CheckBinderDist", &Script_CheckBinderDist }, + { "RetrieveCorpse", &Script_RetrieveCorpse }, + { "BindEnchant", &Script_BindEnchant }, + { "ReplaceEnchant", &Script_ReplaceEnchant }, + { "ReplaceTradeEnchant", &Script_ReplaceTradeEnchant }, + { "NotWhileDeadError", &Script_NotWhileDeadError }, + { "GetRestState", &Script_GetRestState }, + { "GetXPExhaustion", &Script_GetXPExhaustion }, + { "GetTimeToWellRested", &Script_GetTimeToWellRested }, + { "GMRequestPlayerInfo", &Script_GMRequestPlayerInfo }, + { "GetCoinIcon", &Script_GetCoinIcon }, + { "GetCoinText", &Script_GetCoinText }, + { "GetCoinTextureString", &Script_GetCoinTextureString }, + { "IsSubZonePVPPOI", &Script_IsSubZonePVPPOI }, + { "GetZonePVPInfo", &Script_GetZonePVPInfo }, + { "TogglePVP", &Script_TogglePVP }, + { "SetPVP", &Script_SetPVP }, + { "GetPVPDesired", &Script_GetPVPDesired }, + { "GetPVPTimer", &Script_GetPVPTimer }, + { "IsPVPTimerRunning", &Script_IsPVPTimerRunning }, + { "ConfirmBindOnUse", &Script_ConfirmBindOnUse }, + { "SetPortraitToTexture", &Script_SetPortraitToTexture }, + { "GetLocale", &Script_GetLocale }, + { "GetGMTicketCategories", &Script_GetGMTicketCategories }, + { "DropItemOnUnit", &Script_DropItemOnUnit }, + { "RestartGx", &Script_RestartGx }, + { "RestoreVideoResolutionDefaults", &Script_RestoreVideoResolutionDefaults }, + { "RestoreVideoEffectsDefaults", &Script_RestoreVideoEffectsDefaults }, + { "RestoreVideoStereoDefaults", &Script_RestoreVideoStereoDefaults }, + { "GetBindLocation", &Script_GetBindLocation }, + { "ConfirmTalentWipe", &Script_ConfirmTalentWipe }, + { "ConfirmBinder", &Script_ConfirmBinder }, + { "ShowingHelm", &Script_ShowingHelm }, + { "ShowingCloak", &Script_ShowingCloak }, + { "ShowHelm", &Script_ShowHelm }, + { "ShowCloak", &Script_ShowCloak }, + { "SetEuropeanNumbers", &Script_SetEuropeanNumbers }, + { "GetAreaSpiritHealerTime", &Script_GetAreaSpiritHealerTime }, + { "AcceptAreaSpiritHeal", &Script_AcceptAreaSpiritHeal }, + { "CancelAreaSpiritHeal", &Script_CancelAreaSpiritHeal }, + { "GetMouseFocus", &Script_GetMouseFocus }, + { "GetRealmName", &Script_GetRealmName }, + { "GetItemQualityColor", &Script_GetItemQualityColor }, + { "GetItemInfo", &Script_GetItemInfo }, + { "GetItemGem", &Script_GetItemGem }, + { "GetExtendedItemInfo", &Script_GetExtendedItemInfo }, + { "GetItemIcon", &Script_GetItemIcon }, + { "GetItemFamily", &Script_GetItemFamily }, + { "GetItemCount", &Script_GetItemCount }, + { "GetItemSpell", &Script_GetItemSpell }, + { "GetItemCooldown", &Script_GetItemCooldown }, + { "PickupItem", &Script_PickupItem }, + { "IsCurrentItem", &Script_IsCurrentItem }, + { "IsUsableItem", &Script_IsUsableItem }, + { "IsHelpfulItem", &Script_IsHelpfulItem }, + { "IsHarmfulItem", &Script_IsHarmfulItem }, + { "IsConsumableItem", &Script_IsConsumableItem }, + { "IsEquippableItem", &Script_IsEquippableItem }, + { "IsEquippedItem", &Script_IsEquippedItem }, + { "IsEquippedItemType", &Script_IsEquippedItemType }, + { "IsDressableItem", &Script_IsDressableItem }, + { "ItemHasRange", &Script_ItemHasRange }, + { "IsItemInRange", &Script_IsItemInRange }, + { "GetNumAddOns", &Script_GetNumAddOns }, + { "GetAddOnInfo", &Script_GetAddOnInfo }, + { "GetAddOnMetadata", &Script_GetAddOnMetadata }, + { "UpdateAddOnMemoryUsage", &Script_UpdateAddOnMemoryUsage }, + { "GetAddOnMemoryUsage", &Script_GetAddOnMemoryUsage }, + { "GetScriptCPUUsage", &Script_GetScriptCPUUsage }, + { "UpdateAddOnCPUUsage", &Script_UpdateAddOnCPUUsage }, + { "GetAddOnCPUUsage", &Script_GetAddOnCPUUsage }, + { "GetFunctionCPUUsage", &Script_GetFunctionCPUUsage }, + { "GetFrameCPUUsage", &Script_GetFrameCPUUsage }, + { "GetEventCPUUsage", &Script_GetEventCPUUsage }, + { "ResetCPUUsage", &Script_ResetCPUUsage }, + { "GetAddOnDependencies", &Script_GetAddOnDependencies }, + { "EnableAddOn", &Script_EnableAddOn }, + { "EnableAllAddOns", &Script_EnableAllAddOns }, + { "DisableAddOn", &Script_DisableAddOn }, + { "DisableAllAddOns", &Script_DisableAllAddOns }, + { "ResetDisabledAddOns", &Script_ResetDisabledAddOns }, + { "IsAddOnLoadOnDemand", &Script_IsAddOnLoadOnDemand }, + { "IsAddOnLoaded", &Script_IsAddOnLoaded }, + { "LoadAddOn", &Script_LoadAddOn }, + { "PartialPlayTime", &Script_PartialPlayTime }, + { "NoPlayTime", &Script_NoPlayTime }, + { "GetBillingTimeRested", &Script_GetBillingTimeRested }, + { "CanShowResetInstances", &Script_CanShowResetInstances }, + { "ResetInstances", &Script_ResetInstances }, + { "IsInInstance", &Script_IsInInstance }, + { "GetInstanceDifficulty", &Script_GetInstanceDifficulty }, + { "GetInstanceInfo", &Script_GetInstanceInfo }, + { "GetDungeonDifficulty", &Script_GetDungeonDifficulty }, + { "SetDungeonDifficulty", &Script_SetDungeonDifficulty }, + { "GetRaidDifficulty", &Script_GetRaidDifficulty }, + { "SetRaidDifficulty", &Script_SetRaidDifficulty }, + { "ReportBug", &Script_ReportBug }, + { "ReportSuggestion", &Script_ReportSuggestion }, + { "GetMirrorTimerInfo", &Script_GetMirrorTimerInfo }, + { "GetMirrorTimerProgress", &Script_GetMirrorTimerProgress }, + { "GetNumTitles", &Script_GetNumTitles }, + { "GetCurrentTitle", &Script_GetCurrentTitle }, + { "SetCurrentTitle", &Script_SetCurrentTitle }, + { "IsTitleKnown", &Script_IsTitleKnown }, + { "GetTitleName", &Script_GetTitleName }, + { "UseItemByName", &Script_UseItemByName }, + { "EquipItemByName", &Script_EquipItemByName }, + { "GetExistingLocales", &Script_GetExistingLocales }, + { "InCombatLockdown", &Script_InCombatLockdown }, + { "StartAttack", &Script_StartAttack }, + { "StopAttack", &Script_StopAttack }, + { "SetTaxiBenchmarkMode", &Script_SetTaxiBenchmarkMode }, + { "GetTaxiBenchmarkMode", &Script_GetTaxiBenchmarkMode }, + { "Dismount", &Script_Dismount }, + { "VoicePushToTalkStart", &Script_VoicePushToTalkStart }, + { "VoicePushToTalkStop", &Script_VoicePushToTalkStop }, + { "SetUIVisibility", &Script_SetUIVisibility }, + { "IsReferAFriendLinked", &Script_IsReferAFriendLinked }, + { "CanGrantLevel", &Script_CanGrantLevel }, + { "GrantLevel", &Script_GrantLevel }, + { "CanSummonFriend", &Script_CanSummonFriend }, + { "SummonFriend", &Script_SummonFriend }, + { "GetSummonFriendCooldown", &Script_GetSummonFriendCooldown }, + { "GetTotemInfo", &Script_GetTotemInfo }, + { "GetTotemTimeLeft", &Script_GetTotemTimeLeft }, + { "TargetTotem", &Script_TargetTotem }, + { "DestroyTotem", &Script_DestroyTotem }, + { "GetNumDeclensionSets", &Script_GetNumDeclensionSets }, + { "DeclineName", &Script_DeclineName }, + { "AcceptLevelGrant", &Script_AcceptLevelGrant }, + { "DeclineLevelGrant", &Script_DeclineLevelGrant }, + { "UploadSettings", &Script_UploadSettings }, + { "DownloadSettings", &Script_DownloadSettings }, + { "GetMovieResolution", &Script_GetMovieResolution }, + { "GameMovieFinished", &Script_GameMovieFinished }, + { "IsDesaturateSupported", &Script_IsDesaturateSupported }, + { "GetThreatStatusColor", &Script_GetThreatStatusColor }, + { "IsThreatWarningEnabled", &Script_IsThreatWarningEnabled }, + { "ConsoleAddMessage", &Script_ConsoleAddMessage }, + { "GetItemUniqueness", &Script_GetItemUniqueness }, + { "EndRefund", &Script_EndRefund }, + { "EndBoundTradeable", &Script_EndBoundTradeable }, + { "CanMapChangeDifficulty", &Script_CanMapChangeDifficulty }, + { "GetExpansionLevel", &Script_GetExpansionLevel }, + { "GetAllowLowLevelRaid", &Script_GetAllowLowLevelRaid }, + { "SetAllowLowLevelRaid", &Script_SetAllowLowLevelRaid }, +}; + +void GameScriptRegisterFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/GameScript.hpp b/src/ui/game/GameScript.hpp new file mode 100644 index 0000000..ffab4a3 --- /dev/null +++ b/src/ui/game/GameScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_GAME_SCRIPT_HPP +#define UI_GAME_GAME_SCRIPT_HPP + +void GameScriptRegisterFunctions(); + +#endif From e8724502024c50ca2055100fd807c4c284cead7a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 07:56:30 -0600 Subject: [PATCH 020/114] fix(ui): fix infinite loop in CSimpleFrame::SetBeingScrolled --- src/ui/simple/CSimpleFrame.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index cc176e7..4832f4f 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -1342,7 +1342,7 @@ void CSimpleFrame::SetBeingScrolled(int32_t a2, int32_t a3) { this->m_batchDirty |= 0x1F; } - for (auto child = this->m_children.Head(); child; this->m_children.Link(child)->Next()) { + for (auto child = this->m_children.Head(); child; child = this->m_children.Link(child)->Next()) { if (!(child->frame->m_flags & 0x4000)) { child->frame->SetBeingScrolled(a2, -1); } From ba5006a4d8e69547ac80b9a0b5955c5185a328d9 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 08:20:56 -0600 Subject: [PATCH 021/114] feat(ui): implement CSimpleFontString_IsVisible --- src/ui/simple/CSimpleFontStringScript.cpp | 11 ++++++++++- src/ui/simple/CSimpleRegion.cpp | 4 ++++ src/ui/simple/CSimpleRegion.hpp | 1 + 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFontStringScript.cpp b/src/ui/simple/CSimpleFontStringScript.cpp index 57893eb..62f2415 100644 --- a/src/ui/simple/CSimpleFontStringScript.cpp +++ b/src/ui/simple/CSimpleFontStringScript.cpp @@ -73,7 +73,16 @@ int32_t CSimpleFontString_Hide(lua_State* L) { } int32_t CSimpleFontString_IsVisible(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFontString::GetObjectType(); + auto string = static_cast(FrameScript_GetObjectThis(L, type)); + + if (string->IsVisible()) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t CSimpleFontString_IsShown(lua_State* L) { diff --git a/src/ui/simple/CSimpleRegion.cpp b/src/ui/simple/CSimpleRegion.cpp index aa82007..c33c754 100644 --- a/src/ui/simple/CSimpleRegion.cpp +++ b/src/ui/simple/CSimpleRegion.cpp @@ -49,6 +49,10 @@ bool CSimpleRegion::IsShown() { return this->m_shown == 1; } +bool CSimpleRegion::IsVisible() { + return this->m_visible == 1; +} + void CSimpleRegion::OnColorChanged(bool a2) { if (this->m_parent) { uint8_t effectiveAlpha = this->m_parent->m_alpha * this->m_parent->alphaBD / 255; diff --git a/src/ui/simple/CSimpleRegion.hpp b/src/ui/simple/CSimpleRegion.hpp index 6c56534..733834a 100644 --- a/src/ui/simple/CSimpleRegion.hpp +++ b/src/ui/simple/CSimpleRegion.hpp @@ -32,6 +32,7 @@ class CSimpleRegion : public CScriptRegion { void Hide(); void HideThis(); bool IsShown(); + bool IsVisible(); void OnRegionChanged(); void SetVertexColor(const CImVector& color); void SetVertexGradient(ORIENTATION orientation, const CImVector& minColor, const CImVector& maxColor); From 98ea3099855e87e5a1424ef4d2cfc1aae8c8cae5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 08:24:29 -0600 Subject: [PATCH 022/114] feat(ui): implement CSimpleTexture_IsVisible --- src/ui/simple/CSimpleTextureScript.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleTextureScript.cpp b/src/ui/simple/CSimpleTextureScript.cpp index a6ea6ac..473204f 100644 --- a/src/ui/simple/CSimpleTextureScript.cpp +++ b/src/ui/simple/CSimpleTextureScript.cpp @@ -97,7 +97,16 @@ int32_t CSimpleTexture_Hide(lua_State* L) { } int32_t CSimpleTexture_IsVisible(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleTexture::GetObjectType(); + auto texture = static_cast(FrameScript_GetObjectThis(L, type)); + + if (texture->IsVisible()) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t CSimpleTexture_IsShown(lua_State* L) { From 7d9173b880707c6750be95e665b7d167d89861a6 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 08:26:08 -0600 Subject: [PATCH 023/114] feat(ui): implement CSimpleTexture_IsShown --- src/ui/simple/CSimpleTextureScript.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleTextureScript.cpp b/src/ui/simple/CSimpleTextureScript.cpp index 473204f..2dbe992 100644 --- a/src/ui/simple/CSimpleTextureScript.cpp +++ b/src/ui/simple/CSimpleTextureScript.cpp @@ -110,7 +110,16 @@ int32_t CSimpleTexture_IsVisible(lua_State* L) { } int32_t CSimpleTexture_IsShown(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleTexture::GetObjectType(); + auto texture = static_cast(FrameScript_GetObjectThis(L, type)); + + if (texture->IsShown()) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t CSimpleTexture_GetTexture(lua_State* L) { From 5f7bf8c95c84e8f7d0500ed254a4ebd8183f8149 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 08:44:58 -0600 Subject: [PATCH 024/114] feat(ui): implement Script_GetCVarBool --- src/ui/game/GameScript.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ui/game/GameScript.cpp b/src/ui/game/GameScript.cpp index bc194d8..0def051 100644 --- a/src/ui/game/GameScript.cpp +++ b/src/ui/game/GameScript.cpp @@ -1,6 +1,8 @@ #include "ui/game/GameScript.hpp" +#include "console/CVar.hpp" #include "ui/FrameScript.hpp" #include "ui/ScriptFunctionsShared.hpp" +#include "util/StringTo.hpp" #include "util/Unimplemented.hpp" namespace { @@ -133,7 +135,21 @@ int32_t Script_GetCVar(lua_State* L) { } int32_t Script_GetCVarBool(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + luaL_error(L, "Usage: GetCVarBool(\"cvar\")"); + return 0; + } + + auto varName = lua_tostring(L, 1); + auto var = CVar::LookupRegistered(varName); + + if (var && !(var->m_flags & 0x40) && StringToBOOL(var->GetString())) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t Script_GetCVarDefault(lua_State* L) { From b9f2c609667a5a2c383d7569d54f01f0c45fe507 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 09:01:17 -0600 Subject: [PATCH 025/114] feat(ui): implement Script_GetCursorPosition --- src/ui/game/GameScript.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/ui/game/GameScript.cpp b/src/ui/game/GameScript.cpp index 0def051..111b13a 100644 --- a/src/ui/game/GameScript.cpp +++ b/src/ui/game/GameScript.cpp @@ -1,7 +1,9 @@ #include "ui/game/GameScript.hpp" #include "console/CVar.hpp" +#include "gx/Coordinate.hpp" #include "ui/FrameScript.hpp" #include "ui/ScriptFunctionsShared.hpp" +#include "ui/simple/CSimpleTop.hpp" #include "util/StringTo.hpp" #include "util/Unimplemented.hpp" @@ -617,7 +619,25 @@ int32_t Script_CancelSummon(lua_State* L) { } int32_t Script_GetCursorPosition(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + STORM_ASSERT(CSimpleTop::s_instance); + + float ddcX = 0.0f; + float ddcY = 0.0f; + + NDCToDDC( + CSimpleTop::s_instance->m_mousePosition.x, + CSimpleTop::s_instance->m_mousePosition.y, + &ddcX, + &ddcY + ); + + float ndcX = DDCToNDCWidth(CoordinateGetAspectCompensation() * 1024.0f * ddcX); + lua_pushnumber(L, ndcX); + + float ndcY = DDCToNDCWidth(CoordinateGetAspectCompensation() * 1024.0f * ddcY); + lua_pushnumber(L, ndcY); + + return 2; } int32_t Script_GetNetStats(lua_State* L) { From c4077daa3f7eab3d7c9f0667b348f7424c39222e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 10:39:50 -0600 Subject: [PATCH 026/114] feat(ui): implement CSimpleFrame_EnableMouse --- src/ui/simple/CSimpleFrame.cpp | 12 ++++++++++++ src/ui/simple/CSimpleFrame.hpp | 1 + src/ui/simple/CSimpleFrameScript.cpp | 18 +++++++++++++++++- 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 4832f4f..1257cd1 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -100,6 +100,18 @@ void CSimpleFrame::DisableDrawLayer(uint32_t drawlayer) { this->NotifyDrawLayerChanged(drawlayer); } +void CSimpleFrame::DisableEvent(CSimpleEventType eventType) { + if (!(this->m_eventmask & (1 << eventType))) { + return; + } + + if (this->m_visible) { + this->m_top->UnregisterForEvent(this, eventType, 0); + } + + this->m_eventmask &= ~(1 << eventType); +} + void CSimpleFrame::EnableDrawLayer(uint32_t drawlayer) { this->m_drawenabled[drawlayer] = 1; this->NotifyDrawLayerChanged(drawlayer); diff --git a/src/ui/simple/CSimpleFrame.hpp b/src/ui/simple/CSimpleFrame.hpp index 2807794..2f08b23 100644 --- a/src/ui/simple/CSimpleFrame.hpp +++ b/src/ui/simple/CSimpleFrame.hpp @@ -123,6 +123,7 @@ class CSimpleFrame : public CScriptRegion { CSimpleFrame(CSimpleFrame* parent); void AddFrameRegion(CSimpleRegion* region, uint32_t drawlayer); void DisableDrawLayer(uint32_t drawlayer); + void DisableEvent(CSimpleEventType eventType); void EnableDrawLayer(uint32_t drawlayer); void EnableEvent(CSimpleEventType eventType, int32_t priority); int32_t GetHitRect(CRect& rect); diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index 2b63fb0..ca9d743 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -4,6 +4,7 @@ #include "ui/FrameScript.hpp" #include "ui/simple/CSimpleFrame.hpp" #include "util/Lua.hpp" +#include "util/StringTo.hpp" #include "util/Unimplemented.hpp" #include #include @@ -459,7 +460,22 @@ int32_t CSimpleFrame_IsKeyboardEnabled(lua_State* L) { } int32_t CSimpleFrame_EnableMouse(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!frame->ProtectedFunctionsAllowed()) { + // TODO disallowed logic + + return 0; + } + + if (StringToBOOL(L, 2, 1)) { + frame->EnableEvent(SIMPLE_EVENT_MOUSE, -1); + } else { + frame->DisableEvent(SIMPLE_EVENT_MOUSE); + } + + return 0; } int32_t CSimpleFrame_IsMouseEnabled(lua_State* L) { From 1c1e4f587536e83002d6189c60744fec25709adf Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 12:25:49 -0600 Subject: [PATCH 027/114] feat(ui): register GameTooltip factory --- src/ui/game/CGGameUI.cpp | 2 ++ src/ui/game/CGTooltip.cpp | 11 +++++++++++ src/ui/game/CGTooltip.hpp | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+) create mode 100644 src/ui/game/CGTooltip.cpp create mode 100644 src/ui/game/CGTooltip.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 0f527fd..35a392f 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -2,6 +2,7 @@ #include "client/Client.hpp" #include "ui/FrameXML.hpp" #include "ui/Key.hpp" +#include "ui/game/CGTooltip.hpp" #include "ui/game/CGWorldFrame.hpp" #include "ui/game/GMTicketInfoScript.hpp" #include "ui/game/GameScript.hpp" @@ -112,6 +113,7 @@ void CGGameUI::InitializeGame() { void CGGameUI::RegisterFrameFactories() { FrameXML_RegisterFactory("WorldFrame", &CGWorldFrame::Create, true); + FrameXML_RegisterFactory("GameTooltip", &CGTooltip::Create, false); // TODO register remaining factories } diff --git a/src/ui/game/CGTooltip.cpp b/src/ui/game/CGTooltip.cpp new file mode 100644 index 0000000..57e78a7 --- /dev/null +++ b/src/ui/game/CGTooltip.cpp @@ -0,0 +1,11 @@ +#include "ui/game/CGTooltip.hpp" + +CSimpleFrame* CGTooltip::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGTooltip)(parent); +} + +CGTooltip::CGTooltip(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO +} diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp new file mode 100644 index 0000000..f59c5a6 --- /dev/null +++ b/src/ui/game/CGTooltip.hpp @@ -0,0 +1,18 @@ +#ifndef UI_GAME_C_G_TOOLTIP_HPP +#define UI_GAME_C_G_TOOLTIP_HPP + +#include "ui/simple/CSimpleFrame.hpp" + +class CGTooltip : public CSimpleFrame { + public: + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + + // Member variables + // TODO + + // Member functions + CGTooltip(CSimpleFrame* parent); +}; + +#endif From 8ee1586a142e5166c7122266c67e562d2def5cb9 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 16:17:40 -0600 Subject: [PATCH 028/114] feat(ui): add CharacterInfoRegisterScriptFunctions --- src/ui/game/CGGameUI.cpp | 7 +- src/ui/game/CharacterInfoScript.cpp | 181 ++++++++++++++++++++++++++++ src/ui/game/CharacterInfoScript.hpp | 6 + 3 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/ui/game/CharacterInfoScript.cpp create mode 100644 src/ui/game/CharacterInfoScript.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 35a392f..91f1e80 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -4,8 +4,9 @@ #include "ui/Key.hpp" #include "ui/game/CGTooltip.hpp" #include "ui/game/CGWorldFrame.hpp" -#include "ui/game/GMTicketInfoScript.hpp" +#include "ui/game/CharacterInfoScript.hpp" #include "ui/game/GameScript.hpp" +#include "ui/game/GMTicketInfoScript.hpp" #include "ui/game/ScriptEvents.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" @@ -24,6 +25,10 @@ void LoadScriptFunctions() { // TODO + CharacterInfoRegisterScriptFunctions(); + + // TODO + GMTicketInfoRegisterScriptFunctions(); // TODO diff --git a/src/ui/game/CharacterInfoScript.cpp b/src/ui/game/CharacterInfoScript.cpp new file mode 100644 index 0000000..1b70462 --- /dev/null +++ b/src/ui/game/CharacterInfoScript.cpp @@ -0,0 +1,181 @@ +#include "ui/game/CharacterInfoScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_GetInventorySlotInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemsForSlot(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemBroken(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemCount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemQuality(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemDurability(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemLink(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemID(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryItemGems(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_KeyRingButtonIDToInvSlotID(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PickupInventoryItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UseInventoryItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SocketInventoryItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsInventoryItemLocked(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PutItemInBag(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PutItemInBackpack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PickupBagFromSlot(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CursorCanGoInSlot(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ShowInventorySellCursor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetInventoryPortraitTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetGuildInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInventoryAlertStatus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UpdateInventoryAlertStatus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_OffhandHasWeapon(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasInspectHonorData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RequestInspectHonorData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInspectHonorData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetInspectArenaTeamData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ClearInspectPlayer(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetWeaponEnchantInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasWandEquipped(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "GetInventorySlotInfo", &Script_GetInventorySlotInfo }, + { "GetInventoryItemsForSlot", &Script_GetInventoryItemsForSlot }, + { "GetInventoryItemTexture", &Script_GetInventoryItemTexture }, + { "GetInventoryItemBroken", &Script_GetInventoryItemBroken }, + { "GetInventoryItemCount", &Script_GetInventoryItemCount }, + { "GetInventoryItemQuality", &Script_GetInventoryItemQuality }, + { "GetInventoryItemCooldown", &Script_GetInventoryItemCooldown }, + { "GetInventoryItemDurability", &Script_GetInventoryItemDurability }, + { "GetInventoryItemLink", &Script_GetInventoryItemLink }, + { "GetInventoryItemID", &Script_GetInventoryItemID }, + { "GetInventoryItemGems", &Script_GetInventoryItemGems }, + { "KeyRingButtonIDToInvSlotID", &Script_KeyRingButtonIDToInvSlotID }, + { "PickupInventoryItem", &Script_PickupInventoryItem }, + { "UseInventoryItem", &Script_UseInventoryItem }, + { "SocketInventoryItem", &Script_SocketInventoryItem }, + { "IsInventoryItemLocked", &Script_IsInventoryItemLocked }, + { "PutItemInBag", &Script_PutItemInBag }, + { "PutItemInBackpack", &Script_PutItemInBackpack }, + { "PickupBagFromSlot", &Script_PickupBagFromSlot }, + { "CursorCanGoInSlot", &Script_CursorCanGoInSlot }, + { "ShowInventorySellCursor", &Script_ShowInventorySellCursor }, + { "SetInventoryPortraitTexture", &Script_SetInventoryPortraitTexture }, + { "GetGuildInfo", &Script_GetGuildInfo }, + { "GetInventoryAlertStatus", &Script_GetInventoryAlertStatus }, + { "UpdateInventoryAlertStatus", &Script_UpdateInventoryAlertStatus }, + { "OffhandHasWeapon", &Script_OffhandHasWeapon }, + { "HasInspectHonorData", &Script_HasInspectHonorData }, + { "RequestInspectHonorData", &Script_RequestInspectHonorData }, + { "GetInspectHonorData", &Script_GetInspectHonorData }, + { "GetInspectArenaTeamData", &Script_GetInspectArenaTeamData }, + { "ClearInspectPlayer", &Script_ClearInspectPlayer }, + { "GetWeaponEnchantInfo", &Script_GetWeaponEnchantInfo }, + { "HasWandEquipped", &Script_HasWandEquipped }, +}; + +void CharacterInfoRegisterScriptFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/CharacterInfoScript.hpp b/src/ui/game/CharacterInfoScript.hpp new file mode 100644 index 0000000..96ebefc --- /dev/null +++ b/src/ui/game/CharacterInfoScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_CHARACTER_INFO_SCRIPT_HPP +#define UI_GAME_CHARACTER_INFO_SCRIPT_HPP + +void CharacterInfoRegisterScriptFunctions(); + +#endif From 94731f53c35fd93fc2d978fac791a51d5ecab125 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 17:46:48 -0600 Subject: [PATCH 029/114] feat(ui): add BattlefieldInfoRegisterScriptFunctions --- src/ui/game/BattlefieldInfoScript.cpp | 271 ++++++++++++++++++++++++++ src/ui/game/BattlefieldInfoScript.hpp | 6 + src/ui/game/CGGameUI.cpp | 7 +- 3 files changed, 283 insertions(+), 1 deletion(-) create mode 100644 src/ui/game/BattlefieldInfoScript.cpp create mode 100644 src/ui/game/BattlefieldInfoScript.hpp diff --git a/src/ui/game/BattlefieldInfoScript.cpp b/src/ui/game/BattlefieldInfoScript.cpp new file mode 100644 index 0000000..11c22c8 --- /dev/null +++ b/src/ui/game/BattlefieldInfoScript.cpp @@ -0,0 +1,271 @@ +#include "ui/game/BattlefieldInfoScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_GetNumBattlefields(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldInstanceInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsBattlefieldArena(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsActiveBattlefieldArena(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_JoinBattlefield(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetSelectedBattlefield(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetSelectedBattlefield(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_AcceptBattlefieldPort(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldStatus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldPortExpiration(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldInstanceExpiration(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldInstanceRunTime(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldEstimatedWaitTime(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldTimeWaited(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CloseBattlefield(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RequestBattlefieldScoreData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlefieldScores(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldScore(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldWinner(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBattlefieldScoreFaction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_LeaveBattlefield(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlefieldStats(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldStatInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldStatData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RequestBattlefieldPositions(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlefieldPositions(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldPosition(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlefieldFlagPositions(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldFlagPosition(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlefieldVehicles(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldVehicleInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanJoinBattlefieldAsGroup(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldMapIconScale(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldTeamInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlefieldArenaFaction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SortBattlefieldScoreData(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HearthAndResurrectFromArea(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_CanHearthAndResurrectFromArea(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumBattlegroundTypes(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBattlegroundInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RequestBattlegroundInstanceInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumArenaOpponents(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BattlefieldMgrEntryInviteResponse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BattlefieldMgrQueueRequest(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BattlefieldMgrQueueInviteResponse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_BattlefieldMgrExitRequest(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetWorldPVPQueueStatus(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetHolidayBGHonorCurrencyBonuses(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetRandomBGHonorCurrencyBonuses(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SortBGList(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "GetNumBattlefields", &Script_GetNumBattlefields }, + { "GetBattlefieldInfo", &Script_GetBattlefieldInfo }, + { "GetBattlefieldInstanceInfo", &Script_GetBattlefieldInstanceInfo }, + { "IsBattlefieldArena", &Script_IsBattlefieldArena }, + { "IsActiveBattlefieldArena", &Script_IsActiveBattlefieldArena }, + { "JoinBattlefield", &Script_JoinBattlefield }, + { "SetSelectedBattlefield", &Script_SetSelectedBattlefield }, + { "GetSelectedBattlefield", &Script_GetSelectedBattlefield }, + { "AcceptBattlefieldPort", &Script_AcceptBattlefieldPort }, + { "GetBattlefieldStatus", &Script_GetBattlefieldStatus }, + { "GetBattlefieldPortExpiration", &Script_GetBattlefieldPortExpiration }, + { "GetBattlefieldInstanceExpiration", &Script_GetBattlefieldInstanceExpiration }, + { "GetBattlefieldInstanceRunTime", &Script_GetBattlefieldInstanceRunTime }, + { "GetBattlefieldEstimatedWaitTime", &Script_GetBattlefieldEstimatedWaitTime }, + { "GetBattlefieldTimeWaited", &Script_GetBattlefieldTimeWaited }, + { "CloseBattlefield", &Script_CloseBattlefield }, + { "RequestBattlefieldScoreData", &Script_RequestBattlefieldScoreData }, + { "GetNumBattlefieldScores", &Script_GetNumBattlefieldScores }, + { "GetBattlefieldScore", &Script_GetBattlefieldScore }, + { "GetBattlefieldWinner", &Script_GetBattlefieldWinner }, + { "SetBattlefieldScoreFaction", &Script_SetBattlefieldScoreFaction }, + { "LeaveBattlefield", &Script_LeaveBattlefield }, + { "GetNumBattlefieldStats", &Script_GetNumBattlefieldStats }, + { "GetBattlefieldStatInfo", &Script_GetBattlefieldStatInfo }, + { "GetBattlefieldStatData", &Script_GetBattlefieldStatData }, + { "RequestBattlefieldPositions", &Script_RequestBattlefieldPositions }, + { "GetNumBattlefieldPositions", &Script_GetNumBattlefieldPositions }, + { "GetBattlefieldPosition", &Script_GetBattlefieldPosition }, + { "GetNumBattlefieldFlagPositions", &Script_GetNumBattlefieldFlagPositions }, + { "GetBattlefieldFlagPosition", &Script_GetBattlefieldFlagPosition }, + { "GetNumBattlefieldVehicles", &Script_GetNumBattlefieldVehicles }, + { "GetBattlefieldVehicleInfo", &Script_GetBattlefieldVehicleInfo }, + { "CanJoinBattlefieldAsGroup", &Script_CanJoinBattlefieldAsGroup }, + { "GetBattlefieldMapIconScale", &Script_GetBattlefieldMapIconScale }, + { "GetBattlefieldTeamInfo", &Script_GetBattlefieldTeamInfo }, + { "GetBattlefieldArenaFaction", &Script_GetBattlefieldArenaFaction }, + { "SortBattlefieldScoreData", &Script_SortBattlefieldScoreData }, + { "HearthAndResurrectFromArea", &Script_HearthAndResurrectFromArea }, + { "CanHearthAndResurrectFromArea", &Script_CanHearthAndResurrectFromArea }, + { "GetNumBattlegroundTypes", &Script_GetNumBattlegroundTypes }, + { "GetBattlegroundInfo", &Script_GetBattlegroundInfo }, + { "RequestBattlegroundInstanceInfo", &Script_RequestBattlegroundInstanceInfo }, + { "GetNumArenaOpponents", &Script_GetNumArenaOpponents }, + { "BattlefieldMgrEntryInviteResponse", &Script_BattlefieldMgrEntryInviteResponse }, + { "BattlefieldMgrQueueRequest", &Script_BattlefieldMgrQueueRequest }, + { "BattlefieldMgrQueueInviteResponse", &Script_BattlefieldMgrQueueInviteResponse }, + { "BattlefieldMgrExitRequest", &Script_BattlefieldMgrExitRequest }, + { "GetWorldPVPQueueStatus", &Script_GetWorldPVPQueueStatus }, + { "GetHolidayBGHonorCurrencyBonuses", &Script_GetHolidayBGHonorCurrencyBonuses }, + { "GetRandomBGHonorCurrencyBonuses", &Script_GetRandomBGHonorCurrencyBonuses }, + { "SortBGList", &Script_SortBGList }, +}; + +void BattlefieldInfoRegisterScriptFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/BattlefieldInfoScript.hpp b/src/ui/game/BattlefieldInfoScript.hpp new file mode 100644 index 0000000..7eb21aa --- /dev/null +++ b/src/ui/game/BattlefieldInfoScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_BATTLEFIELD_INFO_SCRIPT_HPP +#define UI_GAME_BATTLEFIELD_INFO_SCRIPT_HPP + +void BattlefieldInfoRegisterScriptFunctions(); + +#endif diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 91f1e80..6a4e49e 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -2,11 +2,12 @@ #include "client/Client.hpp" #include "ui/FrameXML.hpp" #include "ui/Key.hpp" +#include "ui/game/BattlefieldInfoScript.hpp" #include "ui/game/CGTooltip.hpp" #include "ui/game/CGWorldFrame.hpp" #include "ui/game/CharacterInfoScript.hpp" -#include "ui/game/GameScript.hpp" #include "ui/game/GMTicketInfoScript.hpp" +#include "ui/game/GameScript.hpp" #include "ui/game/ScriptEvents.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" @@ -29,6 +30,10 @@ void LoadScriptFunctions() { // TODO + BattlefieldInfoRegisterScriptFunctions(); + + // TODO + GMTicketInfoRegisterScriptFunctions(); // TODO From 501935ffc2717390c836100e1a061813929a481d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 17:49:22 -0600 Subject: [PATCH 030/114] feat(ui): stub Script_GetGameTime --- src/ui/ScriptFunctionsSystem.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/ui/ScriptFunctionsSystem.cpp b/src/ui/ScriptFunctionsSystem.cpp index 72c13dd..bc484aa 100644 --- a/src/ui/ScriptFunctionsSystem.cpp +++ b/src/ui/ScriptFunctionsSystem.cpp @@ -14,7 +14,10 @@ int32_t Script_GetTime(lua_State* L) { } int32_t Script_GetGameTime(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO real implementation + lua_pushnumber(L, 1.0); + lua_pushnumber(L, 15.0); + WHOA_UNIMPLEMENTED(2); } int32_t Script_ConsoleExec(lua_State* L) { From ac0930497c4e2db8bc7d3fe0dad640cf13e0020e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 17:54:56 -0600 Subject: [PATCH 031/114] feat(ui): add CGTooltip::GetObjectType --- src/ui/game/CGTooltip.cpp | 10 ++++++++++ src/ui/game/CGTooltip.hpp | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/ui/game/CGTooltip.cpp b/src/ui/game/CGTooltip.cpp index 57e78a7..e319dd4 100644 --- a/src/ui/game/CGTooltip.cpp +++ b/src/ui/game/CGTooltip.cpp @@ -1,11 +1,21 @@ #include "ui/game/CGTooltip.hpp" +int32_t CGTooltip::s_objectType; + CSimpleFrame* CGTooltip::Create(CSimpleFrame* parent) { // TODO use CDataAllocator return STORM_NEW(CGTooltip)(parent); } +int32_t CGTooltip::GetObjectType() { + if (!CGTooltip::s_objectType) { + CGTooltip::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGTooltip::s_objectType; +} + CGTooltip::CGTooltip(CSimpleFrame* parent) : CSimpleFrame(parent) { // TODO } diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp index f59c5a6..8bcfa62 100644 --- a/src/ui/game/CGTooltip.hpp +++ b/src/ui/game/CGTooltip.hpp @@ -5,8 +5,12 @@ class CGTooltip : public CSimpleFrame { public: + // Static variables + static int32_t s_objectType; + // Static functions static CSimpleFrame* Create(CSimpleFrame* parent); + static int32_t GetObjectType(); // Member variables // TODO From 1334d1407c2dac6a8115b6c862252e27044cab7a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 18:45:52 -0600 Subject: [PATCH 032/114] feat(ui): add CGTooltip::CreateScriptMetaTable --- src/ui/game/CGGameUI.cpp | 4 + src/ui/game/CGTooltip.cpp | 12 ++ src/ui/game/CGTooltip.hpp | 3 + src/ui/game/CGTooltipScript.cpp | 355 ++++++++++++++++++++++++++++++++ src/ui/game/CGTooltipScript.hpp | 10 + 5 files changed, 384 insertions(+) create mode 100644 src/ui/game/CGTooltipScript.cpp create mode 100644 src/ui/game/CGTooltipScript.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 6a4e49e..5af07f7 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -18,6 +18,10 @@ CSimpleTop* CGGameUI::s_simpleTop; void LoadScriptFunctions() { // TODO + CGTooltip::CreateScriptMetaTable(); + + // TODO + GameScriptRegisterFunctions(); // TODO diff --git a/src/ui/game/CGTooltip.cpp b/src/ui/game/CGTooltip.cpp index e319dd4..ceb5bfa 100644 --- a/src/ui/game/CGTooltip.cpp +++ b/src/ui/game/CGTooltip.cpp @@ -1,5 +1,7 @@ #include "ui/game/CGTooltip.hpp" +#include "ui/game/CGTooltipScript.hpp" +int32_t CGTooltip::s_metatable; int32_t CGTooltip::s_objectType; CSimpleFrame* CGTooltip::Create(CSimpleFrame* parent) { @@ -8,6 +10,11 @@ CSimpleFrame* CGTooltip::Create(CSimpleFrame* parent) { return STORM_NEW(CGTooltip)(parent); } +void CGTooltip::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGTooltip::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGTooltip::RegisterScriptMethods); +} + int32_t CGTooltip::GetObjectType() { if (!CGTooltip::s_objectType) { CGTooltip::s_objectType = ++FrameScript_Object::s_objectTypes; @@ -16,6 +23,11 @@ int32_t CGTooltip::GetObjectType() { return CGTooltip::s_objectType; } +void CGTooltip::RegisterScriptMethods(lua_State* L) { + CSimpleFrame::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGTooltipMethods, NUM_CG_TOOLTIP_SCRIPT_METHODS); +} + CGTooltip::CGTooltip(CSimpleFrame* parent) : CSimpleFrame(parent) { // TODO } diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp index 8bcfa62..5b32efa 100644 --- a/src/ui/game/CGTooltip.hpp +++ b/src/ui/game/CGTooltip.hpp @@ -6,11 +6,14 @@ class CGTooltip : public CSimpleFrame { public: // Static variables + static int32_t s_metatable; static int32_t s_objectType; // Static functions static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); // Member variables // TODO diff --git a/src/ui/game/CGTooltipScript.cpp b/src/ui/game/CGTooltipScript.cpp new file mode 100644 index 0000000..91b296d --- /dev/null +++ b/src/ui/game/CGTooltipScript.cpp @@ -0,0 +1,355 @@ +#include "ui/game/CGTooltipScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CGTooltip_AddFontStrings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetMinimumWidth(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetMinimumWidth(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetPadding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetPadding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_IsOwned(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetOwner(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetOwner(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetAnchorType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetAnchorType(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_ClearLines(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_AddLine(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_AddDoubleLine(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_AddTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_AppendText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_FadeOut(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetHyperlink(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetPetAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetShapeshift(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetPossession(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTracking(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetSpellByID(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetGlyph(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetInventoryItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetLootItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetQuestItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetQuestLogItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTrainerService(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTradeSkillItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetMerchantItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetMerchantCostItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTradePlayerItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTradeTargetItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetBagItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetUnitBuff(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetUnitDebuff(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetUnitAura(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTalent(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetSendMailItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetInboxItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetAuctionSellItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetAuctionItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_NumLines(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetQuestRewardSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetQuestLogRewardSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetHyperlinkCompareItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetBuybackItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetLootRollItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetSocketedItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetSocketGem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetExistingSocketGem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetGuildBankItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_IsUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_GetSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetTotem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetCurrencyToken(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetBackpackToken(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_IsEquippedItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetQuestLogSpecialItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetEquipmentSet(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetFrameStack(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetLFGDungeonReward(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTooltip_SetLFGCompletionReward(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGTooltipMethods[] = { + { "AddFontStrings", &CGTooltip_AddFontStrings }, + { "SetMinimumWidth", &CGTooltip_SetMinimumWidth }, + { "GetMinimumWidth", &CGTooltip_GetMinimumWidth }, + { "SetPadding", &CGTooltip_SetPadding }, + { "GetPadding", &CGTooltip_GetPadding }, + { "IsOwned", &CGTooltip_IsOwned }, + { "GetOwner", &CGTooltip_GetOwner }, + { "SetOwner", &CGTooltip_SetOwner }, + { "GetAnchorType", &CGTooltip_GetAnchorType }, + { "SetAnchorType", &CGTooltip_SetAnchorType }, + { "ClearLines", &CGTooltip_ClearLines }, + { "AddLine", &CGTooltip_AddLine }, + { "AddDoubleLine", &CGTooltip_AddDoubleLine }, + { "AddTexture", &CGTooltip_AddTexture }, + { "SetText", &CGTooltip_SetText }, + { "AppendText", &CGTooltip_AppendText }, + { "FadeOut", &CGTooltip_FadeOut }, + { "SetHyperlink", &CGTooltip_SetHyperlink }, + { "SetAction", &CGTooltip_SetAction }, + { "SetPetAction", &CGTooltip_SetPetAction }, + { "SetShapeshift", &CGTooltip_SetShapeshift }, + { "SetPossession", &CGTooltip_SetPossession }, + { "SetTracking", &CGTooltip_SetTracking }, + { "SetSpell", &CGTooltip_SetSpell }, + { "SetSpellByID", &CGTooltip_SetSpellByID }, + { "SetGlyph", &CGTooltip_SetGlyph }, + { "SetInventoryItem", &CGTooltip_SetInventoryItem }, + { "SetLootItem", &CGTooltip_SetLootItem }, + { "SetQuestItem", &CGTooltip_SetQuestItem }, + { "SetQuestLogItem", &CGTooltip_SetQuestLogItem }, + { "SetTrainerService", &CGTooltip_SetTrainerService }, + { "SetTradeSkillItem", &CGTooltip_SetTradeSkillItem }, + { "SetMerchantItem", &CGTooltip_SetMerchantItem }, + { "SetMerchantCostItem", &CGTooltip_SetMerchantCostItem }, + { "SetTradePlayerItem", &CGTooltip_SetTradePlayerItem }, + { "SetTradeTargetItem", &CGTooltip_SetTradeTargetItem }, + { "SetBagItem", &CGTooltip_SetBagItem }, + { "SetUnit", &CGTooltip_SetUnit }, + { "SetUnitBuff", &CGTooltip_SetUnitBuff }, + { "SetUnitDebuff", &CGTooltip_SetUnitDebuff }, + { "SetUnitAura", &CGTooltip_SetUnitAura }, + { "SetTalent", &CGTooltip_SetTalent }, + { "SetSendMailItem", &CGTooltip_SetSendMailItem }, + { "SetInboxItem", &CGTooltip_SetInboxItem }, + { "SetAuctionSellItem", &CGTooltip_SetAuctionSellItem }, + { "SetAuctionItem", &CGTooltip_SetAuctionItem }, + { "NumLines", &CGTooltip_NumLines }, + { "SetQuestRewardSpell", &CGTooltip_SetQuestRewardSpell }, + { "SetQuestLogRewardSpell", &CGTooltip_SetQuestLogRewardSpell }, + { "SetHyperlinkCompareItem", &CGTooltip_SetHyperlinkCompareItem }, + { "SetBuybackItem", &CGTooltip_SetBuybackItem }, + { "SetLootRollItem", &CGTooltip_SetLootRollItem }, + { "SetSocketedItem", &CGTooltip_SetSocketedItem }, + { "SetSocketGem", &CGTooltip_SetSocketGem }, + { "SetExistingSocketGem", &CGTooltip_SetExistingSocketGem }, + { "SetGuildBankItem", &CGTooltip_SetGuildBankItem }, + { "IsUnit", &CGTooltip_IsUnit }, + { "GetUnit", &CGTooltip_GetUnit }, + { "GetItem", &CGTooltip_GetItem }, + { "GetSpell", &CGTooltip_GetSpell }, + { "SetTotem", &CGTooltip_SetTotem }, + { "SetCurrencyToken", &CGTooltip_SetCurrencyToken }, + { "SetBackpackToken", &CGTooltip_SetBackpackToken }, + { "IsEquippedItem", &CGTooltip_IsEquippedItem }, + { "SetQuestLogSpecialItem", &CGTooltip_SetQuestLogSpecialItem }, + { "SetEquipmentSet", &CGTooltip_SetEquipmentSet }, + { "SetFrameStack", &CGTooltip_SetFrameStack }, + { "SetLFGDungeonReward", &CGTooltip_SetLFGDungeonReward }, + { "SetLFGCompletionReward", &CGTooltip_SetLFGCompletionReward }, +}; diff --git a/src/ui/game/CGTooltipScript.hpp b/src/ui/game/CGTooltipScript.hpp new file mode 100644 index 0000000..635099f --- /dev/null +++ b/src/ui/game/CGTooltipScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_TOOLTIP_SCRIPT_HPP +#define UI_GAME_C_G_TOOLTIP_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_TOOLTIP_SCRIPT_METHODS 69 + +extern FrameScript_Method CGTooltipMethods[NUM_CG_TOOLTIP_SCRIPT_METHODS]; + +#endif From 6b916d56d1d13fc6151f5abf2d55a1ccfce038fe Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 19:12:52 -0600 Subject: [PATCH 033/114] feat(ui): add CGTooltip::GetScriptMetaTable --- src/ui/game/CGTooltip.cpp | 4 ++++ src/ui/game/CGTooltip.hpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/ui/game/CGTooltip.cpp b/src/ui/game/CGTooltip.cpp index ceb5bfa..328dd4b 100644 --- a/src/ui/game/CGTooltip.cpp +++ b/src/ui/game/CGTooltip.cpp @@ -31,3 +31,7 @@ void CGTooltip::RegisterScriptMethods(lua_State* L) { CGTooltip::CGTooltip(CSimpleFrame* parent) : CSimpleFrame(parent) { // TODO } + +int32_t CGTooltip::GetScriptMetaTable() { + return CGTooltip::s_metatable; +} diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp index 5b32efa..f6a5961 100644 --- a/src/ui/game/CGTooltip.hpp +++ b/src/ui/game/CGTooltip.hpp @@ -18,6 +18,9 @@ class CGTooltip : public CSimpleFrame { // Member variables // TODO + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + // Member functions CGTooltip(CSimpleFrame* parent); }; From 379cbf7e6170461194158702e38d3acc2acd3623 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 19:28:48 -0600 Subject: [PATCH 034/114] feat(ui): add UIBindingsRegisterScriptFunctions --- src/ui/game/CGGameUI.cpp | 2 + src/ui/game/UIBindingsScript.cpp | 146 +++++++++++++++++++++++++++++++ src/ui/game/UIBindingsScript.hpp | 6 ++ 3 files changed, 154 insertions(+) create mode 100644 src/ui/game/UIBindingsScript.cpp create mode 100644 src/ui/game/UIBindingsScript.hpp diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 5af07f7..3c88c85 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -9,6 +9,7 @@ #include "ui/game/GMTicketInfoScript.hpp" #include "ui/game/GameScript.hpp" #include "ui/game/ScriptEvents.hpp" +#include "ui/game/UIBindingsScript.hpp" #include "ui/simple/CSimpleTop.hpp" #include "util/CStatus.hpp" #include @@ -23,6 +24,7 @@ void LoadScriptFunctions() { // TODO GameScriptRegisterFunctions(); + UIBindingsRegisterScriptFunctions(); // TODO diff --git a/src/ui/game/UIBindingsScript.cpp b/src/ui/game/UIBindingsScript.cpp new file mode 100644 index 0000000..8d488a1 --- /dev/null +++ b/src/ui/game/UIBindingsScript.cpp @@ -0,0 +1,146 @@ +#include "ui/game/UIBindingsScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_GetNumBindings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBinding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBinding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBindingSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBindingItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBindingMacro(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetBindingClick(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetOverrideBinding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetOverrideBindingSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetOverrideBindingItem(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetOverrideBindingMacro(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetOverrideBindingClick(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ClearOverrideBindings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBindingKey(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBindingAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBindingByKey(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RunBinding(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetCurrentBindingSet(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_LoadBindings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SaveBindings(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetNumModifiedClickActions(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetModifiedClickAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetModifiedClick(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetModifiedClick(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsModifiedClick(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetClickFrame(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "GetNumBindings", &Script_GetNumBindings }, + { "GetBinding", &Script_GetBinding }, + { "SetBinding", &Script_SetBinding }, + { "SetBindingSpell", &Script_SetBindingSpell }, + { "SetBindingItem", &Script_SetBindingItem }, + { "SetBindingMacro", &Script_SetBindingMacro }, + { "SetBindingClick", &Script_SetBindingClick }, + { "SetOverrideBinding", &Script_SetOverrideBinding }, + { "SetOverrideBindingSpell", &Script_SetOverrideBindingSpell }, + { "SetOverrideBindingItem", &Script_SetOverrideBindingItem }, + { "SetOverrideBindingMacro", &Script_SetOverrideBindingMacro }, + { "SetOverrideBindingClick", &Script_SetOverrideBindingClick }, + { "ClearOverrideBindings", &Script_ClearOverrideBindings }, + { "GetBindingKey", &Script_GetBindingKey }, + { "GetBindingAction", &Script_GetBindingAction }, + { "GetBindingByKey", &Script_GetBindingByKey }, + { "RunBinding", &Script_RunBinding }, + { "GetCurrentBindingSet", &Script_GetCurrentBindingSet }, + { "LoadBindings", &Script_LoadBindings }, + { "SaveBindings", &Script_SaveBindings }, + { "GetNumModifiedClickActions", &Script_GetNumModifiedClickActions }, + { "GetModifiedClickAction", &Script_GetModifiedClickAction }, + { "SetModifiedClick", &Script_SetModifiedClick }, + { "GetModifiedClick", &Script_GetModifiedClick }, + { "IsModifiedClick", &Script_IsModifiedClick }, + { "GetClickFrame", &Script_GetClickFrame }, +}; + +void UIBindingsRegisterScriptFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/UIBindingsScript.hpp b/src/ui/game/UIBindingsScript.hpp new file mode 100644 index 0000000..a74a0b9 --- /dev/null +++ b/src/ui/game/UIBindingsScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_UI_BINDINGS_SCRIPT_HPP +#define UI_GAME_UI_BINDINGS_SCRIPT_HPP + +void UIBindingsRegisterScriptFunctions(); + +#endif From cd167c54a32b6622882fa15755b83b5a9c0e038c Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 27 Jan 2026 19:31:19 -0600 Subject: [PATCH 035/114] feat(ui): store tooltip pointer in CGGameUI::Initialize --- src/ui/game/CGGameUI.cpp | 7 +++++++ src/ui/game/CGGameUI.hpp | 2 ++ 2 files changed, 9 insertions(+) diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 3c88c85..2729222 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -1,5 +1,6 @@ #include "ui/game/CGGameUI.hpp" #include "client/Client.hpp" +#include "ui/CScriptObject.hpp" #include "ui/FrameXML.hpp" #include "ui/Key.hpp" #include "ui/game/BattlefieldInfoScript.hpp" @@ -14,6 +15,7 @@ #include "util/CStatus.hpp" #include +CScriptObject* CGGameUI::s_gameTooltip; CSimpleTop* CGGameUI::s_simpleTop; void LoadScriptFunctions() { @@ -117,6 +119,11 @@ void CGGameUI::Initialize() { // TODO digest validation // TODO + + CGGameUI::s_gameTooltip = CScriptObject::GetScriptObjectByName("GameTooltip", CGTooltip::GetObjectType()); + // TODO STORM_ASSERT(CGGameUI::s_gameTooltip); + + // TODO } void CGGameUI::InitializeGame() { diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp index 17b86f1..567ab2f 100644 --- a/src/ui/game/CGGameUI.hpp +++ b/src/ui/game/CGGameUI.hpp @@ -1,11 +1,13 @@ #ifndef UI_GAME_C_G_GAME_UI_HPP #define UI_GAME_C_G_GAME_UI_HPP +class CScriptObject; class CSimpleTop; class CGGameUI { public: // Static variables + static CScriptObject* s_gameTooltip; static CSimpleTop* s_simpleTop; // Static functions From bfcceed8fda9a4cbbe09e91162024b7866814dcf Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 15:44:42 -0600 Subject: [PATCH 036/114] feat(util): add initial implementation of WowTime --- src/util/CMakeLists.txt | 1 + src/util/Time.hpp | 6 ++ src/util/time/WowTime.cpp | 166 +++++++++++++++++++++++++++++++++++++ src/util/time/WowTime.hpp | 29 +++++++ test/CMakeLists.txt | 1 + test/util/time/WowTime.cpp | 146 ++++++++++++++++++++++++++++++++ 6 files changed, 349 insertions(+) create mode 100644 src/util/Time.hpp create mode 100644 src/util/time/WowTime.cpp create mode 100644 src/util/time/WowTime.hpp create mode 100644 test/util/time/WowTime.cpp diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index a0696b6..3c2f020 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -1,6 +1,7 @@ file(GLOB PRIVATE_SOURCES "*.cpp" "guid/*.cpp" + "time/*.cpp" ) if(WHOA_SYSTEM_MAC) diff --git a/src/util/Time.hpp b/src/util/Time.hpp new file mode 100644 index 0000000..8edb391 --- /dev/null +++ b/src/util/Time.hpp @@ -0,0 +1,6 @@ +#ifndef UTIL_TIME_HPP +#define UTIL_TIME_HPP + +#include "util/time/WowTime.hpp" + +#endif diff --git a/src/util/time/WowTime.cpp b/src/util/time/WowTime.cpp new file mode 100644 index 0000000..3005a3c --- /dev/null +++ b/src/util/time/WowTime.cpp @@ -0,0 +1,166 @@ +#include "util/time/WowTime.hpp" +#include +#include + +static const char* s_weekdays[] = { + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat", +}; + +void WowTime::WowDecodeTime(uint32_t value, int32_t* minute, int32_t* hour, int32_t* weekday, int32_t* monthday, int32_t* month, int32_t* year, int32_t* flags) { + // Minute: bits 0-5 (6 bits, max 63) + if (minute) { + auto m = static_cast(value & 63); + *minute = (m == 63) ? -1 : m; + } + + // Hour: bits 6-10 (5 bits, max 31) + if (hour) { + auto h = static_cast((value >> 6) & 31); + *hour = (h == 31) ? -1 : h; + } + + // Weekday: bits 11-13 (3 bits, max 7) + if (weekday) { + auto wd = static_cast((value >> 11) & 7); + *weekday = (wd == 7) ? -1 : wd; + } + + // Month day: bits 14-19 (6 bits, max 63) + if (monthday) { + auto md = static_cast((value >> 14) & 63); + *monthday = (md == 63) ? -1 : md; + } + + // Month: bits 20-23 (4 bits, max 15) + if (month) { + auto mo = static_cast((value >> 20) & 15); + *month = (mo == 15) ? -1 : mo; + } + + // Year: bits 24-28 (5 bits, max 31) + if (year) { + auto y = static_cast((value >> 24) & 31); + *year = (y == 31) ? -1 : y; + } + + // Flags: bits 29-30 (2 bits, max 3) + if (flags) { + auto f = static_cast((value >> 29) & 3); + *flags = (f == 3) ? -1 : f; + } +} + +void WowTime::WowDecodeTime(uint32_t value, WowTime* time) { + WowTime::WowDecodeTime( + value, + &time->m_minute, + &time->m_hour, + &time->m_weekday, + &time->m_monthday, + &time->m_month, + &time->m_year, + &time->m_flags + ); +} + +void WowTime::WowEncodeTime(uint32_t& value, int32_t minute, int32_t hour, int32_t weekday, int32_t monthday, int32_t month, int32_t year, int32_t flags) { + STORM_ASSERT(minute == -1 || (minute >= 0 && minute < 60)); + STORM_ASSERT(hour == -1 || (hour >= 0 && hour < 24)); + STORM_ASSERT(weekday == -1 || (weekday >= 0 && weekday < 7)); + STORM_ASSERT(monthday == -1 || (monthday >= 0 && monthday < 32)); + STORM_ASSERT(month == -1 || (month >= 0 && month < 12)); + STORM_ASSERT(year == -1 || year >= 0 && year <= ((1 << 5) - 1)); + STORM_ASSERT(flags >= 0 && flags <= ((1 << 2) - 1)); + + value = ((flags & 3) << 29) // Flags: bits 29-30 (2 bits, max 3) + | ((year & 31) << 24) // Year: bits 24-28 (5 bits, max 31) + | ((month & 15) << 20) // Month: bits 20-23 (4 bits, max 15) + | ((monthday & 63) << 14) // Month day: bits 14-19 (6 bits, max 63) + | ((weekday & 7) << 11) // Weekday: bits 11-13 (3 bits, max 7) + | ((hour & 31) << 6) // Hour: bits 6-10 (5 bits, max 31) + | (minute & 63); // Minute: bits 0-5 (6 bits, max 63) +} + +void WowTime::WowEncodeTime(uint32_t& value, const WowTime* time) { + WowTime::WowEncodeTime( + value, + time->m_minute, + time->m_hour, + time->m_weekday, + time->m_monthday, + time->m_month, + time->m_year, + time->m_flags + ); +} + +char* WowTime::WowGetTimeString(WowTime* time, char* str, int32_t len) { + uint32_t encoded; + WowTime::WowEncodeTime(encoded, time); + + if (encoded == 0) { + SStrPrintf(str, len, "Not Set"); + return str; + } + + char yearStr[8]; + char monthStr[8]; + char monthdayStr[8]; + char weekdayStr[8]; + char hourStr[8]; + char minuteStr[8]; + + if (time->m_year >= 0) { + SStrPrintf(yearStr, sizeof(yearStr), "%i", time->m_year + 2000); + } else { + SStrPrintf(yearStr, sizeof(yearStr), "A"); + } + + if (time->m_month >= 0) { + SStrPrintf(monthStr, sizeof(monthStr), "%i", time->m_month + 1); + } else { + SStrPrintf(monthStr, sizeof(monthStr), "A"); + } + + if (time->m_monthday >= 0) { + SStrPrintf(monthdayStr, sizeof(monthdayStr), "%i", time->m_monthday + 1); + } else { + SStrPrintf(monthdayStr, sizeof(monthdayStr), "A"); + } + + if (time->m_weekday >= 0) { + SStrPrintf(weekdayStr, sizeof(weekdayStr), s_weekdays[time->m_weekday]); + } else { + SStrPrintf(weekdayStr, sizeof(weekdayStr), "Any"); + } + + if (time->m_hour >= 0) { + SStrPrintf(hourStr, sizeof(hourStr), "%i", time->m_hour); + } else { + SStrPrintf(hourStr, sizeof(hourStr), "A"); + } + + if (time->m_minute >= 0) { + SStrPrintf(minuteStr, sizeof(minuteStr), "%2.2i", time->m_minute); + } else { + SStrPrintf(minuteStr, sizeof(minuteStr), "A"); + } + + SStrPrintf(str, len, "%s/%s/%s (%s) %s:%s", monthStr, monthdayStr, yearStr, weekdayStr, hourStr, minuteStr); + + return str; +} + +int32_t WowTime::GetHourAndMinutes() { + if (this->m_hour < 0 || this->m_minute < 0) { + return 0; + } + + return this->m_hour * 60 + this->m_minute; +} diff --git a/src/util/time/WowTime.hpp b/src/util/time/WowTime.hpp new file mode 100644 index 0000000..b4931c6 --- /dev/null +++ b/src/util/time/WowTime.hpp @@ -0,0 +1,29 @@ +#ifndef UTIL_TIME_WOW_TIME_HPP +#define UTIL_TIME_WOW_TIME_HPP + +#include + +class WowTime { + public: + // Static functions + static void WowDecodeTime(uint32_t value, int32_t* minute, int32_t* hour, int32_t* weekday, int32_t* monthday, int32_t* month, int32_t* year, int32_t* flags); + static void WowDecodeTime(uint32_t value, WowTime* time); + static void WowEncodeTime(uint32_t& value, int32_t minute, int32_t hour, int32_t weekday, int32_t monthday, int32_t month, int32_t year, int32_t flags); + static void WowEncodeTime(uint32_t& value, const WowTime* time); + static char* WowGetTimeString(WowTime* time, char* str, int32_t len); + + // Member variables + int32_t m_minute = -1; + int32_t m_hour = -1; + int32_t m_weekday = -1; + int32_t m_monthday = -1; + int32_t m_month = -1; + int32_t m_year = -1; + int32_t m_flags = 0x0; + int32_t m_holidayOffset = 0; + + // Member functions + int32_t GetHourAndMinutes(); +}; + +#endif diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a2292d6..519fe25 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,6 +5,7 @@ if(WHOA_SYSTEM_MAC) "gx/*.cpp" "gx/font/*.cpp" "util/*.cpp" + "util/time/*.cpp" ) set_source_files_properties(${PRIVATE_SOURCES} diff --git a/test/util/time/WowTime.cpp b/test/util/time/WowTime.cpp new file mode 100644 index 0000000..b76a5ed --- /dev/null +++ b/test/util/time/WowTime.cpp @@ -0,0 +1,146 @@ +#include "util/time/WowTime.hpp" +#include "catch.hpp" +#include "storm/String.hpp" + +TEST_CASE("WowTime::WowTime", "[util]") { + SECTION("constructs correctly") { + WowTime time; + + CHECK(time.m_minute == -1); + CHECK(time.m_hour == -1); + CHECK(time.m_weekday == -1); + CHECK(time.m_monthday == -1); + CHECK(time.m_month == -1); + CHECK(time.m_year == -1); + CHECK(time.m_flags == 0x0); + CHECK(time.m_holidayOffset == 0); + } +} + +TEST_CASE("WowTime::WowDecodeTime", "[util]") { + SECTION("decodes 1234567890 as expected") { + uint32_t value = 1234567890; + WowTime time; + + WowTime::WowDecodeTime(value, &time.m_minute, &time.m_hour, &time.m_weekday, &time.m_monthday, &time.m_month, &time.m_year, &time.m_flags); + + CHECK(time.m_minute == 18); + CHECK(time.m_hour == 11); + CHECK(time.m_weekday == 0); + CHECK(time.m_monthday == 24); + CHECK(time.m_month == 9); + CHECK(time.m_year == 9); + CHECK(time.m_flags == 0x2); + } + + SECTION("decodes 0xFFFFFFFF as expected") { + uint32_t value = 0xFFFFFFFF; + WowTime time; + + WowTime::WowDecodeTime(value, &time.m_minute, &time.m_hour, &time.m_weekday, &time.m_monthday, &time.m_month, &time.m_year, &time.m_flags); + + CHECK(time.m_minute == -1); + CHECK(time.m_hour == -1); + CHECK(time.m_weekday == -1); + CHECK(time.m_monthday == -1); + CHECK(time.m_month == -1); + CHECK(time.m_year == -1); + CHECK(time.m_flags == -1); + } +} + +TEST_CASE("WowTime::WowEncodeTime", "[util]") { + SECTION("encodes 10/25/2009 (Sun) 11:18 with flag 0x2 set as expected") { + uint32_t value = 0; + + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + time.m_weekday = 0; + time.m_monthday = 24; + time.m_month = 9; + time.m_year = 9; + time.m_flags = 0x2; + + WowTime::WowEncodeTime(value, &time); + + REQUIRE(value == 1234567890); + } + + SECTION("encodes empty time as expected") { + uint32_t value = 0; + WowTime time; + + WowTime::WowEncodeTime(value, &time); + + REQUIRE(value == 0x1FFFFFFF); + } + + SECTION("encodes, decodes, and reencodes as expected") { + uint32_t value = 0; + + WowTime time1; + time1.m_minute = 18; + time1.m_hour = 11; + time1.m_weekday = 0; + time1.m_monthday = 24; + time1.m_month = 9; + time1.m_year = 9; + time1.m_flags = 0x2; + + WowTime time2; + + CHECK(time2.m_minute != time1.m_minute); + CHECK(time2.m_hour != time1.m_hour); + CHECK(time2.m_weekday != time1.m_weekday); + CHECK(time2.m_monthday != time1.m_monthday); + CHECK(time2.m_month != time1.m_month); + CHECK(time2.m_year != time1.m_year); + CHECK(time2.m_flags != time1.m_flags); + + WowTime::WowEncodeTime(value, &time1); + WowTime::WowDecodeTime(value, &time2); + + CHECK(time2.m_minute == time1.m_minute); + CHECK(time2.m_hour == time1.m_hour); + CHECK(time2.m_weekday == time1.m_weekday); + CHECK(time2.m_monthday == time1.m_monthday); + CHECK(time2.m_month == time1.m_month); + CHECK(time2.m_year == time1.m_year); + CHECK(time2.m_flags == time1.m_flags); + } +} + +TEST_CASE("WowTime::WowGetTimeString", "[util]") { + SECTION("gets expected string") { + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + time.m_weekday = 0; + time.m_monthday = 24; + time.m_month = 9; + time.m_year = 9; + time.m_flags = 0x2; + + char buf[128]; + auto timeStr = WowTime::WowGetTimeString(&time, buf, sizeof(buf)); + + REQUIRE(!SStrCmp(timeStr, "10/25/2009 (Sun) 11:18")); + } +} + +TEST_CASE("WowTime::GetHourAndMinutes", "[util]") { + SECTION("gets expected hour and minutes for default constructed time") { + WowTime time; + + REQUIRE(time.GetHourAndMinutes() == 0); + } + + SECTION("gets expected hour and minutes for 11:18") { + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + + REQUIRE(time.GetHourAndMinutes() == 11 * 60 + 18); + } +} From 335bd21a26ae5ee6d40302ecd30c439bb02512a1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 18:50:12 -0600 Subject: [PATCH 037/114] feat(util): add WowTime::SetHourAndMinutes --- src/util/time/WowTime.cpp | 5 +++++ src/util/time/WowTime.hpp | 1 + test/util/time/WowTime.cpp | 10 ++++++++++ 3 files changed, 16 insertions(+) diff --git a/src/util/time/WowTime.cpp b/src/util/time/WowTime.cpp index 3005a3c..7abdd9d 100644 --- a/src/util/time/WowTime.cpp +++ b/src/util/time/WowTime.cpp @@ -164,3 +164,8 @@ int32_t WowTime::GetHourAndMinutes() { return this->m_hour * 60 + this->m_minute; } + +void WowTime::SetHourAndMinutes(int32_t minutes) { + this->m_hour = minutes / 60; + this->m_minute = minutes % 60; +} diff --git a/src/util/time/WowTime.hpp b/src/util/time/WowTime.hpp index b4931c6..f363ebe 100644 --- a/src/util/time/WowTime.hpp +++ b/src/util/time/WowTime.hpp @@ -24,6 +24,7 @@ class WowTime { // Member functions int32_t GetHourAndMinutes(); + void SetHourAndMinutes(int32_t minutes); }; #endif diff --git a/test/util/time/WowTime.cpp b/test/util/time/WowTime.cpp index b76a5ed..d6cb15b 100644 --- a/test/util/time/WowTime.cpp +++ b/test/util/time/WowTime.cpp @@ -144,3 +144,13 @@ TEST_CASE("WowTime::GetHourAndMinutes", "[util]") { REQUIRE(time.GetHourAndMinutes() == 11 * 60 + 18); } } + +TEST_CASE("WowTime::SetHourAndMinutes", "[util]") { + SECTION("sets expected hour and minutes for 11:18") { + WowTime time; + time.SetHourAndMinutes(11 * 60 + 18); + + CHECK(time.m_hour == 11); + CHECK(time.m_minute == 18); + } +} From 661b77091fca49f1c2e1d57741bc06ad817e1081 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 18:56:12 -0600 Subject: [PATCH 038/114] feat(util): add WowTime::SetHourAndMinute overload --- src/util/time/WowTime.cpp | 11 +++++++++++ src/util/time/WowTime.hpp | 1 + test/util/time/WowTime.cpp | 13 +++++++++++++ 3 files changed, 25 insertions(+) diff --git a/src/util/time/WowTime.cpp b/src/util/time/WowTime.cpp index 7abdd9d..65534ea 100644 --- a/src/util/time/WowTime.cpp +++ b/src/util/time/WowTime.cpp @@ -169,3 +169,14 @@ void WowTime::SetHourAndMinutes(int32_t minutes) { this->m_hour = minutes / 60; this->m_minute = minutes % 60; } + +int32_t WowTime::SetHourAndMinutes(uint32_t hour, uint32_t minutes) { + if (hour >= 24 || minutes >= 60) { + return 0; + } + + this->m_hour = hour; + this->m_minute = minutes; + + return 1; +} diff --git a/src/util/time/WowTime.hpp b/src/util/time/WowTime.hpp index f363ebe..125c48b 100644 --- a/src/util/time/WowTime.hpp +++ b/src/util/time/WowTime.hpp @@ -25,6 +25,7 @@ class WowTime { // Member functions int32_t GetHourAndMinutes(); void SetHourAndMinutes(int32_t minutes); + int32_t SetHourAndMinutes(uint32_t hour, uint32_t minutes); }; #endif diff --git a/test/util/time/WowTime.cpp b/test/util/time/WowTime.cpp index d6cb15b..640bdf1 100644 --- a/test/util/time/WowTime.cpp +++ b/test/util/time/WowTime.cpp @@ -152,5 +152,18 @@ TEST_CASE("WowTime::SetHourAndMinutes", "[util]") { CHECK(time.m_hour == 11); CHECK(time.m_minute == 18); + + time.SetHourAndMinutes(11, 18); + + CHECK(time.m_hour == 11); + CHECK(time.m_minute == 18); + } + + SECTION("does not set invalid hour and minutes") { + WowTime time; + + CHECK(time.SetHourAndMinutes(25, 61) == 0); + CHECK(time.m_hour == -1); + CHECK(time.m_minute == -1); } } From aed2aebb66b025862d0805c4961568f6b3faa8bd Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 20:13:11 -0600 Subject: [PATCH 039/114] feat(util): add WowTime::AddDays --- src/util/time/WowTime.cpp | 54 ++++++++++++++++++++++++++++++++++++++ src/util/time/WowTime.hpp | 1 + test/util/time/WowTime.cpp | 21 +++++++++++++++ 3 files changed, 76 insertions(+) diff --git a/src/util/time/WowTime.cpp b/src/util/time/WowTime.cpp index 65534ea..55ae2e4 100644 --- a/src/util/time/WowTime.cpp +++ b/src/util/time/WowTime.cpp @@ -1,6 +1,7 @@ #include "util/time/WowTime.hpp" #include #include +#include static const char* s_weekdays[] = { "Sun", @@ -157,6 +158,59 @@ char* WowTime::WowGetTimeString(WowTime* time, char* str, int32_t len) { return str; } +void WowTime::AddDays(int32_t days, bool includeTime) { + // Validate date + + if (this->m_year < 0 || this->m_month < 0 || this->m_monthday < 0) { + return; + } + + // Convert WowTime to tm + + tm t = {}; + + t.tm_year = this->m_year + 100; // WowTime year is years since 2000; tm_year is years since 1900 + t.tm_mon = this->m_month; // WowTime month and tm_mon are both 0-based + t.tm_mday = this->m_monthday + 1; // WowTime monthday is 0-based; tm_mday is 1-based + t.tm_isdst = -1; // Let mktime determine DST + + if (includeTime) { + t.tm_hour = this->m_hour; + t.tm_min = this->m_minute; + } + + // Convert tm to time_t and add the specified days + + auto time = mktime(&t); + time += days * 86400; + + + if (!includeTime) { + time += 3600; // Tack on hour to ensure DST boundaries don't muck with days added + } + + // Convert adjusted time back to tm + + auto t_ = localtime(&time); + if (t_) { + t = *t_; + } else { + t = {}; + } + + // Convert adjusted tm back to WowTime + + this->m_year = t.tm_year - 100; + this->m_month = t.tm_mon; + this->m_monthday = t.tm_mday - 1; + this->m_weekday = t.tm_wday; + + if (includeTime) { + this->m_hour = t.tm_hour; + this->m_minute = t.tm_min; + } +} + int32_t WowTime::GetHourAndMinutes() { if (this->m_hour < 0 || this->m_minute < 0) { return 0; diff --git a/src/util/time/WowTime.hpp b/src/util/time/WowTime.hpp index 125c48b..f931e07 100644 --- a/src/util/time/WowTime.hpp +++ b/src/util/time/WowTime.hpp @@ -23,6 +23,7 @@ class WowTime { int32_t m_holidayOffset = 0; // Member functions + void AddDays(int32_t days, bool includeTime); int32_t GetHourAndMinutes(); void SetHourAndMinutes(int32_t minutes); int32_t SetHourAndMinutes(uint32_t hour, uint32_t minutes); diff --git a/test/util/time/WowTime.cpp b/test/util/time/WowTime.cpp index 640bdf1..f30b7f5 100644 --- a/test/util/time/WowTime.cpp +++ b/test/util/time/WowTime.cpp @@ -129,6 +129,27 @@ TEST_CASE("WowTime::WowGetTimeString", "[util]") { } } +TEST_CASE("WowTime::AddDays", "[util]") { + SECTION("adds 1 day to 1/28/2026") { + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + time.m_weekday = 3; + time.m_monthday = 27; + time.m_month = 0; + time.m_year = 26; + + time.AddDays(1, false); + + CHECK(time.m_minute == 18); + CHECK(time.m_hour == 11); + CHECK(time.m_weekday == 4); + CHECK(time.m_monthday == 28); + CHECK(time.m_month == 0); + CHECK(time.m_year == 26); + } +} + TEST_CASE("WowTime::GetHourAndMinutes", "[util]") { SECTION("gets expected hour and minutes for default constructed time") { WowTime time; From 1d91a4946287d49d815a4071182683e2889aa8c0 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 20:39:49 -0600 Subject: [PATCH 040/114] feat(util): add initial implementation of CGameTime --- src/util/Time.hpp | 1 + src/util/time/CGameTime.cpp | 29 +++++++++++++++++++++++++++++ src/util/time/CGameTime.hpp | 29 +++++++++++++++++++++++++++++ test/util/time/CGameTime.cpp | 28 ++++++++++++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 src/util/time/CGameTime.cpp create mode 100644 src/util/time/CGameTime.hpp create mode 100644 test/util/time/CGameTime.cpp diff --git a/src/util/Time.hpp b/src/util/Time.hpp index 8edb391..db18ed3 100644 --- a/src/util/Time.hpp +++ b/src/util/Time.hpp @@ -1,6 +1,7 @@ #ifndef UTIL_TIME_HPP #define UTIL_TIME_HPP +#include "util/time/CGameTime.hpp" #include "util/time/WowTime.hpp" #endif diff --git a/src/util/time/CGameTime.cpp b/src/util/time/CGameTime.cpp new file mode 100644 index 0000000..94810ab --- /dev/null +++ b/src/util/time/CGameTime.cpp @@ -0,0 +1,29 @@ +#include "util/time/CGameTime.hpp" +#include "common/Time.hpp" + +void CGameTime::PerformCallbacks(int32_t minutes) { + // TODO +} + +void CGameTime::TickMinute() { + // Increment minute + int32_t minutes = (this->GetHourAndMinutes() + 1) % 1440; + + // Update hours and minutes + this->SetHourAndMinutes(minutes); + + // Increment day if minute crossed day boundary + if (minutes == 0) { + this->AddDays(1, false); + } + + this->m_gameMinutesElapsed++; + + this->PerformCallbacks(minutes); + + this->m_lastTickMinute = OsGetAsyncTimeMsPrecise(); + + this->uint40 = 1; + + this->m_dayProgression = this->m_gameMinutesThisTick + static_cast(minutes); +} diff --git a/src/util/time/CGameTime.hpp b/src/util/time/CGameTime.hpp new file mode 100644 index 0000000..d8f53c0 --- /dev/null +++ b/src/util/time/CGameTime.hpp @@ -0,0 +1,29 @@ +#ifndef UTIL_TIME_C_GAME_TIME_HPP +#define UTIL_TIME_C_GAME_TIME_HPP + +#include "util/time/WowTime.hpp" + +class CGameTime : public WowTime { + public: + // Public member functions + void PerformCallbacks(int32_t minutes); + void TickMinute(); + + private: + // Private member variables + uint32_t m_lastTick = 0; + int32_t m_timeBias = 0; + int32_t m_dateBias = 0; + uint32_t m_gameMinutesElapsed = 0; + float m_gameMinutesPerRealSecond = 1.0f / 60.0f; + float m_gameMinutesThisTick = 0.0f; + uint32_t m_timeDifferential = 0; + uint32_t m_lastTickMinute = 0; + uint8_t uint40 = 0; + float m_dayProgression = 0.0f; + float float48 = 0.0f; + float float4C = 0.0f; + // TODO m_callbackLists +}; + +#endif diff --git a/test/util/time/CGameTime.cpp b/test/util/time/CGameTime.cpp new file mode 100644 index 0000000..825da49 --- /dev/null +++ b/test/util/time/CGameTime.cpp @@ -0,0 +1,28 @@ +#include "util/time/CGameTime.hpp" +#include "catch.hpp" + +TEST_CASE("CGameTime::CGameTime", "[util]") { + SECTION("constructs correctly") { + CGameTime time; + + CHECK(time.m_minute == -1); + CHECK(time.m_hour == -1); + CHECK(time.m_weekday == -1); + CHECK(time.m_monthday == -1); + CHECK(time.m_month == -1); + CHECK(time.m_year == -1); + CHECK(time.m_flags == 0x0); + CHECK(time.m_holidayOffset == 0); + } +} + +TEST_CASE("CGameTime::TickMinute", "[util]") { + SECTION("ticks minute correctly") { + CGameTime time; + time.SetHourAndMinutes(0, 0); + time.TickMinute(); + + CHECK(time.m_hour == 0); + CHECK(time.m_minute == 1); + } +} From 886ababae9e7757117aa15536ac41d30e5d4e001 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 21:31:24 -0600 Subject: [PATCH 041/114] feat(util): add CGameTime::GameTimeSetTime --- src/util/time/CGameTime.cpp | 41 ++++++++++++++++++++++++++++++++++++ src/util/time/CGameTime.hpp | 7 ++++-- test/util/time/CGameTime.cpp | 25 ++++++++++++++++------ 3 files changed, 64 insertions(+), 9 deletions(-) diff --git a/src/util/time/CGameTime.cpp b/src/util/time/CGameTime.cpp index 94810ab..6cf165c 100644 --- a/src/util/time/CGameTime.cpp +++ b/src/util/time/CGameTime.cpp @@ -1,6 +1,47 @@ #include "util/time/CGameTime.hpp" #include "common/Time.hpp" +void CGameTime::GameTimeSetTime(const WowTime& time, bool shouldTick) { + WowTime biasTime = time; + + if (this->m_timeBias) { + auto minutes = biasTime.GetHourAndMinutes() + this->m_timeBias; + + if (minutes < 0) { + minutes += 1440; + } else { + minutes %= 1440; + } + + biasTime.SetHourAndMinutes(minutes); + } + + if (this->m_dateBias) { + biasTime.AddDays(this->m_dateBias, false); + } + + static_cast(*this) = biasTime; + + if (shouldTick) { + // Rewind time by exactly one minute + if (this->m_minute != 0) { + this->m_minute--; + } else { + this->m_minute = 59; + + if (this->m_hour != 0) { + this->m_hour--; + } else { + this->m_hour = 23; + this->AddDays(-1, false); + } + } + + // Tick ahead exactly one minute (ensures callbacks fire and various counters update) + this->TickMinute(); + } +} + void CGameTime::PerformCallbacks(int32_t minutes) { // TODO } diff --git a/src/util/time/CGameTime.hpp b/src/util/time/CGameTime.hpp index d8f53c0..445dbf9 100644 --- a/src/util/time/CGameTime.hpp +++ b/src/util/time/CGameTime.hpp @@ -6,8 +6,7 @@ class CGameTime : public WowTime { public: // Public member functions - void PerformCallbacks(int32_t minutes); - void TickMinute(); + void GameTimeSetTime(const WowTime& time, bool shouldTick); private: // Private member variables @@ -24,6 +23,10 @@ class CGameTime : public WowTime { float float48 = 0.0f; float float4C = 0.0f; // TODO m_callbackLists + + // Private member functions + void PerformCallbacks(int32_t minutes); + void TickMinute(); }; #endif diff --git a/test/util/time/CGameTime.cpp b/test/util/time/CGameTime.cpp index 825da49..88dfd6d 100644 --- a/test/util/time/CGameTime.cpp +++ b/test/util/time/CGameTime.cpp @@ -16,13 +16,24 @@ TEST_CASE("CGameTime::CGameTime", "[util]") { } } -TEST_CASE("CGameTime::TickMinute", "[util]") { - SECTION("ticks minute correctly") { - CGameTime time; - time.SetHourAndMinutes(0, 0); - time.TickMinute(); +TEST_CASE("CGameTime::GameTimeSetTime", "[util]") { + SECTION("sets game time correctly") { + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + time.m_weekday = 3; + time.m_monthday = 27; + time.m_month = 0; + time.m_year = 26; - CHECK(time.m_hour == 0); - CHECK(time.m_minute == 1); + CGameTime gameTime; + gameTime.GameTimeSetTime(time, true); + + CHECK(gameTime.m_minute == 18); + CHECK(gameTime.m_hour == 11); + CHECK(gameTime.m_weekday == 3); + CHECK(gameTime.m_monthday == 27); + CHECK(gameTime.m_month == 0); + CHECK(gameTime.m_year == 26); } } From 721ee527eb3291867784228827880bea86093d2f Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 28 Jan 2026 22:01:23 -0600 Subject: [PATCH 042/114] feat(util): add CGameTime::GameTimeUpdate --- src/util/time/CGameTime.cpp | 22 ++++++++++++++++++++++ src/util/time/CGameTime.hpp | 1 + test/util/time/CGameTime.cpp | 20 ++++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/src/util/time/CGameTime.cpp b/src/util/time/CGameTime.cpp index 6cf165c..f0ecf39 100644 --- a/src/util/time/CGameTime.cpp +++ b/src/util/time/CGameTime.cpp @@ -42,6 +42,28 @@ void CGameTime::GameTimeSetTime(const WowTime& time, bool shouldTick) { } } +void CGameTime::GameTimeUpdate(float elapsedSec) { + this->m_gameMinutesThisTick += this->m_gameMinutesPerRealSecond * elapsedSec; + + // Skip minute ticks for time differential + if (this->m_timeDifferential != 0 && this->m_gameMinutesThisTick >= 1.0f) { + auto minutesToConsume = static_cast(this->m_gameMinutesThisTick); + + // Clamp to differential + if (this->m_timeDifferential < minutesToConsume) { + minutesToConsume = this->m_timeDifferential; + } + + this->m_timeDifferential -= minutesToConsume; + this->m_gameMinutesThisTick -= static_cast(minutesToConsume); + } + + while (this->m_gameMinutesThisTick >= 1.0f) { + this->m_gameMinutesThisTick -= 1.0f; + this->TickMinute(); + } +} + void CGameTime::PerformCallbacks(int32_t minutes) { // TODO } diff --git a/src/util/time/CGameTime.hpp b/src/util/time/CGameTime.hpp index 445dbf9..ed02236 100644 --- a/src/util/time/CGameTime.hpp +++ b/src/util/time/CGameTime.hpp @@ -7,6 +7,7 @@ class CGameTime : public WowTime { public: // Public member functions void GameTimeSetTime(const WowTime& time, bool shouldTick); + void GameTimeUpdate(float elapsedSec); private: // Private member variables diff --git a/test/util/time/CGameTime.cpp b/test/util/time/CGameTime.cpp index 88dfd6d..4f1d20c 100644 --- a/test/util/time/CGameTime.cpp +++ b/test/util/time/CGameTime.cpp @@ -37,3 +37,23 @@ TEST_CASE("CGameTime::GameTimeSetTime", "[util]") { CHECK(gameTime.m_year == 26); } } + +TEST_CASE("CGameTime::GameTimeUpdate", "[util]") { + SECTION("updates game time correctly") { + WowTime time; + time.m_minute = 18; + time.m_hour = 11; + time.m_weekday = 3; + time.m_monthday = 27; + time.m_month = 0; + time.m_year = 26; + + CGameTime gameTime; + gameTime.GameTimeSetTime(time, true); + + gameTime.GameTimeUpdate(60.0f); + + CHECK(gameTime.m_hour == 11); + CHECK(gameTime.m_minute == 19); + } +} From efd3f8e8f4b0f6c3898631a18e9d29bf8b0ee0fa Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 07:33:50 -0600 Subject: [PATCH 043/114] feat(client): add ClientGameTimeTickHandler --- src/client/Client.cpp | 17 ++++++++++++++--- src/client/Client.hpp | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/client/Client.cpp b/src/client/Client.cpp index a193f64..98a7dca 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -20,6 +20,7 @@ #include "ui/FrameXML.hpp" #include "ui/Game.hpp" #include "util/Random.hpp" +#include "util/Time.hpp" #include "world/World.hpp" #include #include @@ -30,6 +31,8 @@ CVar* Client::g_accountNameVar; CVar* Client::g_accountListVar; HEVENTCONTEXT Client::g_clientEventContext; +CGameTime g_clientGameTime; + static CVar* s_desktopGammaCvar; static CVar* s_gammaCvar; static CVar* s_textureCacheSizeCvar; @@ -70,10 +73,18 @@ void BaseInitializeGlobal() { PropInitialize(); } +int32_t ClientGameTimeTickHandler(const void* data, void* param) { + STORM_ASSERT(data); + + g_clientGameTime.GameTimeUpdate(static_cast(data)->elapsedSec); + + return 1; +} + int32_t ClientIdle(const void* data, void* param) { - // TODO - // ClientGameTimeTickHandler(data, param); - // Player_C_ZoneUpdateHandler(data, param); + ClientGameTimeTickHandler(data, nullptr); + + // TODO Player_C_ZoneUpdateHandler(data, nullptr); return 1; } diff --git a/src/client/Client.hpp b/src/client/Client.hpp index fba112d..92365b8 100644 --- a/src/client/Client.hpp +++ b/src/client/Client.hpp @@ -5,6 +5,7 @@ #include class CVar; +class CGameTime; namespace Client { extern CVar* g_accountNameVar; @@ -12,6 +13,8 @@ namespace Client { extern HEVENTCONTEXT g_clientEventContext; } +extern CGameTime g_clientGameTime; + void ClientInitializeGame(uint32_t mapId, C3Vector position); void ClientPostClose(int32_t a1); From 50a24e8564f84bacaf6f0cea9c66672853abdf1d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 07:37:43 -0600 Subject: [PATCH 044/114] feat(ui): implement Script_GetGameTime --- src/client/Client.cpp | 1 - src/client/Client.hpp | 2 +- src/ui/ScriptFunctionsSystem.cpp | 9 +++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/client/Client.cpp b/src/client/Client.cpp index 98a7dca..af9a2dd 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -20,7 +20,6 @@ #include "ui/FrameXML.hpp" #include "ui/Game.hpp" #include "util/Random.hpp" -#include "util/Time.hpp" #include "world/World.hpp" #include #include diff --git a/src/client/Client.hpp b/src/client/Client.hpp index 92365b8..49dac65 100644 --- a/src/client/Client.hpp +++ b/src/client/Client.hpp @@ -2,10 +2,10 @@ #define CLIENT_CLIENT_HPP #include "event/Event.hpp" +#include "util/Time.hpp" #include class CVar; -class CGameTime; namespace Client { extern CVar* g_accountNameVar; diff --git a/src/ui/ScriptFunctionsSystem.cpp b/src/ui/ScriptFunctionsSystem.cpp index bc484aa..0b4c225 100644 --- a/src/ui/ScriptFunctionsSystem.cpp +++ b/src/ui/ScriptFunctionsSystem.cpp @@ -1,4 +1,5 @@ #include "ui/FrameScript.hpp" +#include "client/Client.hpp" #include "ui/ScriptFunctionsShared.hpp" #include "ui/Types.hpp" #include "util/Lua.hpp" @@ -14,10 +15,10 @@ int32_t Script_GetTime(lua_State* L) { } int32_t Script_GetGameTime(lua_State* L) { - // TODO real implementation - lua_pushnumber(L, 1.0); - lua_pushnumber(L, 15.0); - WHOA_UNIMPLEMENTED(2); + lua_pushnumber(L, g_clientGameTime.m_hour); + lua_pushnumber(L, g_clientGameTime.m_minute); + + return 2; } int32_t Script_ConsoleExec(lua_State* L) { From 6e7c267d3e8462a12e047a1c9be3972fa12b77c7 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 07:52:43 -0600 Subject: [PATCH 045/114] feat(client): add ClientInitializeGameTime --- src/client/Client.cpp | 11 +++++++++++ src/client/ClientHandlers.cpp | 21 +++++++++++++++++++++ src/client/ClientHandlers.hpp | 10 ++++++++++ 3 files changed, 42 insertions(+) diff --git a/src/client/Client.cpp b/src/client/Client.cpp index af9a2dd..069bd3f 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -80,6 +80,16 @@ int32_t ClientGameTimeTickHandler(const void* data, void* param) { return 1; } +void ClientInitializeGameTime() { + ClientServices::SetMessageHandler(SMSG_GAME_SPEED_SET, &ReceiveNewGameSpeed, nullptr); + ClientServices::SetMessageHandler(SMSG_LOGIN_SET_TIME_SPEED, &ReceiveNewTimeSpeed, nullptr); + ClientServices::SetMessageHandler(SMSG_GAME_TIME_UPDATE, &ReceiveGameTimeUpdate, nullptr); + ClientServices::SetMessageHandler(SMSG_SERVERTIME, &ReceiveServerTime, nullptr); + ClientServices::SetMessageHandler(SMSG_GAME_TIME_SET, &ReceiveNewGameTime, nullptr); + + // TODO initialize s_forcedChangeCallbacks +} + int32_t ClientIdle(const void* data, void* param) { ClientGameTimeTickHandler(data, nullptr); @@ -101,6 +111,7 @@ void ClientInitializeGame(uint32_t mapId, C3Vector position) { // TODO EventRegister(EVENT_ID_IDLE, ClientIdle); + ClientInitializeGameTime(); // TODO diff --git a/src/client/ClientHandlers.cpp b/src/client/ClientHandlers.cpp index 1eeab84..ecd90c1 100644 --- a/src/client/ClientHandlers.cpp +++ b/src/client/ClientHandlers.cpp @@ -2,6 +2,7 @@ #include "console/Console.hpp" #include "db/Db.hpp" #include "object/Client.hpp" +#include "util/Unimplemented.hpp" #include "world/World.hpp" #include #include @@ -77,6 +78,26 @@ int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataSto return 0; } +int32_t ReceiveGameTimeUpdate(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t ReceiveNewGameSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t ReceiveNewGameTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t ReceiveNewTimeSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t ReceiveServerTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { + WHOA_UNIMPLEMENTED(0); +} + int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { // TODO diff --git a/src/client/ClientHandlers.hpp b/src/client/ClientHandlers.hpp index 4cb756c..47bc1f8 100644 --- a/src/client/ClientHandlers.hpp +++ b/src/client/ClientHandlers.hpp @@ -14,6 +14,16 @@ int32_t NotifyHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* int32_t PlayedTimeHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); +int32_t ReceiveGameTimeUpdate(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); + +int32_t ReceiveNewGameSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); + +int32_t ReceiveNewGameTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); + +int32_t ReceiveNewTimeSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); + +int32_t ReceiveServerTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); + int32_t TransferAbortedHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); int32_t TransferPendingHandler(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg); From 53b26169f3dbeedfbe84d35eb9d42b82b6558dbc Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 08:46:57 -0600 Subject: [PATCH 046/114] feat(util): add CGameTime::GameTimeSetMinutesPerSecond --- src/util/time/CGameTime.cpp | 14 ++++++++++++++ src/util/time/CGameTime.hpp | 7 ++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/util/time/CGameTime.cpp b/src/util/time/CGameTime.cpp index f0ecf39..e91a35d 100644 --- a/src/util/time/CGameTime.cpp +++ b/src/util/time/CGameTime.cpp @@ -1,6 +1,20 @@ #include "util/time/CGameTime.hpp" #include "common/Time.hpp" +float CGameTime::GameTimeSetMinutesPerSecond(float minutesPerSec) { + float oldMinutesPerSec = this->m_gameMinutesPerRealSecond; + + if (minutesPerSec > CGameTime::MAX_SPEED) { + minutesPerSec = CGameTime::MAX_SPEED; + } else if (minutesPerSec < CGameTime::MIN_SPEED) { + minutesPerSec = CGameTime::MIN_SPEED; + } + + this->m_gameMinutesPerRealSecond = minutesPerSec; + + return oldMinutesPerSec; +} + void CGameTime::GameTimeSetTime(const WowTime& time, bool shouldTick) { WowTime biasTime = time; diff --git a/src/util/time/CGameTime.hpp b/src/util/time/CGameTime.hpp index ed02236..8d18b5d 100644 --- a/src/util/time/CGameTime.hpp +++ b/src/util/time/CGameTime.hpp @@ -5,7 +5,12 @@ class CGameTime : public WowTime { public: + // Public static variables + static constexpr float MIN_SPEED = 1.0f / 60.0f; + static constexpr float MAX_SPEED = 60.0f; + // Public member functions + float GameTimeSetMinutesPerSecond(float minutesPerSec); void GameTimeSetTime(const WowTime& time, bool shouldTick); void GameTimeUpdate(float elapsedSec); @@ -15,7 +20,7 @@ class CGameTime : public WowTime { int32_t m_timeBias = 0; int32_t m_dateBias = 0; uint32_t m_gameMinutesElapsed = 0; - float m_gameMinutesPerRealSecond = 1.0f / 60.0f; + float m_gameMinutesPerRealSecond = MIN_SPEED; float m_gameMinutesThisTick = 0.0f; uint32_t m_timeDifferential = 0; uint32_t m_lastTickMinute = 0; From 0bb3ac157fa00303d211a5b4e9d5f44009b6f1a5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 08:47:19 -0600 Subject: [PATCH 047/114] feat(client): implement ReceiveNewTimeSpeed --- src/client/ClientHandlers.cpp | 36 +++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/src/client/ClientHandlers.cpp b/src/client/ClientHandlers.cpp index ecd90c1..70c4adb 100644 --- a/src/client/ClientHandlers.cpp +++ b/src/client/ClientHandlers.cpp @@ -1,12 +1,14 @@ #include "client/ClientHandlers.hpp" +#include "Client.hpp" #include "console/Console.hpp" #include "db/Db.hpp" #include "object/Client.hpp" +#include "util/Time.hpp" #include "util/Unimplemented.hpp" #include "world/World.hpp" #include -#include #include +#include static float s_newFacing; static C3Vector s_newPosition; @@ -91,7 +93,37 @@ int32_t ReceiveNewGameTime(void* param, NETMESSAGE msgId, uint32_t time, CDataSt } int32_t ReceiveNewTimeSpeed(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { - WHOA_UNIMPLEMENTED(0); + uint32_t encodedTime; + msg->Get(encodedTime); + + float newSpeed; + msg->Get(newSpeed); + + uint32_t holidayOffset; + msg->Get(holidayOffset); + + if (!msg->IsRead()) { + STORM_ASSERT(msg->IsFinal()); + // TODO ConsoleWriteA("Malformed message received: Id = %d, Len = %d, Read = %d\n", DEFAULT_COLOR, msgId, msg->Size(), msg->Tell()); + + return 0; + } + + WowTime newTime; + WowTime::WowDecodeTime(encodedTime, &newTime); + newTime.m_holidayOffset = holidayOffset; + + g_clientGameTime.GameTimeSetTime(newTime, true); + + // TODO UpdateTime(); + + auto oldSpeed = g_clientGameTime.GameTimeSetMinutesPerSecond(newSpeed); + + char logStr[256]; + SStrPrintf(logStr, sizeof(logStr), "Gamespeed set from %.03f to %.03f", oldSpeed, newSpeed); + ConsoleWrite(logStr, DEFAULT_COLOR); + + return 1; } int32_t ReceiveServerTime(void* param, NETMESSAGE msgId, uint32_t time, CDataStore* msg) { From 26522016e06053fa88b0c27b2a455f135bfe03e2 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 12:46:31 -0600 Subject: [PATCH 048/114] feat(ui): implement Script_GetCVar --- src/ui/game/GameScript.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ui/game/GameScript.cpp b/src/ui/game/GameScript.cpp index 111b13a..236b5b9 100644 --- a/src/ui/game/GameScript.cpp +++ b/src/ui/game/GameScript.cpp @@ -133,7 +133,21 @@ int32_t Script_SetCVar(lua_State* L) { } int32_t Script_GetCVar(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + luaL_error(L, "Usage: GetCVar(\"cvar\")"); + return 0; + } + + auto varName = lua_tostring(L, 1); + auto var = CVar::LookupRegistered(varName); + + if (var && !(var->m_flags & 0x40)) { + lua_pushstring(L, var->GetString()); + } else { + lua_pushnil(L); + } + + return 1; } int32_t Script_GetCVarBool(lua_State* L) { From f19894ef126436ed648ab6776d8e6f8b12c01da3 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 21:33:04 -0600 Subject: [PATCH 049/114] feat(ui): add stub implementations of remaining game frame classes --- src/ui/game/CGCharacterModelBase.cpp | 37 ++++++++++ src/ui/game/CGCharacterModelBase.hpp | 28 +++++++ src/ui/game/CGCharacterModelBaseScript.cpp | 30 ++++++++ src/ui/game/CGCharacterModelBaseScript.hpp | 10 +++ src/ui/game/CGCooldown.cpp | 37 ++++++++++ src/ui/game/CGCooldown.hpp | 28 +++++++ src/ui/game/CGCooldownScript.cpp | 35 +++++++++ src/ui/game/CGCooldownScript.hpp | 10 +++ src/ui/game/CGDressUpModelFrame.cpp | 37 ++++++++++ src/ui/game/CGDressUpModelFrame.hpp | 28 +++++++ src/ui/game/CGDressUpModelFrameScript.cpp | 25 +++++++ src/ui/game/CGDressUpModelFrameScript.hpp | 10 +++ src/ui/game/CGGameUI.cpp | 22 +++++- src/ui/game/CGMinimapFrame.cpp | 37 ++++++++++ src/ui/game/CGMinimapFrame.hpp | 28 +++++++ src/ui/game/CGMinimapFrameScript.cpp | 85 ++++++++++++++++++++++ src/ui/game/CGMinimapFrameScript.hpp | 10 +++ src/ui/game/CGQuestPOIFrame.cpp | 38 ++++++++++ src/ui/game/CGQuestPOIFrame.hpp | 28 +++++++ src/ui/game/CGQuestPOIFrameScript.cpp | 80 ++++++++++++++++++++ src/ui/game/CGQuestPOIFrameScript.hpp | 10 +++ src/ui/game/CGTabardModelFrame.cpp | 37 ++++++++++ src/ui/game/CGTabardModelFrame.hpp | 28 +++++++ src/ui/game/CGTabardModelFrameScript.cpp | 60 +++++++++++++++ src/ui/game/CGTabardModelFrameScript.hpp | 10 +++ 25 files changed, 784 insertions(+), 4 deletions(-) create mode 100644 src/ui/game/CGCharacterModelBase.cpp create mode 100644 src/ui/game/CGCharacterModelBase.hpp create mode 100644 src/ui/game/CGCharacterModelBaseScript.cpp create mode 100644 src/ui/game/CGCharacterModelBaseScript.hpp create mode 100644 src/ui/game/CGCooldown.cpp create mode 100644 src/ui/game/CGCooldown.hpp create mode 100644 src/ui/game/CGCooldownScript.cpp create mode 100644 src/ui/game/CGCooldownScript.hpp create mode 100644 src/ui/game/CGDressUpModelFrame.cpp create mode 100644 src/ui/game/CGDressUpModelFrame.hpp create mode 100644 src/ui/game/CGDressUpModelFrameScript.cpp create mode 100644 src/ui/game/CGDressUpModelFrameScript.hpp create mode 100644 src/ui/game/CGMinimapFrame.cpp create mode 100644 src/ui/game/CGMinimapFrame.hpp create mode 100644 src/ui/game/CGMinimapFrameScript.cpp create mode 100644 src/ui/game/CGMinimapFrameScript.hpp create mode 100644 src/ui/game/CGQuestPOIFrame.cpp create mode 100644 src/ui/game/CGQuestPOIFrame.hpp create mode 100644 src/ui/game/CGQuestPOIFrameScript.cpp create mode 100644 src/ui/game/CGQuestPOIFrameScript.hpp create mode 100644 src/ui/game/CGTabardModelFrame.cpp create mode 100644 src/ui/game/CGTabardModelFrame.hpp create mode 100644 src/ui/game/CGTabardModelFrameScript.cpp create mode 100644 src/ui/game/CGTabardModelFrameScript.hpp diff --git a/src/ui/game/CGCharacterModelBase.cpp b/src/ui/game/CGCharacterModelBase.cpp new file mode 100644 index 0000000..089afbe --- /dev/null +++ b/src/ui/game/CGCharacterModelBase.cpp @@ -0,0 +1,37 @@ +#include "ui/game/CGCharacterModelBase.hpp" +#include "ui/game/CGCharacterModelBaseScript.hpp" + +int32_t CGCharacterModelBase::s_metatable; +int32_t CGCharacterModelBase::s_objectType; + +CSimpleFrame* CGCharacterModelBase::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGCharacterModelBase)(parent); +} + +void CGCharacterModelBase::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGCharacterModelBase::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGCharacterModelBase::RegisterScriptMethods); +} + +int32_t CGCharacterModelBase::GetObjectType() { + if (!CGCharacterModelBase::s_objectType) { + CGCharacterModelBase::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGCharacterModelBase::s_objectType; +} + +void CGCharacterModelBase::RegisterScriptMethods(lua_State* L) { + CSimpleModel::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGCharacterModelBaseMethods, NUM_CG_CHARACTER_MODEL_BASE_SCRIPT_METHODS); +} + +CGCharacterModelBase::CGCharacterModelBase(CSimpleFrame* parent) : CSimpleModel(parent) { + // TODO +} + +int32_t CGCharacterModelBase::GetScriptMetaTable() { + return CGCharacterModelBase::s_metatable; +} diff --git a/src/ui/game/CGCharacterModelBase.hpp b/src/ui/game/CGCharacterModelBase.hpp new file mode 100644 index 0000000..b67b3e2 --- /dev/null +++ b/src/ui/game/CGCharacterModelBase.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_CHARACTER_MODEL_BASE_HPP +#define UI_GAME_C_G_CHARACTER_MODEL_BASE_HPP + +#include "ui/simple/CSimpleModel.hpp" + +class CGCharacterModelBase : public CSimpleModel { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGCharacterModelBase(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGCharacterModelBaseScript.cpp b/src/ui/game/CGCharacterModelBaseScript.cpp new file mode 100644 index 0000000..b4d92a9 --- /dev/null +++ b/src/ui/game/CGCharacterModelBaseScript.cpp @@ -0,0 +1,30 @@ +#include "ui/game/CGCharacterModelBaseScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_SetUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetCreature(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_RefreshUnit(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetRotation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGCharacterModelBaseMethods[] = { + { "SetUnit", &Script_SetUnit }, + { "SetCreature", &Script_SetCreature }, + { "RefreshUnit", &Script_RefreshUnit }, + { "SetRotation", &Script_SetRotation }, +}; diff --git a/src/ui/game/CGCharacterModelBaseScript.hpp b/src/ui/game/CGCharacterModelBaseScript.hpp new file mode 100644 index 0000000..7c9deb5 --- /dev/null +++ b/src/ui/game/CGCharacterModelBaseScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_CHARACTER_MODEL_BASE_SCRIPT_HPP +#define UI_GAME_C_G_CHARACTER_MODEL_BASE_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_CHARACTER_MODEL_BASE_SCRIPT_METHODS 4 + +extern FrameScript_Method CGCharacterModelBaseMethods[NUM_CG_CHARACTER_MODEL_BASE_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/game/CGCooldown.cpp b/src/ui/game/CGCooldown.cpp new file mode 100644 index 0000000..fb6aef8 --- /dev/null +++ b/src/ui/game/CGCooldown.cpp @@ -0,0 +1,37 @@ +#include "ui/game/CGCooldown.hpp" +#include "ui/game/CGCooldownScript.hpp" + +int32_t CGCooldown::s_metatable; +int32_t CGCooldown::s_objectType; + +CSimpleFrame* CGCooldown::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGCooldown)(parent); +} + +void CGCooldown::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGCooldown::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGCooldown::RegisterScriptMethods); +} + +int32_t CGCooldown::GetObjectType() { + if (!CGCooldown::s_objectType) { + CGCooldown::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGCooldown::s_objectType; +} + +void CGCooldown::RegisterScriptMethods(lua_State* L) { + CSimpleFrame::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGCooldownMethods, NUM_CG_COOLDOWN_SCRIPT_METHODS); +} + +CGCooldown::CGCooldown(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO +} + +int32_t CGCooldown::GetScriptMetaTable() { + return CGCooldown::s_metatable; +} diff --git a/src/ui/game/CGCooldown.hpp b/src/ui/game/CGCooldown.hpp new file mode 100644 index 0000000..8522fb1 --- /dev/null +++ b/src/ui/game/CGCooldown.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_COOLDOWN_HPP +#define UI_GAME_C_G_COOLDOWN_HPP + +#include "ui/simple/CSimpleFrame.hpp" + +class CGCooldown : public CSimpleFrame { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGCooldown(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGCooldownScript.cpp b/src/ui/game/CGCooldownScript.cpp new file mode 100644 index 0000000..5e7f145 --- /dev/null +++ b/src/ui/game/CGCooldownScript.cpp @@ -0,0 +1,35 @@ +#include "ui/game/CGCooldownScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CGCooldown_SetCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGCooldown_SetReverse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGCooldown_GetReverse(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGCooldown_SetDrawEdge(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGCooldown_GetDrawEdge(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGCooldownMethods[] = { + { "SetCooldown", &CGCooldown_SetCooldown }, + { "SetReverse", &CGCooldown_SetReverse }, + { "GetReverse", &CGCooldown_GetReverse }, + { "SetDrawEdge", &CGCooldown_SetDrawEdge }, + { "GetDrawEdge", &CGCooldown_GetDrawEdge }, +}; diff --git a/src/ui/game/CGCooldownScript.hpp b/src/ui/game/CGCooldownScript.hpp new file mode 100644 index 0000000..34aecc7 --- /dev/null +++ b/src/ui/game/CGCooldownScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_COOLDOWN_SCRIPT_HPP +#define UI_GAME_C_G_COOLDOWN_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_COOLDOWN_SCRIPT_METHODS 5 + +extern FrameScript_Method CGCooldownMethods[NUM_CG_COOLDOWN_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/game/CGDressUpModelFrame.cpp b/src/ui/game/CGDressUpModelFrame.cpp new file mode 100644 index 0000000..8ead82d --- /dev/null +++ b/src/ui/game/CGDressUpModelFrame.cpp @@ -0,0 +1,37 @@ +#include "ui/game/CGDressUpModelFrame.hpp" +#include "ui/game/CGDressUpModelFrameScript.hpp" + +int32_t CGDressUpModelFrame::s_metatable; +int32_t CGDressUpModelFrame::s_objectType; + +CSimpleFrame* CGDressUpModelFrame::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGDressUpModelFrame)(parent); +} + +void CGDressUpModelFrame::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGDressUpModelFrame::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGDressUpModelFrame::RegisterScriptMethods); +} + +int32_t CGDressUpModelFrame::GetObjectType() { + if (!CGDressUpModelFrame::s_objectType) { + CGDressUpModelFrame::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGDressUpModelFrame::s_objectType; +} + +void CGDressUpModelFrame::RegisterScriptMethods(lua_State* L) { + CGCharacterModelBase::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGDressUpModelFrameMethods, NUM_CG_DRESS_UP_MODEL_FRAME_SCRIPT_METHODS); +} + +CGDressUpModelFrame::CGDressUpModelFrame(CSimpleFrame* parent) : CGCharacterModelBase(parent) { + // TODO +} + +int32_t CGDressUpModelFrame::GetScriptMetaTable() { + return CGDressUpModelFrame::s_metatable; +} diff --git a/src/ui/game/CGDressUpModelFrame.hpp b/src/ui/game/CGDressUpModelFrame.hpp new file mode 100644 index 0000000..a74f6d3 --- /dev/null +++ b/src/ui/game/CGDressUpModelFrame.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_DRESS_UP_MODEL_FRAME_HPP +#define UI_GAME_C_G_DRESS_UP_MODEL_FRAME_HPP + +#include "ui/game/CGCharacterModelBase.hpp" + +class CGDressUpModelFrame : public CGCharacterModelBase { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGDressUpModelFrame(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGDressUpModelFrameScript.cpp b/src/ui/game/CGDressUpModelFrameScript.cpp new file mode 100644 index 0000000..14e948b --- /dev/null +++ b/src/ui/game/CGDressUpModelFrameScript.cpp @@ -0,0 +1,25 @@ +#include "ui/game/CGDressUpModelFrameScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_Undress(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_Dress(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_TryOn(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGDressUpModelFrameMethods[] = { + { "Undress", &Script_Undress }, + { "Dress", &Script_Dress }, + { "TryOn", &Script_TryOn }, +}; diff --git a/src/ui/game/CGDressUpModelFrameScript.hpp b/src/ui/game/CGDressUpModelFrameScript.hpp new file mode 100644 index 0000000..fe4aad5 --- /dev/null +++ b/src/ui/game/CGDressUpModelFrameScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_DRESS_UP_MODEL_FRAME_SCRIPT_HPP +#define UI_GAME_C_G_DRESS_UP_MODEL_FRAME_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_DRESS_UP_MODEL_FRAME_SCRIPT_METHODS 3 + +extern FrameScript_Method CGDressUpModelFrameMethods[NUM_CG_DRESS_UP_MODEL_FRAME_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 2729222..21bd423 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -4,6 +4,12 @@ #include "ui/FrameXML.hpp" #include "ui/Key.hpp" #include "ui/game/BattlefieldInfoScript.hpp" +#include "ui/game/CGCharacterModelBase.hpp" +#include "ui/game/CGCooldown.hpp" +#include "ui/game/CGDressUpModelFrame.hpp" +#include "ui/game/CGMinimapFrame.hpp" +#include "ui/game/CGQuestPOIFrame.hpp" +#include "ui/game/CGTabardModelFrame.hpp" #include "ui/game/CGTooltip.hpp" #include "ui/game/CGWorldFrame.hpp" #include "ui/game/CharacterInfoScript.hpp" @@ -22,8 +28,12 @@ void LoadScriptFunctions() { // TODO CGTooltip::CreateScriptMetaTable(); - - // TODO + CGCooldown::CreateScriptMetaTable(); + CGMinimapFrame::CreateScriptMetaTable(); + CGCharacterModelBase::CreateScriptMetaTable(); + CGDressUpModelFrame::CreateScriptMetaTable(); + CGTabardModelFrame::CreateScriptMetaTable(); + CGQuestPOIFrame::CreateScriptMetaTable(); GameScriptRegisterFunctions(); UIBindingsRegisterScriptFunctions(); @@ -137,6 +147,10 @@ void CGGameUI::InitializeGame() { void CGGameUI::RegisterFrameFactories() { FrameXML_RegisterFactory("WorldFrame", &CGWorldFrame::Create, true); FrameXML_RegisterFactory("GameTooltip", &CGTooltip::Create, false); - - // TODO register remaining factories + FrameXML_RegisterFactory("Cooldown", &CGCooldown::Create, false); + FrameXML_RegisterFactory("Minimap", &CGMinimapFrame::Create, false); + FrameXML_RegisterFactory("PlayerModel", &CGCharacterModelBase::Create, false); + FrameXML_RegisterFactory("DressUpModel", &CGDressUpModelFrame::Create, false); + FrameXML_RegisterFactory("TabardModel", &CGTabardModelFrame::Create, false); + FrameXML_RegisterFactory("QuestPOIFrame", &CGQuestPOIFrame::Create, false); } diff --git a/src/ui/game/CGMinimapFrame.cpp b/src/ui/game/CGMinimapFrame.cpp new file mode 100644 index 0000000..40494d3 --- /dev/null +++ b/src/ui/game/CGMinimapFrame.cpp @@ -0,0 +1,37 @@ +#include "ui/game/CGMinimapFrame.hpp" +#include "ui/game/CGMinimapFrameScript.hpp" + +int32_t CGMinimapFrame::s_metatable; +int32_t CGMinimapFrame::s_objectType; + +CSimpleFrame* CGMinimapFrame::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGMinimapFrame)(parent); +} + +void CGMinimapFrame::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGMinimapFrame::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGMinimapFrame::RegisterScriptMethods); +} + +int32_t CGMinimapFrame::GetObjectType() { + if (!CGMinimapFrame::s_objectType) { + CGMinimapFrame::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGMinimapFrame::s_objectType; +} + +void CGMinimapFrame::RegisterScriptMethods(lua_State* L) { + CSimpleFrame::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGMinimapFrameMethods, NUM_CG_MINIMAP_FRAME_SCRIPT_METHODS); +} + +CGMinimapFrame::CGMinimapFrame(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO +} + +int32_t CGMinimapFrame::GetScriptMetaTable() { + return CGMinimapFrame::s_metatable; +} diff --git a/src/ui/game/CGMinimapFrame.hpp b/src/ui/game/CGMinimapFrame.hpp new file mode 100644 index 0000000..d83d199 --- /dev/null +++ b/src/ui/game/CGMinimapFrame.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_MINIMAP_FRAME_HPP +#define UI_GAME_C_G_MINIMAP_FRAME_HPP + +#include "ui/simple/CSimpleFrame.hpp" + +class CGMinimapFrame : public CSimpleFrame { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGMinimapFrame(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGMinimapFrameScript.cpp b/src/ui/game/CGMinimapFrameScript.cpp new file mode 100644 index 0000000..dc914b0 --- /dev/null +++ b/src/ui/game/CGMinimapFrameScript.cpp @@ -0,0 +1,85 @@ +#include "ui/game/CGMinimapFrameScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CGMinimapFrame_SetMaskTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetIconTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetBlipTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetClassBlipTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetPOIArrowTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetStaticPOIArrowTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetCorpsePOIArrowTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetPlayerTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetPlayerTextureHeight(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetPlayerTextureWidth(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_GetZoomLevels(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_GetZoom(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_SetZoom(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_PingLocation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGMinimapFrame_GetPingPosition(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGMinimapFrameMethods[] = { + { "SetMaskTexture", &CGMinimapFrame_SetMaskTexture }, + { "SetIconTexture", &CGMinimapFrame_SetIconTexture }, + { "SetBlipTexture", &CGMinimapFrame_SetBlipTexture }, + { "SetClassBlipTexture", &CGMinimapFrame_SetClassBlipTexture }, + { "SetPOIArrowTexture", &CGMinimapFrame_SetPOIArrowTexture }, + { "SetStaticPOIArrowTexture", &CGMinimapFrame_SetStaticPOIArrowTexture }, + { "SetCorpsePOIArrowTexture", &CGMinimapFrame_SetCorpsePOIArrowTexture }, + { "SetPlayerTexture", &CGMinimapFrame_SetPlayerTexture }, + { "SetPlayerTextureHeight", &CGMinimapFrame_SetPlayerTextureHeight }, + { "SetPlayerTextureWidth", &CGMinimapFrame_SetPlayerTextureWidth }, + { "GetZoomLevels", &CGMinimapFrame_GetZoomLevels }, + { "GetZoom", &CGMinimapFrame_GetZoom }, + { "SetZoom", &CGMinimapFrame_SetZoom }, + { "PingLocation", &CGMinimapFrame_PingLocation }, + { "GetPingPosition", &CGMinimapFrame_GetPingPosition }, +}; diff --git a/src/ui/game/CGMinimapFrameScript.hpp b/src/ui/game/CGMinimapFrameScript.hpp new file mode 100644 index 0000000..2095602 --- /dev/null +++ b/src/ui/game/CGMinimapFrameScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_MINIMAP_FRAME_SCRIPT_HPP +#define UI_GAME_C_G_MINIMAP_FRAME_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_MINIMAP_FRAME_SCRIPT_METHODS 15 + +extern FrameScript_Method CGMinimapFrameMethods[NUM_CG_MINIMAP_FRAME_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/game/CGQuestPOIFrame.cpp b/src/ui/game/CGQuestPOIFrame.cpp new file mode 100644 index 0000000..577692d --- /dev/null +++ b/src/ui/game/CGQuestPOIFrame.cpp @@ -0,0 +1,38 @@ +#include "ui/game/CGQuestPOIFrame.hpp" +#include "ui/game/CGQuestPOIFrameScript.hpp" + +int32_t CGQuestPOIFrame::s_metatable; +int32_t CGQuestPOIFrame::s_objectType; + +CSimpleFrame* CGQuestPOIFrame::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGQuestPOIFrame)(parent); +} + +void CGQuestPOIFrame::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGQuestPOIFrame::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGQuestPOIFrame::RegisterScriptMethods); +} + +int32_t CGQuestPOIFrame::GetObjectType() { + if (!CGQuestPOIFrame::s_objectType) { + CGQuestPOIFrame::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGQuestPOIFrame::s_objectType; +} + +void CGQuestPOIFrame::RegisterScriptMethods(lua_State* L) { + CSimpleFrame::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGQuestPOIFrameMethods, NUM_CG_QUEST_POI_FRAME_SCRIPT_METHODS); +} + +CGQuestPOIFrame::CGQuestPOIFrame(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO +} + +int32_t CGQuestPOIFrame::GetScriptMetaTable() { + return CGQuestPOIFrame::s_metatable; +} + diff --git a/src/ui/game/CGQuestPOIFrame.hpp b/src/ui/game/CGQuestPOIFrame.hpp new file mode 100644 index 0000000..ceb3be9 --- /dev/null +++ b/src/ui/game/CGQuestPOIFrame.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_QUEST_POI_FRAME_HPP +#define UI_GAME_C_G_QUEST_POI_FRAME_HPP + +#include "ui/simple/CSimpleFrame.hpp" + +class CGQuestPOIFrame : public CSimpleFrame { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGQuestPOIFrame(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGQuestPOIFrameScript.cpp b/src/ui/game/CGQuestPOIFrameScript.cpp new file mode 100644 index 0000000..8ab1b01 --- /dev/null +++ b/src/ui/game/CGQuestPOIFrameScript.cpp @@ -0,0 +1,80 @@ +#include "ui/game/CGQuestPOIFrameScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CGQuestPOIFrame_SetFillTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetFillAlpha(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetBorderTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetBorderAlpha(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetBorderScalar(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_DrawQuestBlob(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_EnableSmoothing(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_EnableMerging(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetMergeThreshold(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_SetNumSplinePoints(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_UpdateQuestPOI(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_UpdateMouseOverTooltip(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_GetTooltipIndex(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGQuestPOIFrame_GetNumTooltips(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGQuestPOIFrameMethods[] = { + { "SetFillTexture", &CGQuestPOIFrame_SetFillTexture }, + { "SetFillAlpha", &CGQuestPOIFrame_SetFillAlpha }, + { "SetBorderTexture", &CGQuestPOIFrame_SetBorderTexture }, + { "SetBorderAlpha", &CGQuestPOIFrame_SetBorderAlpha }, + { "SetBorderScalar", &CGQuestPOIFrame_SetBorderScalar }, + { "DrawQuestBlob", &CGQuestPOIFrame_DrawQuestBlob }, + { "EnableSmoothing", &CGQuestPOIFrame_EnableSmoothing }, + { "EnableMerging", &CGQuestPOIFrame_EnableMerging }, + { "SetMergeThreshold", &CGQuestPOIFrame_SetMergeThreshold }, + { "SetNumSplinePoints", &CGQuestPOIFrame_SetNumSplinePoints }, + { "UpdateQuestPOI", &CGQuestPOIFrame_UpdateQuestPOI }, + { "UpdateMouseOverTooltip", &CGQuestPOIFrame_UpdateMouseOverTooltip }, + { "GetTooltipIndex", &CGQuestPOIFrame_GetTooltipIndex }, + { "GetNumTooltips", &CGQuestPOIFrame_GetNumTooltips }, +}; diff --git a/src/ui/game/CGQuestPOIFrameScript.hpp b/src/ui/game/CGQuestPOIFrameScript.hpp new file mode 100644 index 0000000..0e105f7 --- /dev/null +++ b/src/ui/game/CGQuestPOIFrameScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_QUEST_POI_FRAME_SCRIPT_HPP +#define UI_GAME_C_G_QUEST_POI_FRAME_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_QUEST_POI_FRAME_SCRIPT_METHODS 14 + +extern FrameScript_Method CGQuestPOIFrameMethods[NUM_CG_QUEST_POI_FRAME_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/game/CGTabardModelFrame.cpp b/src/ui/game/CGTabardModelFrame.cpp new file mode 100644 index 0000000..29f3600 --- /dev/null +++ b/src/ui/game/CGTabardModelFrame.cpp @@ -0,0 +1,37 @@ +#include "ui/game/CGTabardModelFrame.hpp" +#include "ui/game/CGTabardModelFrameScript.hpp" + +int32_t CGTabardModelFrame::s_metatable; +int32_t CGTabardModelFrame::s_objectType; + +CSimpleFrame* CGTabardModelFrame::Create(CSimpleFrame* parent) { + // TODO use CDataAllocator + + return STORM_NEW(CGTabardModelFrame)(parent); +} + +void CGTabardModelFrame::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CGTabardModelFrame::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CGTabardModelFrame::RegisterScriptMethods); +} + +int32_t CGTabardModelFrame::GetObjectType() { + if (!CGTabardModelFrame::s_objectType) { + CGTabardModelFrame::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CGTabardModelFrame::s_objectType; +} + +void CGTabardModelFrame::RegisterScriptMethods(lua_State* L) { + CGCharacterModelBase::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, CGTabardModelFrameMethods, NUM_CG_TABARD_MODEL_FRAME_SCRIPT_METHODS); +} + +CGTabardModelFrame::CGTabardModelFrame(CSimpleFrame* parent) : CGCharacterModelBase(parent) { + // TODO +} + +int32_t CGTabardModelFrame::GetScriptMetaTable() { + return CGTabardModelFrame::s_metatable; +} diff --git a/src/ui/game/CGTabardModelFrame.hpp b/src/ui/game/CGTabardModelFrame.hpp new file mode 100644 index 0000000..b6e3d72 --- /dev/null +++ b/src/ui/game/CGTabardModelFrame.hpp @@ -0,0 +1,28 @@ +#ifndef UI_GAME_C_G_TABARD_MODEL_FRAME_HPP +#define UI_GAME_C_G_TABARD_MODEL_FRAME_HPP + +#include "ui/game/CGCharacterModelBase.hpp" + +class CGTabardModelFrame : public CGCharacterModelBase { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static CSimpleFrame* Create(CSimpleFrame* parent); + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CGTabardModelFrame(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/game/CGTabardModelFrameScript.cpp b/src/ui/game/CGTabardModelFrameScript.cpp new file mode 100644 index 0000000..405d727 --- /dev/null +++ b/src/ui/game/CGTabardModelFrameScript.cpp @@ -0,0 +1,60 @@ +#include "ui/game/CGTabardModelFrameScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CGTabardModelFrame_InitializeTabardColors(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_Save(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_CycleVariation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetUpperBackgroundFileName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetLowerBackgroundFileName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetUpperEmblemFileName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetLowerEmblemFileName(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetUpperEmblemTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_GetLowerEmblemTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CGTabardModelFrame_CanSaveTabardNow(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method CGTabardModelFrameMethods[] = { + { "InitializeTabardColors", &CGTabardModelFrame_InitializeTabardColors }, + { "Save", &CGTabardModelFrame_Save }, + { "CycleVariation", &CGTabardModelFrame_CycleVariation }, + { "GetUpperBackgroundFileName", &CGTabardModelFrame_GetUpperBackgroundFileName }, + { "GetLowerBackgroundFileName", &CGTabardModelFrame_GetLowerBackgroundFileName }, + { "GetUpperEmblemFileName", &CGTabardModelFrame_GetUpperEmblemFileName }, + { "GetLowerEmblemFileName", &CGTabardModelFrame_GetLowerEmblemFileName }, + { "GetUpperEmblemTexture", &CGTabardModelFrame_GetUpperEmblemTexture }, + { "GetLowerEmblemTexture", &CGTabardModelFrame_GetLowerEmblemTexture }, + { "CanSaveTabardNow", &CGTabardModelFrame_CanSaveTabardNow }, +}; diff --git a/src/ui/game/CGTabardModelFrameScript.hpp b/src/ui/game/CGTabardModelFrameScript.hpp new file mode 100644 index 0000000..4d68cae --- /dev/null +++ b/src/ui/game/CGTabardModelFrameScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_TABARD_MODEL_FRAME_SCRIPT_HPP +#define UI_GAME_C_G_TABARD_MODEL_FRAME_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_CG_TABARD_MODEL_FRAME_SCRIPT_METHODS 10 + +extern FrameScript_Method CGTabardModelFrameMethods[NUM_CG_TABARD_MODEL_FRAME_SCRIPT_METHODS]; + +#endif From df177a40b062e219bfbc8c402c5ea0c08422b00a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 22:16:25 -0600 Subject: [PATCH 050/114] chore(ui): use anonymous namespace consistently for script bindings --- src/ui/game/GMTicketInfoScript.cpp | 4 ++++ src/ui/game/GameScript.cpp | 1 + src/ui/game/ScriptEvents.cpp | 4 ++++ 3 files changed, 9 insertions(+) diff --git a/src/ui/game/GMTicketInfoScript.cpp b/src/ui/game/GMTicketInfoScript.cpp index 302a150..0264338 100644 --- a/src/ui/game/GMTicketInfoScript.cpp +++ b/src/ui/game/GMTicketInfoScript.cpp @@ -2,6 +2,8 @@ #include "ui/FrameScript.hpp" #include "util/Unimplemented.hpp" +namespace { + int32_t Script_GetGMTicket(lua_State* L) { WHOA_UNIMPLEMENTED(0); } @@ -62,6 +64,8 @@ int32_t Script_RegisterStaticConstants(lua_State* L) { WHOA_UNIMPLEMENTED(0); } +} + static FrameScript_Method s_ScriptFunctions[] = { { "GetGMTicket", &Script_GetGMTicket }, { "NewGMTicket", &Script_NewGMTicket }, diff --git a/src/ui/game/GameScript.cpp b/src/ui/game/GameScript.cpp index 236b5b9..0652fba 100644 --- a/src/ui/game/GameScript.cpp +++ b/src/ui/game/GameScript.cpp @@ -8,6 +8,7 @@ #include "util/Unimplemented.hpp" namespace { + int32_t Script_FrameXML_Debug(lua_State* L) { WHOA_UNIMPLEMENTED(0); } diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index 258413b..0367bee 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -3,6 +3,8 @@ #include "ui/ScriptFunctionsSystem.hpp" #include "util/Unimplemented.hpp" +namespace { + int32_t Script_UnitExists(lua_State* L) { WHOA_UNIMPLEMENTED(0); } @@ -679,6 +681,8 @@ int32_t Script_FillLocalizedClassList(lua_State* L) { WHOA_UNIMPLEMENTED(0); } +} + static FrameScript_Method s_UnitFunctions[] = { { "UnitExists", &Script_UnitExists }, { "UnitIsVisible", &Script_UnitIsVisible }, From 1cddac296c82c8d40020cd86ed5df6835b4fa1e5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 22:19:08 -0600 Subject: [PATCH 051/114] chore(ui): use boolean for unique flag in FrameXML_RegisterFactory calls --- src/ui/FrameXML.cpp | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ui/FrameXML.cpp b/src/ui/FrameXML.cpp index 2f99571..720702e 100644 --- a/src/ui/FrameXML.cpp +++ b/src/ui/FrameXML.cpp @@ -541,19 +541,19 @@ int32_t FrameXML_RegisterFactory(const char* type, CSimpleFrame* (*factory)(CSim } void FrameXML_RegisterDefault() { - FrameXML_RegisterFactory("Button", &Create_SimpleButton, 0); - FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, 0); - FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, 0); - FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, 0); - FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, 0); - FrameXML_RegisterFactory("Model", &Create_SimpleModel, 0); - FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, 0); - FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, 0); - FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, 0); - FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, 0); - FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, 0); - FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, 0); - FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, 0); + FrameXML_RegisterFactory("Button", &Create_SimpleButton, false); + FrameXML_RegisterFactory("CheckButton", &Create_SimpleCheckButton, false); + FrameXML_RegisterFactory("EditBox", &Create_SimpleEditBox, false); + FrameXML_RegisterFactory("Frame", &Create_SimpleFrame, false); + FrameXML_RegisterFactory("MessageFrame", &Create_SimpleMessageFrame, false); + FrameXML_RegisterFactory("Model", &Create_SimpleModel, false); + FrameXML_RegisterFactory("ScrollFrame", &Create_SimpleScrollFrame, false); + FrameXML_RegisterFactory("ScrollingMessageFrame", &Create_SimpleScrollingMessageFrame, false); + FrameXML_RegisterFactory("Slider", &Create_SimpleSlider, false); + FrameXML_RegisterFactory("SimpleHTML", &Create_SimpleHTML, false); + FrameXML_RegisterFactory("StatusBar", &Create_SimpleStatusBar, false); + FrameXML_RegisterFactory("ColorSelect", &Create_SimpleColorSelect, false); + FrameXML_RegisterFactory("MovieFrame", &Create_SimpleMovieFrame, false); } void FrameXML_ReleaseHashNode(const char* name) { From 91a4afd976e41a8f707db5fdc7f0f7604095a9b1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 29 Jan 2026 22:41:29 -0600 Subject: [PATCH 052/114] feat(ui): add stubbed implementation of CSimpleStatusBar --- src/ui/FrameXML.cpp | 5 +- src/ui/simple/CSimpleStatusBar.cpp | 31 +++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 27 +++++++++ src/ui/simple/CSimpleStatusBarScript.cpp | 70 ++++++++++++++++++++++++ src/ui/simple/CSimpleStatusBarScript.hpp | 10 ++++ src/ui/simple/ScriptMethods.cpp | 3 +- 6 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 src/ui/simple/CSimpleStatusBar.cpp create mode 100644 src/ui/simple/CSimpleStatusBar.hpp create mode 100644 src/ui/simple/CSimpleStatusBarScript.cpp create mode 100644 src/ui/simple/CSimpleStatusBarScript.hpp diff --git a/src/ui/FrameXML.cpp b/src/ui/FrameXML.cpp index 720702e..6c342ca 100644 --- a/src/ui/FrameXML.cpp +++ b/src/ui/FrameXML.cpp @@ -8,6 +8,7 @@ #include "ui/simple/CSimpleModel.hpp" #include "ui/simple/CSimpleScrollFrame.hpp" #include "ui/simple/CSimpleSlider.hpp" +#include "ui/simple/CSimpleStatusBar.hpp" #include "util/CStatus.hpp" #include "util/SFile.hpp" #include @@ -96,9 +97,9 @@ CSimpleFrame* Create_SimpleHTML(CSimpleFrame* parent) { } CSimpleFrame* Create_SimpleStatusBar(CSimpleFrame* parent) { - // TODO + // TODO CDataAllocator - return nullptr; + return STORM_NEW(CSimpleStatusBar(parent)); } CSimpleFrame* Create_SimpleColorSelect(CSimpleFrame* parent) { diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp new file mode 100644 index 0000000..471c842 --- /dev/null +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -0,0 +1,31 @@ +#include "ui/simple/CSimpleStatusBar.hpp" +#include "ui/simple/CSimpleStatusBarScript.hpp" + +int32_t CSimpleStatusBar::s_metatable; +int32_t CSimpleStatusBar::s_objectType; + +void CSimpleStatusBar::CreateScriptMetaTable() { + auto L = FrameScript_GetContext(); + CSimpleStatusBar::s_metatable = FrameScript_Object::CreateScriptMetaTable(L, &CSimpleStatusBar::RegisterScriptMethods); +} + +int32_t CSimpleStatusBar::GetObjectType() { + if (!CSimpleStatusBar::s_objectType) { + CSimpleStatusBar::s_objectType = ++FrameScript_Object::s_objectTypes; + } + + return CSimpleStatusBar::s_objectType; +} + +void CSimpleStatusBar::RegisterScriptMethods(lua_State* L) { + CSimpleFrame::RegisterScriptMethods(L); + FrameScript_Object::FillScriptMethodTable(L, SimpleStatusBarMethods, NUM_SIMPLE_STATUS_BAR_SCRIPT_METHODS); +} + +CSimpleStatusBar::CSimpleStatusBar(CSimpleFrame* parent) : CSimpleFrame(parent) { + // TODO +} + +int32_t CSimpleStatusBar::GetScriptMetaTable() { + return CSimpleStatusBar::s_metatable; +} diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp new file mode 100644 index 0000000..812439e --- /dev/null +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -0,0 +1,27 @@ +#ifndef UI_SIMPLE_C_SIMPLE_STATUS_BAR_HPP +#define UI_SIMPLE_C_SIMPLE_STATUS_BAR_HPP + +#include "ui/simple/CSimpleFrame.hpp" + +class CSimpleStatusBar : public CSimpleFrame { + public: + // Static variables + static int32_t s_metatable; + static int32_t s_objectType; + + // Static functions + static void CreateScriptMetaTable(); + static int32_t GetObjectType(); + static void RegisterScriptMethods(lua_State* L); + + // Member variables + // TODO + + // Virtual member functions + virtual int32_t GetScriptMetaTable(); + + // Member functions + CSimpleStatusBar(CSimpleFrame* parent); +}; + +#endif diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp new file mode 100644 index 0000000..88dcc40 --- /dev/null +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -0,0 +1,70 @@ +#include "ui/simple/CSimpleStatusBarScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t CSimpleStatusBar_GetOrientation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetOrientation(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_GetMinMaxValues(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetMinMaxValues(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_GetValue(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetValue(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_GetStatusBarTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetStatusBarTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_GetStatusBarColor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetStatusBarColor(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_GetRotatesTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t CSimpleStatusBar_SetRotatesTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +FrameScript_Method SimpleStatusBarMethods[] = { + { "GetOrientation", &CSimpleStatusBar_GetOrientation }, + { "SetOrientation", &CSimpleStatusBar_SetOrientation }, + { "GetMinMaxValues", &CSimpleStatusBar_GetMinMaxValues }, + { "SetMinMaxValues", &CSimpleStatusBar_SetMinMaxValues }, + { "GetValue", &CSimpleStatusBar_GetValue }, + { "SetValue", &CSimpleStatusBar_SetValue }, + { "GetStatusBarTexture", &CSimpleStatusBar_GetStatusBarTexture }, + { "SetStatusBarTexture", &CSimpleStatusBar_SetStatusBarTexture }, + { "GetStatusBarColor", &CSimpleStatusBar_GetStatusBarColor }, + { "SetStatusBarColor", &CSimpleStatusBar_SetStatusBarColor }, + { "GetRotatesTexture", &CSimpleStatusBar_GetRotatesTexture }, + { "SetRotatesTexture", &CSimpleStatusBar_SetRotatesTexture }, +}; diff --git a/src/ui/simple/CSimpleStatusBarScript.hpp b/src/ui/simple/CSimpleStatusBarScript.hpp new file mode 100644 index 0000000..928dfa5 --- /dev/null +++ b/src/ui/simple/CSimpleStatusBarScript.hpp @@ -0,0 +1,10 @@ +#ifndef UI_SIMPLE_C_SIMPLE_STATUS_BAR_SCRIPT_HPP +#define UI_SIMPLE_C_SIMPLE_STATUS_BAR_SCRIPT_HPP + +#include "ui/Types.hpp" + +#define NUM_SIMPLE_STATUS_BAR_SCRIPT_METHODS 12 + +extern FrameScript_Method SimpleStatusBarMethods[NUM_SIMPLE_STATUS_BAR_SCRIPT_METHODS]; + +#endif diff --git a/src/ui/simple/ScriptMethods.cpp b/src/ui/simple/ScriptMethods.cpp index c27b5d7..fe10793 100644 --- a/src/ui/simple/ScriptMethods.cpp +++ b/src/ui/simple/ScriptMethods.cpp @@ -12,6 +12,7 @@ #include "ui/simple/CSimpleModelFFX.hpp" #include "ui/simple/CSimpleScrollFrame.hpp" #include "ui/simple/CSimpleSlider.hpp" +#include "ui/simple/CSimpleStatusBar.hpp" #include "ui/simple/CSimpleTexture.hpp" #include "util/CStatus.hpp" #include "util/Lua.hpp" @@ -190,9 +191,9 @@ void RegisterSimpleFrameScriptMethods() { CSimpleModelFFX::CreateScriptMetaTable(); CSimpleScrollFrame::CreateScriptMetaTable(); CSimpleSlider::CreateScriptMetaTable(); + CSimpleStatusBar::CreateScriptMetaTable(); // TODO - // CSimpleStatusBar::CreateScriptMetaTable(); // CSimpleColorSelect::CreateScriptMetaTable(); // CSimpleMovieFrame::CreateScriptMetaTable(); } From 85b7537faa76889d8fde5a9f96c9525bab6220bd Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Jan 2026 19:39:49 -0600 Subject: [PATCH 053/114] feat(ui): add TOOLTIP_ANCHORPOINT --- src/ui/Types.hpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/ui/Types.hpp b/src/ui/Types.hpp index 23cf83e..dbfccea 100644 --- a/src/ui/Types.hpp +++ b/src/ui/Types.hpp @@ -98,6 +98,21 @@ enum TextureImageMode { ImageMode_Desaturate = 1 }; +enum TOOLTIP_ANCHORPOINT { + TOOLTIP_ANCHOR_LEFT = 0, + TOOLTIP_ANCHOR_RIGHT = 1, + TOOLTIP_ANCHOR_BOTTOMLEFT = 2, + TOOLTIP_ANCHOR_BOTTOM = 3, + TOOLTIP_ANCHOR_BOTTOMRIGHT = 4, + TOOLTIP_ANCHOR_TOPLEFT = 5, + TOOLTIP_ANCHOR_TOP = 6, + TOOLTIP_ANCHOR_TOPRIGHT = 7, + TOOLTIP_ANCHOR_CURSOR = 8, + TOOLTIP_ANCHOR_NONE = 9, + TOOLTIP_ANCHOR_PRESERVE = 10, + TOOLTIP_ANCHOR_CURSOR_RIGHT = 11, +}; + struct FRAMEPRIORITY { CSimpleFrame* frame; uint32_t priority; From bdef61479d9f4688c72bbe883823a90c1614745e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Jan 2026 19:53:03 -0600 Subject: [PATCH 054/114] feat(ui): implement CGTooltip_IsOwned --- src/ui/game/CGTooltip.hpp | 4 ++++ src/ui/game/CGTooltipScript.cpp | 32 +++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp index f6a5961..5914f0e 100644 --- a/src/ui/game/CGTooltip.hpp +++ b/src/ui/game/CGTooltip.hpp @@ -16,6 +16,10 @@ class CGTooltip : public CSimpleFrame { static void RegisterScriptMethods(lua_State* L); // Member variables + CSimpleFrame* m_owner = nullptr; + TOOLTIP_ANCHORPOINT m_anchorPoint; + // TODO + C2Vector m_offset; // TODO // Virtual member functions diff --git a/src/ui/game/CGTooltipScript.cpp b/src/ui/game/CGTooltipScript.cpp index 91b296d..cd4c1bd 100644 --- a/src/ui/game/CGTooltipScript.cpp +++ b/src/ui/game/CGTooltipScript.cpp @@ -1,5 +1,7 @@ #include "ui/game/CGTooltipScript.hpp" +#include "ui/game/CGTooltip.hpp" #include "ui/FrameScript.hpp" +#include "util/Lua.hpp" #include "util/Unimplemented.hpp" namespace { @@ -25,7 +27,35 @@ int32_t CGTooltip_GetPadding(lua_State* L) { } int32_t CGTooltip_IsOwned(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CGTooltip::GetObjectType(); + auto tooltip = static_cast(FrameScript_GetObjectThis(L, type)); + + if (lua_type(L, 2) != LUA_TTABLE) { + luaL_error(L, "Usage: %s:IsOwned(frame)", tooltip->GetDisplayName()); + return 0; + } + + lua_rawgeti(L, 2, 0); + auto frame = static_cast(lua_touserdata(L, -1)); + lua_settop(L, -2); + + if (!frame) { + luaL_error(L, "%s:IsOwned(): Couldn't find 'this' in frame object", tooltip->GetDisplayName()); + return 0; + } + + if (!frame->IsA(CSimpleFrame::GetObjectType())) { + luaL_error(L, "%s:IsOwned(): Wrong object type, expected frame", tooltip->GetDisplayName()); + return 0; + } + + if (tooltip->m_owner == frame) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t CGTooltip_GetOwner(lua_State* L) { From 3d7d000190460936d10e548cd2ffc4ea634a4256 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Jan 2026 20:45:05 -0600 Subject: [PATCH 055/114] feat(ui): implement Script_RequestBattlefieldPositions --- src/ui/game/BattlefieldInfoScript.cpp | 5 ++++- src/ui/game/CGBattlefieldInfo.cpp | 5 +++++ src/ui/game/CGBattlefieldInfo.hpp | 10 ++++++++++ 3 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 src/ui/game/CGBattlefieldInfo.cpp create mode 100644 src/ui/game/CGBattlefieldInfo.hpp diff --git a/src/ui/game/BattlefieldInfoScript.cpp b/src/ui/game/BattlefieldInfoScript.cpp index 11c22c8..5c0929a 100644 --- a/src/ui/game/BattlefieldInfoScript.cpp +++ b/src/ui/game/BattlefieldInfoScript.cpp @@ -1,4 +1,5 @@ #include "ui/game/BattlefieldInfoScript.hpp" +#include "ui/game/CGBattlefieldInfo.hpp" #include "ui/FrameScript.hpp" #include "util/Unimplemented.hpp" @@ -105,7 +106,9 @@ int32_t Script_GetBattlefieldStatData(lua_State* L) { } int32_t Script_RequestBattlefieldPositions(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + CGBattlefieldInfo::RequestPlayerPositions(); + + return 0; } int32_t Script_GetNumBattlefieldPositions(lua_State* L) { diff --git a/src/ui/game/CGBattlefieldInfo.cpp b/src/ui/game/CGBattlefieldInfo.cpp new file mode 100644 index 0000000..7f9eef1 --- /dev/null +++ b/src/ui/game/CGBattlefieldInfo.cpp @@ -0,0 +1,5 @@ +#include "ui/game/CGBattlefieldInfo.hpp" + +void CGBattlefieldInfo::RequestPlayerPositions() { + // TODO +} diff --git a/src/ui/game/CGBattlefieldInfo.hpp b/src/ui/game/CGBattlefieldInfo.hpp new file mode 100644 index 0000000..ccf2bac --- /dev/null +++ b/src/ui/game/CGBattlefieldInfo.hpp @@ -0,0 +1,10 @@ +#ifndef UI_GAME_C_G_BATTLEFIELD_INFO_HPP +#define UI_GAME_C_G_BATTLEFIELD_INFO_HPP + +class CGBattlefieldInfo { + public: + // Static functions + static void RequestPlayerPositions(); +}; + +#endif From 2c181e436c5ad71215cc2cda3611086176a5a737 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Jan 2026 20:57:48 -0600 Subject: [PATCH 056/114] feat(ui): add CGTooltip::IsA --- src/ui/game/CGTooltip.cpp | 7 +++++++ src/ui/game/CGTooltip.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ui/game/CGTooltip.cpp b/src/ui/game/CGTooltip.cpp index 328dd4b..d45687c 100644 --- a/src/ui/game/CGTooltip.cpp +++ b/src/ui/game/CGTooltip.cpp @@ -35,3 +35,10 @@ CGTooltip::CGTooltip(CSimpleFrame* parent) : CSimpleFrame(parent) { int32_t CGTooltip::GetScriptMetaTable() { return CGTooltip::s_metatable; } + +bool CGTooltip::IsA(int32_t type) { + return type == CGTooltip::s_objectType + || type == CSimpleFrame::s_objectType + || type == CScriptRegion::s_objectType + || type == CScriptObject::s_objectType; +} diff --git a/src/ui/game/CGTooltip.hpp b/src/ui/game/CGTooltip.hpp index 5914f0e..1410350 100644 --- a/src/ui/game/CGTooltip.hpp +++ b/src/ui/game/CGTooltip.hpp @@ -23,6 +23,7 @@ class CGTooltip : public CSimpleFrame { // TODO // Virtual member functions + virtual bool IsA(int32_t type); virtual int32_t GetScriptMetaTable(); // Member functions From 22eb04e495693941750903b2681dbe8bfeb7d62d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Fri, 30 Jan 2026 21:41:01 -0600 Subject: [PATCH 057/114] feat(ui): implement CSimpleButton_GetFontString --- src/ui/simple/CSimpleButtonScript.cpp | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleButtonScript.cpp b/src/ui/simple/CSimpleButtonScript.cpp index e5bc4df..f820b9d 100644 --- a/src/ui/simple/CSimpleButtonScript.cpp +++ b/src/ui/simple/CSimpleButtonScript.cpp @@ -218,7 +218,22 @@ int32_t CSimpleButton_SetFontString(lua_State* L) { } int32_t CSimpleButton_GetFontString(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleButton::GetObjectType(); + auto button = static_cast(FrameScript_GetObjectThis(L, type)); + auto text = button->m_text; + + if (!text) { + lua_pushnil(L); + return 1; + } + + if (!text->lua_registered) { + text->RegisterScriptObject(nullptr); + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, text->lua_objectRef); + + return 1; } int32_t CSimpleButton_SetText(lua_State* L) { From 0cf12c9c9040f435f6a10c9bb4cb937a95eee6ad Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sat, 31 Jan 2026 23:47:29 -0600 Subject: [PATCH 058/114] feat(ui): add CGGameUI::GetLockedTarget --- src/ui/game/CGGameUI.cpp | 7 ++++++- src/ui/game/CGGameUI.hpp | 6 ++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 21bd423..0187f65 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -23,6 +23,7 @@ CScriptObject* CGGameUI::s_gameTooltip; CSimpleTop* CGGameUI::s_simpleTop; +WOWGUID CGGameUI::s_lockedTarget; void LoadScriptFunctions() { // TODO @@ -57,6 +58,10 @@ void LoadScriptFunctions() { // TODO } +WOWGUID& CGGameUI::GetLockedTarget() { + return CGGameUI::s_lockedTarget; +} + void CGGameUI::Initialize() { // TODO @@ -131,7 +136,7 @@ void CGGameUI::Initialize() { // TODO CGGameUI::s_gameTooltip = CScriptObject::GetScriptObjectByName("GameTooltip", CGTooltip::GetObjectType()); - // TODO STORM_ASSERT(CGGameUI::s_gameTooltip); + STORM_ASSERT(CGGameUI::s_gameTooltip); // TODO } diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp index 567ab2f..062d8b9 100644 --- a/src/ui/game/CGGameUI.hpp +++ b/src/ui/game/CGGameUI.hpp @@ -1,6 +1,8 @@ #ifndef UI_GAME_C_G_GAME_UI_HPP #define UI_GAME_C_G_GAME_UI_HPP +#include "util/guid/Types.hpp" + class CScriptObject; class CSimpleTop; @@ -11,9 +13,13 @@ class CGGameUI { static CSimpleTop* s_simpleTop; // Static functions + static WOWGUID& GetLockedTarget(); static void Initialize(); static void InitializeGame(); static void RegisterFrameFactories(); + + private: + static WOWGUID s_lockedTarget; }; #endif From e7abae11022cde6d13deae07b46417d318a71c9a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 13:03:52 -0600 Subject: [PATCH 059/114] feat(object): add CGObject::GetGUID --- src/object/client/CGObject.cpp | 4 ++++ src/object/client/CGObject.hpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/object/client/CGObject.cpp b/src/object/client/CGObject.cpp index d292eec..97bf379 100644 --- a/src/object/client/CGObject.cpp +++ b/src/object/client/CGObject.cpp @@ -23,3 +23,7 @@ uint32_t CGObject::TotalFields() { uint32_t CGObject::TotalFieldsSaved() { return CGObject::GetBaseOffsetSaved() + 3; } + +WOWGUID CGObject::GetGUID() const { + return this->m_obj->m_guid; +} diff --git a/src/object/client/CGObject.hpp b/src/object/client/CGObject.hpp index 91b868e..1d1bfd7 100644 --- a/src/object/client/CGObject.hpp +++ b/src/object/client/CGObject.hpp @@ -29,6 +29,9 @@ class CGObject { uint32_t* m_objSaved; uint32_t m_memHandle; OBJECT_TYPE_ID m_typeID; + + // Public member functions + WOWGUID GetGUID() const; }; #endif From 1891bdc5eaa19882dc07242459e84d7688c8add4 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 13:04:16 -0600 Subject: [PATCH 060/114] feat(object): add player class to object client header --- src/object/Client.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/object/Client.hpp b/src/object/Client.hpp index 24a5c2b..3675649 100644 --- a/src/object/Client.hpp +++ b/src/object/Client.hpp @@ -1,6 +1,7 @@ #ifndef OBJECT_CLIENT_HPP #define OBJECT_CLIENT_HPP +#include "client/CGPlayer_C.hpp" #include "client/ObjMgr.hpp" #include "object/Types.hpp" From f5171c0c6caff1a6656cce729c14723ac074b088 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 13:04:37 -0600 Subject: [PATCH 061/114] feat(ui): add CGGameUI::IsRaidMember --- src/ui/game/CGGameUI.cpp | 6 ++++++ src/ui/game/CGGameUI.hpp | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 0187f65..ea8a3fb 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -149,6 +149,12 @@ void CGGameUI::InitializeGame() { // TODO } +int32_t CGGameUI::IsRaidMember(const WOWGUID& guid) { + // TODO + + return false; +} + void CGGameUI::RegisterFrameFactories() { FrameXML_RegisterFactory("WorldFrame", &CGWorldFrame::Create, true); FrameXML_RegisterFactory("GameTooltip", &CGTooltip::Create, false); diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp index 062d8b9..2cf3c8b 100644 --- a/src/ui/game/CGGameUI.hpp +++ b/src/ui/game/CGGameUI.hpp @@ -16,6 +16,7 @@ class CGGameUI { static WOWGUID& GetLockedTarget(); static void Initialize(); static void InitializeGame(); + static int32_t IsRaidMember(const WOWGUID& guid); static void RegisterFrameFactories(); private: From bc3b469266df3c2f747098d758159eaa111b9c2d Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 13:05:32 -0600 Subject: [PATCH 062/114] feat(ui): add Script_GetGUIDFromToken --- src/ui/game/ScriptUtil.cpp | 157 +++++++++++++++++++++++++++++++++++++ src/ui/game/ScriptUtil.hpp | 8 ++ 2 files changed, 165 insertions(+) create mode 100644 src/ui/game/ScriptUtil.cpp create mode 100644 src/ui/game/ScriptUtil.hpp diff --git a/src/ui/game/ScriptUtil.cpp b/src/ui/game/ScriptUtil.cpp new file mode 100644 index 0000000..9ac1fed --- /dev/null +++ b/src/ui/game/ScriptUtil.cpp @@ -0,0 +1,157 @@ +#include "ui/game/ScriptUtil.hpp" +#include "object/Client.hpp" +#include "ui/game/CGGameUI.hpp" +#include + +bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTarget) { + auto activePlayer = static_cast(ClntObjMgrObjectPtr(ClntObjMgrGetActivePlayer(), TYPE_PLAYER, __FILE__, __LINE__)); + + // Null or empty token + if (token == nullptr || *token == '\0') { + if (defaultToTarget) { + guid = CGGameUI::GetLockedTarget(); + + return true; + } + + return false; + } + + guid = 0; + auto parseToken = token; + + // player - active player + if (!SStrCmpI(parseToken, "player", 6)) { + parseToken += 6; + + if (activePlayer) { + guid = activePlayer->GetGUID(); + } + } + + // vehicle - active player's vehicle + else if (!SStrCmpI(parseToken, "vehicle", 7)) { + parseToken += 7; + + // TODO + } + + // pet - active player's pet + else if (!SStrCmpI(parseToken, "pet", 3)) { + parseToken += 3; + + // TODO + } + + // target - current locked target + else if (!SStrCmpI(parseToken, "target", 6)) { + parseToken += 6; + + guid = CGGameUI::GetLockedTarget(); + } + + // partypet1-4 - party member's pet + else if (!SStrCmpI(parseToken, "partypet", 8)) { + parseToken += 8; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // party1-4 - party member + else if (!SStrCmpI(parseToken, "party", 5)) { + parseToken += 5; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // raidpet1-40 - raid member's pet + else if (!SStrCmpI(parseToken, "raidpet", 7)) { + parseToken += 7; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // raid1-40 - raid member + else if (!SStrCmpI(parseToken, "raid", 4)) { + parseToken += 4; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // boss1-5 - boss unit + else if (!SStrCmpI(parseToken, "boss", 4)) { + parseToken += 4; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // arenapet1-5 - arena opponent's pet + else if (!SStrCmpI(parseToken, "arenapet", 8)) { + parseToken += 8; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // arena1-5 - arena opponent + else if (!SStrCmpI(parseToken, "arena", 5)) { + parseToken += 5; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // commentator1-N - commentator arena member + else if (!SStrCmpI(parseToken, "commentator", 11)) { + parseToken += 11; + + auto index = SStrToUnsigned(parseToken); + // TODO + } + + // mouseover - object under cursor + else if (!SStrCmpI(parseToken, "mouseover", 9)) { + parseToken += 9; + + // TODO + } + + // focus - focus target + else if (!SStrCmpI(parseToken, "focus", 5)) { + parseToken += 5; + + // TODO + } + + // npc - NPC interaction target + else if (!SStrCmpI(parseToken, "npc")) { + parseToken += 3; + + // TODO + } + + // questnpc - quest giver NPC + else if (!SStrCmpI(parseToken, "questnpc")) { + parseToken += 8; + + // TODO + } + + // none + else if (!SStrCmpI(parseToken, "none")) { + parseToken += 4; + + guid = -1; + } + + // TODO ParseTrailingTokens + // TODO Script_GetGUIDFromString + // TODO guid -2 + + return false; +} diff --git a/src/ui/game/ScriptUtil.hpp b/src/ui/game/ScriptUtil.hpp new file mode 100644 index 0000000..9cdf7ea --- /dev/null +++ b/src/ui/game/ScriptUtil.hpp @@ -0,0 +1,8 @@ +#ifndef UI_GAME_SCRIPT_UTIL_HPP +#define UI_GAME_SCRIPT_UTIL_HPP + +#include "util/GUID.hpp" + +bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTarget); + +#endif From 184d3b041f73f21657c4077f4df3ed3253cb7222 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 13:05:52 -0600 Subject: [PATCH 063/114] feat(ui): implement Script_UnitIsPlayer --- src/ui/game/ScriptEvents.cpp | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index 0367bee..ca4b472 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -1,6 +1,11 @@ #include "ui/game/ScriptEvents.hpp" +#include "object/client/ObjMgr.hpp" #include "ui/FrameScript.hpp" #include "ui/ScriptFunctionsSystem.hpp" +#include "ui/game/CGGameUI.hpp" +#include "ui/game/ScriptUtil.hpp" +#include "util/GUID.hpp" +#include "util/Lua.hpp" #include "util/Unimplemented.hpp" namespace { @@ -18,7 +23,19 @@ int32_t Script_UnitIsUnit(lua_State* L) { } int32_t Script_UnitIsPlayer(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto token = lua_tostring(L, 1); + WOWGUID guid = 0; + Script_GetGUIDFromToken(token, guid, false); + + auto object = ClntObjMgrObjectPtr(guid, TYPE_PLAYER, __FILE__, __LINE__); + + if (object || CGGameUI::IsRaidMember(guid)) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t Script_UnitIsInMyGuild(lua_State* L) { From 99c00ade9be54019c783658f6631e55ad7453041 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 20:16:33 -0600 Subject: [PATCH 064/114] feat(ui): add CGGameUI::GetCurrentObjectTrack --- src/ui/game/CGGameUI.cpp | 7 ++++++- src/ui/game/CGGameUI.hpp | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index ea8a3fb..8a5f8bd 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -21,9 +21,10 @@ #include "util/CStatus.hpp" #include +WOWGUID CGGameUI::s_currentObjectTrack; CScriptObject* CGGameUI::s_gameTooltip; -CSimpleTop* CGGameUI::s_simpleTop; WOWGUID CGGameUI::s_lockedTarget; +CSimpleTop* CGGameUI::s_simpleTop; void LoadScriptFunctions() { // TODO @@ -58,6 +59,10 @@ void LoadScriptFunctions() { // TODO } +WOWGUID& CGGameUI::GetCurrentObjectTrack() { + return CGGameUI::s_currentObjectTrack; +} + WOWGUID& CGGameUI::GetLockedTarget() { return CGGameUI::s_lockedTarget; } diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp index 2cf3c8b..0044be8 100644 --- a/src/ui/game/CGGameUI.hpp +++ b/src/ui/game/CGGameUI.hpp @@ -13,6 +13,7 @@ class CGGameUI { static CSimpleTop* s_simpleTop; // Static functions + static WOWGUID& GetCurrentObjectTrack(); static WOWGUID& GetLockedTarget(); static void Initialize(); static void InitializeGame(); @@ -20,6 +21,7 @@ class CGGameUI { static void RegisterFrameFactories(); private: + static WOWGUID s_currentObjectTrack; static WOWGUID s_lockedTarget; }; From 43cb20cd0fae14ce0932253eaa63632f12de89d7 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 20:22:17 -0600 Subject: [PATCH 065/114] feat(ui): add CGGameUI::IsRaidMemberOrPet --- src/ui/game/CGGameUI.cpp | 6 ++++++ src/ui/game/CGGameUI.hpp | 1 + 2 files changed, 7 insertions(+) diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index 8a5f8bd..f0f40a9 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -160,6 +160,12 @@ int32_t CGGameUI::IsRaidMember(const WOWGUID& guid) { return false; } +int32_t CGGameUI::IsRaidMemberOrPet(const WOWGUID& guid) { + // TODO + + return false; +} + void CGGameUI::RegisterFrameFactories() { FrameXML_RegisterFactory("WorldFrame", &CGWorldFrame::Create, true); FrameXML_RegisterFactory("GameTooltip", &CGTooltip::Create, false); diff --git a/src/ui/game/CGGameUI.hpp b/src/ui/game/CGGameUI.hpp index 0044be8..2fc782b 100644 --- a/src/ui/game/CGGameUI.hpp +++ b/src/ui/game/CGGameUI.hpp @@ -18,6 +18,7 @@ class CGGameUI { static void Initialize(); static void InitializeGame(); static int32_t IsRaidMember(const WOWGUID& guid); + static int32_t IsRaidMemberOrPet(const WOWGUID& guid); static void RegisterFrameFactories(); private: From 6e1eb93ff9b65494ed09d30698c03a0bbbb1c967 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Sun, 1 Feb 2026 20:22:56 -0600 Subject: [PATCH 066/114] feat(ui): implement post-token-parsing logic in Script_GetGUIDFromToken --- src/ui/game/ScriptUtil.cpp | 42 ++++++++++++++++++++++++++++++++++---- src/ui/game/ScriptUtil.hpp | 2 ++ 2 files changed, 40 insertions(+), 4 deletions(-) diff --git a/src/ui/game/ScriptUtil.cpp b/src/ui/game/ScriptUtil.cpp index 9ac1fed..0f5a809 100644 --- a/src/ui/game/ScriptUtil.cpp +++ b/src/ui/game/ScriptUtil.cpp @@ -3,6 +3,20 @@ #include "ui/game/CGGameUI.hpp" #include +namespace { + +bool ParseTrailingTokens(const char* token, WOWGUID& guid, CGPlayer_C* player) { + // TODO + return true; +} + +} + +bool Script_GetGUIDFromString(const char*& token, WOWGUID& guid) { + // TODO + return true; +} + bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTarget) { auto activePlayer = static_cast(ClntObjMgrObjectPtr(ClntObjMgrGetActivePlayer(), TYPE_PLAYER, __FILE__, __LINE__)); @@ -118,7 +132,11 @@ bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTar else if (!SStrCmpI(parseToken, "mouseover", 9)) { parseToken += 9; - // TODO + auto trackedObjectGuid = CGGameUI::GetCurrentObjectTrack(); + + if (ClntObjMgrObjectPtr(trackedObjectGuid, TYPE_UNIT, __FILE__, __LINE__) || CGGameUI::IsRaidMemberOrPet(trackedObjectGuid)) { + guid = trackedObjectGuid; + } } // focus - focus target @@ -149,9 +167,25 @@ bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTar guid = -1; } - // TODO ParseTrailingTokens - // TODO Script_GetGUIDFromString - // TODO guid -2 + // Token string was fully parsed or GUID was determined and token string potentially includes + // trailing tokens + if ((*parseToken == '\0' || guid) && ParseTrailingTokens(parseToken, guid, activePlayer)) { + if (!guid) { + guid = -2; + } + return true; + } + + // Token string was either not parsed or only partially parsed and GUID was not determined + if (!guid && Script_GetGUIDFromString(token, guid) && ParseTrailingTokens(token, guid, activePlayer)) { + if (!guid) { + guid = -2; + } + + return true; + } + + // GUID was not successfully determined return false; } diff --git a/src/ui/game/ScriptUtil.hpp b/src/ui/game/ScriptUtil.hpp index 9cdf7ea..c06aa58 100644 --- a/src/ui/game/ScriptUtil.hpp +++ b/src/ui/game/ScriptUtil.hpp @@ -3,6 +3,8 @@ #include "util/GUID.hpp" +bool Script_GetGUIDFromString(const char*& token, WOWGUID& guid); + bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTarget); #endif From 4d0c48be5260eeb577a7af1d368792024fc57681 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 08:20:49 -0600 Subject: [PATCH 067/114] feat(object): add model member to CGObject_C --- src/object/client/CGObject_C.cpp | 4 ++++ src/object/client/CGObject_C.hpp | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/object/client/CGObject_C.cpp b/src/object/client/CGObject_C.cpp index f78ad1a..dea307c 100644 --- a/src/object/client/CGObject_C.cpp +++ b/src/object/client/CGObject_C.cpp @@ -5,6 +5,10 @@ CGObject_C::CGObject_C(uint32_t time, CClientObjCreate& objCreate) { // TODO + this->m_model = nullptr; + + // TODO + this->m_lockCount = 0; this->m_disabled = false; this->m_inReenable = false; diff --git a/src/object/client/CGObject_C.hpp b/src/object/client/CGObject_C.hpp index d6b9436..5904559 100644 --- a/src/object/client/CGObject_C.hpp +++ b/src/object/client/CGObject_C.hpp @@ -8,12 +8,16 @@ #include #include +class CM2Model; + class CGObject_C : public CGObject, public TSHashObject { public: // Public member variables TSLink m_link; uint32_t m_disableTimeMs; // TODO + CM2Model* m_model; + // TODO uint32_t m_lockCount : 16; uint32_t m_disabled : 1; uint32_t m_inReenable : 1; From 87ae3b512b19bd65cfb9f9835ad9be0019a15bdf Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 08:47:50 -0600 Subject: [PATCH 068/114] feat(object): clean up data struct visibility --- src/object/client/CGContainer.cpp | 4 ++++ src/object/client/CGContainer.hpp | 6 +++++- src/object/client/CGCorpse.cpp | 4 ++++ src/object/client/CGCorpse.hpp | 6 +++++- src/object/client/CGDynamicObject.cpp | 4 ++++ src/object/client/CGDynamicObject.hpp | 6 +++++- src/object/client/CGGameObject.cpp | 4 ++++ src/object/client/CGGameObject.hpp | 6 +++++- src/object/client/CGItem.cpp | 4 ++++ src/object/client/CGItem.hpp | 6 +++++- src/object/client/CGObject.cpp | 12 ++++++++++++ src/object/client/CGObject.hpp | 14 +++++++++++--- src/object/client/CGPlayer.cpp | 4 ++++ src/object/client/CGPlayer.hpp | 6 +++++- src/object/client/CGUnit.cpp | 4 ++++ src/object/client/CGUnit.hpp | 6 +++++- src/object/client/MessageHandlers.cpp | 8 ++++---- src/object/client/Mirror.cpp | 6 +++--- src/object/client/ObjMgr.cpp | 12 ++++++------ src/object/client/Util.cpp | 4 ++-- 20 files changed, 101 insertions(+), 25 deletions(-) diff --git a/src/object/client/CGContainer.cpp b/src/object/client/CGContainer.cpp index 0c9b943..b6080fa 100644 --- a/src/object/client/CGContainer.cpp +++ b/src/object/client/CGContainer.cpp @@ -24,3 +24,7 @@ uint32_t CGContainer::TotalFields() { uint32_t CGContainer::TotalFieldsSaved() { return CGContainer::GetBaseOffsetSaved() + 72; } + +CGContainerData* CGContainer::Container() const { + return this->m_cont; +} diff --git a/src/object/client/CGContainer.hpp b/src/object/client/CGContainer.hpp index 2134814..d0bd262 100644 --- a/src/object/client/CGContainer.hpp +++ b/src/object/client/CGContainer.hpp @@ -20,9 +20,13 @@ class CGContainer { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGContainerData* m_cont; uint32_t* m_contSaved; + + // Protected member functions + CGContainerData* Container() const; }; #endif diff --git a/src/object/client/CGCorpse.cpp b/src/object/client/CGCorpse.cpp index 3dd6ec2..2838f94 100644 --- a/src/object/client/CGCorpse.cpp +++ b/src/object/client/CGCorpse.cpp @@ -24,3 +24,7 @@ uint32_t CGCorpse::TotalFields() { uint32_t CGCorpse::TotalFieldsSaved() { return CGCorpse::GetBaseOffsetSaved() + 3; } + +CGCorpseData* CGCorpse::Corpse() const { + return this->m_corpse; +} diff --git a/src/object/client/CGCorpse.hpp b/src/object/client/CGCorpse.hpp index be7add3..93d19e7 100644 --- a/src/object/client/CGCorpse.hpp +++ b/src/object/client/CGCorpse.hpp @@ -17,9 +17,13 @@ class CGCorpse { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGCorpseData* m_corpse; uint32_t* m_corpseSaved; + + // Protected member functions + CGCorpseData* Corpse() const; }; #endif diff --git a/src/object/client/CGDynamicObject.cpp b/src/object/client/CGDynamicObject.cpp index f55ca10..bec80ac 100644 --- a/src/object/client/CGDynamicObject.cpp +++ b/src/object/client/CGDynamicObject.cpp @@ -24,3 +24,7 @@ uint32_t CGDynamicObject::TotalFields() { uint32_t CGDynamicObject::TotalFieldsSaved() { return CGDynamicObject::GetBaseOffsetSaved() + 0; } + +CGDynamicObjectData* CGDynamicObject::DynamicObject() const { + return this->m_dynamicObj; +} diff --git a/src/object/client/CGDynamicObject.hpp b/src/object/client/CGDynamicObject.hpp index 8f68718..1292973 100644 --- a/src/object/client/CGDynamicObject.hpp +++ b/src/object/client/CGDynamicObject.hpp @@ -17,9 +17,13 @@ class CGDynamicObject { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGDynamicObjectData* m_dynamicObj; uint32_t* m_dynamicObjSaved; + + // Protected member functions + CGDynamicObjectData* DynamicObject() const; }; #endif diff --git a/src/object/client/CGGameObject.cpp b/src/object/client/CGGameObject.cpp index 5a498f5..76b81c6 100644 --- a/src/object/client/CGGameObject.cpp +++ b/src/object/client/CGGameObject.cpp @@ -24,3 +24,7 @@ uint32_t CGGameObject::TotalFields() { uint32_t CGGameObject::TotalFieldsSaved() { return CGGameObject::GetBaseOffsetSaved() + 4; } + +CGGameObjectData* CGGameObject::GameObject() const { + return this->m_gameObj; +} diff --git a/src/object/client/CGGameObject.hpp b/src/object/client/CGGameObject.hpp index 5469f1f..1f19c12 100644 --- a/src/object/client/CGGameObject.hpp +++ b/src/object/client/CGGameObject.hpp @@ -17,9 +17,13 @@ class CGGameObject { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGGameObjectData* m_gameObj; uint32_t* m_gameObjSaved; + + // Protected member functions + CGGameObjectData* GameObject() const; }; #endif diff --git a/src/object/client/CGItem.cpp b/src/object/client/CGItem.cpp index 5c849cb..7a012c0 100644 --- a/src/object/client/CGItem.cpp +++ b/src/object/client/CGItem.cpp @@ -24,3 +24,7 @@ uint32_t CGItem::TotalFields() { uint32_t CGItem::TotalFieldsSaved() { return CGItem::GetBaseOffsetSaved() + 47; } + +CGItemData* CGItem::Item() const { + return this->m_item; +} diff --git a/src/object/client/CGItem.hpp b/src/object/client/CGItem.hpp index 2fda058..ec22654 100644 --- a/src/object/client/CGItem.hpp +++ b/src/object/client/CGItem.hpp @@ -38,9 +38,13 @@ class CGItem { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGItemData* m_item; uint32_t* m_itemSaved; + + // Protected member functions + CGItemData* Item() const; }; #endif diff --git a/src/object/client/CGObject.cpp b/src/object/client/CGObject.cpp index 97bf379..41236cf 100644 --- a/src/object/client/CGObject.cpp +++ b/src/object/client/CGObject.cpp @@ -27,3 +27,15 @@ uint32_t CGObject::TotalFieldsSaved() { WOWGUID CGObject::GetGUID() const { return this->m_obj->m_guid; } + +OBJECT_TYPE CGObject::GetType() const { + return this->m_obj->m_type; +} + +OBJECT_TYPE_ID CGObject::GetTypeID() const { + return this->m_typeID; +} + +CGObjectData* CGObject::Obj() const { + return this->m_obj; +} diff --git a/src/object/client/CGObject.hpp b/src/object/client/CGObject.hpp index 1d1bfd7..55f4514 100644 --- a/src/object/client/CGObject.hpp +++ b/src/object/client/CGObject.hpp @@ -25,13 +25,21 @@ class CGObject { // Public member variables uint32_t uint0; // TODO what is this? - CGObjectData* m_obj; - uint32_t* m_objSaved; uint32_t m_memHandle; - OBJECT_TYPE_ID m_typeID; // Public member functions WOWGUID GetGUID() const; + OBJECT_TYPE GetType() const; + OBJECT_TYPE_ID GetTypeID() const; + + protected: + // Protected member variables + CGObjectData* m_obj; + uint32_t* m_objSaved; + OBJECT_TYPE_ID m_typeID; + + // Protected member functions + CGObjectData* Obj() const; }; #endif diff --git a/src/object/client/CGPlayer.cpp b/src/object/client/CGPlayer.cpp index 5f30bcb..1e44711 100644 --- a/src/object/client/CGPlayer.cpp +++ b/src/object/client/CGPlayer.cpp @@ -40,3 +40,7 @@ uint32_t CGPlayer::TotalFieldsSaved() { uint32_t CGPlayer::TotalRemoteFieldsSaved() { return CGPlayer::GetBaseOffsetSaved() + 173; } + +CGPlayerData* CGPlayer::Player() const { + return this->m_player; +} diff --git a/src/object/client/CGPlayer.hpp b/src/object/client/CGPlayer.hpp index c20fd0c..707f39f 100644 --- a/src/object/client/CGPlayer.hpp +++ b/src/object/client/CGPlayer.hpp @@ -148,9 +148,13 @@ class CGPlayer { static uint32_t TotalFieldsSaved(); static uint32_t TotalRemoteFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGPlayerData* m_player; uint32_t* m_playerSaved; + + // Protected member functions + CGPlayerData* Player() const; }; #endif diff --git a/src/object/client/CGUnit.cpp b/src/object/client/CGUnit.cpp index 05b42e2..4f525c8 100644 --- a/src/object/client/CGUnit.cpp +++ b/src/object/client/CGUnit.cpp @@ -24,3 +24,7 @@ uint32_t CGUnit::TotalFields() { uint32_t CGUnit::TotalFieldsSaved() { return CGUnit::GetBaseOffsetSaved() + 123; } + +CGUnitData* CGUnit::Unit() const { + return this->m_unit; +} diff --git a/src/object/client/CGUnit.hpp b/src/object/client/CGUnit.hpp index 0577be0..3fb6ddb 100644 --- a/src/object/client/CGUnit.hpp +++ b/src/object/client/CGUnit.hpp @@ -82,9 +82,13 @@ class CGUnit { static uint32_t TotalFields(); static uint32_t TotalFieldsSaved(); - // Public member variables + protected: + // Protected member variables CGUnitData* m_unit; uint32_t* m_unitSaved; + + // Protected member functions + CGUnitData* Unit() const; }; #endif diff --git a/src/object/client/MessageHandlers.cpp b/src/object/client/MessageHandlers.cpp index 72124ae..86679e6 100644 --- a/src/object/client/MessageHandlers.cpp +++ b/src/object/client/MessageHandlers.cpp @@ -61,7 +61,7 @@ int32_t PostInitObject(CDataStore* msg, uint32_t time, bool a3) { return 0; } - if (object->m_inReenable && object->m_obj->m_type & TYPE_UNIT) { + if (object->m_inReenable && object->GetType() & TYPE_UNIT) { // TODO } @@ -139,7 +139,7 @@ void PostMovementUpdate(CDataStore* msg) { return; } - unit->PostMovementUpdate(move, unit->m_obj->m_guid == CGUnit_C::s_activeMover); + unit->PostMovementUpdate(move, unit->GetGUID() == CGUnit_C::s_activeMover); if (reenable) { unit->Reenable(); @@ -201,7 +201,7 @@ int32_t UpdateObject(CDataStore* msg) { auto object = GetUpdateObject(guid, &reenable); if (object) { - if (!FillInPartialObjectData(object, object->m_obj->m_guid, msg, false, false)) { + if (!FillInPartialObjectData(object, object->GetGUID(), msg, false, false)) { return 0; } @@ -329,7 +329,7 @@ int32_t CreateObject(CDataStore* msg, uint32_t time) { if (existingObject) { CClientObjCreate::Skip(msg); - if (!FillInPartialObjectData(existingObject, existingObject->m_obj->m_guid, msg, false, true)) { + if (!FillInPartialObjectData(existingObject, existingObject->GetGUID(), msg, false, true)) { return 0; } diff --git a/src/object/client/Mirror.cpp b/src/object/client/Mirror.cpp index 762cefa..75554a5 100644 --- a/src/object/client/Mirror.cpp +++ b/src/object/client/Mirror.cpp @@ -91,7 +91,7 @@ uint32_t GetNumDwordBlocks(OBJECT_TYPE type, WOWGUID guid) { * to indicate the end of the hierarchy. */ OBJECT_TYPE_ID IncTypeID(CGObject_C* object, OBJECT_TYPE_ID curTypeID) { - switch (object->m_obj->m_type) { + switch (object->GetType()) { // ID_OBJECT -> ID_ITEM -> ID_CONTAINER case HIER_TYPE_ITEM: case HIER_TYPE_CONTAINER: @@ -173,7 +173,7 @@ int32_t CallMirrorHandlers(CDataStore* msg, bool a2, WOWGUID guid) { OBJECT_TYPE_ID typeID = ID_OBJECT; uint32_t blockOffset = 0; - uint32_t numBlocks = GetNumDwordBlocks(object->m_obj->m_type, guid); + uint32_t numBlocks = GetNumDwordBlocks(object->GetType(), guid); for (int32_t block = 0; block < numBlocks; block++) { if (block >= s_objMirrorBlocks[typeID]) { @@ -203,7 +203,7 @@ int32_t FillInPartialObjectData(CGObject_C* object, WOWGUID guid, CDataStore* ms OBJECT_TYPE_ID typeID = ID_OBJECT; uint32_t blockOffset = 0; - uint32_t numBlocks = GetNumDwordBlocks(object->m_obj->m_type, guid); + uint32_t numBlocks = GetNumDwordBlocks(object->GetType(), guid); for (int32_t block = 0; block < numBlocks; block++) { if (block >= s_objMirrorBlocks[typeID]) { diff --git a/src/object/client/ObjMgr.cpp b/src/object/client/ObjMgr.cpp index bcdb488..c817841 100644 --- a/src/object/client/ObjMgr.cpp +++ b/src/object/client/ObjMgr.cpp @@ -93,9 +93,9 @@ CGObject_C* ClntObjMgrAllocObject(OBJECT_TYPE_ID typeID, WOWGUID guid) { void ClntObjMgrFreeObject(CGObject_C* object) { auto playerGUID = ClntObjMgrGetActivePlayer(); - auto isActivePlayer = object->m_obj->m_guid == playerGUID; + auto isActivePlayer = object->GetGUID() == playerGUID; - switch (object->m_obj->m_type) { + switch (object->GetType()) { case TYPE_OBJECT: case HIER_TYPE_ITEM: case HIER_TYPE_CONTAINER: @@ -117,7 +117,7 @@ void ClntObjMgrFreeObject(CGObject_C* object) { if (isActivePlayer) { STORM_FREE(object); } else { - ObjectFree(s_objHeapId[object->m_typeID], object->m_memHandle); + ObjectFree(s_objHeapId[object->GetTypeID()], object->m_memHandle); } } @@ -171,8 +171,8 @@ void ClntObjMgrInitializeStd(uint32_t mapID) { } void ClntObjMgrLinkInNewObject(CGObject_C* object) { - CHashKeyGUID key(object->m_obj->m_guid); - s_curMgr->m_objects.Insert(object, object->m_obj->m_guid, key); + CHashKeyGUID key(object->GetGUID()); + s_curMgr->m_objects.Insert(object, object->GetGUID(), key); } CGObject_C* ClntObjMgrObjectPtr(WOWGUID guid, OBJECT_TYPE type, const char* fileName, int32_t lineNumber) { @@ -186,7 +186,7 @@ CGObject_C* ClntObjMgrObjectPtr(WOWGUID guid, OBJECT_TYPE type, const char* file return nullptr; } - if (!(object->m_obj->m_type & type)) { + if (!(object->GetType() & type)) { return nullptr; } diff --git a/src/object/client/Util.cpp b/src/object/client/Util.cpp index 5ac8c52..1d6f076 100644 --- a/src/object/client/Util.cpp +++ b/src/object/client/Util.cpp @@ -107,11 +107,11 @@ void HandleObjectOutOfRangePass2(CGObject_C* object) { } ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Insert(object, object->m_hashval, CHashKeyGUID(object->m_key)); - ClntObjMgrGetCurrent()->m_lazyCleanupFifo[object->m_typeID - 1].LinkToTail(object); + ClntObjMgrGetCurrent()->m_lazyCleanupFifo[object->GetTypeID() - 1].LinkToTail(object); } void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate) { - switch (object->m_typeID) { + switch (object->GetTypeID()) { case ID_ITEM: { new (object) CGItem_C(time, objCreate); From 1c85269d1c3c270e16f07e340a397e6ba28494f3 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 11:37:30 -0600 Subject: [PATCH 069/114] feat(object): add CGObject_C::CanHighlight --- src/object/client/CGObject_C.cpp | 4 ++++ src/object/client/CGObject_C.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/object/client/CGObject_C.cpp b/src/object/client/CGObject_C.cpp index dea307c..98a4c0b 100644 --- a/src/object/client/CGObject_C.cpp +++ b/src/object/client/CGObject_C.cpp @@ -31,6 +31,10 @@ void CGObject_C::AddWorldObject() { // TODO } +int32_t CGObject_C::CanHighlight() { + return false; +} + void CGObject_C::Disable() { // TODO diff --git a/src/object/client/CGObject_C.hpp b/src/object/client/CGObject_C.hpp index 5904559..5bfd3f7 100644 --- a/src/object/client/CGObject_C.hpp +++ b/src/object/client/CGObject_C.hpp @@ -33,6 +33,7 @@ class CGObject_C : public CGObject, public TSHashObject Date: Mon, 2 Feb 2026 11:39:02 -0600 Subject: [PATCH 070/114] feat(object): add CGObject_C::CanBeTargetted --- src/object/client/CGObject_C.cpp | 4 ++++ src/object/client/CGObject_C.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/object/client/CGObject_C.cpp b/src/object/client/CGObject_C.cpp index 98a4c0b..284cac3 100644 --- a/src/object/client/CGObject_C.cpp +++ b/src/object/client/CGObject_C.cpp @@ -31,6 +31,10 @@ void CGObject_C::AddWorldObject() { // TODO } +int32_t CGObject_C::CanBeTargetted() { + return false; +} + int32_t CGObject_C::CanHighlight() { return false; } diff --git a/src/object/client/CGObject_C.hpp b/src/object/client/CGObject_C.hpp index 5bfd3f7..a0d9770 100644 --- a/src/object/client/CGObject_C.hpp +++ b/src/object/client/CGObject_C.hpp @@ -34,6 +34,7 @@ class CGObject_C : public CGObject, public TSHashObject Date: Mon, 2 Feb 2026 11:41:15 -0600 Subject: [PATCH 071/114] feat(object): add CGUnit_C::CanBeTargetted --- src/object/client/CGUnit_C.cpp | 4 ++++ src/object/client/CGUnit_C.hpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/object/client/CGUnit_C.cpp b/src/object/client/CGUnit_C.cpp index d182d2d..4b2320a 100644 --- a/src/object/client/CGUnit_C.cpp +++ b/src/object/client/CGUnit_C.cpp @@ -99,6 +99,10 @@ CGUnit_C::~CGUnit_C() { // TODO } +int32_t CGUnit_C::CanBeTargetted() { + return this->CanHighlight(); +} + void CGUnit_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) { // TODO diff --git a/src/object/client/CGUnit_C.hpp b/src/object/client/CGUnit_C.hpp index f42fec0..a22e889 100644 --- a/src/object/client/CGUnit_C.hpp +++ b/src/object/client/CGUnit_C.hpp @@ -21,6 +21,9 @@ class CGUnit_C : public CGObject_C, public CGUnit { // Virtual public member functions virtual ~CGUnit_C(); + // TODO + virtual int32_t CanBeTargetted(); + // TODO // Public member functions CGUnit_C(uint32_t time, CClientObjCreate& objCreate); From 71b7b159dec5a829be1d7cbab1186da0eb5d4dc7 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 16:45:58 -0600 Subject: [PATCH 072/114] feat(ui): add CGPetInfo --- src/ui/Game.hpp | 1 + src/ui/game/CGPetInfo.cpp | 6 ++++++ src/ui/game/CGPetInfo.hpp | 13 +++++++++++++ 3 files changed, 20 insertions(+) create mode 100644 src/ui/game/CGPetInfo.cpp create mode 100644 src/ui/game/CGPetInfo.hpp diff --git a/src/ui/Game.hpp b/src/ui/Game.hpp index 6f5e712..e4431b0 100644 --- a/src/ui/Game.hpp +++ b/src/ui/Game.hpp @@ -2,5 +2,6 @@ #define UI_GAME_HPP #include "ui/game/CGGameUI.hpp" +#include "ui/game/CGPetInfo.hpp" #endif diff --git a/src/ui/game/CGPetInfo.cpp b/src/ui/game/CGPetInfo.cpp new file mode 100644 index 0000000..90c337d --- /dev/null +++ b/src/ui/game/CGPetInfo.cpp @@ -0,0 +1,6 @@ +#include "ui/game/CGPetInfo.hpp" + +WOWGUID CGPetInfo::GetPet(uint32_t index) { + // TODO + return 0; +} diff --git a/src/ui/game/CGPetInfo.hpp b/src/ui/game/CGPetInfo.hpp new file mode 100644 index 0000000..036ca81 --- /dev/null +++ b/src/ui/game/CGPetInfo.hpp @@ -0,0 +1,13 @@ +#ifndef UI_GAME_C_G_PET_INFO_HPP +#define UI_GAME_C_G_PET_INFO_HPP + +#include "util/GUID.hpp" +#include + +class CGPetInfo { + public: + // Static functions + static WOWGUID GetPet(uint32_t index); +}; + +#endif From 55e37fd7791394909b9651e568e0b3633e4e2f7c Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 16:46:23 -0600 Subject: [PATCH 073/114] feat(object): add CGUnit_C::CanHighlight --- src/object/client/CGUnit_C.cpp | 12 ++++++++++++ src/object/client/CGUnit_C.hpp | 1 + 2 files changed, 13 insertions(+) diff --git a/src/object/client/CGUnit_C.cpp b/src/object/client/CGUnit_C.cpp index 4b2320a..11f32d2 100644 --- a/src/object/client/CGUnit_C.cpp +++ b/src/object/client/CGUnit_C.cpp @@ -1,5 +1,7 @@ #include "object/client/CGUnit_C.hpp" +#include "object/client/ObjMgr.hpp" #include "db/Db.hpp" +#include "ui/Game.hpp" WOWGUID CGUnit_C::s_activeMover; @@ -99,6 +101,16 @@ CGUnit_C::~CGUnit_C() { // TODO } +int32_t CGUnit_C::CanHighlight() { + if (this->m_unit->flags & 0x2000000) { + if (this->m_unit->createdBy != ClntObjMgrGetActivePlayer() || this->GetGUID() != CGPetInfo::GetPet(0)) { + return false; + } + } + + return true; +} + int32_t CGUnit_C::CanBeTargetted() { return this->CanHighlight(); } diff --git a/src/object/client/CGUnit_C.hpp b/src/object/client/CGUnit_C.hpp index a22e889..b3103ff 100644 --- a/src/object/client/CGUnit_C.hpp +++ b/src/object/client/CGUnit_C.hpp @@ -22,6 +22,7 @@ class CGUnit_C : public CGObject_C, public CGUnit { // Virtual public member functions virtual ~CGUnit_C(); // TODO + virtual int32_t CanHighlight(); virtual int32_t CanBeTargetted(); // TODO From e51df96e8d888352a2ebc06ed349d66902942f21 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 16:46:42 -0600 Subject: [PATCH 074/114] feat(ui): implement Script_UnitExists --- src/ui/game/ScriptEvents.cpp | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index ca4b472..25d33a3 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -11,7 +11,19 @@ namespace { int32_t Script_UnitExists(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto token = lua_tostring(L, 1); + WOWGUID guid = 0; + Script_GetGUIDFromToken(token, guid, false); + + auto object = ClntObjMgrObjectPtr(guid, TYPE_OBJECT, __FILE__, __LINE__); + + if ((object && object->CanBeTargetted()) || CGGameUI::IsRaidMemberOrPet(guid)) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + + return 1; } int32_t Script_UnitIsVisible(lua_State* L) { From 0962e5952e14ffda0836e05a914acf4c41c70a23 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 20:30:52 -0600 Subject: [PATCH 075/114] feat(ui): implement Script_FillLocalizedClassList --- src/ui/game/ScriptEvents.cpp | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index 25d33a3..f58cce5 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -1,11 +1,13 @@ #include "ui/game/ScriptEvents.hpp" -#include "object/client/ObjMgr.hpp" +#include "db/Db.hpp" +#include "object/Client.hpp" #include "ui/FrameScript.hpp" #include "ui/ScriptFunctionsSystem.hpp" #include "ui/game/CGGameUI.hpp" #include "ui/game/ScriptUtil.hpp" #include "util/GUID.hpp" #include "util/Lua.hpp" +#include "util/StringTo.hpp" #include "util/Unimplemented.hpp" namespace { @@ -707,7 +709,29 @@ int32_t Script_IsXPUserDisabled(lua_State* L) { } int32_t Script_FillLocalizedClassList(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (lua_type(L, 1) != LUA_TTABLE) { + luaL_error(L, "Usage: FillLocalizedClassList(classTable[, isFemale])"); + return 0; + } + + auto isFemale = StringToBOOL(L, 2, 0); + auto sex = isFemale ? UNITSEX_FEMALE : UNITSEX_MALE; + + lua_settop(L, 1); + + for (int32_t i = 0; i < g_chrClassesDB.GetNumRecords(); ++i) { + auto classRec = g_chrClassesDB.GetRecordByIndex(i); + if (classRec) { + auto displayName = CGUnit_C::GetDisplayClassNameFromRecord(classRec, sex, 0); + + lua_pushstring(L, classRec->m_filename); + lua_pushstring(L, displayName); + + lua_settable(L, -3); + } + } + + return 1; } } From b076c2c57380db49e3b1f4ca45abb29166a7fb39 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 21:02:29 -0600 Subject: [PATCH 076/114] feat(ui): implement CSimpleFontString_GetText --- src/ui/simple/CSimpleFontStringScript.cpp | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFontStringScript.cpp b/src/ui/simple/CSimpleFontStringScript.cpp index 62f2415..bffae37 100644 --- a/src/ui/simple/CSimpleFontStringScript.cpp +++ b/src/ui/simple/CSimpleFontStringScript.cpp @@ -162,7 +162,17 @@ int32_t CSimpleFontString_SetFont(lua_State* L) { } int32_t CSimpleFontString_GetText(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFontString::GetObjectType(); + auto string = static_cast(FrameScript_GetObjectThis(L, type)); + + auto text = string->GetText(); + if (!text || !*text) { + text = nullptr; + } + + lua_pushstring(L, text); + + return 1; } int32_t CSimpleFontString_GetFieldSize(lua_State* L) { From f42416bd0b049a54d0467c53738a6683f57981a1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 21:09:56 -0600 Subject: [PATCH 077/114] feat(ui): implement CSimpleButton_GetTextHeight --- src/ui/simple/CSimpleButtonScript.cpp | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleButtonScript.cpp b/src/ui/simple/CSimpleButtonScript.cpp index f820b9d..bb38c57 100644 --- a/src/ui/simple/CSimpleButtonScript.cpp +++ b/src/ui/simple/CSimpleButtonScript.cpp @@ -372,7 +372,18 @@ int32_t CSimpleButton_GetTextWidth(lua_State* L) { } int32_t CSimpleButton_GetTextHeight(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleButton::GetObjectType(); + auto button = static_cast(FrameScript_GetObjectThis(L, type)); + + auto text = button->m_text; + + float height = text ? text->GetHeight() : 0.0f; + float ddcHeight = CoordinateGetAspectCompensation() * 1024.0f * height; + float ndcHeight = DDCToNDCWidth(ddcHeight); + + lua_pushnumber(L, ndcHeight); + + return 1; } int32_t CSimpleButton_RegisterForClicks(lua_State* L) { From 728d13b216a895cbf4be155ef5b4bb5d0e75b680 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 22:13:40 -0600 Subject: [PATCH 078/114] fix(object): link to ui lib --- src/object/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/src/object/CMakeLists.txt b/src/object/CMakeLists.txt index a77c62e..e6cd5c6 100644 --- a/src/object/CMakeLists.txt +++ b/src/object/CMakeLists.txt @@ -16,4 +16,5 @@ target_include_directories(object target_link_libraries(object PRIVATE db + ui ) From ae64833a5c9f9cc637834928f1c6a2f123b23cab Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 22:19:15 -0600 Subject: [PATCH 079/114] feat(ui): add CSimpleFrame::m_attributes --- src/ui/simple/CSimpleFrame.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/ui/simple/CSimpleFrame.hpp b/src/ui/simple/CSimpleFrame.hpp index 2f08b23..39e8d19 100644 --- a/src/ui/simple/CSimpleFrame.hpp +++ b/src/ui/simple/CSimpleFrame.hpp @@ -6,6 +6,7 @@ #include "ui/CScriptRegion.hpp" #include "ui/Types.hpp" #include "ui/simple/CSimpleRegion.hpp" +#include #include #include @@ -17,6 +18,10 @@ class CSimpleTitleRegion; class CSimpleTop; struct lua_State; +struct FRAMEATTR : TSHashObject { + int32_t luaRef; +}; + class CSimpleFrame : public CScriptRegion { public: // Static members @@ -71,6 +76,7 @@ class CSimpleFrame : public CScriptRegion { ScriptIx m_onAttributeChange; ScriptIx m_onEnable; ScriptIx m_onDisable; + TSHashTable m_attributes; int32_t m_drawenabled[NUM_SIMPLEFRAME_DRAWLAYERS]; CBackdropGenerator* m_backdrop = nullptr; STORM_EXPLICIT_LIST(CSimpleRegion, m_regionLink) m_regions; From c099226cd271db97e995237f6a08c2f5c157de0e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Mon, 2 Feb 2026 22:29:26 -0600 Subject: [PATCH 080/114] feat(ui): add CSimpleFrame::GetAttribute --- src/ui/simple/CSimpleFrame.cpp | 12 ++++++++++++ src/ui/simple/CSimpleFrame.hpp | 1 + 2 files changed, 13 insertions(+) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 1257cd1..2588bcf 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -522,6 +522,18 @@ void CSimpleFrame::PreLoadXML(XMLNode* node, CStatus* status) { } } +bool CSimpleFrame::GetAttribute(const char* name, int32_t& luaRef) { + auto attr = this->m_attributes.Ptr(name); + + if (!attr || attr->luaRef == -1) { + return false; + } + + luaRef = attr->luaRef; + + return true; +} + int32_t CSimpleFrame::GetBoundsRect(CRect& bounds) { if (this->IsResizePending()) { this->Resize(1); diff --git a/src/ui/simple/CSimpleFrame.hpp b/src/ui/simple/CSimpleFrame.hpp index 39e8d19..d014462 100644 --- a/src/ui/simple/CSimpleFrame.hpp +++ b/src/ui/simple/CSimpleFrame.hpp @@ -132,6 +132,7 @@ class CSimpleFrame : public CScriptRegion { void DisableEvent(CSimpleEventType eventType); void EnableDrawLayer(uint32_t drawlayer); void EnableEvent(CSimpleEventType eventType, int32_t priority); + bool GetAttribute(const char* name, int32_t& luaRef); int32_t GetHitRect(CRect& rect); void Hide(); void LoadXML_Attributes(const XMLNode* node, CStatus* status); From bdce2662056af15077cf168691db4c49b80c2037 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 08:36:04 -0600 Subject: [PATCH 081/114] feat(ui): add CSimpleFrame::SetAttribute --- src/ui/simple/CSimpleFrame.cpp | 35 ++++++++++++++++++++++++++++++++++ src/ui/simple/CSimpleFrame.hpp | 2 ++ 2 files changed, 37 insertions(+) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 2588bcf..67a1da0 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -376,6 +376,29 @@ void CSimpleFrame::RegisterForEvents(int32_t a2) { } } +void CSimpleFrame::RunOnAttributeChangedScript(const char* name, int32_t luaRef) { + if (!this->m_onAttributeChange.luaRef) { + return; + } + + auto L = FrameScript_GetContext(); + + // TODO taint management + + // Attribute name + auto nameLower = static_cast(alloca(SStrLen(name) + 1)); + SStrCopy(nameLower, name); + SStrLower(nameLower); + lua_pushstring(L, nameLower); + + // Attribute ref + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + + this->RunScript(this->m_onAttributeChange, 2, nullptr); + + // TODO taint management +} + void CSimpleFrame::RunOnCharScript(const char* chr) { if (this->m_onChar.luaRef) { auto L = FrameScript_GetContext(); @@ -1329,6 +1352,18 @@ void CSimpleFrame::RemoveFrameRegion(CSimpleRegion* region, uint32_t drawlayer) this->NotifyDrawLayerChanged(drawlayer); } +void CSimpleFrame::SetAttribute(const char* name, int32_t luaRef) { + auto attr = this->m_attributes.Ptr(name); + + if (!attr) { + attr = this->m_attributes.New(name, 0, 0x0); + } + + attr->luaRef = luaRef; + + this->RunOnAttributeChangedScript(name, luaRef); +} + void CSimpleFrame::SetBackdrop(CBackdropGenerator* backdrop) { if (this->m_backdrop) { delete this->m_backdrop; diff --git a/src/ui/simple/CSimpleFrame.hpp b/src/ui/simple/CSimpleFrame.hpp index d014462..21ce7ea 100644 --- a/src/ui/simple/CSimpleFrame.hpp +++ b/src/ui/simple/CSimpleFrame.hpp @@ -146,6 +146,7 @@ class CSimpleFrame : public CScriptRegion { void RegisterForEvents(int32_t a2); void RegisterRegion(CSimpleRegion* region); void RemoveFrameRegion(CSimpleRegion* region, uint32_t drawlayer); + void RunOnAttributeChangedScript(const char* name, int32_t luaRef); void RunOnCharScript(const char* chr); void RunOnEnableScript(); void RunOnEnterScript(int32_t a2); @@ -159,6 +160,7 @@ class CSimpleFrame : public CScriptRegion { void RunOnShowScript(); void RunOnSizeChangedScript(float width, float height); void RunOnUpdateScript(float elapsedSec); + void SetAttribute(const char* name, int32_t luaRef); void SetBackdrop(CBackdropGenerator* backdrop); void SetBeingScrolled(int32_t a2, int32_t a3); void SetFrameAlpha(uint8_t alpha); From 3d8073cf75fdfa48b443a22435929b0c1c69b454 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 09:00:27 -0600 Subject: [PATCH 082/114] feat(ui): implement CSimpleFrame::LoadXML_Attributes --- src/ui/simple/CSimpleFrame.cpp | 64 +++++++++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 67a1da0..6f95f38 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -772,7 +772,69 @@ int32_t CSimpleFrame::HideThis() { } void CSimpleFrame::LoadXML_Attributes(const XMLNode* node, CStatus* status) { - // TODO + auto L = FrameScript_GetContext(); + + auto child = node->GetChild(); + + while (child) { + // Unexpected child node + if (SStrCmpI(child->GetName(), "Attribute")) { + status->Add(STATUS_WARNING, "Frame %s: Unknown attributes element %s", this->GetDisplayName(), child->GetName()); + child = child->GetSibling(); + continue; + } + + auto attrName = child->GetAttributeByName("name"); + + // No attribute name + if (!attrName) { + status->Add(STATUS_WARNING, "Frame %s: unnamed attribute element", this->GetDisplayName()); + child = child->GetSibling(); + continue; + } + + auto attrType = child->GetAttributeByName("type"); + + if (!attrType) { + attrType = "string"; + } + + auto attrValue = child->GetAttributeByName("value"); + + // Missing attribute value for non-nil type + if (SStrCmpI(attrType, "nil") && !attrValue) { + status->Add(STATUS_WARNING, "Frame %s: attribute element named %s missing value", this->GetDisplayName(), attrName); + child = child->GetSibling(); + continue; + } + + // Push attribute value to stack + if (!SStrCmpI(attrType, "nil")) { + lua_pushnil(L); + } else if (!SStrCmpI(attrType, "boolean")) { + lua_pushboolean(L, StringToBOOL(attrValue)); + } else if (!SStrCmpI(attrType, "number")) { + lua_pushnumber(L, SStrToFloat(attrValue)); + } else { + lua_pushstring(L, attrValue); + } + + auto attr = this->m_attributes.Ptr(attrName); + + if (attr) { + luaL_unref(L, LUA_REGISTRYINDEX, attr->luaRef); + } else { + attr = this->m_attributes.New(attrName, 0, 0x0); + } + + // TODO taint management + + attr->luaRef = luaL_ref(L, LUA_REGISTRYINDEX); + + // TODO taint management + + child = child->GetSibling(); + } } void CSimpleFrame::LoadXML_Backdrop(const XMLNode* node, CStatus* status) { From c201da76cd7294eae60769568d3598604be0c12f Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 09:40:46 -0600 Subject: [PATCH 083/114] feat(ui): partially implement CSimpleFrame_GetAttribute --- src/ui/simple/CSimpleFrameScript.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index ca9d743..cd2f78f 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -180,7 +180,32 @@ int32_t CSimpleFrame_CanChangeAttributes(lua_State* L) { } int32_t CSimpleFrame_GetAttribute(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + // 3 argument form + if (lua_gettop(L) == 4 && lua_isstring(L, 3)) { + // TODO 3 argument form isn't handled yet + WHOA_UNIMPLEMENTED(0); + } + + // 1 argument form + if (lua_isstring(L, 2)) { + auto attrName = lua_tostring(L, 2); + int32_t luaRef; + + if (frame->GetAttribute(attrName, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + } else { + lua_pushnil(L); + } + + return 1; + } + + // Invalid call + luaL_error(L, "Usage: %s:GetAttribute(\"name\")", frame->GetDisplayName()); + return 0; } int32_t CSimpleFrame_SetAttribute(lua_State* L) { From 66fd4a65646cd4f3e6cb8a30bb005f7ee0b1ddc2 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 10:13:08 -0600 Subject: [PATCH 084/114] feat(ui): implement CSimpleFrame_SetAttribute --- src/ui/simple/CSimpleFrame.cpp | 4 ++++ src/ui/simple/CSimpleFrame.hpp | 1 + src/ui/simple/CSimpleFrameScript.cpp | 33 +++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrame.cpp b/src/ui/simple/CSimpleFrame.cpp index 6f95f38..0e03001 100644 --- a/src/ui/simple/CSimpleFrame.cpp +++ b/src/ui/simple/CSimpleFrame.cpp @@ -95,6 +95,10 @@ void CSimpleFrame::AddFrameRegion(CSimpleRegion* region, uint32_t drawlayer) { this->NotifyDrawLayerChanged(drawlayer); } +int32_t CSimpleFrame::AttributeChangesAllowed() { + return true; +} + void CSimpleFrame::DisableDrawLayer(uint32_t drawlayer) { this->m_drawenabled[drawlayer] = 0; this->NotifyDrawLayerChanged(drawlayer); diff --git a/src/ui/simple/CSimpleFrame.hpp b/src/ui/simple/CSimpleFrame.hpp index 21ce7ea..f0641da 100644 --- a/src/ui/simple/CSimpleFrame.hpp +++ b/src/ui/simple/CSimpleFrame.hpp @@ -128,6 +128,7 @@ class CSimpleFrame : public CScriptRegion { // Member functions CSimpleFrame(CSimpleFrame* parent); void AddFrameRegion(CSimpleRegion* region, uint32_t drawlayer); + int32_t AttributeChangesAllowed(); void DisableDrawLayer(uint32_t drawlayer); void DisableEvent(CSimpleEventType eventType); void EnableDrawLayer(uint32_t drawlayer); diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index cd2f78f..118c11b 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -209,7 +209,38 @@ int32_t CSimpleFrame_GetAttribute(lua_State* L) { } int32_t CSimpleFrame_SetAttribute(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!frame->ProtectedFunctionsAllowed() && !frame->AttributeChangesAllowed()) { + // TODO disallowed logic + + return 0; + } + + lua_settop(L, 3); + + if (!lua_isstring(L, 2) || lua_type(L, 3) == LUA_TNONE) { + luaL_error(L, "Usage: %s:SetAttribute(\"name\", value)", frame->GetDisplayName()); + return 0; + } + + auto attrName = lua_tostring(L, 2); + int32_t luaRef; + + if (frame->GetAttribute(attrName, luaRef)) { + luaL_unref(L, LUA_REGISTRYINDEX, luaRef); + } + + // TODO taint management + + luaRef = luaL_ref(L, LUA_REGISTRYINDEX); + + // TODO taint management + + frame->SetAttribute(attrName, luaRef); + + return 0; } int32_t CSimpleFrame_GetEffectiveScale(lua_State* L) { From 0681e432e21c7a06b1db24d96f7712f243f556c1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 14:57:22 -0600 Subject: [PATCH 085/114] feat(ui): handle 3 argument form in CSimpleFrame_GetAttribute --- src/ui/simple/CSimpleFrameScript.cpp | 138 ++++++++++++++++++++++++++- 1 file changed, 134 insertions(+), 4 deletions(-) diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index 118c11b..227a892 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -184,26 +184,156 @@ int32_t CSimpleFrame_GetAttribute(lua_State* L) { auto frame = static_cast(FrameScript_GetObjectThis(L, type)); // 3 argument form + if (lua_gettop(L) == 4 && lua_isstring(L, 3)) { - // TODO 3 argument form isn't handled yet - WHOA_UNIMPLEMENTED(0); + size_t prefixLen, nameLen, suffixLen; + auto prefix = lua_tolstring(L, 2, &prefixLen); + auto name = lua_tolstring(L, 3, &nameLen); + auto suffix = lua_tolstring(L, 4, &suffixLen); + + char buffer[256]; + char* write; + size_t remaining; + size_t copyLen; + + int32_t luaRef; + + // Attempt 1: prefix + name + suffix + + write = buffer; + remaining = 255; + + if (prefixLen > 0) { + copyLen = (prefixLen < remaining) ? prefixLen : remaining; + memcpy(write, prefix, copyLen); + write += copyLen; + remaining -= copyLen; + } + + if (nameLen > 0) { + copyLen = (nameLen < remaining) ? nameLen : remaining; + memcpy(write, name, copyLen); + write += copyLen; + remaining -= copyLen; + } + + if (suffixLen > 0) { + copyLen = (suffixLen < remaining) ? suffixLen : remaining; + memcpy(write, suffix, copyLen); + write += copyLen; + } + + *write = '\0'; + + if (frame->GetAttribute(buffer, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + return 1; + } + + // Attempt 2: "*" + name + suffix + + write = buffer; + *write++ = '*'; + remaining = 254; + + if (nameLen > 0) { + copyLen = (nameLen < remaining) ? nameLen : remaining; + memcpy(write, name, copyLen); + write += copyLen; + remaining -= copyLen; + } + + if (suffixLen > 0) { + copyLen = (suffixLen < remaining) ? suffixLen : remaining; + memcpy(write, suffix, copyLen); + write += copyLen; + } + + *write = '\0'; + + if (frame->GetAttribute(buffer, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + return 1; + } + + // Attempt 3: prefix + name + "*" + + write = buffer; + remaining = 254; + + if (prefixLen > 0) { + copyLen = (prefixLen < remaining) ? prefixLen : remaining; + memcpy(write, prefix, copyLen); + write += copyLen; + remaining -= copyLen; + } + + if (nameLen > 0) { + copyLen = (nameLen < remaining) ? nameLen : remaining; + memcpy(write, name, copyLen); + write += copyLen; + } + + *write++ = '*'; + *write = '\0'; + + if (frame->GetAttribute(buffer, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + return 1; + } + + // Attempt 4: "*" + name + "*" + + write = buffer; + *write++ = '*'; + remaining = 253; + + if (nameLen > 0) { + copyLen = (nameLen < remaining) ? nameLen : remaining; + memcpy(write, name, copyLen); + write += copyLen; + } + + *write++ = '*'; + *write = '\0'; + + if (frame->GetAttribute(buffer, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + return 1; + } + + // Attempt 5: name + + if (frame->GetAttribute(name, luaRef)) { + lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); + return 1; + } + + // Not found + + lua_pushnil(L); + return 1; } // 1 argument form + if (lua_isstring(L, 2)) { auto attrName = lua_tostring(L, 2); int32_t luaRef; if (frame->GetAttribute(attrName, luaRef)) { lua_rawgeti(L, LUA_REGISTRYINDEX, luaRef); - } else { - lua_pushnil(L); + return 1; } + // Not found + + lua_pushnil(L); return 1; } // Invalid call + luaL_error(L, "Usage: %s:GetAttribute(\"name\")", frame->GetDisplayName()); return 0; } From 3bf95af10c05c5f2d49c42d814aa9766d7fd7c1b Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 16:24:09 -0600 Subject: [PATCH 086/114] feat(ui): implement CSimpleTexture_SetDrawLayer --- src/ui/simple/CSimpleTextureScript.cpp | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleTextureScript.cpp b/src/ui/simple/CSimpleTextureScript.cpp index 2dbe992..ada51de 100644 --- a/src/ui/simple/CSimpleTextureScript.cpp +++ b/src/ui/simple/CSimpleTextureScript.cpp @@ -19,7 +19,25 @@ int32_t CSimpleTexture_GetDrawLayer(lua_State* L) { } int32_t CSimpleTexture_SetDrawLayer(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleTexture::GetObjectType(); + auto texture = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!lua_isstring(L, 2)) { + luaL_error(L, "Usage: %s:SetDrawLayer(\"layer\")", texture->GetDisplayName()); + return 0; + } + + auto drawlayerStr = lua_tostring(L, 2); + int32_t drawlayer = texture->m_drawlayer; + + if (!StringToDrawLayer(drawlayerStr, drawlayer)) { + luaL_error(L, "Usage: %s:SetDrawLayer(\"layer\")", texture->GetDisplayName()); + return 0; + } + + texture->SetFrame(texture->m_parent, drawlayer, texture->m_shown); + + return 0; } int32_t CSimpleTexture_GetBlendMode(lua_State* L) { From d34336cd7e8d037980b13171e47bab2fccbed629 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 17:03:59 -0600 Subject: [PATCH 087/114] feat(ui): add ActionBarRegisterScriptFunctions --- src/ui/game/ActionBarScript.cpp | 156 ++++++++++++++++++++++++++++++++ src/ui/game/ActionBarScript.hpp | 6 ++ src/ui/game/CGGameUI.cpp | 5 + 3 files changed, 167 insertions(+) create mode 100644 src/ui/game/ActionBarScript.cpp create mode 100644 src/ui/game/ActionBarScript.hpp diff --git a/src/ui/game/ActionBarScript.cpp b/src/ui/game/ActionBarScript.cpp new file mode 100644 index 0000000..88457cc --- /dev/null +++ b/src/ui/game/ActionBarScript.cpp @@ -0,0 +1,156 @@ +#include "ui/game/ActionBarScript.hpp" +#include "ui/FrameScript.hpp" +#include "util/Unimplemented.hpp" + +namespace { + +int32_t Script_GetActionInfo(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionTexture(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionCount(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionCooldown(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionAutocast(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionText(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_HasAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_UseAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PickupAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_PlaceAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsAttackAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsCurrentAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsAutoRepeatAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsUsableAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsConsumableAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsStackableAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsEquippedAction(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ActionHasRange(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsActionInRange(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetBonusBarOffset(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMultiCastBarOffset(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_ChangeActionBarPage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionBarPage(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetActionBarToggles(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetActionBarToggles(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_IsPossessBarVisible(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_GetMultiCastTotemSpells(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +int32_t Script_SetMultiCastSpell(lua_State* L) { + WHOA_UNIMPLEMENTED(0); +} + +} + +static FrameScript_Method s_ScriptFunctions[] = { + { "GetActionInfo", &Script_GetActionInfo }, + { "GetActionTexture", &Script_GetActionTexture }, + { "GetActionCount", &Script_GetActionCount }, + { "GetActionCooldown", &Script_GetActionCooldown }, + { "GetActionAutocast", &Script_GetActionAutocast }, + { "GetActionText", &Script_GetActionText }, + { "HasAction", &Script_HasAction }, + { "UseAction", &Script_UseAction }, + { "PickupAction", &Script_PickupAction }, + { "PlaceAction", &Script_PlaceAction }, + { "IsAttackAction", &Script_IsAttackAction }, + { "IsCurrentAction", &Script_IsCurrentAction }, + { "IsAutoRepeatAction", &Script_IsAutoRepeatAction }, + { "IsUsableAction", &Script_IsUsableAction }, + { "IsConsumableAction", &Script_IsConsumableAction }, + { "IsStackableAction", &Script_IsStackableAction }, + { "IsEquippedAction", &Script_IsEquippedAction }, + { "ActionHasRange", &Script_ActionHasRange }, + { "IsActionInRange", &Script_IsActionInRange }, + { "GetBonusBarOffset", &Script_GetBonusBarOffset }, + { "GetMultiCastBarOffset", &Script_GetMultiCastBarOffset }, + { "ChangeActionBarPage", &Script_ChangeActionBarPage }, + { "GetActionBarPage", &Script_GetActionBarPage }, + { "GetActionBarToggles", &Script_GetActionBarToggles }, + { "SetActionBarToggles", &Script_SetActionBarToggles }, + { "IsPossessBarVisible", &Script_IsPossessBarVisible }, + { "GetMultiCastTotemSpells", &Script_GetMultiCastTotemSpells }, + { "SetMultiCastSpell", &Script_SetMultiCastSpell }, +}; + +void ActionBarRegisterScriptFunctions() { + for (auto& func : s_ScriptFunctions) { + FrameScript_RegisterFunction(func.name, func.method); + } +} diff --git a/src/ui/game/ActionBarScript.hpp b/src/ui/game/ActionBarScript.hpp new file mode 100644 index 0000000..a5c8ad8 --- /dev/null +++ b/src/ui/game/ActionBarScript.hpp @@ -0,0 +1,6 @@ +#ifndef UI_GAME_ACTION_BAR_SCRIPT_HPP +#define UI_GAME_ACTION_BAR_SCRIPT_HPP + +void ActionBarRegisterScriptFunctions(); + +#endif diff --git a/src/ui/game/CGGameUI.cpp b/src/ui/game/CGGameUI.cpp index f0f40a9..4591643 100644 --- a/src/ui/game/CGGameUI.cpp +++ b/src/ui/game/CGGameUI.cpp @@ -3,6 +3,7 @@ #include "ui/CScriptObject.hpp" #include "ui/FrameXML.hpp" #include "ui/Key.hpp" +#include "ui/game/ActionBarScript.hpp" #include "ui/game/BattlefieldInfoScript.hpp" #include "ui/game/CGCharacterModelBase.hpp" #include "ui/game/CGCooldown.hpp" @@ -46,6 +47,10 @@ void LoadScriptFunctions() { // TODO + ActionBarRegisterScriptFunctions(); + + // TODO + CharacterInfoRegisterScriptFunctions(); // TODO From 7d911e453d34c71d2d818008aa5469d248dc1670 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Tue, 3 Feb 2026 17:11:18 -0600 Subject: [PATCH 088/114] feat(ui): implement Script_GetActionBarPage --- src/ui/game/ActionBarScript.cpp | 10 +++++++++- src/ui/game/CGActionBar.cpp | 4 ++++ src/ui/game/CGActionBar.hpp | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 src/ui/game/CGActionBar.cpp create mode 100644 src/ui/game/CGActionBar.hpp diff --git a/src/ui/game/ActionBarScript.cpp b/src/ui/game/ActionBarScript.cpp index 88457cc..14f9f95 100644 --- a/src/ui/game/ActionBarScript.cpp +++ b/src/ui/game/ActionBarScript.cpp @@ -1,5 +1,7 @@ #include "ui/game/ActionBarScript.hpp" #include "ui/FrameScript.hpp" +#include "ui/game/CGActionBar.hpp" +#include "util/Lua.hpp" #include "util/Unimplemented.hpp" namespace { @@ -93,7 +95,13 @@ int32_t Script_ChangeActionBarPage(lua_State* L) { } int32_t Script_GetActionBarPage(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (CGActionBar::s_tempPageActiveFlags) { + lua_pushinteger(L, 1); + } else { + lua_pushinteger(L, CGActionBar::s_currentPage + 1); + } + + return 1; } int32_t Script_GetActionBarToggles(lua_State* L) { diff --git a/src/ui/game/CGActionBar.cpp b/src/ui/game/CGActionBar.cpp new file mode 100644 index 0000000..6d652cc --- /dev/null +++ b/src/ui/game/CGActionBar.cpp @@ -0,0 +1,4 @@ +#include "ui/game/CGActionBar.hpp" + +uint32_t CGActionBar::s_currentPage; +uint32_t CGActionBar::s_tempPageActiveFlags; diff --git a/src/ui/game/CGActionBar.hpp b/src/ui/game/CGActionBar.hpp new file mode 100644 index 0000000..ddced5b --- /dev/null +++ b/src/ui/game/CGActionBar.hpp @@ -0,0 +1,13 @@ +#ifndef UI_GAME_C_G_ACTION_BAR_HPP +#define UI_GAME_C_G_ACTION_BAR_HPP + +#include + +class CGActionBar { + public: + // Static variables + static uint32_t s_currentPage; + static uint32_t s_tempPageActiveFlags; +}; + +#endif From 4857e817c5db2cfd23cb3282aa1ad6413256c4e1 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 09:45:37 -0600 Subject: [PATCH 089/114] feat(ui): implement CSimpleFrame_CreateTexture --- src/ui/simple/CSimpleFrameScript.cpp | 64 +++++++++++++++++++++++++++- 1 file changed, 63 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index 227a892..bfb22f4 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -2,10 +2,13 @@ #include "gx/Coordinate.hpp" #include "ui/CBackdropGenerator.hpp" #include "ui/FrameScript.hpp" +#include "ui/FrameXML.hpp" #include "ui/simple/CSimpleFrame.hpp" +#include "ui/simple/CSimpleTexture.hpp" #include "util/Lua.hpp" #include "util/StringTo.hpp" #include "util/Unimplemented.hpp" +#include #include #include #include @@ -19,7 +22,66 @@ int32_t CSimpleFrame_CreateTitleRegion(lua_State* L) { } int32_t CSimpleFrame_CreateTexture(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + const char* name = nullptr; + if (lua_isstring(L, 2)) { + name = lua_tostring(L, 2); + } + + int32_t drawlayer = DRAWLAYER_ARTWORK; + if (lua_isstring(L, 3)) { + auto drawlayerStr = lua_tostring(L, 3); + StringToDrawLayer(drawlayerStr, drawlayer); + } + + XMLNode* inheritNode = nullptr; + + if (lua_type(L, 4) == LUA_TSTRING) { + auto inheritName = lua_tostring(L, 4); + const char* tainted; + bool locked; + + inheritNode = FrameXML_AcquireHashNode(inheritName, tainted, locked); + + if (!inheritNode) { + luaL_error(L, "%s:CreateTexture(): Couldn't find inherited node \"%s\"", frame->GetDisplayName(), inheritName); + return 0; + } + + if (locked) { + luaL_error(L, "%s:CreateTexture(): Recursively inherited node \"%s\"", frame->GetDisplayName(), inheritName); + return 0; + } + } + + // TODO CDataAllocator::GetData + auto texture = STORM_NEW(CSimpleTexture)(frame, drawlayer, true); + + if (name && *name) { + texture->SetName(name); + } + + if (inheritNode) { + CStatus status; + + texture->LoadXML(inheritNode, &status); + texture->PostLoadXML(inheritNode, &status); + + auto inheritName = lua_tostring(L, 4); + FrameXML_ReleaseHashNode(inheritName); + } + + // TODO anim related logic? + + if (!texture->lua_registered) { + texture->RegisterScriptObject(nullptr); + } + + lua_rawgeti(L, LUA_REGISTRYINDEX, texture->lua_objectRef); + + return 1; } int32_t CSimpleFrame_CreateFontString(lua_State* L) { From 6a4a2110f4a709f5f11a1577e8f2229b60bcf37e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 11:37:30 -0600 Subject: [PATCH 090/114] feat(ui): implement CSimpleFrame_GetScript --- src/ui/FrameScript_Object.cpp | 27 +++++++++++++++++++++++++++ src/ui/FrameScript_Object.hpp | 1 + src/ui/simple/CSimpleFrameScript.cpp | 5 ++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/src/ui/FrameScript_Object.cpp b/src/ui/FrameScript_Object.cpp index 15b19a6..17ff3db 100644 --- a/src/ui/FrameScript_Object.cpp +++ b/src/ui/FrameScript_Object.cpp @@ -35,6 +35,33 @@ const char* FrameScript_Object::GetDisplayName() { return name ? name : ""; } +int32_t FrameScript_Object::GetScript(lua_State* L) { + if (!lua_isstring(L, 2)) { + luaL_error(L, "Usage: %s:GetScript(\"type\")", this->GetDisplayName()); + return 0; + } + + auto name = lua_tostring(L, 2); + ScriptData data; + + auto script = this->GetScriptByName(name, data); + + if (!script) { + luaL_error(L, "%s doesn't have a \"%s\" script", this->GetDisplayName(), lua_tostring(L, 2)); + return 0; + } + + // TODO taint management + + if (script->luaRef > 0) { + lua_rawgeti(L, LUA_REGISTRYINDEX, script->luaRef); + } else { + lua_pushnil(L); + } + + return 1; +} + FrameScript_Object::ScriptIx* FrameScript_Object::GetScriptByName(const char* name, FrameScript_Object::ScriptData& data) { if (!SStrCmpI(name, "OnEvent", STORM_MAX_STR)) { data.wrapper = "return function(self,event,...) %s end"; diff --git a/src/ui/FrameScript_Object.hpp b/src/ui/FrameScript_Object.hpp index e80049e..db4528f 100644 --- a/src/ui/FrameScript_Object.hpp +++ b/src/ui/FrameScript_Object.hpp @@ -43,6 +43,7 @@ class FrameScript_Object { // Member functions const char* GetDisplayName(); + int32_t GetScript(lua_State* L); int32_t RegisterScriptEvent(const char* name); void RegisterScriptObject(const char* name); void RunScript(ScriptIx const& script, int32_t argCount, const char* a4); diff --git a/src/ui/simple/CSimpleFrameScript.cpp b/src/ui/simple/CSimpleFrameScript.cpp index bfb22f4..45b2679 100644 --- a/src/ui/simple/CSimpleFrameScript.cpp +++ b/src/ui/simple/CSimpleFrameScript.cpp @@ -188,7 +188,10 @@ int32_t CSimpleFrame_HasScript(lua_State* L) { } int32_t CSimpleFrame_GetScript(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFrame::GetObjectType(); + auto frame = static_cast(FrameScript_GetObjectThis(L, type)); + + return frame->GetScript(L); } int32_t CSimpleFrame_SetScript(lua_State* L) { From bc2dabeea988da47013dfa04221223af702334a9 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 12:48:52 -0600 Subject: [PATCH 091/114] feat(ui): add CSimpleStatusBar::GetScriptByName --- src/ui/simple/CSimpleStatusBar.cpp | 18 ++++++++++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 25 ++++++++++++++++++------- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index 471c842..2787be3 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -26,6 +26,24 @@ CSimpleStatusBar::CSimpleStatusBar(CSimpleFrame* parent) : CSimpleFrame(parent) // TODO } +FrameScript_Object::ScriptIx* CSimpleStatusBar::GetScriptByName(const char* name, ScriptData& data) { + auto script = this->CSimpleFrame::GetScriptByName(name, data); + + if (script) { + return script; + } + + if (!SStrCmpI(name, "OnValueChanged")) { + script = &this->m_onValueChanged; + data.wrapper = "return function(self,value) %s end"; + } else if (!SStrCmpI(name, "OnMinMaxChanged")) { + script = &this->m_onMinMaxChanged; + data.wrapper = "return function(self,min,max) %s end"; + } + + return script; +} + int32_t CSimpleStatusBar::GetScriptMetaTable() { return CSimpleStatusBar::s_metatable; } diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 812439e..f95d8e7 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -5,23 +5,34 @@ class CSimpleStatusBar : public CSimpleFrame { public: - // Static variables + // Public static variables static int32_t s_metatable; static int32_t s_objectType; - // Static functions + // Public static functions static void CreateScriptMetaTable(); static int32_t GetObjectType(); static void RegisterScriptMethods(lua_State* L); - // Member variables - // TODO - - // Virtual member functions + // Public virtual member functions virtual int32_t GetScriptMetaTable(); + virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); - // Member functions + // Public member functions CSimpleStatusBar(CSimpleFrame* parent); + + protected: + // Protected member variables + uint32_t m_changed : 1; + uint32_t m_rangeSet : 1; + uint32_t m_valueSet : 1; + float m_minValue = 0.0f; + float m_maxValue = 0.0f; + float m_value = 0.0f; + CSimpleTexture* m_barTexture = nullptr; + ORIENTATION m_orientation = ORIENTATION_HORIZONTAL; + ScriptIx m_onValueChanged; + ScriptIx m_onMinMaxChanged; }; #endif From 61484450b83e471fcb9025481045bc82660b2cf2 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 13:23:14 -0600 Subject: [PATCH 092/114] feat(ui): add CSimpleStatusBar::SetValue --- src/ui/simple/CSimpleStatusBar.cpp | 33 ++++++++++++++++++++++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 3 +++ 2 files changed, 36 insertions(+) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index 2787be3..cfa8baa 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -1,5 +1,6 @@ #include "ui/simple/CSimpleStatusBar.hpp" #include "ui/simple/CSimpleStatusBarScript.hpp" +#include "util/Lua.hpp" int32_t CSimpleStatusBar::s_metatable; int32_t CSimpleStatusBar::s_objectType; @@ -47,3 +48,35 @@ FrameScript_Object::ScriptIx* CSimpleStatusBar::GetScriptByName(const char* name int32_t CSimpleStatusBar::GetScriptMetaTable() { return CSimpleStatusBar::s_metatable; } + +void CSimpleStatusBar::RunOnValueChangedScript() { + if (!this->m_onValueChanged.luaRef) { + return; + } + + auto L = FrameScript_GetContext(); + + lua_pushnumber(L, this->m_value); + + this->RunScript(this->m_onValueChanged, 1, nullptr); +} + +void CSimpleStatusBar::SetValue(float value) { + if (!this->m_rangeSet) { + return; + } + + // Clamp value + value = std::min(std::max(value, this->m_minValue), this->m_maxValue); + + if (this->m_valueSet && this->m_value == value) { + return; + } + + this->m_value = value; + + this->m_changed = true; + this->m_valueSet = true; + + this->RunOnValueChangedScript(); +} diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index f95d8e7..2e4ca12 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -17,9 +17,12 @@ class CSimpleStatusBar : public CSimpleFrame { // Public virtual member functions virtual int32_t GetScriptMetaTable(); virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); + // TODO + virtual void SetValue(float value); // Public member functions CSimpleStatusBar(CSimpleFrame* parent); + void RunOnValueChangedScript(); protected: // Protected member variables From 35699af8d21465d3c0a1a22c513f6dc633e52dc2 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 14:28:55 -0600 Subject: [PATCH 093/114] feat(ui): add CSimpleStatusBar::SetMinMaxValues --- src/ui/simple/CSimpleStatusBar.cpp | 37 ++++++++++++++++++++++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 2 ++ 2 files changed, 39 insertions(+) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index cfa8baa..f743019 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -49,6 +49,19 @@ int32_t CSimpleStatusBar::GetScriptMetaTable() { return CSimpleStatusBar::s_metatable; } +void CSimpleStatusBar::RunOnMinMaxChangedScript() { + if (!this->m_onMinMaxChanged.luaRef) { + return; + } + + auto L = FrameScript_GetContext(); + + lua_pushnumber(L, this->m_minValue); + lua_pushnumber(L, this->m_maxValue); + + this->RunScript(this->m_onMinMaxChanged, 2, nullptr); +} + void CSimpleStatusBar::RunOnValueChangedScript() { if (!this->m_onValueChanged.luaRef) { return; @@ -61,6 +74,29 @@ void CSimpleStatusBar::RunOnValueChangedScript() { this->RunScript(this->m_onValueChanged, 1, nullptr); } +void CSimpleStatusBar::SetMinMaxValues(float min, float max) { + if (min > max) { + min = max; + } + + // No change + if (this->m_rangeSet && this->m_minValue == min && this->m_maxValue == max) { + return; + } + + this->m_minValue = min; + this->m_maxValue = max; + + this->m_changed = true; + this->m_rangeSet = true; + + this->RunOnMinMaxChangedScript(); + + if (this->m_valueSet) { + this->SetValue(this->m_value); + } +} + void CSimpleStatusBar::SetValue(float value) { if (!this->m_rangeSet) { return; @@ -69,6 +105,7 @@ void CSimpleStatusBar::SetValue(float value) { // Clamp value value = std::min(std::max(value, this->m_minValue), this->m_maxValue); + // No change if (this->m_valueSet && this->m_value == value) { return; } diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 2e4ca12..a8bbe61 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -22,7 +22,9 @@ class CSimpleStatusBar : public CSimpleFrame { // Public member functions CSimpleStatusBar(CSimpleFrame* parent); + void RunOnMinMaxChangedScript(); void RunOnValueChangedScript(); + void SetMinMaxValues(float min, float max); protected: // Protected member variables From c54dda367b197861c250a97d0be4579745ef6f59 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 14:33:23 -0600 Subject: [PATCH 094/114] feat(ui): implement CSimpleStatusBar_SetValue --- src/ui/simple/CSimpleStatusBarScript.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp index 88dcc40..7e7dbf7 100644 --- a/src/ui/simple/CSimpleStatusBarScript.cpp +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -1,5 +1,7 @@ #include "ui/simple/CSimpleStatusBarScript.hpp" +#include "ui/simple/CSimpleStatusBar.hpp" #include "ui/FrameScript.hpp" +#include "util/Lua.hpp" #include "util/Unimplemented.hpp" namespace { @@ -25,7 +27,19 @@ int32_t CSimpleStatusBar_GetValue(lua_State* L) { } int32_t CSimpleStatusBar_SetValue(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!lua_isnumber(L, 2)) { + luaL_error(L, "Usage: %s:SetValue(value)", statusBar->GetDisplayName()); + return 0; + } + + auto value = static_cast(lua_tonumber(L, 2)); + + statusBar->SetValue(value); + + return 0; } int32_t CSimpleStatusBar_GetStatusBarTexture(lua_State* L) { From 977a3051db871c3c31555bfde682bcf65c9ce69b Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 15:08:45 -0600 Subject: [PATCH 095/114] feat(ui): implement CSimpleStatusBar_SetMinMaxValues --- src/ui/simple/CSimpleStatusBarScript.cpp | 25 +++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp index 7e7dbf7..562f01f 100644 --- a/src/ui/simple/CSimpleStatusBarScript.cpp +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -19,7 +19,30 @@ int32_t CSimpleStatusBar_GetMinMaxValues(lua_State* L) { } int32_t CSimpleStatusBar_SetMinMaxValues(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!lua_isnumber(L, 2) || !lua_isnumber(L, 3)) { + luaL_error(L, "Usage: %s:SetMinMaxValues(min, max)", statusBar->GetDisplayName()); + return 0; + } + + auto min = lua_tonumber(L, 2); + auto max = lua_tonumber(L, 3); + + if (min < -1.0e12 || min > 1.0e12 || max < -1.0e12 || max > 1.0e12) { + luaL_error(L, "Min or Max out of range"); + return 0; + } + + if (max - min > 1.0e12) { + luaL_error(L, "Min and Max too far apart"); + return 0; + } + + statusBar->SetMinMaxValues(static_cast(min), static_cast(max)); + + return 0; } int32_t CSimpleStatusBar_GetValue(lua_State* L) { From dc22db2f1822fb071edf08ce3ea4914740b1a7e9 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 15:16:33 -0600 Subject: [PATCH 096/114] feat(ui): implement CSimpleStatusBar_GetValue --- src/ui/simple/CSimpleStatusBar.cpp | 4 ++++ src/ui/simple/CSimpleStatusBar.hpp | 1 + src/ui/simple/CSimpleStatusBarScript.cpp | 7 ++++++- 3 files changed, 11 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index f743019..ae0aec8 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -49,6 +49,10 @@ int32_t CSimpleStatusBar::GetScriptMetaTable() { return CSimpleStatusBar::s_metatable; } +float CSimpleStatusBar::GetValue() const { + return this->m_value; +} + void CSimpleStatusBar::RunOnMinMaxChangedScript() { if (!this->m_onMinMaxChanged.luaRef) { return; diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index a8bbe61..974309e 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -22,6 +22,7 @@ class CSimpleStatusBar : public CSimpleFrame { // Public member functions CSimpleStatusBar(CSimpleFrame* parent); + float GetValue() const; void RunOnMinMaxChangedScript(); void RunOnValueChangedScript(); void SetMinMaxValues(float min, float max); diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp index 562f01f..2aae2b1 100644 --- a/src/ui/simple/CSimpleStatusBarScript.cpp +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -46,7 +46,12 @@ int32_t CSimpleStatusBar_SetMinMaxValues(lua_State* L) { } int32_t CSimpleStatusBar_GetValue(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + lua_pushnumber(L, statusBar->GetValue()); + + return 1; } int32_t CSimpleStatusBar_SetValue(lua_State* L) { From d9b6647c42e6715f60e4de9d1fa0dbc1666072a5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 15:22:58 -0600 Subject: [PATCH 097/114] feat(ui): add CSimpleStatusBar::IsA --- src/ui/simple/CSimpleStatusBar.cpp | 7 +++++++ src/ui/simple/CSimpleStatusBar.hpp | 1 + 2 files changed, 8 insertions(+) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index ae0aec8..f221801 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -53,6 +53,13 @@ float CSimpleStatusBar::GetValue() const { return this->m_value; } +bool CSimpleStatusBar::IsA(int32_t type) { + return type == CSimpleStatusBar::s_objectType + || type == CSimpleFrame::s_objectType + || type == CScriptRegion::s_objectType + || type == CScriptObject::s_objectType; +} + void CSimpleStatusBar::RunOnMinMaxChangedScript() { if (!this->m_onMinMaxChanged.luaRef) { return; diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 974309e..7cca58d 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -17,6 +17,7 @@ class CSimpleStatusBar : public CSimpleFrame { // Public virtual member functions virtual int32_t GetScriptMetaTable(); virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); + virtual bool IsA(int32_t type); // TODO virtual void SetValue(float value); From 78f2afb8918541f1ec90bb6e39d9a9c9f56f0d58 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 17:08:31 -0600 Subject: [PATCH 098/114] feat(ui): add CSimpleStatusBar::LoadXML --- src/ui/simple/CSimpleStatusBar.cpp | 80 ++++++++++++++++++++++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 5 ++ 2 files changed, 85 insertions(+) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index f221801..1546869 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -1,6 +1,10 @@ #include "ui/simple/CSimpleStatusBar.hpp" +#include "ui/LoadXML.hpp" #include "ui/simple/CSimpleStatusBarScript.hpp" +#include "util/CStatus.hpp" #include "util/Lua.hpp" +#include "util/StringTo.hpp" +#include int32_t CSimpleStatusBar::s_metatable; int32_t CSimpleStatusBar::s_objectType; @@ -60,6 +64,66 @@ bool CSimpleStatusBar::IsA(int32_t type) { || type == CScriptObject::s_objectType; } +void CSimpleStatusBar::LoadXML(const XMLNode* node, CStatus* status) { + this->CSimpleFrame::LoadXML(node, status); + + int32_t drawlayer = DRAWLAYER_ARTWORK; + auto drawlayerAttr = node->GetAttributeByName("drawLayer"); + if (drawlayerAttr && *drawlayerAttr) { + StringToDrawLayer(drawlayerAttr, drawlayer); + } + + for (auto child = node->GetChild(); child; child = child->GetSibling()) { + if (!SStrCmpI(child->GetName(), "BarTexture")) { + auto texture = LoadXML_Texture(child, this, status); + this->SetBarTexture(texture, drawlayer); + } else if (!SStrCmpI(child->GetName(), "BarColor")) { + CImVector color = {}; + LoadXML_Color(child, color); + this->SetStatusBarColor(color); + } + } + + auto minValueAttr = node->GetAttributeByName("minValue"); + if (minValueAttr && *minValueAttr) { + auto maxValueAttr = node->GetAttributeByName("maxValue"); + if (maxValueAttr && *maxValueAttr) { + auto minValue = SStrToFloat(minValueAttr); + auto maxValue = SStrToFloat(maxValueAttr); + + if (minValue < -1.0e12 || minValue > 1.0e12 || maxValue < -1.0e12 || maxValue > 1.0e12) { + status->Add(STATUS_ERROR, "Frame %s: Min or Max out of range", this->GetDisplayName()); + } else if (maxValue - minValue > 1.0e12) { + status->Add(STATUS_ERROR, "Frame %s: Min and Max too far apart", this->GetDisplayName()); + } else { + this->SetMinMaxValues(minValue, maxValue); + } + + auto defaultValueAttr = node->GetAttributeByName("defaultValue"); + if (defaultValueAttr && *defaultValueAttr) { + auto defaultValue = SStrToFloat(defaultValueAttr); + this->SetValue(defaultValue); + } + } + } + + auto orientationAttr = node->GetAttributeByName("orientation"); + if (orientationAttr && *orientationAttr) { + ORIENTATION orientation; + if (StringToOrientation(orientationAttr, orientation)) { + this->SetOrientation(orientation); + } else { + status->Add(STATUS_WARNING, "Frame %s: Unknown orientation %s in element %s", this->GetDisplayName(), orientationAttr, node->GetName()); + } + } + + auto rotatesTextureAttr = node->GetAttributeByName("rotatesTexture"); + if (rotatesTextureAttr && *rotatesTextureAttr) { + auto rotatesTexture = StringToBOOL(rotatesTextureAttr); + this->SetRotatesTexture(rotatesTexture); + } +} + void CSimpleStatusBar::RunOnMinMaxChangedScript() { if (!this->m_onMinMaxChanged.luaRef) { return; @@ -85,6 +149,10 @@ void CSimpleStatusBar::RunOnValueChangedScript() { this->RunScript(this->m_onValueChanged, 1, nullptr); } +void CSimpleStatusBar::SetBarTexture(CSimpleTexture* texture, int32_t drawlayer) { + // TODO +} + void CSimpleStatusBar::SetMinMaxValues(float min, float max) { if (min > max) { min = max; @@ -108,6 +176,18 @@ void CSimpleStatusBar::SetMinMaxValues(float min, float max) { } } +void CSimpleStatusBar::SetOrientation(ORIENTATION orientation) { + // TODO +} + +void CSimpleStatusBar::SetRotatesTexture(int32_t enabled) { + // TODO +} + +void CSimpleStatusBar::SetStatusBarColor(const CImVector& color) { + // TODO +} + void CSimpleStatusBar::SetValue(float value) { if (!this->m_rangeSet) { return; diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 7cca58d..1655a46 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -20,13 +20,18 @@ class CSimpleStatusBar : public CSimpleFrame { virtual bool IsA(int32_t type); // TODO virtual void SetValue(float value); + virtual void LoadXML(const XMLNode* node, CStatus* status); // Public member functions CSimpleStatusBar(CSimpleFrame* parent); float GetValue() const; void RunOnMinMaxChangedScript(); void RunOnValueChangedScript(); + void SetBarTexture(CSimpleTexture* texture, int32_t drawlayer); void SetMinMaxValues(float min, float max); + void SetOrientation(ORIENTATION orientation); + void SetRotatesTexture(int32_t enabled); + void SetStatusBarColor(const CImVector& color); protected: // Protected member variables From fd31a10eafbfa1d51eb3f38324c4e33da3b3099f Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 21:06:53 -0600 Subject: [PATCH 099/114] feat(ui): implement CSimpleStatusBar::SetBarTexture --- src/ui/simple/CSimpleStatusBar.cpp | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index 1546869..0e33201 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -1,6 +1,7 @@ #include "ui/simple/CSimpleStatusBar.hpp" #include "ui/LoadXML.hpp" #include "ui/simple/CSimpleStatusBarScript.hpp" +#include "ui/simple/CSimpleTexture.hpp" #include "util/CStatus.hpp" #include "util/Lua.hpp" #include "util/StringTo.hpp" @@ -150,7 +151,27 @@ void CSimpleStatusBar::RunOnValueChangedScript() { } void CSimpleStatusBar::SetBarTexture(CSimpleTexture* texture, int32_t drawlayer) { - // TODO + // No change + if (this->m_barTexture == texture) { + return; + } + + if (this->m_barTexture) { + delete this->m_barTexture; + } + + if (texture) { + texture->SetFrame(this, drawlayer, true); + + texture->SetPoint(FRAMEPOINT_BOTTOMLEFT, this, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, true); + texture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, this, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f, true); + texture->SetPoint(FRAMEPOINT_TOPLEFT, this, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f, true); + texture->SetPoint(FRAMEPOINT_TOPRIGHT, this, FRAMEPOINT_TOPRIGHT, 0.0f, 0.0f, true); + } + + this->m_barTexture = texture; + + this->m_changed = true; } void CSimpleStatusBar::SetMinMaxValues(float min, float max) { From d0621df975b6e440f74e95329fb91c4137f56578 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 21:10:42 -0600 Subject: [PATCH 100/114] feat(ui): implement CSimpleStatusBar::SetStatusBarColor --- src/ui/simple/CSimpleStatusBar.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index 0e33201..1190a48 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -206,7 +206,9 @@ void CSimpleStatusBar::SetRotatesTexture(int32_t enabled) { } void CSimpleStatusBar::SetStatusBarColor(const CImVector& color) { - // TODO + if (this->m_barTexture) { + this->m_barTexture->SetVertexColor(color); + } } void CSimpleStatusBar::SetValue(float value) { From 98103db5eea5772200f7e6be932893ac7dd2b39a Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 21:15:32 -0600 Subject: [PATCH 101/114] feat(ui): implement CSimpleStatusBar_SetStatusBarColor --- src/ui/simple/CSimpleStatusBarScript.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp index 2aae2b1..56bc271 100644 --- a/src/ui/simple/CSimpleStatusBarScript.cpp +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -83,7 +83,15 @@ int32_t CSimpleStatusBar_GetStatusBarColor(lua_State* L) { } int32_t CSimpleStatusBar_SetStatusBarColor(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + CImVector color = {}; + FrameScript_GetColor(L, 2, color); + + statusBar->SetStatusBarColor(color); + + return 0; } int32_t CSimpleStatusBar_GetRotatesTexture(lua_State* L) { From 3713a7ee893ba56644672e9fbe2b507c665e15ac Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 21:40:42 -0600 Subject: [PATCH 102/114] feat(ui): implement CSimpleStatusBar_GetMinMaxValues --- src/ui/simple/CSimpleStatusBar.cpp | 8 ++++++++ src/ui/simple/CSimpleStatusBar.hpp | 2 ++ src/ui/simple/CSimpleStatusBarScript.cpp | 8 +++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index 1190a48..a2b1c8a 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -54,6 +54,14 @@ int32_t CSimpleStatusBar::GetScriptMetaTable() { return CSimpleStatusBar::s_metatable; } +float CSimpleStatusBar::GetMaxValue() const { + return this->m_maxValue; +} + +float CSimpleStatusBar::GetMinValue() const { + return this->m_minValue; +} + float CSimpleStatusBar::GetValue() const { return this->m_value; } diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 1655a46..1bdb821 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -24,6 +24,8 @@ class CSimpleStatusBar : public CSimpleFrame { // Public member functions CSimpleStatusBar(CSimpleFrame* parent); + float GetMaxValue() const; + float GetMinValue() const; float GetValue() const; void RunOnMinMaxChangedScript(); void RunOnValueChangedScript(); diff --git a/src/ui/simple/CSimpleStatusBarScript.cpp b/src/ui/simple/CSimpleStatusBarScript.cpp index 56bc271..2701c2f 100644 --- a/src/ui/simple/CSimpleStatusBarScript.cpp +++ b/src/ui/simple/CSimpleStatusBarScript.cpp @@ -15,7 +15,13 @@ int32_t CSimpleStatusBar_SetOrientation(lua_State* L) { } int32_t CSimpleStatusBar_GetMinMaxValues(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + lua_pushnumber(L, statusBar->GetMinValue()); + lua_pushnumber(L, statusBar->GetMaxValue()); + + return 2; } int32_t CSimpleStatusBar_SetMinMaxValues(lua_State* L) { From 856bb72e1a0051599ab93dfcb4365769e9dab287 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Wed, 4 Feb 2026 21:53:51 -0600 Subject: [PATCH 103/114] chore(ui): improve CSimpleStatusBar ctor --- src/ui/simple/CSimpleStatusBar.cpp | 4 ---- src/ui/simple/CSimpleStatusBar.hpp | 6 +++++- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index a2b1c8a..e5c3f20 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -28,10 +28,6 @@ void CSimpleStatusBar::RegisterScriptMethods(lua_State* L) { FrameScript_Object::FillScriptMethodTable(L, SimpleStatusBarMethods, NUM_SIMPLE_STATUS_BAR_SCRIPT_METHODS); } -CSimpleStatusBar::CSimpleStatusBar(CSimpleFrame* parent) : CSimpleFrame(parent) { - // TODO -} - FrameScript_Object::ScriptIx* CSimpleStatusBar::GetScriptByName(const char* name, ScriptData& data) { auto script = this->CSimpleFrame::GetScriptByName(name, data); diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 1bdb821..203f6a4 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -23,7 +23,11 @@ class CSimpleStatusBar : public CSimpleFrame { virtual void LoadXML(const XMLNode* node, CStatus* status); // Public member functions - CSimpleStatusBar(CSimpleFrame* parent); + CSimpleStatusBar(CSimpleFrame* parent) + : CSimpleFrame(parent) + , m_changed(false) + , m_rangeSet(false) + , m_valueSet(false) {}; float GetMaxValue() const; float GetMinValue() const; float GetValue() const; From 534e05be93cacf4820ed3ab5c9d79531e14a31ff Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 07:01:30 -0600 Subject: [PATCH 104/114] feat(ui): add CLayoutFrame::GetSize --- src/ui/CLayoutFrame.cpp | 20 ++++++++++++++++++-- src/ui/CLayoutFrame.hpp | 1 + 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/ui/CLayoutFrame.cpp b/src/ui/CLayoutFrame.cpp index 4df0f77..886d776 100644 --- a/src/ui/CLayoutFrame.cpp +++ b/src/ui/CLayoutFrame.cpp @@ -332,6 +332,10 @@ void CLayoutFrame::GetFirstPointY(const FRAMEPOINT* const pointarray, int32_t el } } +float CLayoutFrame::GetHeight() { + return this->m_height; +} + CLayoutFrame* CLayoutFrame::GetLayoutFrameByName(const char* name) { return nullptr; } @@ -353,8 +357,20 @@ int32_t CLayoutFrame::GetRect(CRect* rect) { return 1; } -float CLayoutFrame::GetHeight() { - return this->m_height; +void CLayoutFrame::GetSize(float& width, float& height, int32_t a4) { + width = this->GetWidth(); + height = this->GetHeight(); + + if (!a4 && (width == 0.0f || height == 0.0f)) { + if (this->m_flags & FLAG_RESIZE_PENDING) { + this->Resize(1); + } + + if (this->m_flags & 0x1) { + width = (this->m_rect.maxX - this->m_rect.minX) / this->m_layoutScale; + height = (this->m_rect.maxY - this->m_rect.minY) / this->m_layoutScale; + } + } } float CLayoutFrame::GetWidth() { diff --git a/src/ui/CLayoutFrame.hpp b/src/ui/CLayoutFrame.hpp index 7e0da91..53ab714 100644 --- a/src/ui/CLayoutFrame.hpp +++ b/src/ui/CLayoutFrame.hpp @@ -51,6 +51,7 @@ class CLayoutFrame { virtual void SetHeight(float height); virtual float GetWidth(); virtual float GetHeight(); + virtual void GetSize(float& width, float& height, int32_t a4); virtual void GetClampRectInsets(float& a1, float& a2, float& a3, float& a4); virtual int32_t IsAttachmentOrigin(); virtual CLayoutFrame* GetLayoutFrameByName(const char* name); From aa22dd952a86b03826bc960413133c42d3e18cd8 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 07:05:28 -0600 Subject: [PATCH 105/114] feat(ui): add CSimpleStatusBar::OnLayerUpdate --- src/ui/simple/CSimpleStatusBar.cpp | 50 ++++++++++++++++++++++++++++++ src/ui/simple/CSimpleStatusBar.hpp | 3 ++ 2 files changed, 53 insertions(+) diff --git a/src/ui/simple/CSimpleStatusBar.cpp b/src/ui/simple/CSimpleStatusBar.cpp index e5c3f20..c3c0d28 100644 --- a/src/ui/simple/CSimpleStatusBar.cpp +++ b/src/ui/simple/CSimpleStatusBar.cpp @@ -28,6 +28,16 @@ void CSimpleStatusBar::RegisterScriptMethods(lua_State* L) { FrameScript_Object::FillScriptMethodTable(L, SimpleStatusBarMethods, NUM_SIMPLE_STATUS_BAR_SCRIPT_METHODS); } +float CSimpleStatusBar::GetAnimValue() const { + auto range = this->m_maxValue - this->m_minValue; + + if (range <= 0.0f) { + return 0.0f; + } + + return (this->m_value - this->m_minValue) / range; +} + FrameScript_Object::ScriptIx* CSimpleStatusBar::GetScriptByName(const char* name, ScriptData& data) { auto script = this->CSimpleFrame::GetScriptByName(name, data); @@ -129,6 +139,46 @@ void CSimpleStatusBar::LoadXML(const XMLNode* node, CStatus* status) { } } +void CSimpleStatusBar::OnLayerUpdate(float elapsedSec) { + this->CSimpleFrame::OnLayerUpdate(elapsedSec); + + if (!this->m_changed || !this->m_rangeSet || !this->m_valueSet || !this->m_barTexture) { + return; + } + + auto animValue = this->GetAnimValue(); + + if (animValue <= 0.0f) { + this->m_barTexture->Hide(); + this->m_changed = false; + + return; + } + + float width, height; + this->GetSize(width, height, false); + + auto fill = 1.0f - animValue; + + this->m_barTexture->Show(); + + if (this->m_orientation == ORIENTATION_VERTICAL) { + this->m_barTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, this, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, true); + this->m_barTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, this, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f, true); + + this->m_barTexture->SetPoint(FRAMEPOINT_TOPLEFT, this, FRAMEPOINT_TOPLEFT, 0.0f, -(fill * height), true); + this->m_barTexture->SetPoint(FRAMEPOINT_TOPRIGHT, this, FRAMEPOINT_TOPRIGHT, 0.0f, -(fill * height), true); + } else { + this->m_barTexture->SetPoint(FRAMEPOINT_TOPLEFT, this, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f, true); + this->m_barTexture->SetPoint(FRAMEPOINT_BOTTOMLEFT, this, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, true); + + this->m_barTexture->SetPoint(FRAMEPOINT_TOPRIGHT, this, FRAMEPOINT_TOPRIGHT, -(fill * width), 0.0f, true); + this->m_barTexture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, this, FRAMEPOINT_BOTTOMRIGHT, -(fill * width), 0.0f, true); + } + + this->m_changed = false; +} + void CSimpleStatusBar::RunOnMinMaxChangedScript() { if (!this->m_onMinMaxChanged.luaRef) { return; diff --git a/src/ui/simple/CSimpleStatusBar.hpp b/src/ui/simple/CSimpleStatusBar.hpp index 203f6a4..0a81141 100644 --- a/src/ui/simple/CSimpleStatusBar.hpp +++ b/src/ui/simple/CSimpleStatusBar.hpp @@ -19,6 +19,8 @@ class CSimpleStatusBar : public CSimpleFrame { virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); virtual bool IsA(int32_t type); // TODO + virtual void OnLayerUpdate(float elapsedSec); + // TODO virtual void SetValue(float value); virtual void LoadXML(const XMLNode* node, CStatus* status); @@ -28,6 +30,7 @@ class CSimpleStatusBar : public CSimpleFrame { , m_changed(false) , m_rangeSet(false) , m_valueSet(false) {}; + float GetAnimValue() const; float GetMaxValue() const; float GetMinValue() const; float GetValue() const; From aac8cf0855322eedf049b62f1490c72ba51543f5 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 13:26:59 -0600 Subject: [PATCH 106/114] feat(object): add CGObject::IsA --- src/object/client/CGObject.cpp | 4 ++++ src/object/client/CGObject.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/object/client/CGObject.cpp b/src/object/client/CGObject.cpp index 41236cf..64d8359 100644 --- a/src/object/client/CGObject.cpp +++ b/src/object/client/CGObject.cpp @@ -36,6 +36,10 @@ OBJECT_TYPE_ID CGObject::GetTypeID() const { return this->m_typeID; } +int32_t CGObject::IsA(OBJECT_TYPE type) const { + return (this->GetType() & type) != 0; +} + CGObjectData* CGObject::Obj() const { return this->m_obj; } diff --git a/src/object/client/CGObject.hpp b/src/object/client/CGObject.hpp index 55f4514..4331157 100644 --- a/src/object/client/CGObject.hpp +++ b/src/object/client/CGObject.hpp @@ -31,6 +31,7 @@ class CGObject { WOWGUID GetGUID() const; OBJECT_TYPE GetType() const; OBJECT_TYPE_ID GetTypeID() const; + int32_t IsA(OBJECT_TYPE type) const; protected: // Protected member variables From f567a3a7c87c004c3903188fe9e421d77b7f9701 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 14:51:17 -0600 Subject: [PATCH 107/114] feat(object): add CGPlayer::GetXP --- src/object/client/CGPlayer.cpp | 4 ++++ src/object/client/CGPlayer.hpp | 3 +++ 2 files changed, 7 insertions(+) diff --git a/src/object/client/CGPlayer.cpp b/src/object/client/CGPlayer.cpp index 1e44711..422f8dd 100644 --- a/src/object/client/CGPlayer.cpp +++ b/src/object/client/CGPlayer.cpp @@ -41,6 +41,10 @@ uint32_t CGPlayer::TotalRemoteFieldsSaved() { return CGPlayer::GetBaseOffsetSaved() + 173; } +uint32_t CGPlayer::GetXP() const { + return this->Player()->xp; +} + CGPlayerData* CGPlayer::Player() const { return this->m_player; } diff --git a/src/object/client/CGPlayer.hpp b/src/object/client/CGPlayer.hpp index 707f39f..d6090e1 100644 --- a/src/object/client/CGPlayer.hpp +++ b/src/object/client/CGPlayer.hpp @@ -148,6 +148,9 @@ class CGPlayer { static uint32_t TotalFieldsSaved(); static uint32_t TotalRemoteFieldsSaved(); + // Public member functions + uint32_t GetXP() const; + protected: // Protected member variables CGPlayerData* m_player; From c9f26b6666f33e23504e231dcdf06e499a42b9a6 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 14:53:58 -0600 Subject: [PATCH 108/114] feat(object): add CGObject::IsExactlyA --- src/object/client/CGObject.cpp | 4 ++++ src/object/client/CGObject.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/object/client/CGObject.cpp b/src/object/client/CGObject.cpp index 64d8359..153cce1 100644 --- a/src/object/client/CGObject.cpp +++ b/src/object/client/CGObject.cpp @@ -40,6 +40,10 @@ int32_t CGObject::IsA(OBJECT_TYPE type) const { return (this->GetType() & type) != 0; } +int32_t CGObject::IsExactlyA(OBJECT_TYPE_ID typeID) const { + return this->m_typeID == typeID; +} + CGObjectData* CGObject::Obj() const { return this->m_obj; } diff --git a/src/object/client/CGObject.hpp b/src/object/client/CGObject.hpp index 4331157..506cddd 100644 --- a/src/object/client/CGObject.hpp +++ b/src/object/client/CGObject.hpp @@ -32,6 +32,7 @@ class CGObject { OBJECT_TYPE GetType() const; OBJECT_TYPE_ID GetTypeID() const; int32_t IsA(OBJECT_TYPE type) const; + int32_t IsExactlyA(OBJECT_TYPE_ID typeID) const; protected: // Protected member variables From 5d81022c749476adbb90d7b92c0da86b0871521e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 15:00:32 -0600 Subject: [PATCH 109/114] feat(object): add CGPlayer::GetNextLevelXP --- src/object/client/CGPlayer.cpp | 4 ++++ src/object/client/CGPlayer.hpp | 1 + 2 files changed, 5 insertions(+) diff --git a/src/object/client/CGPlayer.cpp b/src/object/client/CGPlayer.cpp index 422f8dd..568baf3 100644 --- a/src/object/client/CGPlayer.cpp +++ b/src/object/client/CGPlayer.cpp @@ -41,6 +41,10 @@ uint32_t CGPlayer::TotalRemoteFieldsSaved() { return CGPlayer::GetBaseOffsetSaved() + 173; } +uint32_t CGPlayer::GetNextLevelXP() const { + return this->Player()->nextLevelXP; +} + uint32_t CGPlayer::GetXP() const { return this->Player()->xp; } diff --git a/src/object/client/CGPlayer.hpp b/src/object/client/CGPlayer.hpp index d6090e1..3d18372 100644 --- a/src/object/client/CGPlayer.hpp +++ b/src/object/client/CGPlayer.hpp @@ -149,6 +149,7 @@ class CGPlayer { static uint32_t TotalRemoteFieldsSaved(); // Public member functions + uint32_t GetNextLevelXP() const; uint32_t GetXP() const; protected: From ee48e47992791de8af679b4146cac4ffdcb2aef6 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 15:58:48 -0600 Subject: [PATCH 110/114] feat(object): add CGPlayer_C::GetActiveXP --- src/object/client/CGPlayer_C.cpp | 9 +++++++++ src/object/client/CGPlayer_C.hpp | 1 + 2 files changed, 10 insertions(+) diff --git a/src/object/client/CGPlayer_C.cpp b/src/object/client/CGPlayer_C.cpp index e34f048..cb43f4c 100644 --- a/src/object/client/CGPlayer_C.cpp +++ b/src/object/client/CGPlayer_C.cpp @@ -1,5 +1,6 @@ #include "object/client/CGPlayer_C.hpp" #include "db/Db.hpp" +#include "object/client/ObjMgr.hpp" #include "object/Types.hpp" #include @@ -11,6 +12,14 @@ CGPlayer_C::~CGPlayer_C() { // TODO } +uint32_t CGPlayer_C::GetActiveXP() const { + if (this->GetGUID() != ClntObjMgrGetActivePlayer()) { + return 0; + } + + return this->GetXP(); +} + void CGPlayer_C::PostInit(uint32_t time, const CClientObjCreate& init, bool a4) { // TODO diff --git a/src/object/client/CGPlayer_C.hpp b/src/object/client/CGPlayer_C.hpp index e224be4..85db184 100644 --- a/src/object/client/CGPlayer_C.hpp +++ b/src/object/client/CGPlayer_C.hpp @@ -15,6 +15,7 @@ class CGPlayer_C : public CGUnit_C, public CGPlayer { // Public member functions CGPlayer_C(uint32_t time, CClientObjCreate& objCreate); + uint32_t GetActiveXP() const; void PostInit(uint32_t time, const CClientObjCreate& init, bool a4); void SetStorage(uint32_t* storage, uint32_t* saved); }; From ed9c68360242301276e48bd6bbe18e34ccaaae1e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 16:01:46 -0600 Subject: [PATCH 111/114] feat(object): add CGPlayer_C::GetActiveNextLevelXP --- src/object/client/CGPlayer_C.cpp | 8 ++++++++ src/object/client/CGPlayer_C.hpp | 1 + 2 files changed, 9 insertions(+) diff --git a/src/object/client/CGPlayer_C.cpp b/src/object/client/CGPlayer_C.cpp index cb43f4c..34ccb52 100644 --- a/src/object/client/CGPlayer_C.cpp +++ b/src/object/client/CGPlayer_C.cpp @@ -12,6 +12,14 @@ CGPlayer_C::~CGPlayer_C() { // TODO } +uint32_t CGPlayer_C::GetActiveNextLevelXP() const { + if (this->GetGUID() != ClntObjMgrGetActivePlayer()) { + return 0; + } + + return this->GetNextLevelXP(); +} + uint32_t CGPlayer_C::GetActiveXP() const { if (this->GetGUID() != ClntObjMgrGetActivePlayer()) { return 0; diff --git a/src/object/client/CGPlayer_C.hpp b/src/object/client/CGPlayer_C.hpp index 85db184..20813a8 100644 --- a/src/object/client/CGPlayer_C.hpp +++ b/src/object/client/CGPlayer_C.hpp @@ -15,6 +15,7 @@ class CGPlayer_C : public CGUnit_C, public CGPlayer { // Public member functions CGPlayer_C(uint32_t time, CClientObjCreate& objCreate); + uint32_t GetActiveNextLevelXP() const; uint32_t GetActiveXP() const; void PostInit(uint32_t time, const CClientObjCreate& init, bool a4); void SetStorage(uint32_t* storage, uint32_t* saved); From cfb8f2bae11eadbb00333028d3330a5b4351814e Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 16:05:12 -0600 Subject: [PATCH 112/114] feat(ui): add Script_GetUnitFromName --- src/ui/game/ScriptUtil.cpp | 10 ++++++++++ src/ui/game/ScriptUtil.hpp | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/src/ui/game/ScriptUtil.cpp b/src/ui/game/ScriptUtil.cpp index 0f5a809..1822389 100644 --- a/src/ui/game/ScriptUtil.cpp +++ b/src/ui/game/ScriptUtil.cpp @@ -12,6 +12,16 @@ bool ParseTrailingTokens(const char* token, WOWGUID& guid, CGPlayer_C* player) { } +CGUnit_C* Script_GetUnitFromName(const char* name) { + WOWGUID guid; + + if (!Script_GetGUIDFromToken(name, guid, false)) { + return nullptr; + } + + return static_cast(ClntObjMgrObjectPtr(guid, TYPE_UNIT, __FILE__, __LINE__)); +} + bool Script_GetGUIDFromString(const char*& token, WOWGUID& guid) { // TODO return true; diff --git a/src/ui/game/ScriptUtil.hpp b/src/ui/game/ScriptUtil.hpp index c06aa58..3d3c1c8 100644 --- a/src/ui/game/ScriptUtil.hpp +++ b/src/ui/game/ScriptUtil.hpp @@ -3,6 +3,10 @@ #include "util/GUID.hpp" +class CGUnit_C; + +CGUnit_C* Script_GetUnitFromName(const char* name); + bool Script_GetGUIDFromString(const char*& token, WOWGUID& guid); bool Script_GetGUIDFromToken(const char* token, WOWGUID& guid, bool defaultToTarget); From a53e1360a4e5cc422fa2df6efa4e9d7445816a44 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 16:12:04 -0600 Subject: [PATCH 113/114] feat(ui): implement Script_UnitXP --- src/ui/game/ScriptEvents.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index f58cce5..7139e84 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -173,7 +173,23 @@ int32_t Script_UnitPVPName(lua_State* L) { } int32_t Script_UnitXP(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + luaL_error(L, "Usage: UnitXP(\"unit\")"); + return 0; + } + + auto name = lua_tostring(L, 1); + auto unit = Script_GetUnitFromName(name); + + float xp = 0.0f; + + if (unit && unit->IsA(TYPE_PLAYER)) { + xp = static_cast(unit)->GetActiveXP(); + } + + lua_pushnumber(L, xp); + + return 1; } int32_t Script_UnitXPMax(lua_State* L) { From 315ea05ba048cd4d43e332a797fddf34c882f5e8 Mon Sep 17 00:00:00 2001 From: fallenoak Date: Thu, 5 Feb 2026 16:56:44 -0600 Subject: [PATCH 114/114] feat(ui): implement Script_UnitXPMax --- src/ui/game/ScriptEvents.cpp | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/ui/game/ScriptEvents.cpp b/src/ui/game/ScriptEvents.cpp index 7139e84..7aa33f2 100644 --- a/src/ui/game/ScriptEvents.cpp +++ b/src/ui/game/ScriptEvents.cpp @@ -193,7 +193,23 @@ int32_t Script_UnitXP(lua_State* L) { } int32_t Script_UnitXPMax(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + luaL_error(L, "Usage: UnitXPMax(\"unit\")"); + return 0; + } + + auto name = lua_tostring(L, 1); + auto unit = Script_GetUnitFromName(name); + + float xpMax = 0.0f; + + if (unit && unit->IsA(TYPE_PLAYER)) { + xpMax = static_cast(unit)->GetActiveNextLevelXP(); + } + + lua_pushnumber(L, xpMax); + + return 1; } int32_t Script_UnitHealth(lua_State* L) {