1 QuestHelper_File
["tracker.lua"] = "Development Version"
2 QuestHelper_Loadtime
["tracker.lua"] = GetTime()
4 local debug_output
= false
5 if QuestHelper_File
["tracker.lua"] == "Development Version" then debug_output
= true end
9 So here's what we want to do.
11 We want a "refresh notification" where we send it the current route.
13 If things aren't in the route, we don't care about them . . . unless they're pinned.
15 So we have "refresh notification" and "pin toggles". In both cases, the objective and only the objective is passed in. Right now there's no concept of priority within the pins.
17 We're also not bothering with the whole metaobjective tree, we're just going one step up.
21 Note that "add" means "add iff it hasn't already been added."
23 Iff we haven't loaded yet, add a loaded message and a gap.
25 For each pinned objective, add the metaobjective and all objectives in its internal order. Iff we added things, add a gap.
27 For each route objective, add the metaobjective and all objectives in route order.
29 Later on we'll add an option for "splitting" metaobjectives, or possibly following the metaobjective tree all the way up.
33 So, "add" is complicated, due to the two requirements. We have to both add everything, and not add everything *yet*. I think the goal here is to make an Add function for adding a metaobjective that takes a list of objectives to be children, then doublecheck inside the function that we have all objectives.
35 We don't actually want "all objectives" long-term, note, we want only unfinished objectives. I sort of don't like the idea of keeping "finished objectives" around, however. Maybe we should only toss objectives in if they're in the routing system? Then how do I handle unknown objectives? (Simple - you pin them, and point out that we don't know how to do them.)
37 Also, to handle the "moving things around", we need to be a little clever. One line might be either a metaobjective or an objective, but in either case, we need a counter for which case it is. If everything shuffles, and we had two copies of metaobjective, MO1 moves to MO1 and MO2 moves to MO2. Easy.
40 local tracker
= CreateFrame("Frame", "QuestHelperQuestWatchFrame", UIParent
)
41 local minbutton
= CreateFrame("Button", "QuestHelperQuestWatchFrameMinimizeButton", UIParent
)
43 QuestHelper
.tracker
= tracker
45 local resizing
= false
47 tracker
:SetHeight(100)
48 tracker
.dw
, tracker
.dh
= 200, 100
52 minbutton
:SetFrameStrata("DIALOG")
54 minbutton
:SetPoint("TOPRIGHT", WatchFrame
) -- We default to a different location to make it more likely to display the right item.
55 minbutton
:SetMovable(true)
56 minbutton
:SetUserPlaced(true)
57 minbutton
:SetWidth(32 / 1.6)
58 minbutton
:SetHeight(32)
59 local minbutton_tex
= minbutton
:CreateTexture()
60 minbutton_tex
:SetAllPoints()
61 minbutton_tex
:SetTexture(.6, .6, .6)
63 local sigil
= minbutton
:CreateTexture("BACKGROUND", minbutton_tex
)
66 --sigil:SetPoint("CENTER", 0, 0)
67 sigil
:SetTexture("Interface\\AddOns\\QuestHelper\\sigil")
68 sigil
:SetPoint("CENTER", minbutton
, "CENTER")
71 tracker
:SetPoint("CENTER", minbutton
)
73 function minbutton
:moved()
74 local x
, y
= self
:GetCenter()
75 local w
, h
= UIParent
:GetWidth(), UIParent
:GetHeight()
76 local anchor
= (y
< h
*.45 and "BOTTOM" or y
> h
*.55 and "TOP" or "")..(x
< w
*.45 and "LEFT" or x
> w
*.55 and "RIGHT" or "")
78 tracker
:ClearAllPoints()
79 tracker
:SetPoint("CENTER", self
)
82 tracker
:SetPoint(anchor
, self
)
86 function QuestHelper
:ResetTrackerPosition(cmd
)
87 minbutton
:ClearAllPoints()
88 if cmd
and string.find(cmd
, "center") then
89 minbutton
:SetPoint("CENTER", nil, "CENTER", 100, 100)
91 minbutton
:SetPoint("RIGHT", nil, "RIGHT", -20, 230)
94 QuestHelper_Pref
.track_minimized
= false
96 self
:TextOut("Quest tracker postion reset.")
99 QH_Event({"DISPLAY_SIZE_CHANGED", "PLAYER_ENTERING_WORLD"}, function () minbutton
:moved() end)
101 QH_Hook(minbutton
, "OnClick", function ()
102 QuestHelper_Pref
.track_minimized
= not QuestHelper_Pref
.track_minimized
103 if QuestHelper_Pref
.track_minimized
then
110 minbutton
:RegisterForDrag("LeftButton")
112 QH_Hook(minbutton
, "OnDragStart", function(self
)
113 if self
:IsVisible() then
115 QH_Hook(self
, "OnUpdate", self
.moved
)
119 QH_Hook(minbutton
, "OnDragStop", function(self
)
120 QH_Hook(self
, "OnUpdate", nil)
121 self
:StopMovingOrSizing()
125 QH_Hook(minbutton
, "OnEnter", function (self
)
129 QH_Hook(minbutton
, "OnLeave", function (self
)
130 self
:SetAlpha(QuestHelper_Pref
.track_minimized
and .3 or .5)
133 -- used_items[objective][index]
134 -- used_count[objective] is incremented as the last valid index
135 -- so, therefore, used_items[objective][used_count[objective]] is not nil
136 local used_items
= {}
137 local used_count
= {}
139 -- it's possible for an item to be in neither used_items nor recycled_items, if it's in the process of fading out
140 local recycled_items
= {}
142 -- These two functions are basically identical. Combine them.
143 local function itemupdate(item
, delta
)
146 local a
= item
:GetAlpha()
156 local t
= item
.t
+ delta
161 local sp
= math
.sqrt(t
-t
*t
)
162 item
.x
, item
.y
= item
.sx
*it
+item
.ex
*t
+(item
.sy
-item
.ey
)*sp
, item
.sy
*it
+item
.ey
*t
+(item
.ex
-item
.sx
)*sp
166 item
.x
, item
.y
= item
.ex
, item
.ey
169 item
:ClearAllPoints()
170 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
173 QH_Hook(item
, "OnUpdate", nil)
177 local function itemfadeout(item
, delta
)
178 local a
= item
:GetAlpha()
186 QH_Hook(item
, "OnUpdate", nil)
187 table.insert(recycled_items
, item
)
191 local t
= item
.t
+ delta
196 local sp
= math
.sqrt(t
-t
*t
)
197 item
.x
, item
.y
= item
.sx
*it
+item
.ex
*t
+(item
.sy
-item
.ey
)*sp
, item
.sy
*it
+item
.ey
*t
+(item
.ex
-item
.sx
)*sp
200 item
.x
, item
.y
= item
.ex
, item
.ey
203 item
:ClearAllPoints()
204 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
207 --[[function QH_ToggleQuestLog() -- This seems to be gone in 3.0, so I'm adding it here.
208 if (QuestLogFrame:IsShown()) then
209 HideUIPanel(QuestLogFrame);
211 ShowUIPanel(QuestLogFrame);
215 -- Grim stuff with uberquest, I need a better way to handle this
216 local function itemclick(item, button)
217 if button == "RightButton" then
218 local quest = item.quest
221 local title = GetQuestLogTitle(index)
222 if not title then break end
224 if title == quest then
226 -- UberQuest needs a little extra effort to work properly.
228 if UberQuest_List:IsShown() and GetQuestLogSelection() == index then
231 QuestLog_SetSelection(index)
233 -- By hiding the list, the replaced ToggleQuestLog function should try to reshow it
234 -- and in the process update the frames to reflect the selected quest.
235 UberQuest_List:Hide()
236 UberQuest_Details:Show()
240 -- This code seems to work properly with the builtin questlog, as well as bEQL and DoubleWide.
242 if QuestLogFrame:IsShown() and GetQuestLogSelection() == index then
243 -- If the selected quest is already being shown, hide it.
246 -- Otherwise, select it and show it.
247 QuestLog_SetSelection(index)
249 if not QuestLogFrame:IsShown() then
263 local function allocateItem()
266 item
= table.remove(recycled_items
)
267 if item
then return item
end
269 item
= CreateFrame("Frame", nil, tracker
)
270 item
.text
= item
:CreateFontString()
271 item
.text
:SetShadowColor(0, 0, 0, .8)
272 item
.text
:SetShadowOffset(1, -1)
273 item
.text
:SetPoint("TOPLEFT", item
)
277 local specitem_max
= 1
278 local specitem_unused
= {}
280 -- This is adding a *single item*. This won't be called by the main parsing loop, but it does need some serious hackery. Let's see now
281 local function addItem(objective
, y
, meta
)
282 local obj_key
= objective
283 if obj_key
.cluster
then obj_key
= obj_key
.cluster
end
284 used_count
[obj_key
] = (used_count
[obj_key
] or 0) + 1
285 if not used_items
[obj_key
] then used_items
[obj_key
] = QuestHelper
:CreateTable("additem used_items") end
286 local item
= used_items
[obj_key
][used_count
[obj_key]]
288 local x
= meta
and 4 or 20
291 used_items
[obj_key
][used_count
[obj_key]]
= allocateItem()
292 item
= used_items
[obj_key
][used_count
[obj_key]]
295 item
.text
:SetFont(QuestHelper
.font
.serif
, 12)
296 item
.text
:SetTextColor(.82, .65, 0)
298 item
.text
:SetFont(QuestHelper
.font
.sans
, 12)
299 item
.text
:SetTextColor(.82, .82, .82)
304 item
.sx
, item
.sy
, item
.x
, item
.y
, item
.ex
, item
.ey
, item
.t
= x
+30, y
, x
, y
, x
, y
, 0
305 QH_Hook(item
, "OnUpdate", itemupdate
)
310 item
.text
:SetText(item
.obj
.tracker_desc
or "(no description)")
312 local w
, h
= item
.text
:GetWidth(), item
.text
:GetHeight()
316 if objective
.tracker_clicked
then
317 QH_Hook(item
, "OnMouseDown", function (self
, button
) if button
== "RightButton" then objective
.tracker_clicked() end end)
318 item
:EnableMouse(true)
321 if item
.ex
~= x
or item
.ey
~= y
then
322 item
.sx
, item
.sy
, item
.ex
, item
.ey
= item
.x
, item
.y
, x
, y
324 QH_Hook(item
, "OnUpdate", itemupdate
)
327 -- we're just going to recycle this each time
328 if item
.specitem
then
330 table.insert(specitem_unused
, item
.specitem
)
335 -- hacky - progress only shows up if we're not on a metaobjective. wheee
336 if objective
.type_quest
and objective
.type_quest
.index
and not objective
.progress
and GetQuestLogSpecialItemInfo(objective
.type_quest
.index
) then
337 item
.specitem
= table.remove(specitem_unused
)
338 if not item
.specitem
then
339 item
.specitem
= CreateFrame("BUTTON", "QH_SpecItem_" .. tostring(specitem_max
), item
, "WatchFrameItemButtonTemplate")
340 QuestHelper
: Assert(item
.specitem
)
342 local rangey
= _G
["QH_SpecItem_" .. tostring(specitem_max
) .. "HotKey"]
343 QuestHelper
: Assert(rangey
)
344 local fn
, fh
, ff
= rangey
:GetFont()
345 rangey
:SetFont("Fonts\\ARIALN.TTF", fh
, ff
)
346 rangey
:SetText(RANGE_INDICATOR
)
347 rangey
:ClearAllPoints()
348 rangey
:SetPoint("BOTTOMRIGHT", item
.specitem
, "BOTTOMRIGHT", 0, 2)
350 specitem_max
= specitem_max
+ 1
353 item
.specitem
:SetScale(0.9)
354 item
.specitem
:ClearAllPoints()
355 item
.specitem
:SetParent(item
)
356 item
.specitem
:SetPoint("TOPRIGHT", item
, "TOPLEFT", 0, 0)
358 local _
, tex
, charges
= GetQuestLogSpecialItemInfo(objective
.type_quest
.index
)
359 item
.specitem
:SetID(objective
.type_quest
.index
)
360 SetItemButtonTexture(item
.specitem
, tex
)
361 item
.specitem
.rangeTimer
= -1 -- This makes the little dot go away. Why does it do that?
362 item
.specitem
.charges
= charges
369 return w
+x
+4, y
+h
, y
+h
+spacer
372 local function addMetaObjective(metaobj
, items
, y
, depth
)
374 x
, y
, spacer
= addItem(metaobj
, y
, true)
375 for _
, v
in ipairs(items
) do
376 x
, y
= addItem(v
, y
, false)
378 return math
.max(y
, spacer
), depth
+ #items
+ 1
381 --[[ -- these will be plugged in later one way or another
382 local function ccode(r1, g1, b1, r2, g2, b2, p)
384 p, ip = p*255, 255-p*255
385 return string.format("|cff%02x%02x%02x", r1*ip+r2*p, g1*ip+g2*p, b1*ip+b2*p)
388 local function qname(title, level)
389 if QuestHelper_Pref.track_level and level ~= 7777 and level ~= 7778 then
390 title = string.format("[%d] %s", level, title)
393 if level == 7778 then
397 if QuestHelper_Pref.track_qcolour then
398 local player_level = QuestHelper.player_level
399 local delta = level - player_level
404 colour = "|cffff0000"
405 elseif delta >= 0 then
406 colour = ccode(1, 1, 0, 1, 0, 0, delta/5)
410 if player_level >= 60 then grey = player_level - 9
411 elseif player_level >= 40 then grey = player_level - math.floor(player_level/5) - 1
412 elseif player_level >= 6 then grey = player_level - math.floor(player_level/10) - 5
415 if level == -7778 then
416 colour = "|cff808080"
417 elseif level > grey then
418 colour = ccode(0, 1, 0, 1, 1, 0, (grey-level)/(grey-player_level))
420 colour = ccode(.4, .4, .4, .2, .8, .2, (1-level)/(1-grey))
424 title = string.format("%s%s", colour, title)
430 local function oname(text, pct)
431 if QuestHelper_Pref.track_ocolour then
432 text = string.format("%s%s", pct < 0.5 and ccode(1, 0, 0, 1, 1, 0, pct*2) or ccode(1, 1, 0, 0, 1, 0, pct*2-1), text)
439 local function removeUnusedItem(item
)
441 item
.sx
, item
.sy
, item
.dx
, item
.dy
= item
.x
, item
.y
, item
.x
+30, item
.y
442 QH_Hook(item
, "OnMouseDown", nil)
443 item
:EnableMouse(false)
444 QH_Hook(item
, "OnUpdate", itemfadeout
)
446 if item
.specitem
then
448 table.insert(specitem_unused
, item
.specitem
)
454 local was_inside
= false
458 local function addobj(objective
, seen
, obj_index_lookup
, filter
, x
, y
, gap
)
462 if objective
.cat
== "quest" then
465 quest
= objective
.quest
468 if quest
and quest
.watched
and not seen
[quest
] and (not filter
or filter(quest
)) then
471 local level
, name
= string.match(quest
.obj
, "^(%d+)/%d*/(.*)$")
474 level
, name
= string.match(quest
.obj
, "^(%d+)/(.*)$")
476 level
, name
= 1, quest
.obj
480 level
= tonumber(level
) or 1
483 local w
, h
= addItem(qname(name
, level
), true, quest
, -(y
+gap
), name
, quest
.index
)
488 for obj
in pairs(quest
.swap_after
or quest
.after
) do
490 table.insert(obj_list
, obj
)
494 table.sort(obj_list
, objlist_sort
)
496 for i
, obj
in ipairs(obj_list
) do
497 local pct
, text
= 0, obj
.obj
498 local seen_sum
, seen_max
= 0, 0
501 local seen_have
, seen_need
= QuestHelper
:CreateTable(), QuestHelper
:CreateTable()
503 for user
, progress
in pairs(obj
.progress
) do
504 seen_sum
= seen_sum
+ progress
[3]
505 seen_max
= seen_max
+ 1
506 seen_have
[progress
[1]]
= true
507 seen_need
[progress
[2]]
= true
511 pct
= seen_sum
/ seen_max
512 local list
= QuestHelper
:CreateTable()
514 for val
in pairs(seen_have
) do
515 table.insert(list
, val
)
520 local have
= table.concat(list
, ", ")
522 for i
= #list
,1,-1 do
526 for val
in pairs(seen_need
) do
527 table.insert(list
, val
)
530 if #list
~= 1 or list
[1] ~= 1 then
531 -- If there is only one thing needed, ignore the progress, it's redundant.
532 -- It's either shown or it isn't.
536 local need
= table.concat(list
, ", ")
538 text
= string.format((tonumber(have
) and tonumber(need
) and QUEST_ITEMS_NEEDED
) or QUEST_FACTION_NEEDED
,
542 QuestHelper
:ReleaseTable(list
)
545 QuestHelper
:ReleaseTable(seen_have
)
546 QuestHelper
:ReleaseTable(seen_need
)
549 if seen_sum
~= seen_max
then
551 w
, h
= addItem(oname(text
, pct
), quest
, obj
, -y
)
557 for i
= #obj_list
, 1, -1 do obj_list
[i
] = nil end
560 return x
, y
, gap
, count
564 local loading_vquest
= {tracker_desc
= QHFormat("QH_LOADING", "0")}
565 local flightpath_vquest
= {tracker_desc
= QHFormat("QH_FLIGHTPATH", "0")}
568 local hidden_vquest1
= { tracker_desc
= QHText("QUESTS_HIDDEN_1"), tracker_clicked
= QH_Hidden_Menu
}
569 local hidden_vquest2
= { tracker_desc
= " " .. QHText("QUESTS_HIDDEN_2"), tracker_clicked
= QH_Hidden_Menu
}
574 -- This is actually called surprisingly often.
575 function QH_Tracker_Rescan()
576 used_count
= QuestHelper
:CreateTable("tracker rescan used_count")
578 local mo_done
= QuestHelper
:CreateTable("tracker rescan mo_done")
579 local obj_done
= QuestHelper
:CreateTable("tracker rescan obj_done")
581 local y
, depth
= 0, 0
584 local had_pinned
= false
586 local objs
= QuestHelper
:CreateTable("tracker objs")
587 for k
, v
in pairs(pinned
) do
588 if not objs
[k
.why
] then objs
[k
.why
] = QuestHelper
:CreateTable("tracker objs sub") end
589 if not k
.ignore
and not k
.tracker_hidden
then table.insert(objs
[k
.why
], k
) end
590 obj_done
[k
.cluster
] = true
593 local sort_objs
= QuestHelper
:CreateTable("tracker sobjs")
594 for k
, v
in pairs(objs
) do
597 table.insert(sort_objs
, v
)
600 table.sort(sort_objs
, function (a
, b
) return tostring(a
.trackkey
) < tostring(b
.trackkey
) end)
602 for _
, v
in ipairs(sort_objs
) do
603 y
, depth
= addMetaObjective(v
.cluster
, v
, y
, depth
)
605 QuestHelper
:ReleaseTable(v
)
607 QuestHelper
:ReleaseTable(sort_objs
)
608 QuestHelper
:ReleaseTable(objs
)
610 if had_pinned
then y
= y
+ 10 end
613 if QuestHelper
.loading_main
then
614 loading_vquest
.tracker_desc
= QHFormat("QH_LOADING", string.format("%d", QuestHelper
.loading_main
:GetPercentage() * 100))
615 local x
, ty
= addItem(loading_vquest
, y
)
618 if QuestHelper
.flightpathing
then
619 flightpath_vquest
.tracker_desc
= QHFormat("QH_FLIGHTPATH", string.format("%d", QuestHelper
.flightpathing
:GetPercentage() * 100))
620 local x
, ty
= addItem(flightpath_vquest
, y
)
624 local metalookup
= QuestHelper
:CreateTable("tracker rescan metalookup")
625 for k
, v
in ipairs(route
) do
627 if not metalookup
[v
.why
] then metalookup
[v
.why
] = QuestHelper
:CreateTable("tracker rescan metalookup item") end
628 if not v
.tracker_hidden
then table.insert(metalookup
[v
.why
], v
) end
634 local current_mo_cluster
635 for k
, v
in ipairs(route
) do
636 if depth
> QuestHelper_Pref
.track_size
and not debug_output
then break end
637 if not v
.ignore
and not v
.why
.tracker_hidden
and not obj_done
[v
.cluster
] then
638 if current_mo
and v
.why
~= current_mo
then
639 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
640 QuestHelper
:ReleaseTable(current_mo_cluster
)
641 current_mo
, current_mo_cluster
= nil, nil
644 if not v
.why
.tracker_split
then
645 if not mo_done
[v
.why
] then
646 y
, depth
= addMetaObjective(v
.why
, metalookup
[v
.why
], y
, depth
)
647 mo_done
[v
.why
] = true
650 if not current_mo
then
652 current_mo_cluster
= QuestHelper
:CreateTable("tracker current cluster")
654 if not v
.tracker_hidden
then table.insert(current_mo_cluster
, v
) end
660 if current_mo
and not (depth
> QuestHelper_Pref
.track_size
and not debug_output
) then
661 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
663 if current_mo_cluster
then
664 QuestHelper
:ReleaseTable(current_mo_cluster
)
668 -- now we check to see if we need a hidden display
669 if (debug_output
or depth
< QuestHelper_Pref
.track_size
) and not QuestHelper
.loading_main
and not QuestHelper_Pref
.filter_done
and not QuestHelper_Pref
.filter_zone
and not QuestHelper_Pref
.filter_watched
then
672 QH_Route_TraverseClusters(
675 QH_Route_IgnoredReasons_Cluster(clust
, function (reason
)
679 for _
, v
in ipairs(clust
) do
680 QH_Route_IgnoredReasons_Node(v
, function (reason
)
690 _
, y
= addItem(hidden_vquest1
, y
)
691 _
, y
= addItem(hidden_vquest2
, y
)
696 -- any manipulations of the tracker should be done by now, everything after this is bookkeeping
698 for k
, v
in pairs(used_items
) do
699 if not used_count
[k
] or used_count
[k
] < #v
then
700 local ttp
= QuestHelper
:CreateTable("used_items ttp")
701 for m
= 1, (used_count
[k
] or 0) do
702 table.insert(ttp
, v
[m
])
704 for m
= (used_count
[k
] or 0) + 1, #v
do
705 removeUnusedItem(v
[m
])
708 if used_items
[k
] then
709 QuestHelper
:ReleaseTable(used_items
[k
])
716 QuestHelper
:ReleaseTable(ttp
)
721 QuestHelper
:ReleaseTable(mo_done
)
722 QuestHelper
:ReleaseTable(obj_done
)
723 for k
, v
in pairs(metalookup
) do
724 QuestHelper
:ReleaseTable(v
)
726 QuestHelper
:ReleaseTable(metalookup
)
728 QuestHelper
:ReleaseTable(used_count
)
731 if y
~= tracker
.dh
then
733 tracker
.sh
= tracker
:GetHeight()
735 tracker
.sw
= tracker
.dw
745 if x ~= tracker.dw or y ~= tracker.dy then
747 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
748 tracker.dw, tracker.dh = x, y
754 local quests = QuestHelper.quest_log
758 local track_size = QuestHelper_Pref.track_size
759 local quests_added = {}
761 for quest, objs in pairs(used_items) do
762 for obj, item in pairs(objs) do
767 for i, objective in pairs(QuestHelper.route) do
768 if objective.watched then
769 obj_index_lookup[objective] = i
773 for q, data in pairs(QuestHelper.quest_log) do
774 quest_lookup[data.index] = q
777 -- Add our little "not yet loaded" notification
778 local loadedshow = false
779 if not QuestHelper.Routing.map_walker then
781 x, y, gap, count = addobj(loading_vquest, seen, nil, nil, x, y, gap)
782 added = added + count
785 if QuestHelper_Flight_Updates and QuestHelper_Flight_Updates_Current and QuestHelper_Flight_Updates > 0 and QuestHelper_Flight_Updates_Current < QuestHelper_Flight_Updates then
786 loading_vquest.obj = string.format("7777/" .. QHFormat("QH_LOADING", string.format("%d", QuestHelper_Flight_Updates_Current * 100 / QuestHelper_Flight_Updates)))
790 -- Add an extra large gap to seperate the notification from everything else
793 -- Add Quests that are watched but not in the route.
795 local uq_settings = UberQuest_Config[UnitName("player")]
797 local list = uq_settings.selected
801 local name = GetQuestLogTitle(i)
802 if not name then break end
803 quest_lookup[name] = quest_lookup[i]
806 for name in pairs(list) do
807 local q = quest_lookup[name]
808 if q and not obj_index_lookup[q] then
810 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
811 added = added + count
812 quests_added[q] = true
818 for i = 1,GetNumQuestWatches() do
819 local q = quest_lookup[GetQuestIndexForWatch(i)]
820 if q and not obj_index_lookup[q] then
822 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
823 added = added + count
828 -- Add Quests that are watched and are in the route.
829 for i, objective in ipairs(QuestHelper.route) do
831 x, y, gap, count = addobj(objective, seen, obj_index_lookup, watched_filter, x, y, gap)
832 added = added + count
833 quests_added[objective] = true
836 -- Add an extra large gap to seperate the watched objectives from the automatic objectives.
839 -- Add Quests that aren't watched and are in the route.
840 if added <= track_size then
841 for i, objective in ipairs(QuestHelper.route) do
843 x, y, gap, count = addobj(objective, seen, obj_index_lookup, nil, x, y, gap)
844 added = added + count
845 quests_added[objective] = true
847 if added > track_size then
853 if not loadedshow and added < track_size and not QuestHelper_Pref.filter_done and not QuestHelper_Pref.filter_zone and not QuestHelper_Pref.filter_watched then
856 for k, v in pairs(quest_lookup) do
857 if not quests_added[v] then
858 notadded = notadded + 1
866 x, y, gap, count = addobj(hidden_vquest1, seen, nil, nil, x, y, gap)
867 added = added + count
868 x, y, gap, count = addobj(hidden_vquest2, seen, nil, nil, x, y, gap)
869 added = added + count
873 for obj in pairs(obj_index_lookup) do
874 obj_index_lookup[obj] = nil
877 for key in pairs(quest_lookup) do
878 quest_lookup[key] = nil
881 for quest, objs in pairs(used_items) do
882 for obj, item in pairs(objs) do
883 if not item.used then
884 removeUnusedItem(quest, obj, item)
889 for key in pairs(seen) do
895 if x ~= tracker.dw or y ~= tracker.dy then
897 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
898 tracker.dw, tracker.dh = x, y
906 function QH_Tracker_UpdateRoute(new_route
)
911 function QH_Tracker_Pin(metaobjective
, suppress
)
912 if not pinned
[metaobjective
] then
913 pinned
[metaobjective
] = true
921 function QH_Tracker_Unpin(metaobjective
, suppress
)
922 if pinned
[metaobjective
] then
923 pinned
[metaobjective
] = nil -- nil, not false, so it'll be garbage-collected appropriately
931 function QH_Tracker_SetPin(metaobjective
, flag
, suppress
)
933 QH_Tracker_Pin(metaobjective
, suppress
)
935 QH_Tracker_Unpin(metaobjective
, suppress
)
940 local check_delay
= 4
942 -- This function does the grunt work of cursor positioning and rescaling. It does not actually reorganize items.
943 function tracker
:update(delta
)
945 -- This is called without a value when the questlog is updated.
946 -- We'll make sure we update the display on the next update.
952 local t
= self
.t
+delta
955 self
:SetWidth(self
.dw
)
956 self
:SetHeight(self
.dh
)
961 self
:SetWidth(self
.sw
*it
+self
.dw
*t
)
962 self
:SetHeight(self
.sh
*it
+self
.dh
*t
)
966 -- Manually checking if the mouse is in the frame, because if I used on OnEnter, i'd have to enable mouse input,
967 -- and if I did that, it would prevent the player from using the mouse to change the view if they clicked inside
969 local x
, y
= GetCursorPosition()
970 local s
= 1/self
:GetEffectiveScale()
973 QuestHelper
: Assert(x
)
974 QuestHelper
: Assert(y
)
975 --[[ QuestHelper: Assert(self:GetLeft())
976 QuestHelper: Assert(self:GetBottom())
977 QuestHelper: Assert(self:GetRight())
978 QuestHelper: Assert(self:GetTop())]]
980 -- Sometimes it just doesn't know its own coordinates. Not sure why. Maybe this will fix it.
981 local inside
= (self
:GetLeft() and (x
>= self
:GetLeft() and y
>= self
:GetBottom() and x
< self
:GetRight() and y
< self
:GetTop()))
982 if inside
~= was_inside
then
985 minbutton
:SetAlpha(.5)
986 elseif not QuestHelper_Pref
.track_minimized
then
987 minbutton
:SetAlpha(0)
991 check_delay
= check_delay
+ delta
992 if check_delay
> 1 then
999 QH_Hook(tracker
, "OnUpdate", tracker
.update
)
1001 -- Some hooks to update the tracker when quests are added or removed. These should be moved into the quest director.
1003 local orig_AddQuestWatch, orig_RemoveQuestWatch = AddQuestWatch, RemoveQuestWatch
1005 function AddQuestWatch(...)
1007 return orig_AddQuestWatch(...)
1010 function RemoveQuestWatch(...)
1012 return orig_RemoveQuestWatch(...)
1015 -------------------------------------------------------------------------------------------------
1016 -- This batch of stuff is to make sure the original tracker (and any modifications) stay hidden
1018 local orig_TrackerBackdropOnShow
-- bEQL (and perhaps other mods) add a backdrop to the tracker
1019 local TrackerBackdropFound
= false
1021 local function TrackerBackdropOnShow(self
, ...)
1022 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
1023 TrackerBackdropFound
:Hide()
1026 if orig_TrackerBackdropOnShow
then
1027 return orig_TrackerBackdropOnShow(self
, ...)
1031 function tracker
:HideDefaultTracker()
1032 -- The easy part: hide the original tracker
1033 WatchFrame_RemoveObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1034 WatchFrame_ClearDisplay()
1037 -- The harder part: hide all those little buttons
1041 local orig
= _G
["WatchFrameItem" .. tostring(index
)]
1042 if orig
then orig
:Hide() else break end
1047 -- The harder part: check if a known backdrop is present (but we don't already know about it).
1048 -- If it is, make sure it's hidden, and hook its OnShow to make sure it stays that way.
1049 -- Unfortunately, I can't figure out a good time to check for this once, so we'll just have
1050 -- to keep checking. Hopefully, this won't happen too often.
1051 if not TrackerBackdropFound
then
1052 if QuestWatchFrameBackdrop
then
1053 -- Found bEQL's QuestWatchFrameBackdrop...
1054 TrackerBackdropFound
= QuestWatchFrameBackdrop
1057 if TrackerBackdropFound
then
1058 -- OK, we found something - so hide it, and make sure it doesn't rear its ugly head again
1059 TrackerBackdropFound
:Hide()
1061 orig_TrackerBackdropOnShow
= TrackerBackdropFound
:GetScript("OnShow")
1062 QH_Hook(TrackerBackdropFound
, "OnShow", TrackerBackdropOnShow
)
1067 function tracker
:ShowDefaultTracker()
1068 -- I like how there's code explicitly to allow us to do this without checking if it's already added
1069 WatchFrame_AddObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1070 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1073 if TrackerBackdropFound
then
1074 TrackerBackdropFound
:Show()
1078 function QuestHelper
:ShowTracker()
1079 tracker
:HideDefaultTracker()
1082 if QuestHelper_Pref
.track_minimized
then
1083 minbutton
:SetAlpha(.3)
1085 minbutton
:SetAlpha(0)
1090 function QuestHelper
:HideTracker()
1091 tracker
:ShowDefaultTracker()