mirror of
https://github.com/Kelsidavis/WoWee.git
synced 2026-03-22 23:30:14 +00:00
feat: add quest objective leaderboard API for WatchFrame quest tracking
Implement GetNumQuestLeaderBoards and GetQuestLogLeaderBoard — the core
functions WatchFrame.lua and QuestLogFrame.lua use to display objective
progress like "Kobold Vermin slain: 3/8" or "Linen Cloth: 2/6".
GetNumQuestLeaderBoards counts kill + item objectives from the parsed
SMSG_QUEST_QUERY_RESPONSE data. GetQuestLogLeaderBoard returns the
formatted progress text, type ("monster"/"item"/"object"), and
completion status for each objective.
Also adds ExpandQuestHeader/CollapseQuestHeader (no-ops for flat quest
list) and GetQuestLogSpecialItemInfo stub.
This commit is contained in:
parent
296121f5e7
commit
cbdf03c07e
1 changed files with 90 additions and 0 deletions
|
|
@ -2371,6 +2371,91 @@ static int lua_GetQuestLink(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
// GetNumQuestLeaderBoards(questLogIndex) → count of objectives
|
||||
static int lua_GetNumQuestLeaderBoards(lua_State* L) {
|
||||
auto* gh = getGameHandler(L);
|
||||
int index = static_cast<int>(luaL_checknumber(L, 1));
|
||||
if (!gh || index < 1) { lua_pushnumber(L, 0); return 1; }
|
||||
const auto& ql = gh->getQuestLog();
|
||||
if (index > static_cast<int>(ql.size())) { lua_pushnumber(L, 0); return 1; }
|
||||
const auto& q = ql[index - 1];
|
||||
int count = 0;
|
||||
for (const auto& ko : q.killObjectives) {
|
||||
if (ko.npcOrGoId != 0 || ko.required > 0) ++count;
|
||||
}
|
||||
for (const auto& io : q.itemObjectives) {
|
||||
if (io.itemId != 0 || io.required > 0) ++count;
|
||||
}
|
||||
lua_pushnumber(L, count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// GetQuestLogLeaderBoard(objIndex, questLogIndex) → text, type, finished
|
||||
// objIndex is 1-based within the quest's objectives
|
||||
static int lua_GetQuestLogLeaderBoard(lua_State* L) {
|
||||
auto* gh = getGameHandler(L);
|
||||
int objIdx = static_cast<int>(luaL_checknumber(L, 1));
|
||||
int questIdx = static_cast<int>(luaL_optnumber(L, 2,
|
||||
gh ? gh->getSelectedQuestLogIndex() : 0));
|
||||
if (!gh || questIdx < 1 || objIdx < 1) { lua_pushnil(L); return 1; }
|
||||
const auto& ql = gh->getQuestLog();
|
||||
if (questIdx > static_cast<int>(ql.size())) { lua_pushnil(L); return 1; }
|
||||
const auto& q = ql[questIdx - 1];
|
||||
|
||||
// Build ordered list: kill objectives first, then item objectives
|
||||
int cur = 0;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
if (q.killObjectives[i].npcOrGoId == 0 && q.killObjectives[i].required == 0) continue;
|
||||
++cur;
|
||||
if (cur == objIdx) {
|
||||
// Get current count from killCounts map (keyed by abs(npcOrGoId))
|
||||
uint32_t key = static_cast<uint32_t>(std::abs(q.killObjectives[i].npcOrGoId));
|
||||
uint32_t current = 0;
|
||||
auto it = q.killCounts.find(key);
|
||||
if (it != q.killCounts.end()) current = it->second.first;
|
||||
uint32_t required = q.killObjectives[i].required;
|
||||
bool finished = (current >= required);
|
||||
// Build display text like "Kobold Vermin slain: 3/8"
|
||||
std::string text = (q.killObjectives[i].npcOrGoId < 0 ? "Object" : "Creature")
|
||||
+ std::string(" slain: ") + std::to_string(current) + "/" + std::to_string(required);
|
||||
lua_pushstring(L, text.c_str());
|
||||
lua_pushstring(L, q.killObjectives[i].npcOrGoId < 0 ? "object" : "monster");
|
||||
lua_pushboolean(L, finished ? 1 : 0);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
if (q.itemObjectives[i].itemId == 0 && q.itemObjectives[i].required == 0) continue;
|
||||
++cur;
|
||||
if (cur == objIdx) {
|
||||
uint32_t current = 0;
|
||||
auto it = q.itemCounts.find(q.itemObjectives[i].itemId);
|
||||
if (it != q.itemCounts.end()) current = it->second;
|
||||
uint32_t required = q.itemObjectives[i].required;
|
||||
bool finished = (current >= required);
|
||||
// Get item name if available
|
||||
std::string itemName;
|
||||
const auto* info = gh->getItemInfo(q.itemObjectives[i].itemId);
|
||||
if (info && !info->name.empty()) itemName = info->name;
|
||||
else itemName = "Item #" + std::to_string(q.itemObjectives[i].itemId);
|
||||
std::string text = itemName + ": " + std::to_string(current) + "/" + std::to_string(required);
|
||||
lua_pushstring(L, text.c_str());
|
||||
lua_pushstring(L, "item");
|
||||
lua_pushboolean(L, finished ? 1 : 0);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// ExpandQuestHeader / CollapseQuestHeader — no-ops (flat quest list, no headers)
|
||||
static int lua_ExpandQuestHeader(lua_State* L) { (void)L; return 0; }
|
||||
static int lua_CollapseQuestHeader(lua_State* L) { (void)L; return 0; }
|
||||
|
||||
// GetQuestLogSpecialItemInfo(questLogIndex) — returns nil (no special items)
|
||||
static int lua_GetQuestLogSpecialItemInfo(lua_State* L) { (void)L; lua_pushnil(L); return 1; }
|
||||
|
||||
// --- Skill Line API ---
|
||||
|
||||
// GetNumSkillLines() → count
|
||||
|
|
@ -4142,6 +4227,11 @@ void LuaEngine::registerCoreAPI() {
|
|||
{"RemoveQuestWatch", lua_RemoveQuestWatch},
|
||||
{"IsQuestWatched", lua_IsQuestWatched},
|
||||
{"GetQuestLink", lua_GetQuestLink},
|
||||
{"GetNumQuestLeaderBoards", lua_GetNumQuestLeaderBoards},
|
||||
{"GetQuestLogLeaderBoard", lua_GetQuestLogLeaderBoard},
|
||||
{"ExpandQuestHeader", lua_ExpandQuestHeader},
|
||||
{"CollapseQuestHeader", lua_CollapseQuestHeader},
|
||||
{"GetQuestLogSpecialItemInfo", lua_GetQuestLogSpecialItemInfo},
|
||||
// Skill line API
|
||||
{"GetNumSkillLines", lua_GetNumSkillLines},
|
||||
{"GetSkillLineInfo", lua_GetSkillLineInfo},
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue