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 QH_Event({"DISPLAY_SIZE_CHANGED", "PLAYER_ENTERING_WORLD"}, function () minbutton
:moved() end)
94 QH_Hook(minbutton
, "OnClick", function ()
95 QuestHelper_Pref
.track_minimized
= not QuestHelper_Pref
.track_minimized
96 if QuestHelper_Pref
.track_minimized
then
103 minbutton
:RegisterForDrag("LeftButton")
105 QH_Hook(minbutton
, "OnDragStart", function(self
)
106 if self
:IsVisible() then
108 QH_Hook(self
, "OnUpdate", self
.moved
)
112 QH_Hook(minbutton
, "OnDragStop", function(self
)
113 QH_Hook(self
, "OnUpdate", nil)
114 self
:StopMovingOrSizing()
118 QH_Hook(minbutton
, "OnEnter", function (self
)
122 QH_Hook(minbutton
, "OnLeave", function (self
)
123 self
:SetAlpha(QuestHelper_Pref
.track_minimized
and .3 or .5)
126 -- used_items[objective][index]
127 -- used_count[objective] is incremented as the last valid index
128 -- so, therefore, used_items[objective][used_count[objective]] is not nil
129 local used_items
= {}
130 local used_count
= {}
132 -- it's possible for an item to be in neither used_items nor recycled_items, if it's in the process of fading out
133 local recycled_items
= {}
135 -- These two functions are basically identical. Combine them.
136 local function itemupdate(item
, delta
)
139 local a
= item
:GetAlpha()
149 local t
= item
.t
+ delta
154 local sp
= math
.sqrt(t
-t
*t
)
155 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
159 item
.x
, item
.y
= item
.ex
, item
.ey
162 item
:ClearAllPoints()
163 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
166 QH_Hook(item
, "OnUpdate", nil)
170 local function itemfadeout(item
, delta
)
171 local a
= item
:GetAlpha()
179 QH_Hook(item
, "OnUpdate", nil)
180 table.insert(recycled_items
, item
)
184 local t
= item
.t
+ delta
189 local sp
= math
.sqrt(t
-t
*t
)
190 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
193 item
.x
, item
.y
= item
.ex
, item
.ey
196 item
:ClearAllPoints()
197 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
200 --[[function QH_ToggleQuestLog() -- This seems to be gone in 3.0, so I'm adding it here.
201 if (QuestLogFrame:IsShown()) then
202 HideUIPanel(QuestLogFrame);
204 ShowUIPanel(QuestLogFrame);
208 -- Grim stuff with uberquest, I need a better way to handle this
209 local function itemclick(item, button)
210 if button == "RightButton" then
211 local quest = item.quest
214 local title = GetQuestLogTitle(index)
215 if not title then break end
217 if title == quest then
219 -- UberQuest needs a little extra effort to work properly.
221 if UberQuest_List:IsShown() and GetQuestLogSelection() == index then
224 QuestLog_SetSelection(index)
226 -- By hiding the list, the replaced ToggleQuestLog function should try to reshow it
227 -- and in the process update the frames to reflect the selected quest.
228 UberQuest_List:Hide()
229 UberQuest_Details:Show()
233 -- This code seems to work properly with the builtin questlog, as well as bEQL and DoubleWide.
235 if QuestLogFrame:IsShown() and GetQuestLogSelection() == index then
236 -- If the selected quest is already being shown, hide it.
239 -- Otherwise, select it and show it.
240 QuestLog_SetSelection(index)
242 if not QuestLogFrame:IsShown() then
256 local function allocateItem()
259 item
= table.remove(recycled_items
)
260 if item
then return item
end
262 item
= CreateFrame("Frame", nil, tracker
)
263 item
.text
= item
:CreateFontString()
264 item
.text
:SetShadowColor(0, 0, 0, .8)
265 item
.text
:SetShadowOffset(1, -1)
266 item
.text
:SetPoint("TOPLEFT", item
)
270 local specitem_max
= 1
271 local specitem_unused
= {}
273 -- 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
274 local function addItem(objective
, y
, meta
)
275 local obj_key
= objective
276 if obj_key
.cluster
then obj_key
= obj_key
.cluster
end
277 used_count
[obj_key
] = (used_count
[obj_key
] or 0) + 1
278 if not used_items
[obj_key
] then used_items
[obj_key
] = QuestHelper
:CreateTable("additem used_items") end
279 local item
= used_items
[obj_key
][used_count
[obj_key]]
281 local x
= meta
and 4 or 20
284 used_items
[obj_key
][used_count
[obj_key]]
= allocateItem()
285 item
= used_items
[obj_key
][used_count
[obj_key]]
288 item
.text
:SetFont(QuestHelper
.font
.serif
, 12)
289 item
.text
:SetTextColor(.82, .65, 0)
291 item
.text
:SetFont(QuestHelper
.font
.sans
, 12)
292 item
.text
:SetTextColor(.82, .82, .82)
297 item
.sx
, item
.sy
, item
.x
, item
.y
, item
.ex
, item
.ey
, item
.t
= x
+30, y
, x
, y
, x
, y
, 0
298 QH_Hook(item
, "OnUpdate", itemupdate
)
303 item
.text
:SetText(item
.obj
.tracker_desc
or "(no description)")
305 local w
, h
= item
.text
:GetWidth(), item
.text
:GetHeight()
309 if objective
.tracker_clicked
then
310 QH_Hook(item
, "OnMouseDown", function (self
, button
) if button
== "RightButton" then objective
.tracker_clicked() end end)
311 item
:EnableMouse(true)
314 if item
.ex
~= x
or item
.ey
~= y
then
315 item
.sx
, item
.sy
, item
.ex
, item
.ey
= item
.x
, item
.y
, x
, y
317 QH_Hook(item
, "OnUpdate", itemupdate
)
320 -- we're just going to recycle this each time
321 if item
.specitem
then
323 table.insert(specitem_unused
, item
.specitem
)
328 -- hacky - progress only shows up if we're not on a metaobjective. wheee
329 if objective
.type_quest
and objective
.type_quest
.index
and not objective
.progress
and GetQuestLogSpecialItemInfo(objective
.type_quest
.index
) then
330 item
.specitem
= table.remove(specitem_unused
)
331 if not item
.specitem
then
332 item
.specitem
= CreateFrame("BUTTON", "QH_SpecItem_" .. tostring(specitem_max
), item
, "WatchFrameItemButtonTemplate")
333 QuestHelper
: Assert(item
.specitem
)
335 local rangey
= _G
["QH_SpecItem_" .. tostring(specitem_max
) .. "HotKey"]
336 QuestHelper
: Assert(rangey
)
337 local fn
, fh
, ff
= rangey
:GetFont()
338 rangey
:SetFont("Fonts\\ARIALN.TTF", fh
, ff
)
339 rangey
:SetText(RANGE_INDICATOR
)
340 rangey
:ClearAllPoints()
341 rangey
:SetPoint("BOTTOMRIGHT", item
.specitem
, "BOTTOMRIGHT", 0, 2)
343 specitem_max
= specitem_max
+ 1
346 item
.specitem
:SetScale(0.9)
347 item
.specitem
:ClearAllPoints()
348 item
.specitem
:SetParent(item
)
349 item
.specitem
:SetPoint("TOPRIGHT", item
, "TOPLEFT", 0, 0)
351 local _
, tex
= GetQuestLogSpecialItemInfo(objective
.type_quest
.index
)
352 item
.specitem
:SetID(objective
.type_quest
.index
)
353 SetItemButtonTexture(item
.specitem
, tex
)
354 item
.specitem
.rangeTimer
= -1 -- This makes the little dot go away. Why does it do that?
361 return w
+x
+4, y
+h
, y
+h
+spacer
364 local function addMetaObjective(metaobj
, items
, y
, depth
)
366 x
, y
, spacer
= addItem(metaobj
, y
, true)
367 for _
, v
in ipairs(items
) do
368 x
, y
= addItem(v
, y
, false)
370 return math
.max(y
, spacer
), depth
+ #items
+ 1
373 --[[ -- these will be plugged in later one way or another
374 local function ccode(r1, g1, b1, r2, g2, b2, p)
376 p, ip = p*255, 255-p*255
377 return string.format("|cff%02x%02x%02x", r1*ip+r2*p, g1*ip+g2*p, b1*ip+b2*p)
380 local function qname(title, level)
381 if QuestHelper_Pref.track_level and level ~= 7777 and level ~= 7778 then
382 title = string.format("[%d] %s", level, title)
385 if level == 7778 then
389 if QuestHelper_Pref.track_qcolour then
390 local player_level = QuestHelper.player_level
391 local delta = level - player_level
396 colour = "|cffff0000"
397 elseif delta >= 0 then
398 colour = ccode(1, 1, 0, 1, 0, 0, delta/5)
402 if player_level >= 60 then grey = player_level - 9
403 elseif player_level >= 40 then grey = player_level - math.floor(player_level/5) - 1
404 elseif player_level >= 6 then grey = player_level - math.floor(player_level/10) - 5
407 if level == -7778 then
408 colour = "|cff808080"
409 elseif level > grey then
410 colour = ccode(0, 1, 0, 1, 1, 0, (grey-level)/(grey-player_level))
412 colour = ccode(.4, .4, .4, .2, .8, .2, (1-level)/(1-grey))
416 title = string.format("%s%s", colour, title)
422 local function oname(text, pct)
423 if QuestHelper_Pref.track_ocolour then
424 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)
431 local function removeUnusedItem(item
)
433 item
.sx
, item
.sy
, item
.dx
, item
.dy
= item
.x
, item
.y
, item
.x
+30, item
.y
434 QH_Hook(item
, "OnMouseDown", nil)
435 item
:EnableMouse(false)
436 QH_Hook(item
, "OnUpdate", itemfadeout
)
438 if item
.specitem
then
440 table.insert(specitem_unused
, item
.specitem
)
446 local was_inside
= false
450 local function addobj(objective
, seen
, obj_index_lookup
, filter
, x
, y
, gap
)
454 if objective
.cat
== "quest" then
457 quest
= objective
.quest
460 if quest
and quest
.watched
and not seen
[quest
] and (not filter
or filter(quest
)) then
463 local level
, name
= string.match(quest
.obj
, "^(%d+)/%d*/(.*)$")
466 level
, name
= string.match(quest
.obj
, "^(%d+)/(.*)$")
468 level
, name
= 1, quest
.obj
472 level
= tonumber(level
) or 1
475 local w
, h
= addItem(qname(name
, level
), true, quest
, -(y
+gap
), name
, quest
.index
)
480 for obj
in pairs(quest
.swap_after
or quest
.after
) do
482 table.insert(obj_list
, obj
)
486 table.sort(obj_list
, objlist_sort
)
488 for i
, obj
in ipairs(obj_list
) do
489 local pct
, text
= 0, obj
.obj
490 local seen_sum
, seen_max
= 0, 0
493 local seen_have
, seen_need
= QuestHelper
:CreateTable(), QuestHelper
:CreateTable()
495 for user
, progress
in pairs(obj
.progress
) do
496 seen_sum
= seen_sum
+ progress
[3]
497 seen_max
= seen_max
+ 1
498 seen_have
[progress
[1]]
= true
499 seen_need
[progress
[2]]
= true
503 pct
= seen_sum
/ seen_max
504 local list
= QuestHelper
:CreateTable()
506 for val
in pairs(seen_have
) do
507 table.insert(list
, val
)
512 local have
= table.concat(list
, ", ")
514 for i
= #list
,1,-1 do
518 for val
in pairs(seen_need
) do
519 table.insert(list
, val
)
522 if #list
~= 1 or list
[1] ~= 1 then
523 -- If there is only one thing needed, ignore the progress, it's redundant.
524 -- It's either shown or it isn't.
528 local need
= table.concat(list
, ", ")
530 text
= string.format((tonumber(have
) and tonumber(need
) and QUEST_ITEMS_NEEDED
) or QUEST_FACTION_NEEDED
,
534 QuestHelper
:ReleaseTable(list
)
537 QuestHelper
:ReleaseTable(seen_have
)
538 QuestHelper
:ReleaseTable(seen_need
)
541 if seen_sum
~= seen_max
then
543 w
, h
= addItem(oname(text
, pct
), quest
, obj
, -y
)
549 for i
= #obj_list
, 1, -1 do obj_list
[i
] = nil end
552 return x
, y
, gap
, count
556 local loading_vquest
= {tracker_desc
= QHFormat("QH_LOADING", "0")}
557 local flightpath_vquest
= {tracker_desc
= QHFormat("QH_FLIGHTPATH", "0")}
559 --local hidden_vquest1 = { cat = "quest", obj = "7778/" .. QHText("QUESTS_HIDDEN_1"), after = {}, watched = true }
560 --local hidden_vquest2 = { cat = "quest", obj = "7778/ " .. QHText("QUESTS_HIDDEN_2"), after = {}, watched = true }
565 -- This is actually called surprisingly often.
566 function QH_Tracker_Rescan()
567 used_count
= QuestHelper
:CreateTable("tracker rescan used_count")
569 local mo_done
= QuestHelper
:CreateTable("tracker rescan mo_done")
570 local obj_done
= QuestHelper
:CreateTable("tracker rescan obj_done")
572 local y
, depth
= 0, 0
575 local had_pinned
= false
577 local objs
= QuestHelper
:CreateTable("tracker objs")
578 for k
, v
in pairs(pinned
) do
579 if not objs
[k
.why
] then objs
[k
.why
] = QuestHelper
:CreateTable("tracker objs sub") end
580 if not k
.ignore
and not k
.tracker_hidden
then table.insert(objs
[k
.why
], k
) end
581 obj_done
[k
.cluster
] = true
584 local sort_objs
= QuestHelper
:CreateTable("tracker sobjs")
585 for k
, v
in pairs(objs
) do
588 table.insert(sort_objs
, v
)
591 table.sort(sort_objs
, function (a
, b
) return tostring(a
.trackkey
) < tostring(b
.trackkey
) end)
593 for _
, v
in ipairs(sort_objs
) do
594 y
, depth
= addMetaObjective(v
.cluster
, v
, y
, depth
)
596 QuestHelper
:ReleaseTable(v
)
598 QuestHelper
:ReleaseTable(sort_objs
)
599 QuestHelper
:ReleaseTable(objs
)
601 if had_pinned
then y
= y
+ 10 end
604 if QuestHelper
.loading_main
then
605 loading_vquest
.tracker_desc
= QHFormat("QH_LOADING", string.format("%d", QuestHelper
.loading_main
:GetPercentage() * 100))
606 local x
, ty
= addItem(loading_vquest
, y
)
609 if QuestHelper
.flightpathing
then
610 flightpath_vquest
.tracker_desc
= QHFormat("QH_FLIGHTPATH", string.format("%d", QuestHelper
.flightpathing
:GetPercentage() * 100))
611 local x
, ty
= addItem(flightpath_vquest
, y
)
615 local metalookup
= QuestHelper
:CreateTable("tracker rescan metalookup")
616 for k
, v
in ipairs(route
) do
618 if not metalookup
[v
.why
] then metalookup
[v
.why
] = QuestHelper
:CreateTable("tracker rescan metalookup item") end
619 if not v
.tracker_hidden
then table.insert(metalookup
[v
.why
], v
) end
625 local current_mo_cluster
626 for k
, v
in ipairs(route
) do
627 if depth
> QuestHelper_Pref
.track_size
and not debug_output
then break end
628 if not v
.ignore
and not v
.why
.tracker_hidden
and not obj_done
[v
.cluster
] then
629 if current_mo
and v
.why
~= current_mo
then
630 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
631 QuestHelper
:ReleaseTable(current_mo_cluster
)
632 current_mo
, current_mo_cluster
= nil, nil
635 if not v
.why
.tracker_split
then
636 if not mo_done
[v
.why
] then
637 y
, depth
= addMetaObjective(v
.why
, metalookup
[v
.why
], y
, depth
)
638 mo_done
[v
.why
] = true
641 if not current_mo
then
643 current_mo_cluster
= QuestHelper
:CreateTable("tracker current cluster")
645 if not v
.tracker_hidden
then table.insert(current_mo_cluster
, v
) end
651 if current_mo
and not (depth
> QuestHelper_Pref
.track_size
and not debug_output
) then
652 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
654 if current_mo_cluster
then
655 QuestHelper
:ReleaseTable(current_mo_cluster
)
659 for k
, v
in pairs(used_items
) do
660 if not used_count
[k
] or used_count
[k
] < #v
then
661 local ttp
= QuestHelper
:CreateTable("used_items ttp")
662 for m
= 1, (used_count
[k
] or 0) do
663 table.insert(ttp
, v
[m
])
665 for m
= (used_count
[k
] or 0) + 1, #v
do
666 removeUnusedItem(v
[m
])
669 if used_items
[k
] then
670 QuestHelper
:ReleaseTable(used_items
[k
])
677 QuestHelper
:ReleaseTable(ttp
)
682 QuestHelper
:ReleaseTable(mo_done
)
683 QuestHelper
:ReleaseTable(obj_done
)
684 for k
, v
in pairs(metalookup
) do
685 QuestHelper
:ReleaseTable(v
)
687 QuestHelper
:ReleaseTable(metalookup
)
689 QuestHelper
:ReleaseTable(used_count
)
692 if y
~= tracker
.dh
then
694 tracker
.sh
= tracker
:GetHeight()
696 tracker
.sw
= tracker
.dw
701 if x ~= tracker.dw or y ~= tracker.dy then
703 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
704 tracker.dw, tracker.dh = x, y
710 local quests = QuestHelper.quest_log
714 local track_size = QuestHelper_Pref.track_size
715 local quests_added = {}
717 for quest, objs in pairs(used_items) do
718 for obj, item in pairs(objs) do
723 for i, objective in pairs(QuestHelper.route) do
724 if objective.watched then
725 obj_index_lookup[objective] = i
729 for q, data in pairs(QuestHelper.quest_log) do
730 quest_lookup[data.index] = q
733 -- Add our little "not yet loaded" notification
734 local loadedshow = false
735 if not QuestHelper.Routing.map_walker then
737 x, y, gap, count = addobj(loading_vquest, seen, nil, nil, x, y, gap)
738 added = added + count
741 if QuestHelper_Flight_Updates and QuestHelper_Flight_Updates_Current and QuestHelper_Flight_Updates > 0 and QuestHelper_Flight_Updates_Current < QuestHelper_Flight_Updates then
742 loading_vquest.obj = string.format("7777/" .. QHFormat("QH_LOADING", string.format("%d", QuestHelper_Flight_Updates_Current * 100 / QuestHelper_Flight_Updates)))
746 -- Add an extra large gap to seperate the notification from everything else
749 -- Add Quests that are watched but not in the route.
751 local uq_settings = UberQuest_Config[UnitName("player")]
753 local list = uq_settings.selected
757 local name = GetQuestLogTitle(i)
758 if not name then break end
759 quest_lookup[name] = quest_lookup[i]
762 for name in pairs(list) do
763 local q = quest_lookup[name]
764 if q and not obj_index_lookup[q] then
766 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
767 added = added + count
768 quests_added[q] = true
774 for i = 1,GetNumQuestWatches() do
775 local q = quest_lookup[GetQuestIndexForWatch(i)]
776 if q and not obj_index_lookup[q] then
778 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
779 added = added + count
784 -- Add Quests that are watched and are in the route.
785 for i, objective in ipairs(QuestHelper.route) do
787 x, y, gap, count = addobj(objective, seen, obj_index_lookup, watched_filter, x, y, gap)
788 added = added + count
789 quests_added[objective] = true
792 -- Add an extra large gap to seperate the watched objectives from the automatic objectives.
795 -- Add Quests that aren't watched and are in the route.
796 if added <= track_size then
797 for i, objective in ipairs(QuestHelper.route) do
799 x, y, gap, count = addobj(objective, seen, obj_index_lookup, nil, x, y, gap)
800 added = added + count
801 quests_added[objective] = true
803 if added > track_size then
809 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
812 for k, v in pairs(quest_lookup) do
813 if not quests_added[v] then
814 notadded = notadded + 1
822 x, y, gap, count = addobj(hidden_vquest1, seen, nil, nil, x, y, gap)
823 added = added + count
824 x, y, gap, count = addobj(hidden_vquest2, seen, nil, nil, x, y, gap)
825 added = added + count
829 for obj in pairs(obj_index_lookup) do
830 obj_index_lookup[obj] = nil
833 for key in pairs(quest_lookup) do
834 quest_lookup[key] = nil
837 for quest, objs in pairs(used_items) do
838 for obj, item in pairs(objs) do
839 if not item.used then
840 removeUnusedItem(quest, obj, item)
845 for key in pairs(seen) do
851 if x ~= tracker.dw or y ~= tracker.dy then
853 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
854 tracker.dw, tracker.dh = x, y
862 function QH_Tracker_UpdateRoute(new_route
)
867 function QH_Tracker_Pin(metaobjective
)
868 if not pinned
[metaobjective
] then
869 pinned
[metaobjective
] = true
874 function QH_Tracker_Unpin(metaobjective
)
875 if pinned
[metaobjective
] then
876 pinned
[metaobjective
] = nil -- nil, not false, so it'll be garbage-collected appropriately
881 function QH_Tracker_SetPin(metaobjective
, flag
)
883 QH_Tracker_Pin(metaobjective
)
885 QH_Tracker_Unpin(metaobjective
)
890 local check_delay
= 4
892 -- This function does the grunt work of cursor positioning and rescaling. It does not actually reorganize items.
893 function tracker
:update(delta
)
895 -- This is called without a value when the questlog is updated.
896 -- We'll make sure we update the display on the next update.
902 local t
= self
.t
+delta
905 self
:SetWidth(self
.dw
)
906 self
:SetHeight(self
.dh
)
911 self
:SetWidth(self
.sw
*it
+self
.dw
*t
)
912 self
:SetHeight(self
.sh
*it
+self
.dh
*t
)
916 -- Manually checking if the mouse is in the frame, because if I used on OnEnter, i'd have to enable mouse input,
917 -- and if I did that, it would prevent the player from using the mouse to change the view if they clicked inside
919 local x
, y
= GetCursorPosition()
920 local s
= 1/self
:GetEffectiveScale()
923 QuestHelper
: Assert(x
)
924 QuestHelper
: Assert(y
)
925 --[[ QuestHelper: Assert(self:GetLeft())
926 QuestHelper: Assert(self:GetBottom())
927 QuestHelper: Assert(self:GetRight())
928 QuestHelper: Assert(self:GetTop())]]
930 -- Sometimes it just doesn't know its own coordinates. Not sure why. Maybe this will fix it.
931 local inside
= (self
:GetLeft() and (x
>= self
:GetLeft() and y
>= self
:GetBottom() and x
< self
:GetRight() and y
< self
:GetTop()))
932 if inside
~= was_inside
then
935 minbutton
:SetAlpha(.7)
936 elseif not QuestHelper_Pref
.track_minimized
then
937 minbutton
:SetAlpha(0)
941 check_delay
= check_delay
+ delta
942 if check_delay
> 1 then
949 QH_Hook(tracker
, "OnUpdate", tracker
.update
)
951 -- Some hooks to update the tracker when quests are added or removed. These should be moved into the quest director.
953 local orig_AddQuestWatch, orig_RemoveQuestWatch = AddQuestWatch, RemoveQuestWatch
955 function AddQuestWatch(...)
957 return orig_AddQuestWatch(...)
960 function RemoveQuestWatch(...)
962 return orig_RemoveQuestWatch(...)
965 -------------------------------------------------------------------------------------------------
966 -- This batch of stuff is to make sure the original tracker (and any modifications) stay hidden
968 local orig_TrackerOnShow
969 if QuestWatchFrame
then -- 3.1 hackery
970 orig_TrackerOnShow
= QuestWatchFrame
:GetScript("OnShow")
972 local orig_TrackerBackdropOnShow
-- bEQL (and perhaps other mods) add a backdrop to the tracker
973 local TrackerBackdropFound
= false
975 local function TrackerBackdropOnShow(self
, ...)
976 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
977 TrackerBackdropFound
:Hide()
980 if orig_TrackerBackdropOnShow
then
981 return orig_TrackerBackdropOnShow(self
, ...)
985 function tracker
:HideDefaultTracker()
986 -- The easy part: hide the original tracker
987 WatchFrame_RemoveObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
988 WatchFrame_ClearDisplay()
991 -- The harder part: hide all those little buttons
995 local orig
= _G
["WatchFrameItem" .. tostring(index
)]
996 if orig
then orig
:Hide() else break end
1001 -- The harder part: check if a known backdrop is present (but we don't already know about it).
1002 -- If it is, make sure it's hidden, and hook its OnShow to make sure it stays that way.
1003 -- Unfortunately, I can't figure out a good time to check for this once, so we'll just have
1004 -- to keep checking. Hopefully, this won't happen too often.
1005 if not TrackerBackdropFound
then
1006 if QuestWatchFrameBackdrop
then
1007 -- Found bEQL's QuestWatchFrameBackdrop...
1008 TrackerBackdropFound
= QuestWatchFrameBackdrop
1011 if TrackerBackdropFound
then
1012 -- OK, we found something - so hide it, and make sure it doesn't rear its ugly head again
1013 TrackerBackdropFound
:Hide()
1015 orig_TrackerBackdropOnShow
= TrackerBackdropFound
:GetScript("OnShow")
1016 QH_Hook(TrackerBackdropFound
, "OnShow", TrackerBackdropOnShow
)
1021 function tracker
:ShowDefaultTracker()
1022 if QuestWatchFrame
then -- 3.1 hackery
1023 QuestWatchFrame
:Show()
1024 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1027 -- I like how there's code explicitly to allow us to do this without checking if it's already added
1028 WatchFrame_AddObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1029 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1033 if TrackerBackdropFound
then
1034 TrackerBackdropFound
:Show()
1038 if QuestWatchFrame
then -- 3.1 hackery
1039 local function QuestWatchFrameOnShow(self
, ...)
1040 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
1041 tracker
:HideDefaultTracker()
1044 if orig_TrackerOnShow
then
1045 return orig_TrackerOnShow(self
, ...)
1049 QH_Hook(QuestWatchFrame
, "OnShow", QuestWatchFrameOnShow
)
1052 function QuestHelper
:ShowTracker()
1053 tracker
:HideDefaultTracker()
1056 if QuestHelper_Pref
.track_minimized
then
1057 minbutton
:SetAlpha(.3)
1059 minbutton
:SetAlpha(0)
1064 function QuestHelper
:HideTracker()
1065 tracker
:ShowDefaultTracker()