mirror of
https://github.com/Blaststar/Questie-Octo-Vanilla.git
synced 2026-10-19 20:00:49 +00:00
218 lines
6.6 KiB
Lua
218 lines
6.6 KiB
Lua
-- Right-click quest menu, rendered with the native Vanilla UIDropDownMenu so it
|
|
-- matches Blizzard/Titan context menus (submenu arrows, checks, highlight).
|
|
QuestieOcto.QuestMenu = QuestieOcto.QuestMenu or {}
|
|
local QM = QuestieOcto.QuestMenu
|
|
|
|
local function DB()
|
|
QuestieOctoDB=QuestieOctoDB or {}
|
|
QuestieOctoDB.questMenu=QuestieOctoDB.questMenu or {}
|
|
local d=QuestieOctoDB.questMenu
|
|
d.hiddenObjectives=d.hiddenObjectives or {}
|
|
d.hiddenQuests=d.hiddenQuests or {}
|
|
return d
|
|
end
|
|
|
|
local function ObjectiveKey(questID,objIndex)
|
|
return tostring(questID).." "..tostring(objIndex)
|
|
end
|
|
|
|
local function IsObjectiveRole(role)
|
|
return role=="objectiveCreature" or role=="objectiveObject" or role=="objectiveItemSource"
|
|
end
|
|
|
|
-- State queries -------------------------------------------------------------
|
|
|
|
function QM:IsQuestHidden(questID)
|
|
return DB().hiddenQuests[tonumber(questID)] and true or false
|
|
end
|
|
|
|
function QM:IsObjectiveHidden(questID,objIndex)
|
|
return DB().hiddenObjectives[ObjectiveKey(questID,objIndex)] and true or false
|
|
end
|
|
|
|
function QM:GetFocus()
|
|
local f=DB().focus
|
|
if type(f)~="string" then return nil,nil end
|
|
local _,_,qid,oi=string.find(f,"^(%d+) (%d+)$")
|
|
return tonumber(qid),tonumber(oi)
|
|
end
|
|
|
|
function QM:IsFocused(questID,objIndex)
|
|
local fq,fo=self:GetFocus()
|
|
return fq==tonumber(questID) and fo==tonumber(objIndex)
|
|
end
|
|
|
|
-- A node is hidden when its whole quest is hidden (objective nodes only) or when
|
|
-- its specific objective is hidden.
|
|
function QM:IsNodeHidden(node)
|
|
if not node then return false end
|
|
local qid=tonumber(node.questID)
|
|
if not qid or qid<=0 then return false end
|
|
if IsObjectiveRole(node.role) then
|
|
if self:IsQuestHidden(qid) then return true end
|
|
local oi=tonumber(node.objectiveIndex)
|
|
if oi and self:IsObjectiveHidden(qid,oi) then return true end
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Toggles -------------------------------------------------------------------
|
|
|
|
function QM:RefreshMaps()
|
|
if QuestieOcto.Minimap and QuestieOcto.Minimap.RefreshVisualSettings then
|
|
QuestieOcto.Minimap:RefreshVisualSettings()
|
|
end
|
|
if QuestieOcto.Map and QuestieOcto.Map.RequestSync then
|
|
QuestieOcto.Map:RequestSync(true)
|
|
end
|
|
end
|
|
|
|
function QM:ToggleFocus(questID,objIndex)
|
|
local d=DB()
|
|
if self:IsFocused(questID,objIndex) then
|
|
d.focus=nil
|
|
else
|
|
d.focus=ObjectiveKey(questID,objIndex)
|
|
end
|
|
end
|
|
|
|
function QM:ToggleObjectiveHidden(questID,objIndex)
|
|
local d=DB()
|
|
local key=ObjectiveKey(questID,objIndex)
|
|
d.hiddenObjectives[key]=(not d.hiddenObjectives[key]) or nil
|
|
self:RefreshMaps()
|
|
end
|
|
|
|
function QM:ToggleQuestHidden(questID)
|
|
local d=DB()
|
|
questID=tonumber(questID)
|
|
d.hiddenQuests[questID]=(not d.hiddenQuests[questID]) or nil
|
|
self:RefreshMaps()
|
|
end
|
|
|
|
-- Menu data -----------------------------------------------------------------
|
|
|
|
local function ObjectiveName(q,row)
|
|
local defs=q and q.objectiveData or nil
|
|
local def=defs and row.dataIndex and defs[tonumber(row.dataIndex)] or nil
|
|
if def and def.id then
|
|
if def.kind=="creature" then return QuestieOcto.DatabaseAPI:GetCreatureName(def.id) end
|
|
if def.kind=="gameObject" then return QuestieOcto.DatabaseAPI:GetObjectName(def.id) end
|
|
if def.kind=="item" then return QuestieOcto.DatabaseAPI:GetItemName(def.id) end
|
|
end
|
|
local text=row.rawText or row.text or ""
|
|
local stripped=string.gsub(text,"%s*:?%s*%d+%s*/%s*%d+%s*$","")
|
|
-- Drop a trailing objective verb (e.g. "... slain") so only the name remains.
|
|
local nameOnly=string.gsub(stripped,"%s+%l+$","")
|
|
if nameOnly~="" then return nameOnly end
|
|
if stripped~="" then return stripped end
|
|
return text
|
|
end
|
|
|
|
local function ActiveState(questID)
|
|
return QuestieOcto.QuestLog and QuestieOcto.QuestLog.active and QuestieOcto.QuestLog.active[tonumber(questID)] or nil
|
|
end
|
|
|
|
local function HasIncompleteObjectives(state)
|
|
local objectives=state and state.objectives or {}
|
|
local i=1
|
|
while i<=table.getn(objectives) do
|
|
if not objectives[i].complete then return true end
|
|
i=i+1
|
|
end
|
|
return false
|
|
end
|
|
|
|
-- Native UIDropDownMenu rendering -------------------------------------------
|
|
|
|
local function AddTitle(text)
|
|
local info={}
|
|
info.text=text
|
|
info.isTitle=1
|
|
info.notClickable=1
|
|
info.notCheckable=1
|
|
UIDropDownMenu_AddButton(info,UIDROPDOWNMENU_MENU_LEVEL)
|
|
end
|
|
|
|
local function AddArrow(text,value)
|
|
local info={}
|
|
info.text=text
|
|
info.value=value
|
|
info.hasArrow=1
|
|
info.notCheckable=1
|
|
UIDropDownMenu_AddButton(info,UIDROPDOWNMENU_MENU_LEVEL)
|
|
end
|
|
|
|
local function AddToggle(text,isChecked,onToggle)
|
|
local info={}
|
|
info.text=text
|
|
info.checked=isChecked and 1 or nil
|
|
info.keepShownOnClick=1
|
|
info.func=onToggle
|
|
UIDropDownMenu_AddButton(info,UIDROPDOWNMENU_MENU_LEVEL)
|
|
end
|
|
|
|
local function Initialize()
|
|
local questID=QM.currentQuestID
|
|
if not questID then return end
|
|
local state=ActiveState(questID)
|
|
local q=QuestieOcto.QuestModel and QuestieOcto.QuestModel:Get(questID) or nil
|
|
local level=UIDROPDOWNMENU_MENU_LEVEL or 1
|
|
|
|
if level==1 then
|
|
local title=(q and q.title) or (state and state.title) or ("Quest "..tostring(questID))
|
|
local qlevel=q and tonumber(q.level)
|
|
if qlevel and qlevel>0 then title="["..tostring(qlevel).."] "..title end
|
|
AddTitle(title)
|
|
if HasIncompleteObjectives(state) then
|
|
AddArrow("Objectives","objectives")
|
|
end
|
|
AddToggle("Hide icons",QM:IsQuestHidden(questID),function()
|
|
QM:ToggleQuestHidden(questID)
|
|
end)
|
|
return
|
|
end
|
|
|
|
if level==2 and UIDROPDOWNMENU_MENU_VALUE=="objectives" then
|
|
local objectives=state and state.objectives or {}
|
|
local oi=1
|
|
while oi<=table.getn(objectives) do
|
|
local row=objectives[oi]
|
|
local objIndex=tonumber(row.index)
|
|
if objIndex and not row.complete then
|
|
AddArrow(ObjectiveName(q,row),"obj:"..objIndex)
|
|
end
|
|
oi=oi+1
|
|
end
|
|
return
|
|
end
|
|
|
|
if level==3 then
|
|
local _,_,idx=string.find(tostring(UIDROPDOWNMENU_MENU_VALUE),"^obj:(%d+)$")
|
|
local objIndex=tonumber(idx)
|
|
if objIndex then
|
|
AddToggle("Focus Objective",QM:IsFocused(questID,objIndex),function()
|
|
QM:ToggleFocus(questID,objIndex)
|
|
end)
|
|
AddToggle("Hide icons",QM:IsObjectiveHidden(questID,objIndex),function()
|
|
QM:ToggleObjectiveHidden(questID,objIndex)
|
|
end)
|
|
end
|
|
return
|
|
end
|
|
end
|
|
|
|
function QM:Open(questID,row)
|
|
questID=tonumber(questID)
|
|
-- No menu for a quest that is already complete/ready to turn in.
|
|
local state=ActiveState(questID)
|
|
if state and state.complete then return end
|
|
|
|
if not self.dropdown then
|
|
self.dropdown=CreateFrame("Frame","QuestieOctoQuestMenuDropDown",UIParent,"UIDropDownMenuTemplate")
|
|
end
|
|
self.currentQuestID=questID
|
|
UIDropDownMenu_Initialize(self.dropdown,Initialize,"MENU")
|
|
ToggleDropDownMenu(1,nil,self.dropdown,"cursor",0,0)
|
|
end
|