diff --git a/src/glue/CRealmList.cpp b/src/glue/CRealmList.cpp index 4e8c51c..1952faa 100644 --- a/src/glue/CRealmList.cpp +++ b/src/glue/CRealmList.cpp @@ -26,6 +26,93 @@ void CRealmList::Initialize() { // TODO Initialize CRealmList::s_sortCriteria } +void CRealmList::SetPreferredInfo(uint32_t categoryIndex, int32_t pvp, int32_t rp) { + if (CRealmList::s_categories.Count() == 0) { + return; + } + + auto selectedCategory = CRealmList::Sub4DE910(categoryIndex - 1); + if (selectedCategory > CRealmList::s_categories.Count()) { + selectedCategory = 0; + } + + CRealmList::s_selectedCategory = static_cast(selectedCategory); + CRealmList::s_preferredCategory = CRealmList::s_categories[selectedCategory]->m_category->GetID(); + + auto realmCategory = CRealmList::s_categories[selectedCategory]; + int32_t realmId = -1; + + // Attempt to find realm that matches selected category and pvp / rp type + for (int32_t i = 0; i < realmCategory->uint14; i++) { + auto realmIndex = static_cast(realmCategory->m_realms[i]); + auto realmInfo = ClientServices::GetRealmInfoByIndex(realmIndex); + + // 0x1 - INVALID, 0x2 - OFFLINE + if (realmInfo->flags & (0x1 | 0x2)) { + continue; + } + + // 0x20 - FORCE_RECOMMENDED + if (realmInfo->flags & 0x20) { + realmId = i + 1; + break; + } + + // Look up realm pvp / rp type based on realm type + int32_t realmIsPvp = 0; + int32_t realmIsRp = 0; + for (int32_t j = 0; j < g_cfg_ConfigsDB.m_numRecords; j++) { + auto config = g_cfg_ConfigsDB.GetRecordByIndex(j); + + if (config->m_realmType == realmInfo->type) { + realmIsPvp = config->m_playerKillingAllowed != 0; + realmIsRp = config->m_roleplaying != 0; + break; + } + } + + if (pvp == realmIsPvp && rp == realmIsRp) { + realmId = i + 1; + + // 0x80 - FORCE_FULL + if (!(realmInfo->flags & 0x80)) { + break; + } + } + } + + // No match found for selected category and pvp / rp type + if (realmId == -1) { + FrameScript_SignalEvent(9, nullptr); + return; + } + + FrameScript_SignalEvent(18, "%d%d", categoryIndex, realmId); +} + +uint32_t CRealmList::Sub4DE910(uint32_t a1) { + if (CRealmList::s_categories.Count() == 0) { + return 0; + } + + int32_t v1 = -1; + + uint32_t i; + for (i = 0; i < CRealmList::s_categories.Count(); i++) { + auto realmCategory = CRealmList::s_categories[i]; + + if (realmCategory && realmCategory->uint14 > 0) { + v1++; + + if (v1 == a1) { + break; + } + } + } + + return i; +} + void CRealmList::UpdateList() { CRealmList::s_avgLoad = 0.0f; int32_t category = -1; diff --git a/src/glue/CRealmList.hpp b/src/glue/CRealmList.hpp index 35ad34d..bb7e9e1 100644 --- a/src/glue/CRealmList.hpp +++ b/src/glue/CRealmList.hpp @@ -22,6 +22,8 @@ class CRealmList { // Static functions static void Initialize(); + static void SetPreferredInfo(uint32_t index, int32_t pvp, int32_t rp); + static uint32_t Sub4DE910(uint32_t a1); static void UpdateList(); }; diff --git a/src/ui/ScriptFunctionsRealmList.cpp b/src/ui/ScriptFunctionsRealmList.cpp index 59bc1ce..52f7b5c 100644 --- a/src/ui/ScriptFunctionsRealmList.cpp +++ b/src/ui/ScriptFunctionsRealmList.cpp @@ -1,4 +1,6 @@ #include "ui/ScriptFunctions.hpp" +#include "glue/CRealmList.hpp" +#include "util/StringTo.hpp" #include "ui/Types.hpp" #include "util/Lua.hpp" #include "util/Unimplemented.hpp" @@ -33,7 +35,17 @@ int32_t Script_GetRealmCategories(lua_State* L) { } int32_t Script_SetPreferredInfo(lua_State* L) { - WHOA_UNIMPLEMENTED(); + if (!lua_isnumber(L, 1)) { + return luaL_error(L, "Usage: SetPreferredInfo(index, pvp, rp)"); + } + + uint32_t index = lua_tonumber(L, 1); + int32_t pvp = StringToBOOL(L, 2, 0); + int32_t rp = StringToBOOL(L, 3, 0); + + CRealmList::SetPreferredInfo(index, pvp, rp); + + return 0; } int32_t Script_SortRealms(lua_State* L) {