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
)
329 if objective
.type_quest
then
330 QuestHelper
: Assert(objective
.type_quest
.index
)
334 -- hacky - progress only shows up if we're not on a metaobjective. wheee
335 if objective
.type_quest
and not objective
.progress
and GetQuestLogSpecialItemInfo(objective
.type_quest
.index
) then
336 item
.specitem
= table.remove(specitem_unused
)
337 if not item
.specitem
then
338 item
.specitem
= CreateFrame("BUTTON", "QH_SpecItem_" .. tostring(specitem_max
), item
, "WatchFrameItemButtonTemplate")
339 QuestHelper
: Assert(item
.specitem
)
341 local rangey
= _G
["QH_SpecItem_" .. tostring(specitem_max
) .. "HotKey"]
342 QuestHelper
: Assert(rangey
)
343 local fn
, fh
, ff
= rangey
:GetFont()
344 rangey
:SetFont("Fonts\\ARIALN.TTF", fh
, ff
)
345 rangey
:SetText(RANGE_INDICATOR
)
346 rangey
:ClearAllPoints()
347 rangey
:SetPoint("BOTTOMRIGHT", item
.specitem
, "BOTTOMRIGHT", 0, 2)
349 specitem_max
= specitem_max
+ 1
352 item
.specitem
:SetScale(0.9)
353 item
.specitem
:ClearAllPoints()
354 item
.specitem
:SetPoint("TOPRIGHT", item
, "TOPLEFT", 0, 0)
356 local _
, tex
= GetQuestLogSpecialItemInfo(objective
.type_quest
.index
)
357 item
.specitem
:SetID(objective
.type_quest
.index
)
358 SetItemButtonTexture(item
.specitem
, tex
)
359 item
.specitem
.rangeTimer
= -1 -- This makes the little dot go away. Why does it do that?
366 return w
+x
+4, y
+h
, y
+h
+spacer
369 local function addMetaObjective(metaobj
, items
, y
, depth
)
371 x
, y
, spacer
= addItem(metaobj
, y
, true)
372 for _
, v
in ipairs(items
) do
373 x
, y
= addItem(v
, y
, false)
375 return math
.max(y
, spacer
), depth
+ #items
+ 1
378 --[[ -- these will be plugged in later one way or another
379 local function ccode(r1, g1, b1, r2, g2, b2, p)
381 p, ip = p*255, 255-p*255
382 return string.format("|cff%02x%02x%02x", r1*ip+r2*p, g1*ip+g2*p, b1*ip+b2*p)
385 local function qname(title, level)
386 if QuestHelper_Pref.track_level and level ~= 7777 and level ~= 7778 then
387 title = string.format("[%d] %s", level, title)
390 if level == 7778 then
394 if QuestHelper_Pref.track_qcolour then
395 local player_level = QuestHelper.player_level
396 local delta = level - player_level
401 colour = "|cffff0000"
402 elseif delta >= 0 then
403 colour = ccode(1, 1, 0, 1, 0, 0, delta/5)
407 if player_level >= 60 then grey = player_level - 9
408 elseif player_level >= 40 then grey = player_level - math.floor(player_level/5) - 1
409 elseif player_level >= 6 then grey = player_level - math.floor(player_level/10) - 5
412 if level == -7778 then
413 colour = "|cff808080"
414 elseif level > grey then
415 colour = ccode(0, 1, 0, 1, 1, 0, (grey-level)/(grey-player_level))
417 colour = ccode(.4, .4, .4, .2, .8, .2, (1-level)/(1-grey))
421 title = string.format("%s%s", colour, title)
427 local function oname(text, pct)
428 if QuestHelper_Pref.track_ocolour then
429 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)
436 local function removeUnusedItem(item
)
438 item
.sx
, item
.sy
, item
.dx
, item
.dy
= item
.x
, item
.y
, item
.x
+30, item
.y
439 item
:SetScript("OnMouseDown", nil)
440 item
:EnableMouse(false)
441 item
:SetScript("OnUpdate", itemfadeout
)
443 if item
.specitem
then
445 table.insert(specitem_unused
, item
.specitem
)
451 local was_inside
= false
455 local function addobj(objective
, seen
, obj_index_lookup
, filter
, x
, y
, gap
)
459 if objective
.cat
== "quest" then
462 quest
= objective
.quest
465 if quest
and quest
.watched
and not seen
[quest
] and (not filter
or filter(quest
)) then
468 local level
, name
= string.match(quest
.obj
, "^(%d+)/%d*/(.*)$")
471 level
, name
= string.match(quest
.obj
, "^(%d+)/(.*)$")
473 level
, name
= 1, quest
.obj
477 level
= tonumber(level
) or 1
480 local w
, h
= addItem(qname(name
, level
), true, quest
, -(y
+gap
), name
, quest
.index
)
485 for obj
in pairs(quest
.swap_after
or quest
.after
) do
487 table.insert(obj_list
, obj
)
491 table.sort(obj_list
, objlist_sort
)
493 for i
, obj
in ipairs(obj_list
) do
494 local pct
, text
= 0, obj
.obj
495 local seen_sum
, seen_max
= 0, 0
498 local seen_have
, seen_need
= QuestHelper
:CreateTable(), QuestHelper
:CreateTable()
500 for user
, progress
in pairs(obj
.progress
) do
501 seen_sum
= seen_sum
+ progress
[3]
502 seen_max
= seen_max
+ 1
503 seen_have
[progress
[1]]
= true
504 seen_need
[progress
[2]]
= true
508 pct
= seen_sum
/ seen_max
509 local list
= QuestHelper
:CreateTable()
511 for val
in pairs(seen_have
) do
512 table.insert(list
, val
)
517 local have
= table.concat(list
, ", ")
519 for i
= #list
,1,-1 do
523 for val
in pairs(seen_need
) do
524 table.insert(list
, val
)
527 if #list
~= 1 or list
[1] ~= 1 then
528 -- If there is only one thing needed, ignore the progress, it's redundant.
529 -- It's either shown or it isn't.
533 local need
= table.concat(list
, ", ")
535 text
= string.format((tonumber(have
) and tonumber(need
) and QUEST_ITEMS_NEEDED
) or QUEST_FACTION_NEEDED
,
539 QuestHelper
:ReleaseTable(list
)
542 QuestHelper
:ReleaseTable(seen_have
)
543 QuestHelper
:ReleaseTable(seen_need
)
546 if seen_sum
~= seen_max
then
548 w
, h
= addItem(oname(text
, pct
), quest
, obj
, -y
)
554 for i
= #obj_list
, 1, -1 do obj_list
[i
] = nil end
557 return x
, y
, gap
, count
561 local loading_vquest
= {tracker_desc
= QHFormat("QH_LOADING", "0")}
562 local flightpath_vquest
= {tracker_desc
= QHFormat("QH_FLIGHTPATH", "0")}
564 --local hidden_vquest1 = { cat = "quest", obj = "7778/" .. QHText("QUESTS_HIDDEN_1"), after = {}, watched = true }
565 --local hidden_vquest2 = { cat = "quest", obj = "7778/ " .. QHText("QUESTS_HIDDEN_2"), after = {}, watched = true }
570 -- This is actually called surprisingly often.
571 function QH_Tracker_Rescan()
572 used_count
= QuestHelper
:CreateTable("tracker rescan used_count")
574 local mo_done
= QuestHelper
:CreateTable("tracker rescan mo_done")
575 local obj_done
= QuestHelper
:CreateTable("tracker rescan obj_done")
577 local y
, depth
= 0, 0
580 local had_pinned
= false
582 local objs
= QuestHelper
:CreateTable("tracker objs")
583 for k
, v
in pairs(pinned
) do
584 if not objs
[k
.why
] then objs
[k
.why
] = QuestHelper
:CreateTable("tracker objs sub") end
585 if not k
.ignore
and not k
.tracker_hidden
then table.insert(objs
[k
.why
], k
) end
586 obj_done
[k
.cluster
] = true
589 local sort_objs
= QuestHelper
:CreateTable("tracker sobjs")
590 for k
, v
in pairs(objs
) do
593 table.insert(sort_objs
, v
)
596 table.sort(sort_objs
, function (a
, b
) return tostring(a
.trackkey
) < tostring(b
.trackkey
) end)
598 for _
, v
in ipairs(sort_objs
) do
599 y
, depth
= addMetaObjective(v
.cluster
, v
, y
, depth
)
601 QuestHelper
:ReleaseTable(v
)
603 QuestHelper
:ReleaseTable(sort_objs
)
604 QuestHelper
:ReleaseTable(objs
)
606 if had_pinned
then y
= y
+ 10 end
609 if QuestHelper
.loading_main
then
610 loading_vquest
.tracker_desc
= QHFormat("QH_LOADING", string.format("%d", QuestHelper
.loading_main
:GetPercentage() * 100))
611 local x
, ty
= addItem(loading_vquest
, y
)
614 if QuestHelper
.flightpathing
then
615 flightpath_vquest
.tracker_desc
= QHFormat("QH_FLIGHTPATH", string.format("%d", QuestHelper
.flightpathing
:GetPercentage() * 100))
616 local x
, ty
= addItem(flightpath_vquest
, y
)
620 local metalookup
= QuestHelper
:CreateTable("tracker rescan metalookup")
621 for k
, v
in ipairs(route
) do
623 if not metalookup
[v
.why
] then metalookup
[v
.why
] = QuestHelper
:CreateTable("tracker rescan metalookup item") end
624 if not v
.tracker_hidden
then table.insert(metalookup
[v
.why
], v
) end
630 local current_mo_cluster
631 for k
, v
in ipairs(route
) do
632 if depth
> QuestHelper_Pref
.track_size
and not debug_output
then break end
633 if not v
.ignore
and not v
.why
.tracker_hidden
and not obj_done
[v
.cluster
] then
634 if current_mo
and v
.why
~= current_mo
then
635 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
636 QuestHelper
:ReleaseTable(current_mo_cluster
)
637 current_mo
, current_mo_cluster
= nil, nil
640 if not v
.why
.tracker_split
then
641 if not mo_done
[v
.why
] then
642 y
, depth
= addMetaObjective(v
.why
, metalookup
[v
.why
], y
, depth
)
643 mo_done
[v
.why
] = true
646 if not current_mo
then
648 current_mo_cluster
= QuestHelper
:CreateTable("tracker current cluster")
650 if not v
.tracker_hidden
then table.insert(current_mo_cluster
, v
) end
656 if current_mo
and not (depth
> QuestHelper_Pref
.track_size
and not debug_output
) then
657 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
659 if current_mo_cluster
then
660 QuestHelper
:ReleaseTable(current_mo_cluster
)
664 for k
, v
in pairs(used_items
) do
665 if not used_count
[k
] or used_count
[k
] < #v
then
666 local ttp
= QuestHelper
:CreateTable("used_items ttp")
667 for m
= 1, (used_count
[k
] or 0) do
668 table.insert(ttp
, v
[m
])
670 for m
= (used_count
[k
] or 0) + 1, #v
do
671 removeUnusedItem(v
[m
])
674 if used_items
[k
] then
675 QuestHelper
:ReleaseTable(used_items
[k
])
682 QuestHelper
:ReleaseTable(ttp
)
687 QuestHelper
:ReleaseTable(mo_done
)
688 QuestHelper
:ReleaseTable(obj_done
)
689 for k
, v
in pairs(metalookup
) do
690 QuestHelper
:ReleaseTable(v
)
692 QuestHelper
:ReleaseTable(metalookup
)
694 QuestHelper
:ReleaseTable(used_count
)
697 if y
~= tracker
.dh
then
699 tracker
.sh
= tracker
:GetHeight()
701 tracker
.sw
= tracker
.dw
706 if x ~= tracker.dw or y ~= tracker.dy then
708 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
709 tracker.dw, tracker.dh = x, y
715 local quests = QuestHelper.quest_log
719 local track_size = QuestHelper_Pref.track_size
720 local quests_added = {}
722 for quest, objs in pairs(used_items) do
723 for obj, item in pairs(objs) do
728 for i, objective in pairs(QuestHelper.route) do
729 if objective.watched then
730 obj_index_lookup[objective] = i
734 for q, data in pairs(QuestHelper.quest_log) do
735 quest_lookup[data.index] = q
738 -- Add our little "not yet loaded" notification
739 local loadedshow = false
740 if not QuestHelper.Routing.map_walker then
742 x, y, gap, count = addobj(loading_vquest, seen, nil, nil, x, y, gap)
743 added = added + count
746 if QuestHelper_Flight_Updates and QuestHelper_Flight_Updates_Current and QuestHelper_Flight_Updates > 0 and QuestHelper_Flight_Updates_Current < QuestHelper_Flight_Updates then
747 loading_vquest.obj = string.format("7777/" .. QHFormat("QH_LOADING", string.format("%d", QuestHelper_Flight_Updates_Current * 100 / QuestHelper_Flight_Updates)))
751 -- Add an extra large gap to seperate the notification from everything else
754 -- Add Quests that are watched but not in the route.
756 local uq_settings = UberQuest_Config[UnitName("player")]
758 local list = uq_settings.selected
762 local name = GetQuestLogTitle(i)
763 if not name then break end
764 quest_lookup[name] = quest_lookup[i]
767 for name in pairs(list) do
768 local q = quest_lookup[name]
769 if q and not obj_index_lookup[q] then
771 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
772 added = added + count
773 quests_added[q] = true
779 for i = 1,GetNumQuestWatches() do
780 local q = quest_lookup[GetQuestIndexForWatch(i)]
781 if q and not obj_index_lookup[q] then
783 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
784 added = added + count
789 -- Add Quests that are watched and are in the route.
790 for i, objective in ipairs(QuestHelper.route) do
792 x, y, gap, count = addobj(objective, seen, obj_index_lookup, watched_filter, x, y, gap)
793 added = added + count
794 quests_added[objective] = true
797 -- Add an extra large gap to seperate the watched objectives from the automatic objectives.
800 -- Add Quests that aren't watched and are in the route.
801 if added <= track_size then
802 for i, objective in ipairs(QuestHelper.route) do
804 x, y, gap, count = addobj(objective, seen, obj_index_lookup, nil, x, y, gap)
805 added = added + count
806 quests_added[objective] = true
808 if added > track_size then
814 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
817 for k, v in pairs(quest_lookup) do
818 if not quests_added[v] then
819 notadded = notadded + 1
827 x, y, gap, count = addobj(hidden_vquest1, seen, nil, nil, x, y, gap)
828 added = added + count
829 x, y, gap, count = addobj(hidden_vquest2, seen, nil, nil, x, y, gap)
830 added = added + count
834 for obj in pairs(obj_index_lookup) do
835 obj_index_lookup[obj] = nil
838 for key in pairs(quest_lookup) do
839 quest_lookup[key] = nil
842 for quest, objs in pairs(used_items) do
843 for obj, item in pairs(objs) do
844 if not item.used then
845 removeUnusedItem(quest, obj, item)
850 for key in pairs(seen) do
856 if x ~= tracker.dw or y ~= tracker.dy then
858 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
859 tracker.dw, tracker.dh = x, y
867 function QH_Tracker_UpdateRoute(new_route
)
872 function QH_Tracker_Pin(metaobjective
)
873 if not pinned
[metaobjective
] then
874 pinned
[metaobjective
] = true
879 function QH_Tracker_Unpin(metaobjective
)
880 if pinned
[metaobjective
] then
881 pinned
[metaobjective
] = nil -- nil, not false, so it'll be garbage-collected appropriately
886 function QH_Tracker_SetPin(metaobjective
, flag
)
888 QH_Tracker_Pin(metaobjective
)
890 QH_Tracker_Unpin(metaobjective
)
895 local check_delay
= 4
897 -- This function does the grunt work of cursor positioning and rescaling. It does not actually reorganize items.
898 function tracker
:update(delta
)
900 -- This is called without a value when the questlog is updated.
901 -- We'll make sure we update the display on the next update.
907 local t
= self
.t
+delta
910 self
:SetWidth(self
.dw
)
911 self
:SetHeight(self
.dh
)
916 self
:SetWidth(self
.sw
*it
+self
.dw
*t
)
917 self
:SetHeight(self
.sh
*it
+self
.dh
*t
)
921 -- Manually checking if the mouse is in the frame, because if I used on OnEnter, i'd have to enable mouse input,
922 -- and if I did that, it would prevent the player from using the mouse to change the view if they clicked inside
924 local x
, y
= GetCursorPosition()
925 local s
= 1/self
:GetEffectiveScale()
928 QuestHelper
: Assert(x
)
929 QuestHelper
: Assert(y
)
930 --[[ QuestHelper: Assert(self:GetLeft())
931 QuestHelper: Assert(self:GetBottom())
932 QuestHelper: Assert(self:GetRight())
933 QuestHelper: Assert(self:GetTop())]]
935 -- Sometimes it just doesn't know its own coordinates. Not sure why. Maybe this will fix it.
936 local inside
= (self
:GetLeft() and (x
>= self
:GetLeft() and y
>= self
:GetBottom() and x
< self
:GetRight() and y
< self
:GetTop()))
937 if inside
~= was_inside
then
940 minbutton
:SetAlpha(.7)
941 elseif not QuestHelper_Pref
.track_minimized
then
942 minbutton
:SetAlpha(0)
946 check_delay
= check_delay
+ delta
947 if check_delay
> 1 then
954 tracker
:SetScript("OnUpdate", tracker
.update
)
956 -- Some hooks to update the tracker when quests are added or removed. These should be moved into the quest director.
958 local orig_AddQuestWatch, orig_RemoveQuestWatch = AddQuestWatch, RemoveQuestWatch
960 function AddQuestWatch(...)
962 return orig_AddQuestWatch(...)
965 function RemoveQuestWatch(...)
967 return orig_RemoveQuestWatch(...)
970 -------------------------------------------------------------------------------------------------
971 -- This batch of stuff is to make sure the original tracker (and any modifications) stay hidden
973 local orig_TrackerOnShow
974 if QuestWatchFrame
then -- 3.1 hackery
975 orig_TrackerOnShow
= QuestWatchFrame
:GetScript("OnShow")
977 local orig_TrackerBackdropOnShow
-- bEQL (and perhaps other mods) add a backdrop to the tracker
978 local TrackerBackdropFound
= false
980 local function TrackerBackdropOnShow(self
, ...)
981 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
982 TrackerBackdropFound
:Hide()
985 if orig_TrackerBackdropOnShow
then
986 return orig_TrackerBackdropOnShow(self
, ...)
990 function tracker
:HideDefaultTracker()
991 -- The easy part: hide the original tracker
992 WatchFrame_RemoveObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
993 WatchFrame_ClearDisplay()
996 -- The harder part: hide all those little buttons
1000 local orig
= _G
["WatchFrameItem" .. tostring(index
)]
1001 if orig
then orig
:Hide() else break end
1006 -- The harder part: check if a known backdrop is present (but we don't already know about it).
1007 -- If it is, make sure it's hidden, and hook its OnShow to make sure it stays that way.
1008 -- Unfortunately, I can't figure out a good time to check for this once, so we'll just have
1009 -- to keep checking. Hopefully, this won't happen too often.
1010 if not TrackerBackdropFound
then
1011 if QuestWatchFrameBackdrop
then
1012 -- Found bEQL's QuestWatchFrameBackdrop...
1013 TrackerBackdropFound
= QuestWatchFrameBackdrop
1016 if TrackerBackdropFound
then
1017 -- OK, we found something - so hide it, and make sure it doesn't rear its ugly head again
1018 TrackerBackdropFound
:Hide()
1020 orig_TrackerBackdropOnShow
= TrackerBackdropFound
:GetScript("OnShow")
1021 TrackerBackdropFound
:SetScript("OnShow", TrackerBackdropOnShow
)
1026 function tracker
:ShowDefaultTracker()
1027 if QuestWatchFrame
then -- 3.1 hackery
1028 QuestWatchFrame
:Show()
1029 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1032 -- I like how there's code explicitly to allow us to do this without checking if it's already added
1033 WatchFrame_AddObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1034 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1038 if TrackerBackdropFound
then
1039 TrackerBackdropFound
:Show()
1043 if QuestWatchFrame
then -- 3.1 hackery
1044 local function QuestWatchFrameOnShow(self
, ...)
1045 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
1046 tracker
:HideDefaultTracker()
1049 if orig_TrackerOnShow
then
1050 return orig_TrackerOnShow(self
, ...)
1054 QuestWatchFrame
:SetScript("OnShow", QuestWatchFrameOnShow
)
1057 function QuestHelper
:ShowTracker()
1058 tracker
:HideDefaultTracker()
1061 if QuestHelper_Pref
.track_minimized
then
1062 minbutton
:SetAlpha(.3)
1064 minbutton
:SetAlpha(0)
1069 function QuestHelper
:HideTracker()
1070 tracker
:ShowDefaultTracker()