From fa55a29a930cc8010981fbf6ebe06ec04b33c695 Mon Sep 17 00:00:00 2001 From: VDm Date: Tue, 12 Aug 2025 22:23:22 +0400 Subject: [PATCH 1/3] feat(ui): update CSimpleStatusBar to support texture --- src/ui/CSimpleStatusBar.cpp | 86 +++++++++++++++++++++++++++++++ src/ui/CSimpleStatusBar.hpp | 6 +++ src/ui/CSimpleStatusBarScript.cpp | 81 +++++++++++++++++++++++++++-- 3 files changed, 169 insertions(+), 4 deletions(-) diff --git a/src/ui/CSimpleStatusBar.cpp b/src/ui/CSimpleStatusBar.cpp index 0e9107b..f81c921 100644 --- a/src/ui/CSimpleStatusBar.cpp +++ b/src/ui/CSimpleStatusBar.cpp @@ -1,5 +1,7 @@ #include "ui/CSimpleStatusBar.hpp" #include "ui/CSimpleStatusBarScript.hpp" +#include "ui/CSimpleTexture.hpp" +#include "util/Lua.hpp" int32_t CSimpleStatusBar::s_metatable = 0; int32_t CSimpleStatusBar::s_objectType = 0; @@ -32,6 +34,90 @@ void CSimpleStatusBar::SetOrientation(uint32_t orientation) { this->m_orientation = orientation; } +void CSimpleStatusBar::SetMinMaxValues(float minValue, float maxValue) { + if ((this->m_flags & 2) != 0 && this->m_minValue == minValue && this->m_maxValue == maxValue) { + return; + } + + this->m_flags |= 3; + this->m_minValue = minValue; + this->m_maxValue = maxValue; + this->RunOnMinMaxChanged(); + + if (this->m_flags & 4) { + this->SetValue(this->m_value); + } +} + +void CSimpleStatusBar::SetBarTexture(const char* texFile, int32_t layer) { + if (this->m_barTexture) { + this->m_barTexture->SetTexture(texFile, false, false, GxTex_Linear, ImageMode_UI); + return; + } + + // TODO: CDataAllocator__GetData(CSimpleTexture::s_allocator, 0, ".?AVCSimpleTexture@@", -2); + auto texture = NEW(CSimpleTexture, nullptr, DRAWLAYER_ARTWORK, 0); + if (texture->SetTexture(texFile, false, false, GxTex_Linear, ImageMode_UI)) { + texture->SetAllPoints(this, 1); + texture->SetBlendMode(GxBlend_Add); + this->SetBarTexture(texture, layer); + } else if (texture) { + // TODO: FrameScript_Object::LookupScriptMethod(texture, 1); + } +} + +void CSimpleStatusBar::SetBarTexture(CSimpleTexture* texture, int32_t layer) { + if (texture == this->m_barTexture) { + return; + } + + if (this->m_barTexture) { + // TODO: FrameScript_Object::LookupScriptMethod(this->m_checkedTexture, 1); + } + + if (texture) { + texture->SetFrame(this, layer, 1); + texture->SetPoint(FRAMEPOINT_BOTTOMLEFT, this, FRAMEPOINT_BOTTOMLEFT, 0.0f, 0.0f, 1); + texture->SetPoint(FRAMEPOINT_BOTTOMRIGHT, this, FRAMEPOINT_BOTTOMRIGHT, 0.0f, 0.0f, 1); + texture->SetPoint(FRAMEPOINT_TOPLEFT, this, FRAMEPOINT_TOPLEFT, 0.0f, 0.0f, 1); + texture->SetPoint(FRAMEPOINT_TOPRIGHT, this, FRAMEPOINT_TOPRIGHT, 0.0f, 0.0f, 1); + } + + this->m_flags |= 1; + this->m_barTexture = texture; +} + +void CSimpleStatusBar::RunOnMinMaxChanged() { + if (this->m_onMinMaxChanged.luaRef) { + auto L = FrameScript_GetContext(); + lua_pushnumber(L, this->m_minValue); + lua_pushnumber(L, this->m_maxValue); + this->RunScript(this->m_onMinMaxChanged, 2, 0); + } +} + +void CSimpleStatusBar::RunOnValueChanged() { + if (this->m_onValueChanged.luaRef) { + auto L = FrameScript_GetContext(); + lua_pushnumber(L, this->m_value); + this->RunScript(this->m_onMinMaxChanged, 1, 0); + } +} + +void CSimpleStatusBar::SetValue(float value) { + if ((this->m_flags & 2) == 0) { + return; + } + + value = std::min(value, this->m_maxValue); + value = std::max(value, this->m_minValue); + + if ((this->m_flags & 4) == 0 || this->m_value != value) { + this->m_value = value; + this->RunOnValueChanged(); + } +} + bool CSimpleStatusBar::IsA(int32_t type) { return type == CSimpleStatusBar::s_objectType || type == CSimpleFrame::s_objectType diff --git a/src/ui/CSimpleStatusBar.hpp b/src/ui/CSimpleStatusBar.hpp index 180d831..5aea0c6 100644 --- a/src/ui/CSimpleStatusBar.hpp +++ b/src/ui/CSimpleStatusBar.hpp @@ -17,8 +17,14 @@ class CSimpleStatusBar : public CSimpleFrame { // Member functions CSimpleStatusBar(CSimpleFrame* parent); void SetOrientation(uint32_t orientation); + void SetMinMaxValues(float minValue, float maxValue); + void SetBarTexture(const char* texFile, int32_t layer); + void SetBarTexture(CSimpleTexture* texture, int32_t layer); + void RunOnMinMaxChanged(); + void RunOnValueChanged(); // Virtual member functions + virtual void SetValue(float value); virtual bool IsA(int32_t type); virtual int32_t GetScriptMetaTable(); virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); diff --git a/src/ui/CSimpleStatusBarScript.cpp b/src/ui/CSimpleStatusBarScript.cpp index aacd6a2..9aa2905 100644 --- a/src/ui/CSimpleStatusBarScript.cpp +++ b/src/ui/CSimpleStatusBarScript.cpp @@ -1,5 +1,6 @@ #include "ui/CSimpleStatusBarScript.hpp" #include "ui/CSimpleStatusBar.hpp" +#include "ui/CSimpleTexture.hpp" #include "ui/Util.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" @@ -38,7 +39,22 @@ static int32_t Script_GetMinMaxValues(lua_State* L) { } static int32_t Script_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)) { + return luaL_error(L, "Usage: %s:SetMinMaxValues(min, max)", statusBar->GetDisplayName()); + } + + auto minval = lua_tonumber(L, 2); + auto maxval = lua_tonumber(L, 3); + if (minval < -1.0e12 || minval > 1.0e12 || maxval < -1.0e12 || maxval > 1.0e12) { + return luaL_error(L, "Min or Max out of range"); + } + if (maxval - minval > 1.0e12) { + return luaL_error(L, "Min and Max too far apart"); + } + statusBar->SetMinMaxValues(minval, maxval); + return 0; } static int32_t Script_GetValue(lua_State* L) { @@ -49,15 +65,72 @@ static int32_t Script_GetValue(lua_State* L) { } static int32_t Script_SetValue(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + if (!lua_isnumber(L, 2)) { + return luaL_error(L, "Usage: %s:SetValue(value)", statusBar->GetDisplayName()); + } + + auto value = lua_tonumber(L, 2); + statusBar->SetValue(value); + return 0; } static int32_t Script_GetStatusBarTexture(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + auto texture = statusBar->m_barTexture; + if (texture) { + if (!texture->lua_registered) { + texture->RegisterScriptObject(nullptr); + } + lua_rawgeti(L, LUA_REGISTRYINDEX, texture->lua_objectRef); + } else { + lua_pushnil(L); + } + return 1; } static int32_t Script_SetStatusBarTexture(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + + int32_t layer = 2; + + if (lua_isstring(L, 3)) { + StringToDrawLayer(lua_tolstring(L, 3, nullptr), layer); + } + + if (lua_type(L, 2) == LUA_TTABLE) { + lua_rawgeti(L, 2, 0); + auto texture = static_cast(lua_touserdata(L, -1)); + lua_settop(L, -2); + + if (!texture) { + return luaL_error(L, "%s:SetStatusBarTexture(): Couldn't find 'this' in texture", statusBar->GetDisplayName()); + } else { + auto textureType = CSimpleTexture::GetObjectType(); + if (!texture->IsA(textureType)) { + return luaL_error(L, "%s:SetStatusBarTexture(): Wrong object type, expected texture", statusBar->GetDisplayName()); + } + } + + statusBar->SetBarTexture(texture, layer); + return 0; + } + + if (lua_isstring(L, 2)) { + auto texFile = lua_tostring(L, 2); + statusBar->SetBarTexture(texFile, layer); + return 0; + } + + if (lua_type(L, 2) != LUA_TNIL) { + luaL_error(L, "Usage: %s:SetStatusBarTexture(texture or \"texture\" or nil [, \"layer\"])", statusBar->GetDisplayName()); + } + + statusBar->SetBarTexture(static_cast(nullptr), 2); + return 0; } static int32_t Script_GetStatusBarColor(lua_State* L) { From dbc140d1e4702cdc7a0aa10b74dca93ac83df2fa Mon Sep 17 00:00:00 2001 From: VDm Date: Tue, 12 Aug 2025 23:05:22 +0400 Subject: [PATCH 2/3] feat(ui): implement CSimpleStatusBar::LoadXML --- src/ui/CSimpleStatusBar.cpp | 84 +++++++++++++++++++++++++++++++ src/ui/CSimpleStatusBar.hpp | 3 ++ src/ui/CSimpleStatusBarScript.cpp | 40 +++++++++++++-- 3 files changed, 123 insertions(+), 4 deletions(-) diff --git a/src/ui/CSimpleStatusBar.cpp b/src/ui/CSimpleStatusBar.cpp index f81c921..a26689e 100644 --- a/src/ui/CSimpleStatusBar.cpp +++ b/src/ui/CSimpleStatusBar.cpp @@ -1,7 +1,10 @@ #include "ui/CSimpleStatusBar.hpp" #include "ui/CSimpleStatusBarScript.hpp" #include "ui/CSimpleTexture.hpp" +#include "ui/LoadXML.hpp" #include "util/Lua.hpp" +#include "util/StringTo.hpp" +#include int32_t CSimpleStatusBar::s_metatable = 0; int32_t CSimpleStatusBar::s_objectType = 0; @@ -87,6 +90,24 @@ void CSimpleStatusBar::SetBarTexture(CSimpleTexture* texture, int32_t layer) { this->m_barTexture = texture; } +void CSimpleStatusBar::SetRotatesTexture(bool rotates) { + if (rotates) { + C2Vector v[4] = { + { 0.0f, 1.0f }, + { 1.0f, 1.0f }, + { 0.0f, 0.0f }, + { 1.0f, 0.0f } + }; + + this->m_barTexture->SetTexCoord(v); + this->m_flags = this->m_flags ^ (this->m_flags ^ 8) & 8 | 1; + } else { + CRect r(0.0f, 0.0f, 1.0f, 1.0f); + this->m_barTexture->SetTexCoord(r); + this->m_flags = this->m_flags ^ (this->m_flags ^ 0) & 8 | 1; + } +} + void CSimpleStatusBar::RunOnMinMaxChanged() { if (this->m_onMinMaxChanged.luaRef) { auto L = FrameScript_GetContext(); @@ -118,6 +139,12 @@ void CSimpleStatusBar::SetValue(float value) { } } +void CSimpleStatusBar::SetStatusBarColor(CImVector& color) { + if (this->m_barTexture) { + this->m_barTexture->SetVertexColor(color); + } +} + bool CSimpleStatusBar::IsA(int32_t type) { return type == CSimpleStatusBar::s_objectType || type == CSimpleFrame::s_objectType @@ -148,3 +175,60 @@ FrameScript_Object::ScriptIx* CSimpleStatusBar::GetScriptByName(const char* name return nullptr; } + +void CSimpleStatusBar::LoadXML(XMLNode* node, CStatus* status) { + CSimpleFrame::LoadXML(node, status); + + int32_t layer = 2; + + auto drawLayer = node->GetAttributeByName("drawLayer"); + if (drawLayer && *drawLayer) { + StringToDrawLayer(drawLayer, layer); + } + + for (auto child = node->m_child; child; child = child->m_next) { + if (!SStrCmpI(child->GetName(), "BarTexture", STORM_MAX_STR)) { + auto texture = LoadXML_Texture(child, this, status); + this->SetBarTexture(texture, layer); + } else if (!SStrCmpI(child->GetName(), "BarColor", STORM_MAX_STR)) { + CImVector color; + if (LoadXML_Color(child, color)) { + this->SetStatusBarColor(color); + } + } + } + + auto sminValue = node->GetAttributeByName("minValue"); + auto smaxValue = node->GetAttributeByName("maxValue"); + if (sminValue && *sminValue && smaxValue && *smaxValue) { + auto minValue = SStrToFloat(sminValue); + auto maxValue = SStrToFloat(smaxValue); + 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 sdefValue = node->GetAttributeByName("defaultValue"); + if (sdefValue && *sdefValue) { + this->SetValue(SStrToFloat(sdefValue)); + } + } + + auto sorientation = node->GetAttributeByName("orientation"); + if (sorientation && *sorientation) { + uint32_t orientation; + if (StringToOrientation(sorientation, orientation)) { + this->SetOrientation(orientation); + } else { + status->Add(STATUS_WARNING, "Frame %s: Unknown orientation %s in element %s", this->GetDisplayName(), sorientation, node->GetName()); + } + } + + auto rotatesTexture = node->GetAttributeByName("rotatesTexture"); + if (rotatesTexture && *rotatesTexture) { + this->SetRotatesTexture(StringToBOOL(rotatesTexture)); + } +} diff --git a/src/ui/CSimpleStatusBar.hpp b/src/ui/CSimpleStatusBar.hpp index 5aea0c6..7d6c3ca 100644 --- a/src/ui/CSimpleStatusBar.hpp +++ b/src/ui/CSimpleStatusBar.hpp @@ -20,14 +20,17 @@ class CSimpleStatusBar : public CSimpleFrame { void SetMinMaxValues(float minValue, float maxValue); void SetBarTexture(const char* texFile, int32_t layer); void SetBarTexture(CSimpleTexture* texture, int32_t layer); + void SetRotatesTexture(bool rotates); void RunOnMinMaxChanged(); void RunOnValueChanged(); // Virtual member functions virtual void SetValue(float value); + virtual void SetStatusBarColor(CImVector& color); virtual bool IsA(int32_t type); virtual int32_t GetScriptMetaTable(); virtual ScriptIx* GetScriptByName(const char* name, ScriptData& data); + virtual void LoadXML(XMLNode* node, CStatus* status); // Member variables uint32_t m_flags = 0; diff --git a/src/ui/CSimpleStatusBarScript.cpp b/src/ui/CSimpleStatusBarScript.cpp index 9aa2905..6b86c6b 100644 --- a/src/ui/CSimpleStatusBarScript.cpp +++ b/src/ui/CSimpleStatusBarScript.cpp @@ -134,19 +134,51 @@ static int32_t Script_SetStatusBarTexture(lua_State* L) { } static int32_t Script_GetStatusBarColor(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + auto texture = statusBar->m_barTexture; + + CImVector color; + + if (texture) { + texture->GetVertexColor(color); + } else { + color.Set(1.0f, 1.0f, 1.0f, 1.0f); + } + + lua_pushnumber(L, color.r * 0.00392156); + lua_pushnumber(L, color.g * 0.00392156); + lua_pushnumber(L, color.b * 0.00392156); + lua_pushnumber(L, color.a * 0.00392156); + return 4; } static int32_t Script_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; } static int32_t Script_GetRotatesTexture(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + if (statusBar->m_flags & 8) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } static int32_t Script_SetRotatesTexture(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleStatusBar::GetObjectType(); + auto statusBar = static_cast(FrameScript_GetObjectThis(L, type)); + statusBar->SetRotatesTexture(StringToBOOL(L, 2, 0)); + return 0; } From 9d2b94b0cdc5e5638a579419f65fb601401a511f Mon Sep 17 00:00:00 2001 From: VDm Date: Wed, 13 Aug 2025 01:17:15 +0400 Subject: [PATCH 3/3] fix(ui): eliminate script errors --- src/gameui/CGTooltipScript.cpp | 34 +++++++++++++++++-- src/gameui/GameScriptFunctions.cpp | 15 ++++---- .../GameScriptFunctionsBattlefieldInfo.cpp | 3 +- .../GameScriptFunctionsCharacterInfo.cpp | 9 ++++- .../GameScriptFunctionsScriptEvents.cpp | 4 ++- src/ui/CScriptRegion.cpp | 4 +++ src/ui/CScriptRegion.hpp | 1 + src/ui/CScriptRegionScript.cpp | 18 +++++++++- src/ui/CSimpleButtonScript.cpp | 5 ++- src/ui/CSimpleFontStringScript.cpp | 18 ++++++++-- src/ui/CSimpleTextureScript.cpp | 26 +++++++++++--- src/ui/LuaExtraFuncs.cpp | 4 ++- 12 files changed, 121 insertions(+), 20 deletions(-) diff --git a/src/gameui/CGTooltipScript.cpp b/src/gameui/CGTooltipScript.cpp index a9482ae..a26a188 100644 --- a/src/gameui/CGTooltipScript.cpp +++ b/src/gameui/CGTooltipScript.cpp @@ -1,4 +1,5 @@ #include "gameui/CGTooltipScript.hpp" +#include "gameui/CGTooltip.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" @@ -23,11 +24,40 @@ static int32_t Script_GetPadding(lua_State* L) { } static int32_t Script_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) { + return luaL_error(L, "Usage: %s:IsOwned(frame)", tooltip->GetDisplayName()); + } + + lua_rawgeti(L, 2, 0); + auto frame = static_cast(lua_touserdata(L, -1)); + lua_settop(L, -2); + + if (!frame) { + return luaL_error(L, "%s:IsOwned(): Couldn't find 'this' in frame object", tooltip->GetDisplayName()); + } + + if (!frame->IsA(CSimpleFrame::GetObjectType())) { + return luaL_error(L, "%s:IsOwned(): Wrong object type, expected frame", tooltip->GetDisplayName()); + } + + if (tooltip->m_parent == frame) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } static int32_t Script_GetOwner(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CGTooltip::GetObjectType(); + auto tooltip = static_cast(FrameScript_GetObjectThis(L, type)); + + // TODO + lua_pushnil(L); + return 1; } static int32_t Script_SetOwner(lua_State* L) { diff --git a/src/gameui/GameScriptFunctions.cpp b/src/gameui/GameScriptFunctions.cpp index 1dc6fe3..614d3b9 100644 --- a/src/gameui/GameScriptFunctions.cpp +++ b/src/gameui/GameScriptFunctions.cpp @@ -20,6 +20,7 @@ void RegisterSimpleFrameScriptMethods(); int32_t Script_GetScreenWidth(lua_State* L); int32_t Script_GetScreenHeight(lua_State* L); +int32_t Script_GetCursorPosition(lua_State* L); static int32_t Script_FrameXML_Debug(lua_State* L) { @@ -741,10 +742,6 @@ static int32_t Script_CancelSummon(lua_State* L) { WHOA_UNIMPLEMENTED(0); } -static int32_t Script_GetCursorPosition(lua_State* L) { - WHOA_UNIMPLEMENTED(0); -} - static int32_t Script_GetNetStats(lua_State* L) { // v1 = ClientServices__Connection(); // NetClient__GetNetStats(v1, &v5, &v4, (int*)&v3); @@ -1153,11 +1150,17 @@ static int32_t Script_IsAddOnLoadOnDemand(lua_State* L) { } static int32_t Script_IsAddOnLoaded(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + lua_pushnil(L); + return 2; } static int32_t Script_LoadAddOn(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + lua_pushstring(L, "UNKNOWN_ERROR"); + return 2; } static int32_t Script_PartialPlayTime(lua_State* L) { diff --git a/src/gameui/scripts/GameScriptFunctionsBattlefieldInfo.cpp b/src/gameui/scripts/GameScriptFunctionsBattlefieldInfo.cpp index 34476c0..7931aaf 100644 --- a/src/gameui/scripts/GameScriptFunctionsBattlefieldInfo.cpp +++ b/src/gameui/scripts/GameScriptFunctionsBattlefieldInfo.cpp @@ -105,7 +105,8 @@ static int32_t Script_GetBattlefieldStatData(lua_State* L) { } static int32_t Script_RequestBattlefieldPositions(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO: sub_54CF60 + return 0; } static int32_t Script_GetNumBattlefieldPositions(lua_State* L) { diff --git a/src/gameui/scripts/GameScriptFunctionsCharacterInfo.cpp b/src/gameui/scripts/GameScriptFunctionsCharacterInfo.cpp index 5110dd3..165627d 100644 --- a/src/gameui/scripts/GameScriptFunctionsCharacterInfo.cpp +++ b/src/gameui/scripts/GameScriptFunctionsCharacterInfo.cpp @@ -161,7 +161,14 @@ static int32_t Script_ClearInspectPlayer(lua_State* L) { } static int32_t Script_GetWeaponEnchantInfo(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + lua_pushnil(L); + return 6; } static int32_t Script_HasWandEquipped(lua_State* L) { diff --git a/src/gameui/scripts/GameScriptFunctionsScriptEvents.cpp b/src/gameui/scripts/GameScriptFunctionsScriptEvents.cpp index 7174dd2..e9224d4 100644 --- a/src/gameui/scripts/GameScriptFunctionsScriptEvents.cpp +++ b/src/gameui/scripts/GameScriptFunctionsScriptEvents.cpp @@ -257,7 +257,9 @@ static int32_t Script_UnitIsDeadOrGhost(lua_State* L) { } static int32_t Script_UnitIsConnected(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + return 1; } static int32_t Script_UnitAffectingCombat(lua_State* L) { diff --git a/src/ui/CScriptRegion.cpp b/src/ui/CScriptRegion.cpp index 6fe36be..19facee 100644 --- a/src/ui/CScriptRegion.cpp +++ b/src/ui/CScriptRegion.cpp @@ -64,6 +64,10 @@ bool CScriptRegion::IsDragging() { return false; } +bool CScriptRegion::IsMouseOver(float a1, float a2, float a3, float a4) { + return false; +} + void CScriptRegion::LoadXML(XMLNode* node, CStatus* status) { CLayoutFrame::LoadXML(node, status); diff --git a/src/ui/CScriptRegion.hpp b/src/ui/CScriptRegion.hpp index fc68977..2714d37 100644 --- a/src/ui/CScriptRegion.hpp +++ b/src/ui/CScriptRegion.hpp @@ -29,6 +29,7 @@ class CScriptRegion : public CScriptObject, public CLayoutFrame { virtual bool IsA(const char* typeName); virtual const char* GetObjectTypeName(); virtual bool IsDragging(); + virtual bool IsMouseOver(float a1, float a2, float a3, float a4); virtual void PreOnAnimUpdate() {}; virtual void OnLayerUpdate(float elapsedSec); virtual void NotifyAnimBegin(CSimpleAnimGroup* animGroup); diff --git a/src/ui/CScriptRegionScript.cpp b/src/ui/CScriptRegionScript.cpp index ff56269..5abcd14 100644 --- a/src/ui/CScriptRegionScript.cpp +++ b/src/ui/CScriptRegionScript.cpp @@ -518,7 +518,23 @@ int32_t CScriptRegion_IsDragging(lua_State* L) { } int32_t CScriptRegion_IsMouseOver(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + int32_t type = CScriptRegion::GetObjectType(); + auto region = static_cast(FrameScript_GetObjectThis(L, type)); + + float rect[4]; + for (int32_t i = 0; i < 4; ++i) { + if (lua_isnumber(L, i + 2)) { + rect[i] = lua_tonumber(L, i + 2); + rect[i] /= CoordinateGetAspectCompensation() * 1024.0f; + rect[i] = NDCToDDCWidth(rect[i]); + } else { + rect[i] = 0.0f; + } + } + + auto result = region->IsMouseOver(rect[0], rect[1], rect[2], rect[3]); + lua_pushboolean(L, result); + return 1; } FrameScript_Method ScriptRegionMethods[NUM_SCRIPT_REGION_SCRIPT_METHODS] = { diff --git a/src/ui/CSimpleButtonScript.cpp b/src/ui/CSimpleButtonScript.cpp index 8010475..2fa05fc 100644 --- a/src/ui/CSimpleButtonScript.cpp +++ b/src/ui/CSimpleButtonScript.cpp @@ -71,7 +71,10 @@ int32_t CSimpleButton_Disable(lua_State* L) { } int32_t CSimpleButton_IsEnabled(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleButton::GetObjectType(); + auto button = static_cast(FrameScript_GetObjectThis(L, type)); + lua_pushnumber(L, button->GetButtonState() != BUTTONSTATE_DISABLED); + return 1; } int32_t CSimpleButton_GetButtonState(lua_State* L) { diff --git a/src/ui/CSimpleFontStringScript.cpp b/src/ui/CSimpleFontStringScript.cpp index f7b5594..0032ef2 100644 --- a/src/ui/CSimpleFontStringScript.cpp +++ b/src/ui/CSimpleFontStringScript.cpp @@ -56,11 +56,25 @@ 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->m_visible) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } int32_t CSimpleFontString_IsShown(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleFontString::GetObjectType(); + auto string = static_cast(FrameScript_GetObjectThis(L, type)); + if (string->m_shown) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } int32_t CSimpleFontString_GetFontObject(lua_State* L) { diff --git a/src/ui/CSimpleTextureScript.cpp b/src/ui/CSimpleTextureScript.cpp index c5536db..b1ecc61 100644 --- a/src/ui/CSimpleTextureScript.cpp +++ b/src/ui/CSimpleTextureScript.cpp @@ -96,11 +96,25 @@ 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->m_visible) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } int32_t CSimpleTexture_IsShown(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + auto type = CSimpleTexture::GetObjectType(); + auto texture = static_cast(FrameScript_GetObjectThis(L, type)); + if (texture->m_shown) { + lua_pushnumber(L, 1.0); + } else { + lua_pushnil(L); + } + return 1; } int32_t CSimpleTexture_GetTexture(lua_State* L) { @@ -211,11 +225,15 @@ int32_t CSimpleTexture_SetRotation(lua_State* L) { } int32_t CSimpleTexture_SetDesaturated(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + return 1; } int32_t CSimpleTexture_IsDesaturated(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + return 1; } int32_t CSimpleTexture_SetNonBlocking(lua_State* L) { diff --git a/src/ui/LuaExtraFuncs.cpp b/src/ui/LuaExtraFuncs.cpp index 9bde9ef..4720a7b 100644 --- a/src/ui/LuaExtraFuncs.cpp +++ b/src/ui/LuaExtraFuncs.cpp @@ -106,7 +106,9 @@ int32_t strlenutf8(lua_State* L) { } int32_t issecure(lua_State* L) { - WHOA_UNIMPLEMENTED(0); + // TODO + lua_pushnil(L); + return 1; } int32_t issecurevariable(lua_State* L) {