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
:SetFrameStrata("BACKGROUND")
49 tracker
.dw
, tracker
.dh
= 200, 100
53 minbutton
:SetFrameStrata("LOW")
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(24 / 1.6)
59 minbutton
:SetHeight(24)
60 minbutton
:SetFrameLevel(3)
61 local minbutton_tex
= minbutton
:CreateTexture()
62 minbutton_tex
:SetAllPoints()
63 minbutton_tex
:SetTexture(.6, .6, .6)
64 minbutton_tex
:SetParent(minbutton
)
66 local sigargh
= CreateFrame("Frame", minbutton
)
67 sigargh
:SetFrameStrata("LOW")
68 sigargh
:SetFrameLevel(4)
70 local sigil
= sigargh
:CreateTexture("BACKGROUND")
73 --sigil:SetPoint("CENTER", 0, 0)
74 sigil
:SetTexture("Interface\\AddOns\\QuestHelper\\sigil")
75 sigil
:SetPoint("CENTER", minbutton_tex
, "CENTER")
78 tracker
:SetPoint("CENTER", minbutton
)
80 function minbutton
:moved()
81 local x
, y
= self
:GetCenter()
82 local w
, h
= UIParent
:GetWidth(), UIParent
:GetHeight()
83 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 "")
85 tracker
:ClearAllPoints()
86 tracker
:SetPoint("CENTER", self
)
89 tracker
:SetPoint(anchor
, self
)
93 function QuestHelper
:ResetTrackerPosition(cmd
)
94 minbutton
:ClearAllPoints()
95 if cmd
and string.find(cmd
, "center") then
96 minbutton
:SetPoint("CENTER", nil, "CENTER", 100, 100)
98 minbutton
:SetPoint("RIGHT", nil, "RIGHT", -20, 230)
101 QuestHelper_Pref
.track_minimized
= false
103 self
:TextOut("Quest tracker postion reset.")
106 QH_Event({"DISPLAY_SIZE_CHANGED", "PLAYER_ENTERING_WORLD"}, function () minbutton
:moved() end)
108 QH_Hook(minbutton
, "OnClick", function ()
109 QuestHelper_Pref
.track_minimized
= not QuestHelper_Pref
.track_minimized
110 if QuestHelper_Pref
.track_minimized
then
117 minbutton
:RegisterForDrag("LeftButton")
119 QH_Hook(minbutton
, "OnDragStart", function(self
)
120 if self
:IsVisible() then
122 QH_Hook(self
, "OnUpdate", self
.moved
)
126 QH_Hook(minbutton
, "OnDragStop", function(self
)
127 QH_Hook(self
, "OnUpdate", nil)
128 self
:StopMovingOrSizing()
132 local entered_main
= false
133 local entered_tracker
= false
134 local function RefreshColor()
136 minbutton
:SetAlpha(1)
138 elseif entered_tracker
then
139 minbutton
:SetAlpha(.3)
141 elseif QuestHelper_Pref
.track_minimized
then
142 minbutton
:SetAlpha(.3)
145 minbutton
:SetAlpha(0)
149 local function SetEnteredMain(x
)
153 local function SetEnteredTracker(x
)
158 QH_Hook(minbutton
, "OnEnter", function (self
)
162 QH_Hook(minbutton
, "OnLeave", function (self
)
163 SetEnteredMain(false)
166 -- used_items[objective][index]
167 -- used_count[objective] is incremented as the last valid index
168 -- so, therefore, used_items[objective][used_count[objective]] is not nil
169 local used_items
= {}
170 local used_count
= {}
172 -- it's possible for an item to be in neither used_items nor recycled_items, if it's in the process of fading out
173 local recycled_items
= {}
175 -- These two functions are basically identical. Combine them.
176 local function itemupdate(item
, delta
)
179 local a
= item
:GetAlpha()
189 local t
= item
.t
+ delta
194 local sp
= math
.sqrt(t
-t
*t
)
195 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
199 item
.x
, item
.y
= item
.ex
, item
.ey
202 item
:ClearAllPoints()
203 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
206 QH_Hook(item
, "OnUpdate", nil)
210 local function itemfadeout(item
, delta
)
211 local a
= item
:GetAlpha()
219 QH_Hook(item
, "OnUpdate", nil)
220 table.insert(recycled_items
, item
)
224 local t
= item
.t
+ delta
229 local sp
= math
.sqrt(t
-t
*t
)
230 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
233 item
.x
, item
.y
= item
.ex
, item
.ey
236 item
:ClearAllPoints()
237 item
:SetPoint("TOPLEFT", tracker
, "TOPLEFT", item
.x
, -item
.y
)
240 --[[function QH_ToggleQuestLog() -- This seems to be gone in 3.0, so I'm adding it here.
241 if (QuestLogFrame:IsShown()) then
242 HideUIPanel(QuestLogFrame);
244 ShowUIPanel(QuestLogFrame);
248 -- Grim stuff with uberquest, I need a better way to handle this
249 local function itemclick(item, button)
250 if button == "RightButton" then
251 local quest = item.quest
254 local title = GetQuestLogTitle(index)
255 if not title then break end
257 if title == quest then
259 -- UberQuest needs a little extra effort to work properly.
261 if UberQuest_List:IsShown() and GetQuestLogSelection() == index then
264 QuestLog_SetSelection(index)
266 -- By hiding the list, the replaced ToggleQuestLog function should try to reshow it
267 -- and in the process update the frames to reflect the selected quest.
268 UberQuest_List:Hide()
269 UberQuest_Details:Show()
273 -- This code seems to work properly with the builtin questlog, as well as bEQL and DoubleWide.
275 if QuestLogFrame:IsShown() and GetQuestLogSelection() == index then
276 -- If the selected quest is already being shown, hide it.
279 -- Otherwise, select it and show it.
280 QuestLog_SetSelection(index)
282 if not QuestLogFrame:IsShown() then
296 local function allocateItem()
299 item
= table.remove(recycled_items
)
300 if item
then return item
end
302 item
= CreateFrame("Frame", nil, tracker
)
303 item
.text
= item
:CreateFontString()
304 item
.text
:SetShadowColor(0, 0, 0, .8)
305 item
.text
:SetShadowOffset(1, -1)
306 item
.text
:SetPoint("TOPLEFT", item
)
310 local specitem_max
= 1
311 local specitem_unused
= {}
313 -- 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
314 local function addItem(objective
, y
, meta
)
315 local obj_key
= objective
316 if obj_key
.cluster
then obj_key
= obj_key
.cluster
end
317 used_count
[obj_key
] = (used_count
[obj_key
] or 0) + 1
318 if not used_items
[obj_key
] then used_items
[obj_key
] = QuestHelper
:CreateTable("additem used_items") end
319 local item
= used_items
[obj_key
][used_count
[obj_key]]
321 local x
= meta
and 4 or 20
324 used_items
[obj_key
][used_count
[obj_key]]
= allocateItem()
325 item
= used_items
[obj_key
][used_count
[obj_key]]
328 item
.text
:SetFont(QuestHelper
.font
.serif
, 12)
329 item
.text
:SetTextColor(.82, .65, 0)
331 item
.text
:SetFont(QuestHelper
.font
.sans
, 12)
332 item
.text
:SetTextColor(.82, .82, .82)
337 item
.sx
, item
.sy
, item
.x
, item
.y
, item
.ex
, item
.ey
, item
.t
= x
+30, y
, x
, y
, x
, y
, 0
338 QH_Hook(item
, "OnUpdate", itemupdate
)
343 item
.text
:SetText(item
.obj
.tracker_desc
or "(no description)")
345 local w
, h
= item
.text
:GetWidth(), item
.text
:GetHeight()
349 if objective
.tracker_clicked
then
350 QH_Hook(item
, "OnMouseDown", function (self
, button
) if button
== "RightButton" then objective
.tracker_clicked() end end)
351 item
:EnableMouse(true)
354 if item
.ex
~= x
or item
.ey
~= y
then
355 item
.sx
, item
.sy
, item
.ex
, item
.ey
= item
.x
, item
.y
, x
, y
357 QH_Hook(item
, "OnUpdate", itemupdate
)
360 -- we're just going to recycle this each time
361 if item
.specitem
then
363 table.insert(specitem_unused
, item
.specitem
)
368 -- hacky - progress only shows up if we're not on a metaobjective. wheee
369 if objective
.type_quest
and objective
.type_quest
.index
and not objective
.progress
and GetQuestLogSpecialItemInfo(objective
.type_quest
.index
) then
370 item
.specitem
= table.remove(specitem_unused
)
371 if not item
.specitem
then
372 item
.specitem
= CreateFrame("BUTTON", "QH_SpecItem_" .. tostring(specitem_max
), item
, "WatchFrameItemButtonTemplate")
373 QuestHelper
: Assert(item
.specitem
)
375 local rangey
= _G
["QH_SpecItem_" .. tostring(specitem_max
) .. "HotKey"]
376 QuestHelper
: Assert(rangey
)
377 local fn
, fh
, ff
= rangey
:GetFont()
378 rangey
:SetFont("Fonts\\ARIALN.TTF", fh
, ff
)
379 rangey
:SetText(RANGE_INDICATOR
)
380 rangey
:ClearAllPoints()
381 rangey
:SetPoint("BOTTOMRIGHT", item
.specitem
, "BOTTOMRIGHT", 0, 2)
383 specitem_max
= specitem_max
+ 1
386 item
.specitem
:SetScale(0.9)
387 item
.specitem
:ClearAllPoints()
388 item
.specitem
:SetParent(item
)
389 item
.specitem
:SetPoint("TOPRIGHT", item
, "TOPLEFT", 0, 0)
391 local _
, tex
, charges
= GetQuestLogSpecialItemInfo(objective
.type_quest
.index
)
392 item
.specitem
:SetID(objective
.type_quest
.index
)
393 SetItemButtonTexture(item
.specitem
, tex
)
394 item
.specitem
.rangeTimer
= -1 -- This makes the little dot go away. Why does it do that?
395 item
.specitem
.charges
= charges
402 return w
+x
+4, y
+h
, y
+h
+spacer
405 local function addMetaObjective(metaobj
, items
, y
, depth
)
406 local seen_texts
= QuestHelper
:CreateTable("amo_seen_texts")
409 x
, y
, spacer
= addItem(metaobj
, y
, true)
410 for _
, v
in ipairs(items
) do
411 if not v
.tracker_hide_dupes
or not seen_texts
[v
.tracker_desc
] then
412 x
, y
= addItem(v
, y
, false)
413 seen_texts
[v
.tracker_desc
] = true
416 return math
.max(y
, spacer
), depth
+ #items
+ 1
419 --[[ -- these will be plugged in later one way or another
420 local function ccode(r1, g1, b1, r2, g2, b2, p)
422 p, ip = p*255, 255-p*255
423 return string.format("|cff%02x%02x%02x", r1*ip+r2*p, g1*ip+g2*p, b1*ip+b2*p)
426 local function qname(title, level)
427 if QuestHelper_Pref.track_level and level ~= 7777 and level ~= 7778 then
428 title = string.format("[%d] %s", level, title)
431 if level == 7778 then
435 if QuestHelper_Pref.track_qcolour then
436 local player_level = QuestHelper.player_level
437 local delta = level - player_level
442 colour = "|cffff0000"
443 elseif delta >= 0 then
444 colour = ccode(1, 1, 0, 1, 0, 0, delta/5)
448 if player_level >= 60 then grey = player_level - 9
449 elseif player_level >= 40 then grey = player_level - math.floor(player_level/5) - 1
450 elseif player_level >= 6 then grey = player_level - math.floor(player_level/10) - 5
453 if level == -7778 then
454 colour = "|cff808080"
455 elseif level > grey then
456 colour = ccode(0, 1, 0, 1, 1, 0, (grey-level)/(grey-player_level))
458 colour = ccode(.4, .4, .4, .2, .8, .2, (1-level)/(1-grey))
462 title = string.format("%s%s", colour, title)
468 local function oname(text, pct)
469 if QuestHelper_Pref.track_ocolour then
470 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)
477 local function removeUnusedItem(item
)
479 item
.sx
, item
.sy
, item
.dx
, item
.dy
= item
.x
, item
.y
, item
.x
+30, item
.y
480 QH_Hook(item
, "OnMouseDown", nil)
481 item
:EnableMouse(false)
482 QH_Hook(item
, "OnUpdate", itemfadeout
)
484 if item
.specitem
then
486 table.insert(specitem_unused
, item
.specitem
)
492 local was_inside
= false
496 local function addobj(objective
, seen
, obj_index_lookup
, filter
, x
, y
, gap
)
500 if objective
.cat
== "quest" then
503 quest
= objective
.quest
506 if quest
and quest
.watched
and not seen
[quest
] and (not filter
or filter(quest
)) then
509 local level
, name
= string.match(quest
.obj
, "^(%d+)/%d*/(.*)$")
512 level
, name
= string.match(quest
.obj
, "^(%d+)/(.*)$")
514 level
, name
= 1, quest
.obj
518 level
= tonumber(level
) or 1
521 local w
, h
= addItem(qname(name
, level
), true, quest
, -(y
+gap
), name
, quest
.index
)
526 for obj
in pairs(quest
.swap_after
or quest
.after
) do
528 table.insert(obj_list
, obj
)
532 table.sort(obj_list
, objlist_sort
)
534 for i
, obj
in ipairs(obj_list
) do
535 local pct
, text
= 0, obj
.obj
536 local seen_sum
, seen_max
= 0, 0
539 local seen_have
, seen_need
= QuestHelper
:CreateTable(), QuestHelper
:CreateTable()
541 for user
, progress
in pairs(obj
.progress
) do
542 seen_sum
= seen_sum
+ progress
[3]
543 seen_max
= seen_max
+ 1
544 seen_have
[progress
[1]]
= true
545 seen_need
[progress
[2]]
= true
549 pct
= seen_sum
/ seen_max
550 local list
= QuestHelper
:CreateTable()
552 for val
in pairs(seen_have
) do
553 table.insert(list
, val
)
558 local have
= table.concat(list
, ", ")
560 for i
= #list
,1,-1 do
564 for val
in pairs(seen_need
) do
565 table.insert(list
, val
)
568 if #list
~= 1 or list
[1] ~= 1 then
569 -- If there is only one thing needed, ignore the progress, it's redundant.
570 -- It's either shown or it isn't.
574 local need
= table.concat(list
, ", ")
576 text
= string.format((tonumber(have
) and tonumber(need
) and QUEST_ITEMS_NEEDED
) or QUEST_FACTION_NEEDED
,
580 QuestHelper
:ReleaseTable(list
)
583 QuestHelper
:ReleaseTable(seen_have
)
584 QuestHelper
:ReleaseTable(seen_need
)
587 if seen_sum
~= seen_max
then
589 w
, h
= addItem(oname(text
, pct
), quest
, obj
, -y
)
595 for i
= #obj_list
, 1, -1 do obj_list
[i
] = nil end
598 return x
, y
, gap
, count
602 local loading_vquest
= {tracker_desc
= QHFormat("QH_LOADING", "0")}
603 local flightpath_vquest
= {tracker_desc
= QHFormat("QH_FLIGHTPATH", "0")}
604 local recalculating_vquest
= {tracker_desc
= QHFormat("QH_RECALCULATING", "0")}
606 local recalculating_start
= nil
609 local hidden_vquest1
= { tracker_desc
= QHText("QUESTS_HIDDEN_1"), tracker_clicked
= QH_Hidden_Menu
}
610 local hidden_vquest2
= { tracker_desc
= " " .. QHText("QUESTS_HIDDEN_2"), tracker_clicked
= QH_Hidden_Menu
}
615 -- This is actually called surprisingly often.
616 function QH_Tracker_Rescan()
617 used_count
= QuestHelper
:CreateTable("tracker rescan used_count")
619 local mo_done
= QuestHelper
:CreateTable("tracker rescan mo_done")
620 local obj_done
= QuestHelper
:CreateTable("tracker rescan obj_done")
622 local y
, depth
= 0, 0
625 local had_pinned
= false
627 local objs
= QuestHelper
:CreateTable("tracker objs")
628 for k
, v
in pairs(pinned
) do
629 if not objs
[k
.why
] then objs
[k
.why
] = QuestHelper
:CreateTable("tracker objs sub") end
630 if not k
.ignore
and not k
.tracker_hidden
then table.insert(objs
[k
.why
], k
) end
631 obj_done
[k
.cluster
] = true
634 local sort_objs
= QuestHelper
:CreateTable("tracker sobjs")
635 for k
, v
in pairs(objs
) do
638 table.insert(sort_objs
, v
)
641 table.sort(sort_objs
, function (a
, b
) return tostring(a
.trackkey
) < tostring(b
.trackkey
) end)
643 for _
, v
in ipairs(sort_objs
) do
644 y
, depth
= addMetaObjective(v
.cluster
, v
, y
, depth
)
646 QuestHelper
:ReleaseTable(v
)
648 QuestHelper
:ReleaseTable(sort_objs
)
649 QuestHelper
:ReleaseTable(objs
)
651 if had_pinned
then y
= y
+ 10 end
654 if QuestHelper
.loading_main
then
655 loading_vquest
.tracker_desc
= QHFormat("QH_LOADING", string.format("%d", QuestHelper
.loading_main
:GetPercentage() * 100))
656 local x
, ty
= addItem(loading_vquest
, y
)
659 if QuestHelper
.flightpathing
then
660 flightpath_vquest
.tracker_desc
= QHFormat("QH_FLIGHTPATH", string.format("%d", QuestHelper
.flightpathing
:GetPercentage() * 100))
661 local x
, ty
= addItem(flightpath_vquest
, y
)
664 if not QuestHelper
.loading_main
and not QuestHelper
.flightpathing
and QuestHelper
.route_change_progress
then
665 if recalculating_start
then
666 if recalculating_start
+ 5 < GetTime() then
667 recalculating_vquest
.tracker_desc
= QHFormat("QH_RECALCULATING", string.format("%d", QuestHelper
.route_change_progress
:GetPercentage() * 100))
668 local x
, ty
= addItem(recalculating_vquest
, y
)
672 recalculating_start
= GetTime()
675 recalculating_start
= nil
678 local metalookup
= QuestHelper
:CreateTable("tracker rescan metalookup")
679 for k
, v
in ipairs(route
) do
681 if not metalookup
[v
.why
] then metalookup
[v
.why
] = QuestHelper
:CreateTable("tracker rescan metalookup item") end
682 if not v
.tracker_hidden
then table.insert(metalookup
[v
.why
], v
) end
688 local current_mo_cluster
689 for k
, v
in ipairs(route
) do
690 if depth
> QuestHelper_Pref
.track_size
and not debug_output
then break end
691 if not v
.ignore
and not v
.why
.tracker_hidden
and not obj_done
[v
.cluster
] then
692 if current_mo
and v
.why
~= current_mo
and (v
.why
.tracker_split
or not mo_done
[v
.why
]) then
693 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
694 QuestHelper
:ReleaseTable(current_mo_cluster
)
695 current_mo
, current_mo_cluster
= nil, nil
698 if not v
.why
.tracker_split
then
699 if not mo_done
[v
.why
] then
700 y
, depth
= addMetaObjective(v
.why
, metalookup
[v
.why
], y
, depth
)
701 mo_done
[v
.why
] = true
704 if not current_mo
then
706 current_mo_cluster
= QuestHelper
:CreateTable("tracker current cluster")
708 if not v
.tracker_hidden
then table.insert(current_mo_cluster
, v
) end
714 if current_mo
and not (depth
> QuestHelper_Pref
.track_size
and not debug_output
) then
715 y
, depth
= addMetaObjective(current_mo
, current_mo_cluster
, y
, depth
)
717 if current_mo_cluster
then
718 QuestHelper
:ReleaseTable(current_mo_cluster
)
722 -- now we check to see if we need a hidden display
723 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
726 QH_Route_TraverseClusters(
729 QH_Route_IgnoredReasons_Cluster(clust
, function (reason
)
733 for _
, v
in ipairs(clust
) do
734 QH_Route_IgnoredReasons_Node(v
, function (reason
)
744 _
, y
= addItem(hidden_vquest1
, y
)
745 _
, y
= addItem(hidden_vquest2
, y
)
750 -- any manipulations of the tracker should be done by now, everything after this is bookkeeping
752 for k
, v
in pairs(used_items
) do
753 if not used_count
[k
] or used_count
[k
] < #v
then
754 local ttp
= QuestHelper
:CreateTable("used_items ttp")
755 for m
= 1, (used_count
[k
] or 0) do
756 table.insert(ttp
, v
[m
])
758 for m
= (used_count
[k
] or 0) + 1, #v
do
759 removeUnusedItem(v
[m
])
762 if used_items
[k
] then
763 QuestHelper
:ReleaseTable(used_items
[k
])
770 QuestHelper
:ReleaseTable(ttp
)
775 QuestHelper
:ReleaseTable(mo_done
)
776 QuestHelper
:ReleaseTable(obj_done
)
777 for k
, v
in pairs(metalookup
) do
778 QuestHelper
:ReleaseTable(v
)
780 QuestHelper
:ReleaseTable(metalookup
)
782 QuestHelper
:ReleaseTable(used_count
)
785 if y
~= tracker
.dh
then
787 tracker
.sh
= tracker
:GetHeight()
789 tracker
.sw
= tracker
.dw
799 if x ~= tracker.dw or y ~= tracker.dy then
801 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
802 tracker.dw, tracker.dh = x, y
808 local quests = QuestHelper.quest_log
812 local track_size = QuestHelper_Pref.track_size
813 local quests_added = {}
815 for quest, objs in pairs(used_items) do
816 for obj, item in pairs(objs) do
821 for i, objective in pairs(QuestHelper.route) do
822 if objective.watched then
823 obj_index_lookup[objective] = i
827 for q, data in pairs(QuestHelper.quest_log) do
828 quest_lookup[data.index] = q
831 -- Add our little "not yet loaded" notification
832 local loadedshow = false
833 if not QuestHelper.Routing.map_walker then
835 x, y, gap, count = addobj(loading_vquest, seen, nil, nil, x, y, gap)
836 added = added + count
839 if QuestHelper_Flight_Updates and QuestHelper_Flight_Updates_Current and QuestHelper_Flight_Updates > 0 and QuestHelper_Flight_Updates_Current < QuestHelper_Flight_Updates then
840 loading_vquest.obj = string.format("7777/" .. QHFormat("QH_LOADING", string.format("%d", QuestHelper_Flight_Updates_Current * 100 / QuestHelper_Flight_Updates)))
844 -- Add an extra large gap to seperate the notification from everything else
847 -- Add Quests that are watched but not in the route.
849 local uq_settings = UberQuest_Config[UnitName("player")]
851 local list = uq_settings.selected
855 local name = GetQuestLogTitle(i)
856 if not name then break end
857 quest_lookup[name] = quest_lookup[i]
860 for name in pairs(list) do
861 local q = quest_lookup[name]
862 if q and not obj_index_lookup[q] then
864 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
865 added = added + count
866 quests_added[q] = true
872 for i = 1,GetNumQuestWatches() do
873 local q = quest_lookup[GetQuestIndexForWatch(i)]
874 if q and not obj_index_lookup[q] then
876 x, y, gap, count = addobj(q, seen, obj_index_lookup, nil, x, y, gap)
877 added = added + count
882 -- Add Quests that are watched and are in the route.
883 for i, objective in ipairs(QuestHelper.route) do
885 x, y, gap, count = addobj(objective, seen, obj_index_lookup, watched_filter, x, y, gap)
886 added = added + count
887 quests_added[objective] = true
890 -- Add an extra large gap to seperate the watched objectives from the automatic objectives.
893 -- Add Quests that aren't watched and are in the route.
894 if added <= track_size then
895 for i, objective in ipairs(QuestHelper.route) do
897 x, y, gap, count = addobj(objective, seen, obj_index_lookup, nil, x, y, gap)
898 added = added + count
899 quests_added[objective] = true
901 if added > track_size then
907 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
910 for k, v in pairs(quest_lookup) do
911 if not quests_added[v] then
912 notadded = notadded + 1
920 x, y, gap, count = addobj(hidden_vquest1, seen, nil, nil, x, y, gap)
921 added = added + count
922 x, y, gap, count = addobj(hidden_vquest2, seen, nil, nil, x, y, gap)
923 added = added + count
927 for obj in pairs(obj_index_lookup) do
928 obj_index_lookup[obj] = nil
931 for key in pairs(quest_lookup) do
932 quest_lookup[key] = nil
935 for quest, objs in pairs(used_items) do
936 for obj, item in pairs(objs) do
937 if not item.used then
938 removeUnusedItem(quest, obj, item)
943 for key in pairs(seen) do
949 if x ~= tracker.dw or y ~= tracker.dy then
951 tracker.sw, tracker.sh = tracker:GetWidth(), tracker:GetHeight()
952 tracker.dw, tracker.dh = x, y
960 function QH_Tracker_UpdateRoute(new_route
)
965 function QH_Tracker_Pin(metaobjective
, suppress
)
966 if not pinned
[metaobjective
] then
967 pinned
[metaobjective
] = true
975 function QH_Tracker_Unpin(metaobjective
, suppress
)
976 if pinned
[metaobjective
] then
977 pinned
[metaobjective
] = nil -- nil, not false, so it'll be garbage-collected appropriately
985 function QH_Tracker_SetPin(metaobjective
, flag
, suppress
)
987 QH_Tracker_Pin(metaobjective
, suppress
)
989 QH_Tracker_Unpin(metaobjective
, suppress
)
994 local check_delay
= 4
996 -- This function does the grunt work of cursor positioning and rescaling. It does not actually reorganize items.
997 function tracker
:update(delta
)
999 -- This is called without a value when the questlog is updated.
1000 -- We'll make sure we update the display on the next update.
1006 local t
= self
.t
+delta
1009 self
:SetWidth(self
.dw
)
1010 self
:SetHeight(self
.dh
)
1015 self
:SetWidth(self
.sw
*it
+self
.dw
*t
)
1016 self
:SetHeight(self
.sh
*it
+self
.dh
*t
)
1020 -- Manually checking if the mouse is in the frame, because if I used on OnEnter, i'd have to enable mouse input,
1021 -- and if I did that, it would prevent the player from using the mouse to change the view if they clicked inside
1023 local x
, y
= GetCursorPosition()
1024 local s
= 1/self
:GetEffectiveScale()
1027 QuestHelper
: Assert(x
)
1028 QuestHelper
: Assert(y
)
1029 --[[ QuestHelper: Assert(self:GetLeft())
1030 QuestHelper: Assert(self:GetBottom())
1031 QuestHelper: Assert(self:GetRight())
1032 QuestHelper: Assert(self:GetTop())]]
1034 -- Sometimes it just doesn't know its own coordinates. Not sure why. Maybe this will fix it.
1035 local inside
= (self
:GetLeft() and (x
>= self
:GetLeft() and y
>= self
:GetBottom() and x
< self
:GetRight() and y
< self
:GetTop()))
1036 if inside
~= was_inside
then
1039 SetEnteredTracker(true)
1041 SetEnteredTracker(false)
1045 check_delay
= check_delay
+ delta
1046 if check_delay
> 1 then
1053 QH_Hook(tracker
, "OnUpdate", tracker
.update
)
1055 -- Some hooks to update the tracker when quests are added or removed. These should be moved into the quest director.
1057 local orig_AddQuestWatch, orig_RemoveQuestWatch = AddQuestWatch, RemoveQuestWatch
1059 function AddQuestWatch(...)
1061 return orig_AddQuestWatch(...)
1064 function RemoveQuestWatch(...)
1066 return orig_RemoveQuestWatch(...)
1069 -------------------------------------------------------------------------------------------------
1070 -- This batch of stuff is to make sure the original tracker (and any modifications) stay hidden
1072 local orig_TrackerBackdropOnShow
-- bEQL (and perhaps other mods) add a backdrop to the tracker
1073 local TrackerBackdropFound
= false
1075 local function TrackerBackdropOnShow(self
, ...)
1076 if QuestHelper_Pref
.track
and not QuestHelper_Pref
.hide
then
1077 TrackerBackdropFound
:Hide()
1080 if orig_TrackerBackdropOnShow
then
1081 return orig_TrackerBackdropOnShow(self
, ...)
1085 function tracker
:HideDefaultTracker()
1086 -- The easy part: hide the original tracker
1087 WatchFrame_RemoveObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1088 WatchFrame_ClearDisplay()
1091 -- The harder part: hide all those little buttons
1095 local orig
= _G
["WatchFrameItem" .. tostring(index
)]
1096 if orig
then orig
:Hide() else break end
1101 -- The harder part: check if a known backdrop is present (but we don't already know about it).
1102 -- If it is, make sure it's hidden, and hook its OnShow to make sure it stays that way.
1103 -- Unfortunately, I can't figure out a good time to check for this once, so we'll just have
1104 -- to keep checking. Hopefully, this won't happen too often.
1105 if not TrackerBackdropFound
then
1106 if QuestWatchFrameBackdrop
then
1107 -- Found bEQL's QuestWatchFrameBackdrop...
1108 TrackerBackdropFound
= QuestWatchFrameBackdrop
1111 if TrackerBackdropFound
then
1112 -- OK, we found something - so hide it, and make sure it doesn't rear its ugly head again
1113 TrackerBackdropFound
:Hide()
1115 orig_TrackerBackdropOnShow
= TrackerBackdropFound
:GetScript("OnShow")
1116 QH_Hook(TrackerBackdropFound
, "OnShow", TrackerBackdropOnShow
)
1121 function tracker
:ShowDefaultTracker()
1122 -- I like how there's code explicitly to allow us to do this without checking if it's already added
1123 WatchFrame_AddObjectiveHandler(WatchFrame_DisplayTrackedQuests
)
1124 -- Make sure the default tracker is up to date on what what's being watched and what isn't.
1127 if TrackerBackdropFound
then
1128 TrackerBackdropFound
:Show()
1132 function QuestHelper
:ShowTracker()
1133 tracker
:HideDefaultTracker()
1137 if not QuestHelper_Pref
.track_minimized
then
1142 function QuestHelper
:HideTracker()
1143 tracker
:ShowDefaultTracker()