update changes
[QuestHelper.git] / dodads.lua
blob78e322c0e526bb95133df93511d02c7c496f6697
1 QuestHelper_File["dodads.lua"] = "Development Version"
3 local ofs = 0.000723339 * (GetScreenHeight()/GetScreenWidth() + 1/3) * 70.4;
4 local radius = ofs / 1.166666666666667;
6 local function convertLocation(p)
7 local c, x, y = p[1].c, p[3], p[4]
8 x, y = x/QuestHelper.continent_scales_x[c], y/QuestHelper.continent_scales_y[c]
9 return c, 0, x, y
10 end
12 local function convertLocationToScreen(p, c, z)
13 return QuestHelper.Astrolabe:TranslateWorldMapPosition(p[1].c, 0, p[3]/QuestHelper.continent_scales_x[p[1].c], p[4]/QuestHelper.continent_scales_y[p[1].c], c, z)
14 end
16 local function convertNodeToScreen(n, c, z)
17 return QuestHelper.Astrolabe:TranslateWorldMapPosition(n.c, 0, n.x/QuestHelper.continent_scales_x[n.c], n.y/QuestHelper.continent_scales_y[n.c], c, z)
18 end
20 QuestHelper.map_overlay = CreateFrame("FRAME", nil, WorldMapButton)
21 QuestHelper.map_overlay:SetFrameLevel(WorldMapButton:GetFrameLevel()+1)
22 QuestHelper.map_overlay:SetAllPoints()
23 QuestHelper.map_overlay:SetFrameStrata("FULLSCREEN")
25 local function ClampLine(x1, y1, x2, y2)
26 if x1 and y1 and x2 and y2 then
27 local x_div, y_div = (x2-x1), (y2-y1)
28 local x_0 = y1-x1/x_div*y_div
29 local x_1 = y1+(1-x1)/x_div*y_div
30 local y_0 = x1-y1/y_div*x_div
31 local y_1 = x1+(1-y1)/y_div*x_div
33 if y1 < 0 then
34 x1 = y_0
35 y1 = 0
36 end
38 if y2 < 0 then
39 x2 = y_0
40 y2 = 0
41 end
43 if y1 > 1 then
44 x1 = y_1
45 y1 = 1
46 end
48 if y2 > 1 then
49 x2 = y_1
50 y2 = 1
51 end
53 if x1 < 0 then
54 y1 = x_0
55 x1 = 0
56 end
58 if x2 < 0 then
59 y2 = x_0
60 x2 = 0
61 end
63 if x1 > 1 then
64 y1 = x_1
65 x1 = 1
66 end
68 if x2 > 1 then
69 y2 = x_1
70 x2 = 1
71 end
73 if x1 >= 0 and x2 >= 0 and y1 >= 0 and y2 >= 0 and x1 <= 1 and x2 <= 1 and y1 <= 1 and y2 <= 1 then
74 return x1, y1, x2, y2
75 end
76 end
77 end
79 local function pushPath(list, path, c, z)
80 if path then
81 pushPath(list, path.p, c, z)
82 local t = QuestHelper:CreateTable()
83 t[1], t[2] = QuestHelper.Astrolabe:TranslateWorldMapPosition(path.c, 0, path.x/QuestHelper.continent_scales_x[path.c], path.y/QuestHelper.continent_scales_y[path.c], c, z)
84 table.insert(list, t)
85 end
86 end
88 function QuestHelper:CreateWorldMapWalker()
89 local walker = CreateFrame("Button", nil, QuestHelper.map_overlay)
90 walker:SetWidth(0)
91 walker:SetHeight(0)
92 walker:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", 0, 0)
93 walker:Show()
95 walker.phase = 0.0
96 walker.dots = {}
97 walker.points = {}
98 walker.origin = {}
99 walker.frame = self
100 walker.map_dodads = {}
101 walker.used_map_dodads = 0
103 function walker:OnUpdate(elapsed)
104 local out = 0
106 if QuestHelper_Pref.show_ants then
107 local points = self.points
109 self.phase = self.phase + elapsed * 0.66
110 while self.phase > 1 do self.phase = self.phase - 1 end
112 local w, h = QuestHelper.map_overlay:GetWidth(), -QuestHelper.map_overlay:GetHeight()
114 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
116 local last_x, last_y = self.frame.Astrolabe:TranslateWorldMapPosition(self.frame.c, self.frame.z, self.frame.x, self.frame.y, c, z) local remainder = self.phase
118 for i, pos in ipairs(points) do
119 local new_x, new_y = unpack(pos)
120 local x1, y1, x2, y2 = ClampLine(last_x, last_y, new_x, new_y)
121 last_x, last_y = new_x, new_y
123 if x1 then
124 local len = math.sqrt((x1-x2)*(x1-x2)*16/9+(y1-y2)*(y1-y2))
126 if len > 0.0001 then
127 local interval = .025/len
128 local p = remainder*interval
130 while p < 1 do
131 out = out + 1
132 local dot = self.dots[out]
133 if not dot then
134 dot = QuestHelper:CreateDotTexture(self)
135 dot:SetDrawLayer("BACKGROUND")
136 self.dots[out] = dot
139 dot:ClearAllPoints()
140 dot:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x1*w*(1-p)+x2*w*p, y1*h*(1-p)+y2*h*p)
142 p = p + interval
145 remainder = (p-1)/interval
151 while #self.dots > out do
152 QuestHelper:ReleaseTexture(table.remove(self.dots))
156 function walker:RouteChanged()
157 if self.frame.Astrolabe.WorldMapVisible then
158 local points = self.points
159 local cur = self.frame.pos
161 while #points > 0 do self.frame:ReleaseTable(table.remove(points)) end
163 local travel_time = 0.0
165 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
167 if self.frame.target then
168 travel_time = math.max(0, self.frame.target_time-time())
169 cur = self.frame.target
170 local t = self.frame:CreateTable()
171 t[1], t[2] = convertLocationToScreen(cur, c, z)
172 table.insert(points, t)
175 for i, obj in pairs(self.frame.route) do
176 local path, d = self.frame:ComputeRoute(cur, obj.pos)
178 pushPath(points, path, c, z)
180 travel_time = travel_time + d
181 obj.travel_time = travel_time
183 cur = obj.pos
185 local t = self.frame:CreateTable()
186 t[1], t[2] = convertLocationToScreen(cur, c, z)
188 table.insert(points, t)
191 for i = 1, #self.frame.route do
192 local dodad = self.map_dodads[i]
193 if not dodad then
194 self.map_dodads[i] = self.frame:CreateWorldMapDodad(self.frame.route[i], i)
195 else
196 self.map_dodads[i]:SetObjective(self.frame.route[i], i)
200 for i = #self.frame.route+1,self.used_map_dodads do
201 self.map_dodads[i]:SetObjective(nil, 0)
204 self.used_map_dodads = #self.frame.route
208 walker:SetScript("OnEvent", walker.RouteChanged)
209 walker:RegisterEvent("WORLD_MAP_UPDATE")
211 walker:SetScript("OnUpdate", walker.OnUpdate)
213 return walker
216 function QuestHelper:GetOverlapObjectives(obj)
217 local w, h = self.map_overlay:GetWidth(), self.map_overlay:GetHeight()
218 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
220 local list = self.overlap_list
222 if not list then
223 list = {}
224 self.overlap_list = list
225 else
226 while table.remove(list) do end
229 local cx, cy = GetCursorPosition()
231 local es = QuestHelper.map_overlay:GetEffectiveScale()
232 local ies = 1/es
234 cx, cy = (cx-self.map_overlay:GetLeft()*es)*ies, (self.map_overlay:GetTop()*es-cy)*ies
236 local s = 10*QuestHelper_Pref.scale
238 for i, o in ipairs(self.route) do
239 if o == obj then
240 table.insert(list, o)
241 else
242 local x, y = o.pos[3], o.pos[4]
243 x, y = x / self.continent_scales_x[o.pos[1].c], y / self.continent_scales_y[o.pos[1].c]
244 x, y = self.Astrolabe:TranslateWorldMapPosition(o.pos[1].c, 0, x, y, c, z)
246 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
247 x, y = x*w, y*h
249 if cx >= x-s and cy >= y-s and cx <= x+s and cy <= y+s then
250 table.insert(list, o)
256 table.sort(list, function(a, b) return (a.travel_time or 0) < (b.travel_time or 0) end)
258 return list
261 local prog_sort_table = {}
263 function QuestHelper:AppendObjectiveProgressToTooltip(o, tooltip, font, depth)
264 if o.progress then
265 local theme = self:GetColourTheme()
267 local indent = (" "):rep(depth or 0)
269 for user, progress in pairs(o.progress) do
270 table.insert(prog_sort_table, user)
273 table.sort(prog_sort_table, function(a, b)
274 if o.progress[a][3] < o.progress[b][3] then
275 return true
276 elseif o.progress[a][3] == o.progress[b][3] then
277 return a < b
279 return false
280 end)
282 for i, u in ipairs(prog_sort_table) do
283 tooltip:AddDoubleLine(indent..QHFormat("PEER_PROGRESS", u),
284 self:ProgressString(o.progress[u][1].."/"..o.progress[u][2],
285 o.progress[u][3]), unpack(theme.tooltip))
287 if font then
288 local last, name = tooltip:NumLines(), tooltip:GetName()
289 local left, right = _G[name.."TextLeft"..last], _G[name.."TextRight"..last]
291 left:SetFont(font, 13)
292 right:SetFont(font, 13)
296 while table.remove(prog_sort_table) do end
300 function QuestHelper:AppendObjectiveToTooltip(o)
301 local theme = self:GetColourTheme()
303 self.tooltip:AddLine(o:Reason(), unpack(theme.tooltip))
304 self.tooltip:GetPrevLines():SetFont(self.font.serif, 14)
306 self:AppendObjectiveProgressToTooltip(o, self.tooltip, QuestHelper.font.sans)
308 self.tooltip:AddDoubleLine(QHText("TRAVEL_ESTIMATE"), QHFormat("TRAVEL_ESTIMATE_VALUE", o.travel_time or 0), unpack(theme.tooltip))
309 self.tooltip:GetPrevLines():SetFont(self.font.sans, 11)
310 select(2, self.tooltip:GetPrevLines()):SetFont(self.font.sans, 11)
313 function QuestHelper:CreateWorldMapDodad(objective, index)
314 local icon = CreateFrame("Button", nil, QuestHelper.map_overlay)
315 icon:SetFrameStrata("FULLSCREEN")
317 function icon:SetTooltip(list)
318 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
319 QuestHelper.tooltip:ClearLines()
321 local first = true
323 for i, o in ipairs(list) do
324 if first then
325 first = false
326 else
327 QuestHelper.tooltip:AddLine("|c80ff0000 . . . . . .|r")
328 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.sans, 8)
331 QuestHelper:AppendObjectiveToTooltip(o)
334 QuestHelper.tooltip:Show()
337 function icon:SetObjective(objective, i)
338 self:SetHeight(20*QuestHelper_Pref.scale)
339 self:SetWidth(20*QuestHelper_Pref.scale)
341 if self.dot then
342 QuestHelper:ReleaseTexture(self.dot)
343 self.dot = nil
346 if self.bg then
347 QuestHelper:ReleaseTexture(self.bg)
348 self.bg = nil
351 if objective then
352 self.objective = objective
353 self.index = i
355 if i == 1 then
356 -- if it's the very next objective, give it the green background
357 self.bg = QuestHelper:CreateIconTexture(self, 13)
358 elseif objective.filter_blocked then
359 -- if there are still prerequisites, make it grey
360 -- filter_blocked is updated by [Add|Remove]ObjectiveWatch and ObjectiveObjectDependsOn,
361 -- and will be true if there are other objectives that need to be completed before this one.
362 self.bg = QuestHelper:CreateIconTexture(self, 16)
363 else
364 -- otherwise give it the background selected by the objective
365 self.bg = QuestHelper:CreateIconTexture(self, objective.icon_bg)
368 self.dot = QuestHelper:CreateIconTexture(self, objective.icon_id)
370 self.bg:SetDrawLayer("BACKGROUND")
371 self.bg:SetAllPoints()
372 self.dot:SetPoint("TOPLEFT", self, "TOPLEFT", 3*QuestHelper_Pref.scale, -3*QuestHelper_Pref.scale)
373 self.dot:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -3*QuestHelper_Pref.scale, 3*QuestHelper_Pref.scale)
375 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(objective.pos))
376 else
377 self.objective = nil
378 self:Hide()
382 function icon:SetGlow(list)
383 local w, h = QuestHelper.map_overlay:GetWidth(), QuestHelper.map_overlay:GetHeight()
384 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
385 local _, x_size, y_size = QuestHelper.Astrolabe:ComputeDistance(c, z, 0.25, 0.25, c, z, 0.75, 0.75)
387 x_size = math.max(25, 200 / x_size * w)
388 y_size = math.max(25, 200 / y_size * h)
390 local out = 1
391 for _, objective in ipairs(list) do
392 if objective.p then for _, list in pairs(objective.p) do
393 for _, p in ipairs(list) do
394 local x, y = p[3], p[4]
395 x, y = x / QuestHelper.continent_scales_x[p[1].c], y / QuestHelper.continent_scales_y[p[1].c]
396 x, y = QuestHelper.Astrolabe:TranslateWorldMapPosition(p[1].c, 0, x, y, c, z)
397 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
398 if not self.glow_list then
399 self.glow_list = QuestHelper:CreateTable()
402 tex = self.glow_list[out]
403 if not tex then
404 tex = QuestHelper:CreateGlowTexture(self)
405 table.insert(self.glow_list, tex)
407 out = out + 1
409 tex:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x*w, -y*h)
410 tex:SetVertexColor(1,1,1,0)
411 tex:SetWidth(x_size)
412 tex:SetHeight(y_size)
413 tex:Show()
414 tex.max_alpha = 1/p[5]
416 end end
420 if self.glow_list then
421 for i = out,#self.glow_list do
422 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
425 if #self.glow_list == 0 then
426 QuestHelper:ReleaseTable(self.glow_list)
427 self.glow_list = nil
432 icon.show_glow = false
433 icon.glow_pct = 0.0
434 icon.phase = 0.0
435 icon.old_count = 0
437 function icon:OnUpdate(elapsed)
438 self.phase = (self.phase + elapsed)%6.283185307179586476925286766559005768394338798750211641949889185
440 if self.old_count > 0 then
441 local list = QuestHelper:GetOverlapObjectives(self.objective)
442 if #list ~= self.old_count then
443 self:SetTooltip(list)
444 self.old_count = #list
445 self:SetGlow(list)
449 if self.show_glow then
450 self.glow_pct = math.min(1, self.glow_pct+elapsed*1.5)
451 else
452 self.glow_pct = math.max(0, self.glow_pct-elapsed*0.5)
454 if self.glow_pct == 0 then
455 if self.glow_list then
456 while #self.glow_list > 0 do
457 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
459 QuestHelper:ReleaseTable(self.glow_list)
460 self.glow_list = nil
463 self:SetScript("OnUpdate", nil)
464 return
468 if self.glow_list then
469 -- You know, these numbers are harmonics of pi. Would SETI detected them, or would they just be seen as noise?
470 -- I'd vote for the later.
472 -- Pi - circumference over diameter - when was the last time you actually cared about diameters in math?
474 -- Pretty much everything in computer geometry depends on the pythagorean theorem, which you can use for
475 -- circles, spheres, and hyper-spheres, if you use radius.
477 -- It's even the basis of special relativity, with time being multiplied by c so that you get a distance
478 -- that you can use with the spatial dimensions. We're all in agreement that space traveling aliens are
479 -- going to know about relativity, right?
481 -- And if you ever do trig, a full circle would be exactly (circumference over radius) radians instead of
482 -- (circumference over diameter)*2 radians.
484 -- Obviously aliens are much more likely to prefer 6.283185307179586... as constant than our pi.
486 -- Important update: I just noticed that large factorials can be approximated using (2*pi*n)^.5*(n/e)^n
487 -- There's that 2 times pi thing again.
488 local r, g, b = math.sin(self.phase)*0.25+0.75,
489 math.sin(self.phase+2.094395102393195492308428922186335256131446266250070547316629728)*0.25+0.75,
490 math.sin(self.phase+4.188790204786390984616857844372670512262892532500141094633259456)*0.25+0.75
492 for i, tex in ipairs(self.glow_list) do
493 tex:SetVertexColor(r, g, b, self.glow_pct*tex.max_alpha)
498 function icon:OnEnter()
499 local list = QuestHelper:GetOverlapObjectives(self.objective)
500 self:SetTooltip(list)
501 self.old_count = #list
503 icon.show_glow = true
505 self:SetGlow(list)
507 self:SetScript("OnUpdate", self.OnUpdate)
510 function icon:OnLeave()
511 QuestHelper.tooltip:Hide()
512 self.show_glow = false
513 self.old_count = 0
516 function icon:OnEvent(event)
517 if self.objective and self.objective.pos then
518 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(self.objective.pos))
519 else
520 self.objective = nil
521 self:Hide()
525 function icon:OnClick()
526 if self.objective then
527 local menu = QuestHelper:CreateMenu()
528 local list = QuestHelper:GetOverlapObjectives(self.objective)
529 local item
531 if #list > 1 then
532 QuestHelper:CreateMenuTitle(menu, "Objectives")
534 for i, o in ipairs(list) do
535 local submenu = QuestHelper:CreateMenu()
536 item = QuestHelper:CreateMenuItem(menu, o:Reason(true))
537 item:SetSubmenu(submenu)
538 item:AddTexture(QuestHelper:CreateIconTexture(item, o.icon_id), true)
539 QuestHelper:AddObjectiveOptionsToMenu(o, submenu)
541 else
542 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
543 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
546 menu:ShowAtCursor()
550 icon:SetScript("OnClick", icon.OnClick)
551 icon:SetScript("OnEnter", icon.OnEnter)
552 icon:SetScript("OnLeave", icon.OnLeave)
553 icon:SetScript("OnEvent", icon.OnEvent)
555 icon:RegisterForClicks("RightButtonUp")
557 icon:RegisterEvent("WORLD_MAP_UPDATE")
559 icon:SetObjective(objective, index)
560 return icon
563 local callbacks = {}
564 local last_c, last_z, last_x, last_y, last_desc
566 function QuestHelper:AddWaypointCallback(func, ...)
567 local cb = self:CreateTable()
568 callbacks[cb] = true
569 local len = select("#", ...)
570 cb.len = len
571 cb.func = func
572 for i = 1,len do cb[i] = select(i, ...) end
573 cb[len+1] = last_c
574 cb[len+2] = last_z
575 cb[len+3] = last_x
576 cb[len+4] = last_y
577 cb[len+5] = last_desc
579 if last_c then
580 func(unpack(cb, 1, len+5))
583 return cb
586 function QuestHelper:RemoveWaypointCallback(cb)
587 callbacks[cb] = nil
588 self:ReleaseTable(cb)
591 function QuestHelper:InvokeWaypointCallbacks(c, z, x, y, desc)
592 if c ~= last_c or z ~= last_z or x ~= last_x or y ~= last_y or desc ~= last_desc then
593 last_c, last_z, last_x, last_y, last_desc = c, z, x, y, desc
594 for cb in pairs(callbacks) do
595 local len = cb.len
596 cb[len+1] = c
597 cb[len+2] = z
598 cb[len+3] = x
599 cb[len+4] = y
600 cb[len+5] = desc
601 cb.func(unpack(cb, 1, len+5))
606 function QuestHelper:CreateMipmapDodad()
607 local icon = CreateFrame("Button", nil, Minimap)
608 icon:Hide()
609 icon.recalc_timeout = 0
611 icon.arrow = CreateFrame("Model", nil, icon)
612 icon.arrow:SetHeight(140.8)
613 icon.arrow:SetWidth(140.8)
614 icon.arrow:SetPoint("CENTER", Minimap, "CENTER", 0, 0)
615 icon.arrow:SetModel("Interface\\Minimap\\Rotating-MinimapArrow.mdx")
616 icon.arrow:Hide()
618 icon.phase = 0
619 icon.target = {0, 0, 0, 0}
620 icon.icon_id = 7
622 icon.bg = QuestHelper:CreateIconTexture(icon, 16)
623 icon.bg:SetDrawLayer("BACKGROUND")
624 icon.bg:SetAllPoints()
626 function icon:NextObjective()
627 for i, o in ipairs(QuestHelper.route) do
628 if not QuestHelper.to_remove[o] and o.pos and not o.filter_blocked then
629 return o
633 return nil
636 function icon:OnUpdate(elapsed)
637 if self.objective then
638 if not self.objective.pos then
639 self.objective = self:NextObjective()
640 if not self.objective then
641 self:Hide()
642 return
646 self:Show()
648 if self.recalc_timeout == 0 and not QuestHelper.graph_in_limbo then
649 self.recalc_timeout = 50
651 self.objective = self:NextObjective()
653 if not self.objective then
654 self:Hide()
655 return
658 local path, travel_time
660 if QuestHelper.target then
661 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.target, self.objective.pos)
662 travel_time = travel_time + math.max(0, QuestHelper.target_time-time())
663 else
664 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.pos, self.objective.pos)
667 local t = self.target
668 local id = self.objective.icon_id
669 t[1], t[2], t[3], t[4] = convertLocation(self.objective.pos)
670 t[5] = nil
672 self.objective.travel_time = travel_time
674 while path do
675 if path.g > 10.0 then
676 id = 8
677 t[1] = path.c
678 t[2] = 0
679 t[3] = path.x / QuestHelper.continent_scales_x[path.c]
680 t[4] = path.y / QuestHelper.continent_scales_y[path.c]
681 t[5] = path.name or "waypoint"
683 path = path.p
686 if not self.dot or id ~= self.icon_id then
687 self.icon_id = id
688 if self.dot then QuestHelper:ReleaseTexture(self.dot) end
689 self.dot = QuestHelper:CreateIconTexture(self, self.icon_id)
690 self.dot:SetPoint("TOPLEFT", icon, "TOPLEFT", 2, -2)
691 self.dot:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
694 if UnitIsDeadOrGhost("player") then
695 QuestHelper:InvokeWaypointCallbacks()
696 else
697 local reason = (t[5] and (QHFormat("WAYPOINT_REASON", t[5]).."\n"..self.objective:Reason(true)))
698 or self.objective:Reason(true)
700 if QuestHelper.c == t[1] then
701 -- Translate the position to the zone the player is standing in.
702 local c, z = QuestHelper.c, QuestHelper.z
703 local x, y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], c, z)
704 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
705 else
706 -- Try to find the nearest zone on the continent the objective is in.
707 local index, distsqr, x, y
708 for z, i in pairs(QuestHelper_IndexLookup[t[1]]) do
709 local _x, _y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], t[1], z)
710 local d = (_x-0.5)*(_x-0.5)+(_y-0.5)*(_y-0.5)
711 if not index or d < distsqr then
712 index, distsqr, x, y = i, d, _x, _y
715 local c, z = QuestHelper_IndexLookup[index]
716 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
720 QuestHelper.Astrolabe:PlaceIconOnMinimap(self, unpack(self.target))
721 else
722 self.recalc_timeout = self.recalc_timeout - 1
725 local edge = QuestHelper.Astrolabe:IsIconOnEdge(self)
727 if edge then
728 self.arrow:Show()
729 self.dot:Hide()
730 self.bg:Hide()
731 else
732 self.arrow:Hide()
733 self.dot:Show()
734 self.bg:Show()
737 if edge then
738 local angle = QuestHelper.Astrolabe:GetDirectionToIcon(self)
739 if GetCVar("rotateMinimap") == "1" then
740 angle = angle + MiniMapCompassRing:GetFacing()
743 self.arrow:SetFacing(angle)
744 self.arrow:SetPosition(ofs * (137 / 140) - radius * math.sin(angle),
745 ofs + radius * math.cos(angle), 0);
747 if self.phase > 6.283185307179586476925 then
748 self.phase = self.phase-6.283185307179586476925+elapsed*3.5
749 else
750 self.phase = self.phase+elapsed*3.5
752 self.arrow:SetModelScale(0.600000023841879+0.1*math.sin(self.phase))
754 else
755 self:Hide()
759 function icon:SetObjective(objective)
760 self:SetHeight(20*QuestHelper_Pref.scale)
761 self:SetWidth(20*QuestHelper_Pref.scale)
763 if objective ~= self.objective then
764 if objective and not QuestHelper_Pref.hide then
765 self:Show()
766 else
767 QuestHelper:InvokeWaypointCallbacks()
768 self:Hide()
771 self.objective = objective
772 self.recalc_timeout = 0
776 function icon:OnEnter()
777 if self.objective then
778 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
779 QuestHelper.tooltip:ClearLines()
781 if self.target[5] then
782 QuestHelper.tooltip:AddLine(QHFormat("WAYPOINT_REASON", self.target[5]), unpack(QuestHelper:GetColourTheme().tooltip))
783 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.serif, 14)
786 QuestHelper:AppendObjectiveToTooltip(self.objective)
787 QuestHelper.tooltip:Show()
791 function icon:OnLeave()
792 QuestHelper.tooltip:Hide()
795 function icon:OnClick()
796 if self.objective then
797 local menu = QuestHelper:CreateMenu()
798 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
799 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
800 menu:ShowAtCursor()
804 function icon:OnEvent()
805 if self.objective and self.objective.pos then
806 self:Show()
807 else
808 self:Hide()
812 icon:SetScript("OnUpdate", icon.OnUpdate)
813 icon:SetScript("OnEnter", icon.OnEnter)
814 icon:SetScript("OnLeave", icon.OnLeave)
815 icon:SetScript("OnEvent", icon.OnEvent)
816 icon:SetScript("OnClick", icon.OnClick)
818 icon:RegisterForClicks("RightButtonUp")
819 icon:RegisterEvent("PLAYER_ENTERING_WORLD")
821 return icon