Files
2026-08-16 20:28:28 -05:00

209 lines
7.2 KiB
Lua

QuestieOcto.API = QuestieOcto.API or {}
local A = QuestieOcto.API
A.valid = false
A.missing = {}
A.optional = {}
local function Has(tableValue, functionName)
return tableValue and type(tableValue[functionName])=="function"
end
function A:Validate()
self.missing = {}
local required = {
{ "C_QuestLog.GetQuestIDForLogIndex", C_QuestLog, "GetQuestIDForLogIndex" },
{ "C_QuestLog.GetLogIndexForQuestID", C_QuestLog, "GetLogIndexForQuestID" },
{ "C_QuestLog.IsOnQuest", C_QuestLog, "IsOnQuest" },
{ "C_Map.GetBestMapForUnit", C_Map, "GetBestMapForUnit" },
{ "C_GossipInfo.GetAvailableQuests", C_GossipInfo, "GetAvailableQuests" },
{ "C_CreatureInfo.GetCreatureID", C_CreatureInfo, "GetCreatureID" },
{ "C_GameObjectInfo.GetGameObjectInfoByID", C_GameObjectInfo, "GetGameObjectInfoByID" },
{ "C_Item.GetItemNameByID", C_Item, "GetItemNameByID" },
}
for _,req in pairs(required) do
if not Has(req[2],req[3]) then table.insert(self.missing,req[1]) end
end
self.valid = table.getn(self.missing)==0
self.optional = {
coroutines = coroutine and type(coroutine.create)=="function",
hooksecurefunc = type(hooksecurefunc)=="function",
tooltipUnit = GameTooltip and type(GameTooltip.GetUnitGUID)=="function",
tooltipObject = GameTooltip and type(GameTooltip.GetGameObject)=="function",
tooltipItem = GameTooltip and type(GameTooltip.GetItem)=="function",
gossipActive = Has(C_GossipInfo,"GetActiveQuests"),
questDetails = Has(C_QuestLog,"GetQuestDetails"),
questObjectives = Has(C_QuestLog,"GetQuestObjectives"),
questsCompleted = type(GetQuestsCompleted)=="function" or Has(C_QuestLog,"GetQuestsCompleted"),
queryQuestsCompleted = type(QueryQuestsCompleted)=="function",
questFlaggedCompleted = type(IsQuestFlaggedCompleted)=="function" or Has(C_QuestLog,"IsQuestFlaggedCompleted"),
mapWorldSize = Has(C_Map,"GetMapWorldSize"),
instanceInfo = type(GetInstanceInfo)=="function",
leaderboardObjectiveID = type(GetQuestLogLeaderBoardID)=="function",
areaTriggerInfo = Has(C_Map,"GetAreaTriggerInfo"),
}
return self.valid
end
function A:GetQuestIDForLogIndex(index)
if not self.valid then return nil end
return C_QuestLog.GetQuestIDForLogIndex(index)
end
-- Questie-facing normalized quest-log info.
--
-- Questie 5.2.3/6.0.0 and Questie 3.3.5 all consume the normalized fields
-- title, level, tag, isHeader, isCollapsed, isComplete, frequency, questID.
--
-- The raw client signature differs by expansion. For our actual target
-- Interface 11200, the supplied pfQuest Vanilla compatibility layer confirms:
-- title, level, tag, isHeader, isCollapsed, isComplete = GetQuestLogTitle(index)
-- There is NO suggestedGroup return on Vanilla 1.12.
--
-- Questie 3.3.5's raw suggestedGroup handling is a WotLK-era compatibility
-- detail, so applying it directly to Turtle 11200 shifts completion by one
-- field and makes completed quests look incomplete.
function A:GetQuestLogInfo(index)
if not GetQuestLogTitle then return nil end
local _,_,_,client=GetBuildInfo()
client=tonumber(client) or 11200
local title,level,tag,isHeader,isCollapsed,isComplete,isDaily,rawQuestID
if client<=11200 then
title,level,tag,isHeader,isCollapsed,isComplete=GetQuestLogTitle(index)
else
local suggestedGroup
title,level,tag,suggestedGroup,isHeader,isCollapsed,isComplete,isDaily,rawQuestID=GetQuestLogTitle(index)
end
local questID=self:GetQuestIDForLogIndex(index) or tonumber(rawQuestID)
return {
title=title,
level=level,
tag=tag,
isHeader=isHeader and true or false,
isCollapsed=isCollapsed and true or false,
isComplete=isComplete,
isDaily=isDaily,
questID=questID
}
end
function A:GetLogIndexForQuestID(questID)
if not self.valid then return nil end
return C_QuestLog.GetLogIndexForQuestID(questID)
end
function A:IsOnQuest(questID)
if not self.valid then return false end
return C_QuestLog.IsOnQuest(questID) and true or false
end
function A:GetBestMapForPlayer()
if not self.valid then return nil end
return C_Map.GetBestMapForUnit("player")
end
-- ClassicAPI backports the modern GetInstanceInfo() tuple to Vanilla 1.12.
-- Keep instance classification behind the API contract instead of teaching
-- presentation modules about DLL/global availability details.
function A:GetInstanceType()
if type(GetInstanceInfo)~="function" then return "none" end
local ok,name,instanceType=pcall(GetInstanceInfo)
if not ok or type(instanceType)~="string" then return "none" end
return instanceType
end
function A:IsInDungeonOrRaid()
local instanceType=self:GetInstanceType()
return instanceType=="party" or instanceType=="raid"
end
-- pfQuest-classicAPI resolves quest-bound exploration objectives directly from
-- ClassicAPI's AreaTrigger.dbc bridge. Keep this behind the API contract so
-- generic map code never needs to know whether the DLL/global exists.
function A:GetAreaTriggerInfo(areaTriggerID)
areaTriggerID=tonumber(areaTriggerID)
if not areaTriggerID or not C_Map or type(C_Map.GetAreaTriggerInfo)~="function" then return nil end
local ok,info=pcall(C_Map.GetAreaTriggerInfo,areaTriggerID)
if not ok or type(info)~="table" then return nil end
local mapID=tonumber(info.areaID)
local x=tonumber(info.mapX)
local y=tonumber(info.mapY)
if not mapID or not x or not y then return nil end
return {
id=areaTriggerID,
areaID=mapID,
mapX=x,
mapY=y
}
end
function A:GetQuestLogLeaderBoardID(objectiveIndex,questLogIndex)
if type(GetQuestLogLeaderBoardID)~="function" then return nil end
local ok,id=pcall(GetQuestLogLeaderBoardID,objectiveIndex,questLogIndex)
if not ok then return nil end
return tonumber(id)
end
function A:GetQuestObjectives(questID,questLogIndex)
if C_QuestLog and type(C_QuestLog.GetQuestObjectives)=="function" then
-- Questie 3.3.5's Vanilla compatibility implementation accepts the log
-- index as a second argument; modern-style implementations ignore extras.
return C_QuestLog.GetQuestObjectives(questID,questLogIndex)
end
return nil
end
function A:QueryQuestsCompleted()
if type(QueryQuestsCompleted)~="function" then return false end
local ok=pcall(QueryQuestsCompleted)
return ok and true or false
end
function A:GetQuestsCompleted()
if type(GetQuestsCompleted)=="function" then
local ok,result=pcall(GetQuestsCompleted)
if ok and type(result)=="table" then return result end
-- Some compatibility layers use the older "fill table" form.
local target={}
ok=pcall(GetQuestsCompleted,target)
if ok and next(target) then return target end
end
if C_QuestLog and type(C_QuestLog.GetQuestsCompleted)=="function" then
local ok,result=pcall(C_QuestLog.GetQuestsCompleted)
if ok and type(result)=="table" then return result end
end
return nil
end
function A:IsQuestFlaggedCompleted(questID)
if type(IsQuestFlaggedCompleted)=="function" then
local ok,result=pcall(IsQuestFlaggedCompleted,questID)
if ok then return result and true or false end
end
if C_QuestLog and type(C_QuestLog.IsQuestFlaggedCompleted)=="function" then
local ok,result=pcall(C_QuestLog.IsQuestFlaggedCompleted,questID)
if ok then return result and true or false end
end
return nil
end