From fcc3be490c0e8566ecb6ed885952d4fa42eb1b87 Mon Sep 17 00:00:00 2001 From: VDm Date: Mon, 11 Aug 2025 22:38:57 +0400 Subject: [PATCH] feat(gameui): implement CVarGet* script methods --- src/client/CMakeLists.txt | 1 + src/client/Client.cpp | 3 +- src/gameui/GameScriptFunctions.cpp | 127 +++++++++++++++++++++++++++-- src/sound/SI2.cpp | 2 + src/ui/CSimpleFrameScript.cpp | 49 ++++++++++- src/ui/CSimpleStatusBar.hpp | 3 + src/ui/CSimpleStatusBarScript.cpp | 11 ++- src/util/Unimplemented.hpp | 7 +- 8 files changed, 189 insertions(+), 14 deletions(-) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index 9afeb6f..dffcce0 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -43,6 +43,7 @@ target_link_libraries(client gx model net + sound ui util world diff --git a/src/client/Client.cpp b/src/client/Client.cpp index a12dd84..143ac86 100644 --- a/src/client/Client.cpp +++ b/src/client/Client.cpp @@ -18,6 +18,7 @@ #include "gx/Texture.hpp" #include "model/Model2.hpp" #include "net/Poll.hpp" +#include "sound/SI2.hpp" #include "ui/FrameScript.hpp" #include "ui/FrameXML.hpp" #include "world/World.hpp" @@ -728,7 +729,7 @@ void WowClientInit() { FrameScript_Initialize(0); // TODO - // SI2::Init(0); + SI2::Init(0); // sub_6F66B0(); FrameXML_RegisterDefault(); diff --git a/src/gameui/GameScriptFunctions.cpp b/src/gameui/GameScriptFunctions.cpp index 2480b7f..1dc6fe3 100644 --- a/src/gameui/GameScriptFunctions.cpp +++ b/src/gameui/GameScriptFunctions.cpp @@ -8,11 +8,13 @@ #include "gameui/CGTabardModelFrame.hpp" #include "gameui/CGQuestPOIFrame.hpp" #include "console/Console.hpp" +#include "console/CVar.hpp" #include "gx/CGVideoOptions.hpp" #include "ui/FrameXML.hpp" #include "ui/FrameScript.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" +#include "util/StringTo.hpp" // External from "ui/ScriptFunctions.hpp" void RegisterSimpleFrameScriptMethods(); @@ -163,31 +165,142 @@ static int32_t Script_SetCVar(lua_State* L) { } static int32_t Script_GetCVar(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVar(\"cvar\")"); + } + + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(lua_tolstring(L, 1, nullptr)); + if (!cvar || (cvar->m_flags & 0x40)) { + lua_pushnil(L); + } else { + lua_pushstring(L, cvar->GetString()); + } + return 1; } static int32_t Script_GetCVarBool(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarBool(\"cvar\")"); + } + + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(lua_tolstring(L, 1, nullptr)); + if (cvar && (cvar->m_flags & 0x40) == 0 && StringToBOOL(cvar->GetString())) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } static int32_t Script_GetCVarDefault(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarDefault(\"cvar\")"); + } + + auto name = lua_tolstring(L, 1, nullptr); + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(name); + if (!cvar || (cvar->m_flags & 0x40)) { + return luaL_error(L, "Couldn't find CVar named '%s'", name); + } else { + lua_pushstring(L, cvar->m_defaultValue.GetString()); + } + return 1; } static int32_t Script_GetCVarMin(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarMin(\"cvar\")"); + } + + auto name = lua_tolstring(L, 1, nullptr); + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(name); + if (!cvar || (cvar->m_flags & 0x40)) { + return luaL_error(L, "Couldn't find CVar named '%s'", name); + } + + auto key = cvar->m_key.m_str; + if (!SStrCmpI(key, "extShadowQuality", STORM_MAX_STR)) { + lua_pushnumber(L, 0.0); + } else if (!SStrCmpI(key, "farclip", STORM_MAX_STR)) { + lua_pushnumber(L, 177.0); + } else { + lua_pushnil(L); + } + + return 1; } static int32_t Script_GetCVarMax(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarMax(\"cvar\")"); + } + + auto name = lua_tolstring(L, 1, nullptr); + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(name); + if (!cvar || (cvar->m_flags & 0x40)) { + return luaL_error(L, "Couldn't find CVar named '%s'", name); + } + + auto key = cvar->m_key.m_str; + if (!SStrCmpI(key, "extShadowQuality", STORM_MAX_STR)) { + // TODO + lua_pushnumber(L, 1.0); + } else if (!SStrCmpI(key, "farclip", STORM_MAX_STR)) { + lua_pushnumber(L, 1277.0); + } else { + lua_pushnil(L); + } + + return 1; } static int32_t Script_GetCVarAbsoluteMin(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarAbsoluteMin(\"cvar\")"); + } + + auto name = lua_tolstring(L, 1, nullptr); + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(name); + if (!cvar || (cvar->m_flags & 0x40)) { + return luaL_error(L, "Couldn't find CVar named '%s'", name); + } + + auto key = cvar->m_key.m_str; + if (!SStrCmpI(key, "extShadowQuality", STORM_MAX_STR)) { + lua_pushnumber(L, 0.0); + } else { + lua_pushnil(L); + } + + return 1; } static int32_t Script_GetCVarAbsoluteMax(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + if (!lua_isstring(L, 1)) { + return luaL_error(L, "Usage: GetCVarAbsoluteMax(\"cvar\")"); + } + + auto name = lua_tolstring(L, 1, nullptr); + // TODO: Use LookupRegistered + auto cvar = CVar::Lookup(name); + if (!cvar || (cvar->m_flags & 0x40)) { + return luaL_error(L, "Couldn't find CVar named '%s'", name); + } + + auto key = cvar->m_key.m_str; + if (!SStrCmpI(key, "extShadowQuality", STORM_MAX_STR)) { + lua_pushnumber(L, 5.0); + } else { + lua_pushnil(L); + } + + return 1; } static int32_t Script_GetWaterDetail(lua_State* L) { diff --git a/src/sound/SI2.cpp b/src/sound/SI2.cpp index 54d90a2..cc5890f 100644 --- a/src/sound/SI2.cpp +++ b/src/sound/SI2.cpp @@ -30,6 +30,8 @@ void SI2::RegisterScriptFunctions() { } int32_t SI2::Init(int32_t flag) { + SI2::RegisterCVars(); + Log_Init(); SI2_LOG("=> Version %s (%s) %s", "1.0.0", "00000", "Feb 25 2024"); SI2_LOG(" "); diff --git a/src/ui/CSimpleFrameScript.cpp b/src/ui/CSimpleFrameScript.cpp index 2b68e78..65feedd 100644 --- a/src/ui/CSimpleFrameScript.cpp +++ b/src/ui/CSimpleFrameScript.cpp @@ -180,11 +180,58 @@ int32_t CSimpleFrame_HasScript(lua_State* L) { } int32_t CSimpleFrame_GetScript(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + int32_t type = CSimpleFrame::GetObjectType(); + CSimpleFrame* frame = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!lua_isstring(L, 2)) { + return luaL_error(L, "Usage: %s:GetScript(\"type\")", frame->GetDisplayName()); + } + + auto scriptName = lua_tolstring(L, 2, nullptr); + + FrameScript_Object::ScriptData scriptData; + auto script = frame->GetScriptByName(scriptName, scriptData); + if (!script) { + return luaL_error(L, "%s doesn't have a \"%s\" script", frame->GetDisplayName(), scriptName); + } + + // TODO: if (script->unk && lua_taintexpected && !lua_taintedclosure ) + + if (script->luaRef <= 0) { + lua_pushnil(L); + } else { + lua_rawgeti(L, LUA_REGISTRYINDEX, script->luaRef); + } + return 1; } int32_t CSimpleFrame_SetScript(lua_State* L) { + // WARNING: This implementation breaks the client WHOA_UNIMPLEMENTED(0); + + int32_t type = CSimpleFrame::GetObjectType(); + CSimpleFrame* frame = static_cast(FrameScript_GetObjectThis(L, type)); + + if (!lua_isstring(L, 2) || (lua_type(L, 3) != LUA_TFUNCTION && lua_type(L, 3) != LUA_TNIL)) { + return luaL_error(L, "Usage: %s:SetScript(\"type\", function)", frame->GetDisplayName()); + } + + auto scriptName = lua_tolstring(L, 2, nullptr); + + FrameScript_Object::ScriptData scriptData; + auto script = frame->GetScriptByName(scriptName, scriptData); + if (!script) { + return luaL_error(L, "%s doesn't have a \"%s\" script", frame->GetDisplayName(), scriptName); + } + + if (script->luaRef) { + luaL_unref(L, LUA_REGISTRYINDEX, script->luaRef); + } + + auto ref = luaL_ref(L, LUA_REGISTRYINDEX); + script->luaRef = ref <= 0 ? 0 : ref; + // TODO: script->unk = lua_tainted; + return 0; } int32_t CSimpleFrame_HookScript(lua_State* L) { diff --git a/src/ui/CSimpleStatusBar.hpp b/src/ui/CSimpleStatusBar.hpp index e7973b3..a8e1dc6 100644 --- a/src/ui/CSimpleStatusBar.hpp +++ b/src/ui/CSimpleStatusBar.hpp @@ -23,6 +23,9 @@ class CSimpleStatusBar : public CSimpleFrame { virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); // Member variables + float m_minValue = 0.0f; + float m_maxValue = 0.0f; + float m_value = 0.0f; ScriptIx m_onValueChanged; ScriptIx m_onMinMaxChanged; }; diff --git a/src/ui/CSimpleStatusBarScript.cpp b/src/ui/CSimpleStatusBarScript.cpp index 1172af4..50213e9 100644 --- a/src/ui/CSimpleStatusBarScript.cpp +++ b/src/ui/CSimpleStatusBarScript.cpp @@ -12,7 +12,11 @@ static int32_t Script_SetOrientation(lua_State* L) { } static int32_t Script_GetMinMaxValues(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + lua_pushnumber(L, statusBar->m_minValue); + lua_pushnumber(L, statusBar->m_maxValue); + return 2; } static int32_t Script_SetMinMaxValues(lua_State* L) { @@ -20,7 +24,10 @@ static int32_t Script_SetMinMaxValues(lua_State* L) { } static int32_t Script_GetValue(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + lua_pushnumber(L, statusBar->m_value); + return 1; } static int32_t Script_SetValue(lua_State* L) { diff --git a/src/util/Unimplemented.hpp b/src/util/Unimplemented.hpp index 1044889..aee36f8 100644 --- a/src/util/Unimplemented.hpp +++ b/src/util/Unimplemented.hpp @@ -2,10 +2,11 @@ #define UTIL_UNIMPLEMENTED_HPP #include +#include "os/Debug.hpp" -#define WHOA_UNIMPLEMENTED(...) \ - fprintf(stderr, "Function not yet implemented: %s in %s (line %i)\n", __FUNCTION__, __FILE__, __LINE__); \ - return __VA_ARGS__; \ +#define WHOA_UNIMPLEMENTED(...) \ + OsOutputDebugString("Function not yet implemented: %s in %s (line %i)\n", __FUNCTION__, __FILE__, __LINE__); \ + return __VA_ARGS__; \ (void)0 #endif