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
48 tracker
:SetHeight(100)
49 tracker
.dw
, tracker
.dh
= 200, 100
53 minbutton
:SetFrameStrata("DIALOG")
55 minbutton
:SetPoint("TOPRIGHT", WatchFrame
) -- We default to a different location to make it more likely to display the right item.
56 minbutton
:SetMovable(true)
57 minbutton
:SetUserPlaced(true)
58 minbutton
:SetWidth(10)
59 minbutton
:SetHeight(5)
60 local minbutton_tex
= minbutton
:CreateTexture()
61 minbutton_tex
:SetAllPoints()
62 minbutton_tex
:SetTexture(.8, .8, .8)
64 tracker
:SetPoint("CENTER", minbutton
)
66 function minbutton
:moved()
67 local x
, y
= self
:GetCenter()
68 local w
, h
= UIParent
:GetWidth(), UIParent
:GetHeight()
69 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 "")
71 tracker
:ClearAllPoints()
72 tracker
:SetPoint("CENTER", self
)
75 tracker
:SetPoint(anchor
, self
)
79 function QuestHelper
:ResetTrackerPosition(cmd
)
80 minbutton
:ClearAllPoints()
81 if cmd
and string.find(cmd
, "center") then
82 minbutton
:SetPoint("CENTER", nil, "CENTER", 100, 100)
84 minbutton
:SetPoint("RIGHT", nil, "RIGHT", -20, 230)
87 QuestHelper_Pref
.track_minimized
= false
89 self
:TextOut("Quest tracker postion reset.")
92 minbutton
:SetScript("OnEvent", minbutton
.moved
)
93 minbutton
:RegisterEvent("DISPLAY_SIZE_CHANGED")
94 minbutton
:RegisterEvent("PLAYER_ENTERING_WORLD")
96 minbutton
:SetScript("OnClick", function ()
97 QuestHelper_Pref
.track_minimized
= not QuestHelper_Pref
.track_minimized
98 if QuestHelper_Pref
.track_minimized
then
105 minbutton
:RegisterForDrag("LeftButton")
107 minbutton
:SetScript("OnDragStart", function(self
)
108 if self
:IsVisible() then
110 self
:SetScript("OnUpdate", self
.moved
)
114 minbutton
:SetScript("OnDragStop", function(self
)
115 self
:SetScript("OnUpdate", nil)
116 self
:StopMovingOrSizing()
120 minbutton
:SetScript("OnEnter", function (self
)
124 minbutton
:SetScript("OnLeave", function (self
)
125 self
:SetAlpha(QuestHelper_Pref
.track_minimized
and .3 or .5)
128 -- used_items[objective][index]
129 -- used_count[objective] is incremented as the last valid index
130 -- so, therefore, used_items[objective][used_count[objective]] is not nil
131 local used_items
= {}
132 local used_count
= {}
134 -- it's possible for an item to be in neither used_items nor recycled_items, if it's in the process of fading out
135 local recycled_items
= {}
137 -- These two functions are basically identical. Combine them.
138 local function itemupdate(item
, delta
)
141 local a
= item
:GetAlpha()
151 local t
= item
.t
+ delta
156 local sp
= math
.sqrt(t
-t
*t
)
157 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
161 item
.x
, item
.y
= item
.ex
, item
.ey
164 item
:ClearAllPoints()
165 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
168 item
:SetScript("OnUpdate", nil)
172 local function itemfadeout(item
, delta
)
173 local a
= item
:GetAlpha()
181 item
:SetScript("OnUpdate", nil)
182 table.insert(recycled_items
, item
)
186 local t
= item
.t
+ delta
191 local sp
= math
.sqrt(t
-t
*t
)
192 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
195 item
.x
, item
.y
= item
.ex
, item
.ey
198 item
:ClearAllPoints()
199 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
202 --[[function QH_ToggleQuestLog() -- This seems to be gone in 3.0, so I'm adding it here.
203 if (QuestLogFrame:IsShown()) then
204 HideUIPanel(QuestLogFrame);
206 ShowUIPanel(QuestLogFrame);
210 -- Grim stuff with uberquest, I need a better way to handle this
211 local function itemclick(item, button)
212 if button == "RightButton" then
213 local quest = item.quest
216 local title = GetQuestLogTitle(index)
217 if not title then break end
219 if title == quest then
221 -- UberQuest needs a little extra effort to work properly.
223 if UberQuest_List:IsShown() and GetQuestLogSelection() == index then
226 QuestLog_SetSelection(index)
228 -- By hiding the list, the replaced ToggleQuestLog function should try to reshow it
229 -- and in the process update the frames to reflect the selected quest.
230 UberQuest_List:Hide()
231 UberQuest_Details:Show()
235 -- This code seems to work properly with the builtin questlog, as well as bEQL and DoubleWide.
237 if QuestLogFrame:IsShown() and GetQuestLogSelection() == index then
238 -- If the selected quest is already being shown, hide it.
241 -- Otherwise, select it and show it.
242 QuestLog_SetSelection(index)
244 if not QuestLogFrame:IsShown() then
258 local function allocateItem()
261 item
= table.remove(recycled_items
)
262 if item
then return item
end
264 item
= CreateFrame("Frame", nil, tracker
)
265 item
.text
= item
:CreateFontString()
266 item
.text
:SetShadowColor(0, 0, 0, .8)
267 item
.text
:SetShadowOffset(1, -1)
268 item
.text
:SetPoint("TOPLEFT", item
)
272 local specitem_max
= 1
273 local specitem_unused
= {}
275 -- 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
276 local function addItem(objective
, y
, meta
)
277 local obj_key
= objective
278 if obj_key
.cluster
then obj_key
= obj_key
.cluster
end
279 used_count
[obj_key
] = (used_count
[obj_key
] or 0) + 1
280 if not used_items
[obj_key
] then used_items
[obj_key
] = QuestHelper
:CreateTable("additem used_items") end
281 local item
= used_items
[obj_key
][used_count
[obj_key]]
283 local x
= meta
and 4 or 20
286 used_items
[obj_key
][used_count
[obj_key]]
= allocateItem()
287 item
= used_items
[obj_key
][used_count
[obj_key]]
290 item
.text
:SetFont(QuestHelper
.font
.serif
, 12)
291 item
.text
:SetTextColor(.82, .65, 0)
293 item
.text
:SetFont(QuestHelper
.font
.sans
, 12)
294 item
.text
:SetTextColor(.82, .82, .82)
299 item
.sx
, item
.sy
, item
.x
, item
.y
, item
.ex
, item
.ey
, item
.t
= x
+30, y
, x
, y
, x
, y
, 0
300 item
:SetScript("OnUpdate", itemupdate
)
305 item
.text
:SetText(item
.obj
.tracker_desc
)
307 local w
, h
= item
.text
:GetWidth(), item
.text
:GetHeight()
311 if objective
.tracker_clicked
then
312 item
:SetScript("OnMouseDown", function (self
, button
) if button
== "RightButton" then objective
.tracker_clicked() end end)
313 item
:EnableMouse(true)
316 if item
.ex
~= x
or item
.ey
~= y
then
317 item
.sx
, item
.sy
, item
.ex
, item
.ey
= item
.x
, item
.y
, x
, y
319 item
:SetScript("OnUpdate", itemupdate
)
322 -- we're just going to recycle this each time
323 if item
.specitem
then
325 table.insert(specitem_unused
, item
.specitem
)
330 -- hacky - progress only shows up if we're not on a metaobjective. wheee
331 if objective
.type_quest
and objective
.type_quest
.index
and not objective
.progress
and GetQuestLogSpecialItemInfo(objective
.type_quest
.index
) then
332 item
.specitem
= table.remove(specitem_unused
)
333 if not item
.specitem
then
334 item
.specitem
= CreateFrame("BUTTON", "QH_SpecItem_" .. tostring(specitem_max
), item
, "WatchFrameItemButtonTemplate")
335 QuestHelper
: Assert(item
.specitem
)
337 local rangey
= _G
["QH_SpecItem_" .. tostring(specitem_max
) .. "HotKey"]
338 QuestHelper
: Assert(rangey
)
339 local fn
, fh
, ff
= rangey
:GetFont()
340 rangey
:SetFont("Fonts\\ARIALN.TTF", fh
, ff
)
341 rangey
:SetText(RANGE_INDICATOR
)
342 rangey
:ClearAllPoints()
343 rangey
:SetPoint("BOTTOMRIGHT", item
.specitem
, "BOTTOMRIGHT", 0, 2)
345 specitem_max
= specitem_max
+ 1
348 item
.specitem
:SetScale(0.9)
349 item
.specitem
:ClearAllPoints()
350 item
.specitem
:SetParent(item
)
351 item
.specitem
:SetPoint("TOPRIGHT", item
, "TOPLEFT", 0, 0)
353 local _
, tex
= GetQuestLogSpecialItemInfo(objective
.type_quest
.index
)
354 item
.specitem
:SetID(objective
.type_quest
.index
)
355 SetItemButtonTexture(item
.specitem
, tex
)
356 item
.specitem
.rangeTimer
= -1 -- This makes the little dot go away. Why does it do that?
363 return w
+x
+4, y
+h
, y
+h
+spacer
366 local function addMetaObjective(metaobj
, items
, y
, depth
)
368 x
, y
, spacer
= addItem(metaobj
, y
, true)
369 for _
, v
in ipairs(items
) do
370 x
, y
= addItem(v
, y
, false)
372 return math
.max(y
, spacer
), depth
+ #items
+ 1
375 --[[ -- these will be plugged in later one way or another
376 local function ccode(r1, g1, b1, r2, g2, b2, p)
378 p, ip = p*255, 255-p*255
379 return string.format("|cff%02x%02x%02x", r1*ip+r2*p, g1*ip+g2*p, b1*ip+b2*p)
382 local function qname(title, level)
383 if QuestHelper_Pref.track_level and level ~= 7777 and level ~= 7778 then
384 title = string.format("[%d] %s", level, title)
387 if level == 7778 then
391 if QuestHelper_Pref.track_qcolour then
392 local player_level = QuestHelper.player_level
393 local delta = level - player_level
398 colour = "|cffff0000"
399 elseif delta >= 0 then
400 colour = ccode(1, 1, 0, 1, 0, 0, delta/5)
404 if player_level >= 60 then grey = player_level - 9
405 elseif player_level >= 40 then grey = player_level - math.floor(player_level/5) - 1
406 elseif player_level >= 6 then grey = player_level - math.floor(player_level/10) - 5
409 if level == -7778 then
410 colour = "|cff808080"
411 elseif level > grey then
412 colour = ccode(0, 1, 0, 1, 1, 0, (grey-level)/(grey-player_level))
414 colour = ccode(.4, .4, .4, .2, .8, .2, (1-level)/(1-grey))
418 title = string.format("%s%s", colour, title)
424 local function oname(text, pct)
425 if QuestHelper_Pref.track_ocolour then
426 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)
433 local function removeUnusedItem(item
)
435 item
.sx
, item
.sy
, item
.dx
, item
.dy
= item
.x
, item
.y
, item
.x
+30, item
.y
436 item
:SetScript("OnMouseDown", nil)
437 item
:EnableMouse(false)
438 item
:SetScript("OnUpdate", itemfadeout
)
440 if item
.specitem
then
442 table.insert(specitem_unused
, item
.specitem
)
448 local was_inside
= false
452 local function addobj(objective
, seen
, obj_index_lookup
, filter
, x
, y
, gap
)
456 if objective
.cat
== "quest" then
459 quest
= objective
.quest
462 if quest
and quest
.watched
and not seen
[quest
] and (not filter
or filter(quest
)) then
465 local level
, name
= string.match(quest
.obj
, "^(%d+)/%d*/(.*)$")
468 level
, name
= string.match(quest
.obj
, "^(%d+)/(.*)$")
470 level
, name
= 1, quest
.obj
474 level
= tonumber(level
) or 1
477 local w
, h
= addItem(qname(name
, level
), true, quest
, -(y
+gap
), name
, quest
.index
)
482 for obj
in pairs(quest
.swap_after
or quest
.after
) do
484 table.insert(obj_list
, obj
)
488 table.sort(obj_list
, objlist_sort
)
490 for i
, obj
in ipairs(obj_list
) do
491 local pct
, text
= 0, obj
.obj
492 local seen_sum
, seen_max
= 0, 0
495 local seen_have
, seen_need
= QuestHelper
:CreateTable(), QuestHelper
:CreateTable()
497 for user
, progress
in pairs(obj
.progress
) do
498 seen_sum
= seen_sum
+ progress
[3]
499 seen_max
= seen_max
+ 1
500 seen_have
[progress
[1]]
= true
501 seen_need
[progress
[2]]
= true
505 pct
= seen_sum
/ seen_max
506 local list
= QuestHelper
:CreateTable()
508 for val
in pairs(seen_have
) do
509 table.insert(list
, val
)
514 local have
= table.concat(list
, ", ")
516 for i
= #list
,1,-1 do
520 for val
in pairs(seen_need
) do
521 table.insert(list
, val
)
524 if #list
~= 1 or list
[1] ~= 1 then
525 -- If there is only one thing needed, ignore the progress, it's redundant.
526 -- It's either shown or it isn't.
530 local need
= table.concat(list
, ", ")
532 text
= string.format((tonumber(have
) and tonumber(need
) and QUEST_ITEMS_NEEDED
) or QUEST_FACTION_NEEDED
,
536 QuestHelper
:ReleaseTable(list
)
539 QuestHelper
:ReleaseTable(seen_have
)
540 QuestHelper
:ReleaseTable(seen_need
)
543 if seen_sum
~= seen_max
then
545 w
, h
= addItem(oname(text
, pct
), quest
, obj
, -y
)
551 for i
= #obj_list
, 1, -1 do obj_list
[i
] = nil end
554 return x
, y
, gap
, count
558 local loading_vquest
= {tracker_desc
= QHFormat("QH_LOADING", "0")}
559 local flightpath_vquest
= {tracker_desc
= QHFormat("QH_FLIGHTPATH", "0")}
561 --local hidden_vquest1 = { cat = "quest", obj = "7778/" .. QHText("QUESTS_HIDDEN_1"), after = {}, watched = true }
562 --local hidden_vquest2 = { cat = "quest", obj = "7778/ " .. QHText("QUESTS_HIDDEN_2"), after = {}, watched = true }
567 -- This is actually called surprisingly often.
568 function QH_Tracker_Rescan()
569 used_count
= QuestHelper
:CreateTable("tracker rescan used_count")
571 local mo_done
= QuestHelper
:CreateTable("tracker rescan mo_done")
572 local obj_done
= QuestHelper
:CreateTable("tracker rescan obj_done")
574 local y
, depth
= 0, 0
577 local had_pinned
= false
579 local objs
= QuestHelper
:CreateTable("tracker objs")
580 for k
, v
in pairs(pinned
) do
581 if not objs
[k
.why
] then objs
[k
.why
] = QuestHelper
:CreateTable("tracker objs sub") end
582 if not k
.ignore
and not k
.tracker_hidden
then table.insert(objs
[k
.why
], k
) end
583 obj_done
[k
.cluster
] = true
586 local sort_objs
= QuestHelper
:CreateTable("tracker sobjs")
587 for k
, v
in pairs(objs
) do
590 table.insert(sort_objs
, v
)
593 table.sort(sort_objs
, function (a
, b
) return tostring(a
.trackkey
) < tostring(b
.trackkey
) end)
595 for _
, v
in ipairs(sort_objs
) do
596 y
, depth
= addMetaObjective(v
.cluster
, v
, y
, depth
)
598 QuestHelper
:ReleaseTable(v
)
600 QuestHelper
:ReleaseTable(sort_objs
)
601 QuestHelper
:ReleaseTable(objs
)
603 if had_pinned
then y
= y
+ 10 end
606 if QuestHelper
.loading_main
then
607 loading_vquest
.tracker_desc
= QHFormat("QH_LOADING", string.format("%d", QuestHelper
.loading_main
:GetPercentage() * 100))
608 local x
, ty
= addItem(loading_vquest
, y
)
611 if QuestHelper
.flightpathing
then
612 flightpath_vquest
.tracker_desc
= QHFormat("QH_FLIGHTPATH", string.format("%d", QuestHelper
.flightpathing
:GetPercentage() * 100))
613 local x
, ty
= addItem(flightpath_vquest
, y
)
617 local metalookup
= QuestHelper
:CreateTable("tracker rescan metalookup")
618 for k
, v
in ipairs(route
) do
620 if not metalookup
[v
.why
] then metalookup
[v
.why
] = QuestHelper
:CreateTable("tracker rescan metalookup item") end
621 if not v
.tracker_hidden
then table.insert(metalookup
[v
.why
], v
) end
627 local current_mo_cluster
628 for k
, v
in ipairs(route
) do
629 if depth
> QuestHelper_Pref
.track_size
and not debug_output
then break end
630 if not v
.ignore
and not v
.why
.tracker_hidden
and not obj_done
[v
.cluster
] then
631 if current_mo
and v
.why
~= current_mo
then
632 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
633 QuestHelper
:ReleaseTable(current_mo_cluster
)
634 current_mo
, current_mo_cluster
= nil, nil
637 if not v
.why
.tracker_split
then
638 if not mo_done
[v
.why
] then
639 y
, depth
= addMetaObjective(v
.why
, metalookup
[v
.why
], y
, depth
)
640 mo_done
[v
.why
] = true
643 if not current_mo
then
645 current_mo_cluster
= QuestHelper
:CreateTable("tracker current cluster")
647 if not v
.tracker_hidden
then table.insert(current_mo_cluster
, v
) end
653 if current_mo
and not (depth
> QuestHelper_Pref
.track_size
and not debug_output
) then
654 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
656 if current_mo_cluster
then
657 QuestHelper
:ReleaseTable(current_mo_cluster
)
661 for k
, v
in pairs(used_items
) do
662 if not used_count
[k
] or used_count
[k
] < #v
then
663 local ttp
= QuestHelper
:CreateTable("used_items ttp")
664 for m
= 1, (used_count
[k
] or 0) do
665 table.insert(ttp
, v
[m
])
667 for m
= (used_count
[k
] or 0) + 1, #v
do
668 removeUnusedItem(v
[m
])
671 if used_items
[k
] then
672 QuestHelper
:ReleaseTable(used_items
[k
])
679 QuestHelper
:ReleaseTable(ttp
)
684 QuestHelper
:ReleaseTable(mo_done
)
685 QuestHelper
:ReleaseTable(obj_done
)
686 for k
, v
in pairs(metalookup
) do
687 QuestHelper
:ReleaseTable(v
)
689 QuestHelper
:ReleaseTable(metalookup
)
691 QuestHelper
:ReleaseTable(used_count
)
694 if y
~= tracker
.dh
then
696 tracker
.sh
= tracker
:GetHeight()
698 tracker
.sw
= tracker
.dw
703 if x ~= tracker.dw or y ~= tracker.dy then
705 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
706 tracker.dw, tracker.dh = x, y
712 local quests = QuestHelper.quest_log
716 local track_size = QuestHelper_Pref.track_size
717 local quests_added = {}
719 for quest, objs in pairs(used_items) do
720 for obj, item in pairs(objs) do
725 for i, objective in pairs(QuestHelper.route) do
726 if objective.watched then
727 obj_index_lookup[objective] = i
731 for q, data in pairs(QuestHelper.quest_log) do
732 quest_lookup[data.index] = q
735 -- Add our little "not yet loaded" notification
736 local loadedshow = false
737 if not QuestHelper.Routing.map_walker then
739 x, y, gap, count = addobj(loading_vquest, seen, nil, nil, x, y, gap)
740 added = added + count
743 if QuestHelper_Flight_Updates and QuestHelper_Flight_Updates_Current and QuestHelper_Flight_Updates > 0 and QuestHelper_Flight_Updates_Current < QuestHelper_Flight_Updates then
744 loading_vquest.obj = string.format("7777/" .. QHFormat("QH_LOADING", string.format("%d", QuestHelper_Flight_Updates_Current * 100 / QuestHelper_Flight_Updates)))
748 -- Add an extra large gap to seperate the notification from everything else
751 -- Add Quests that are watched but not in the route.
753 local uq_settings = UberQuest_Config[UnitName("player")]
755 local list = uq_settings.selected
759 local name = GetQuestLogTitle(i)
760 if not name then break end
761 quest_lookup[name] = quest_lookup[i]
764 for name in pairs(list) do
765 local q = quest_lookup[name]
766 if q and not obj_index_lookup[q] then
768 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
769 added = added + count
770 quests_added[q] = true
776 for i = 1,GetNumQuestWatches() do
777 local q = quest_lookup[GetQuestIndexForWatch(i)]
778 if q and not obj_index_lookup[q] then
780 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
781 added = added + count
786 -- Add Quests that are watched and are in the route.
787 for i, objective in ipairs(QuestHelper.route) do
789 x, y, gap, count = addobj(objective, seen, obj_index_lookup, watched_filter, x, y, gap)
790 added = added + count
791 quests_added[objective] = true
794 -- Add an extra large gap to seperate the watched objectives from the automatic objectives.
797 -- Add Quests that aren't watched and are in the route.
798 if added <= track_size then
799 for i, objective in ipairs(QuestHelper.route) do
801 x, y, gap, count = addobj(objective, seen, obj_index_lookup, nil, x, y, gap)
802 added = added + count
803 quests_added[objective] = true
805 if added > track_size then
811 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
814 for k, v in pairs(quest_lookup) do
815 if not quests_added[v] then
816 notadded = notadded + 1
824 x, y, gap, count = addobj(hidden_vquest1, seen, nil, nil, x, y, gap)
825 added = added + count
826 x, y, gap, count = addobj(hidden_vquest2, seen, nil, nil, x, y, gap)
827 added = added + count
831 for obj in pairs(obj_index_lookup) do
832 obj_index_lookup[obj] = nil
835 for key in pairs(quest_lookup) do
836 quest_lookup[key] = nil
839 for quest, objs in pairs(used_items) do
840 for obj, item in pairs(objs) do
841 if not item.used then
842 removeUnusedItem(quest, obj, item)
847 for key in pairs(seen) do
853 if x ~= tracker.dw or y ~= tracker.dy then
855 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
856 tracker.dw, tracker.dh = x, y
864 function QH_Tracker_UpdateRoute(new_route
)
869 function QH_Tracker_Pin(metaobjective
)
870 if not pinned
[metaobjective
] then
871 pinned
[metaobjective
] = true
876 function QH_Tracker_Unpin(metaobjective
)
877 if pinned
[metaobjective
] then
878 pinned
[metaobjective
] = nil -- nil, not false, so it'll be garbage-collected appropriately
883 function QH_Tracker_SetPin(metaobjective
, flag
)
885 QH_Tracker_Pin(metaobjective
)
887 QH_Tracker_Unpin(metaobjective
)
892 local check_delay
= 4
894 -- This function does the grunt work of cursor positioning and rescaling. It does not actually reorganize items.
895 function tracker
:update(delta
)
897 -- This is called without a value when the questlog is updated.
898 -- We'll make sure we update the display on the next update.
904 local t
= self
.t
+delta
907 self
:SetWidth(self
.dw
)
908 self
:SetHeight(self
.dh
)
913 self
:SetWidth(self
.sw
*it
+self
.dw
*t
)
914 self
:SetHeight(self
.sh
*it
+self
.dh
*t
)
918 -- Manually checking if the mouse is in the frame, because if I used on OnEnter, i'd have to enable mouse input,
919 -- and if I did that, it would prevent the player from using the mouse to change the view if they clicked inside
921 local x
, y
= GetCursorPosition()
922 local s
= 1/self
:GetEffectiveScale()
925 QuestHelper
: Assert(x
)
926 QuestHelper
: Assert(y
)
927 --[[ QuestHelper: Assert(self:GetLeft())
928 QuestHelper: Assert(self:GetBottom())
929 QuestHelper: Assert(self:GetRight())
930 QuestHelper: Assert(self:GetTop())]]
932 -- Sometimes it just doesn't know its own coordinates. Not sure why. Maybe this will fix it.
933 local inside
= (self
:GetLeft() and (x
>= self
:GetLeft() and y
>= self
:GetBottom() and x
< self
:GetRight() and y
< self
:GetTop()))
934 if inside
~= was_inside
then
937 minbutton
:SetAlpha(.7)
938 elseif not QuestHelper_Pref
.track_minimized
then
939 minbutton
:SetAlpha(0)
943 check_delay
= check_delay
+ delta
944 if check_delay
> 1 then
951 tracker
:SetScript("OnUpdate", tracker
.update
)
953 -- Some hooks to update the tracker when quests are added or removed. These should be moved into the quest director.
955 local orig_AddQuestWatch, orig_RemoveQuestWatch = AddQuestWatch, RemoveQuestWatch
957 function AddQuestWatch(...)
959 return orig_AddQuestWatch(...)
962 function RemoveQuestWatch(...)
964 return orig_RemoveQuestWatch(...)
967 -------------------------------------------------------------------------------------------------
968 -- This batch of stuff is to make sure the original tracker (and any modifications) stay hidden
970 local orig_TrackerOnShow
971 if QuestWatchFrame
then -- 3.1 hackery
972 orig_TrackerOnShow
= QuestWatchFrame
:GetScript("OnShow")
974 local orig_TrackerBackdropOnShow
-- bEQL (and perhaps other mods) add a backdrop to the tracker
975 local TrackerBackdropFound
= false
977 local function TrackerBackdropOnShow(self
, ...)
978 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
979 TrackerBackdropFound
:Hide()
982 if orig_TrackerBackdropOnShow
then
983 return orig_TrackerBackdropOnShow(self
, ...)
987 function tracker
:HideDefaultTracker()
988 -- The easy part: hide the original tracker
989 WatchFrame_RemoveObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
990 WatchFrame_ClearDisplay()
993 -- The harder part: hide all those little buttons
997 local orig
= _G
["WatchFrameItem" .. tostring(index
)]
998 if orig
then orig
:Hide() else break end
1003 -- The harder part: check if a known backdrop is present (but we don't already know about it).
1004 -- If it is, make sure it's hidden, and hook its OnShow to make sure it stays that way.
1005 -- Unfortunately, I can't figure out a good time to check for this once, so we'll just have
1006 -- to keep checking. Hopefully, this won't happen too often.
1007 if not TrackerBackdropFound
then
1008 if QuestWatchFrameBackdrop
then
1009 -- Found bEQL's QuestWatchFrameBackdrop...
1010 TrackerBackdropFound
= QuestWatchFrameBackdrop
1013 if TrackerBackdropFound
then
1014 -- OK, we found something - so hide it, and make sure it doesn't rear its ugly head again
1015 TrackerBackdropFound
:Hide()
1017 orig_TrackerBackdropOnShow
= TrackerBackdropFound
:GetScript("OnShow")
1018 TrackerBackdropFound
:SetScript("OnShow", TrackerBackdropOnShow
)
1023 function tracker
:ShowDefaultTracker()
1024 if QuestWatchFrame
then -- 3.1 hackery
1025 QuestWatchFrame
:Show()
1026 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1029 -- I like how there's code explicitly to allow us to do this without checking if it's already added
1030 WatchFrame_AddObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1031 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1035 if TrackerBackdropFound
then
1036 TrackerBackdropFound
:Show()
1040 if QuestWatchFrame
then -- 3.1 hackery
1041 local function QuestWatchFrameOnShow(self
, ...)
1042 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
1043 tracker
:HideDefaultTracker()
1046 if orig_TrackerOnShow
then
1047 return orig_TrackerOnShow(self
, ...)
1051 QuestWatchFrame
:SetScript("OnShow", QuestWatchFrameOnShow
)
1054 function QuestHelper
:ShowTracker()
1055 tracker
:HideDefaultTracker()
1058 if QuestHelper_Pref
.track_minimized
then
1059 minbutton
:SetAlpha(.3)
1061 minbutton
:SetAlpha(0)
1066 function QuestHelper
:HideTracker()
1067 tracker
:ShowDefaultTracker()