Fixed a few bugs regarding target locations.
[QuestHelper.git] / dodads.lua
blob3abebe4667b5a792a307e82f68bdd6bda860a716
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
578 func(unpack(cb, 1, len+5))
579 return cb
582 function QuestHelper:RemoveWaypointCallback(cb)
583 callbacks[cb] = nil
584 self:ReleaseTable(cb)
587 function QuestHelper:InvokeWaypointCallbacks(c, z, x, y, desc)
588 if c ~= last_c or z ~= last_z or x ~= last_x or y ~= last_y or desc ~= last_desc then
589 last_c, last_z, last_x, last_y, last_desc = c, z, x, y, desc
590 for cb in pairs(callbacks) do
591 local len = cb.len
592 cb[len+1] = c
593 cb[len+2] = z
594 cb[len+3] = x
595 cb[len+4] = y
596 cb[len+5] = desc
597 cb.func(unpack(cb, 1, len+5))
602 function QuestHelper:CreateMipmapDodad()
603 local icon = CreateFrame("Button", nil, Minimap)
604 icon:Hide()
605 icon.recalc_timeout = 0
607 icon.arrow = CreateFrame("Model", nil, icon)
608 icon.arrow:SetHeight(140.8)
609 icon.arrow:SetWidth(140.8)
610 icon.arrow:SetPoint("CENTER", Minimap, "CENTER", 0, 0)
611 icon.arrow:SetModel("Interface\\Minimap\\Rotating-MinimapArrow.mdx")
612 icon.arrow:Hide()
614 icon.phase = 0
615 icon.target = {0, 0, 0, 0}
616 icon.icon_id = 7
618 icon.bg = QuestHelper:CreateIconTexture(icon, 16)
619 icon.bg:SetDrawLayer("BACKGROUND")
620 icon.bg:SetAllPoints()
622 function icon:NextObjective()
623 for i, o in ipairs(QuestHelper.route) do
624 if not QuestHelper.to_remove[o] and o.pos then
625 return o
629 return nil
632 function icon:OnUpdate(elapsed)
633 if self.objective then
634 if not self.objective.pos then
635 self.objective = self:NextObjective()
636 if not self.objective then
637 self:Hide()
638 return
642 self:Show()
644 if self.recalc_timeout == 0 and not QuestHelper.graph_in_limbo then
645 self.recalc_timeout = 50
647 self.objective = self:NextObjective()
649 if not self.objective then
650 self:Hide()
651 return
654 local path, travel_time
656 if QuestHelper.target then
657 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.target, self.objective.pos)
658 travel_time = travel_time + math.max(0, QuestHelper.target_time-time())
659 else
660 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.pos, self.objective.pos)
663 local t = self.target
664 local id = self.objective.icon_id
665 t[1], t[2], t[3], t[4] = convertLocation(self.objective.pos)
666 t[5] = nil
668 self.objective.travel_time = travel_time
670 while path do
671 if path.g > 10.0 then
672 id = 8
673 t[1] = path.c
674 t[2] = 0
675 t[3] = path.x / QuestHelper.continent_scales_x[path.c]
676 t[4] = path.y / QuestHelper.continent_scales_y[path.c]
677 t[5] = path.name or "waypoint"
679 path = path.p
682 if not self.dot or id ~= self.icon_id then
683 self.icon_id = id
684 if self.dot then QuestHelper:ReleaseTexture(self.dot) end
685 self.dot = QuestHelper:CreateIconTexture(self, self.icon_id)
686 self.dot:SetPoint("TOPLEFT", icon, "TOPLEFT", 2, -2)
687 self.dot:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
690 if UnitIsDeadOrGhost("player") then
691 QuestHelper:InvokeWaypointCallbacks()
692 else
693 local reason = (t[5] and (QHFormat("WAYPOINT_REASON", t[5]).."\n"..self.objective:Reason(true)))
694 or self.objective:Reason(true)
696 if QuestHelper.c == t[1] then
697 -- Translate the position to the zone the player is standing in.
698 local c, z = QuestHelper.c, QuestHelper.z
699 local x, y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], c, z)
700 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
701 else
702 -- Try to find the nearest zone on the continent the objective is in.
703 local index, distsqr, x, y
704 for z, i in pairs(QuestHelper_IndexLookup[t[1]]) do
705 local _x, _y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], t[1], z)
706 local d = (_x-0.5)*(_x-0.5)+(_y-0.5)*(_y-0.5)
707 if not index or d < distsqr then
708 index, distsqr, x, y = i, d, _x, _y
711 local c, z = QuestHelper_IndexLookup[index]
712 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
716 QuestHelper.Astrolabe:PlaceIconOnMinimap(self, unpack(self.target))
717 else
718 self.recalc_timeout = self.recalc_timeout - 1
721 local edge = QuestHelper.Astrolabe:IsIconOnEdge(self)
723 if edge then
724 self.arrow:Show()
725 self.dot:Hide()
726 self.bg:Hide()
727 else
728 self.arrow:Hide()
729 self.dot:Show()
730 self.bg:Show()
733 if edge then
734 local angle = QuestHelper.Astrolabe:GetDirectionToIcon(self)
735 if GetCVar("rotateMinimap") == "1" then
736 angle = angle + MiniMapCompassRing:GetFacing()
739 self.arrow:SetFacing(angle)
740 self.arrow:SetPosition(ofs * (137 / 140) - radius * math.sin(angle),
741 ofs + radius * math.cos(angle), 0);
743 if self.phase > 6.283185307179586476925 then
744 self.phase = self.phase-6.283185307179586476925+elapsed*3.5
745 else
746 self.phase = self.phase+elapsed*3.5
748 self.arrow:SetModelScale(0.600000023841879+0.1*math.sin(self.phase))
750 else
751 self:Hide()
755 function icon:SetObjective(objective)
756 self:SetHeight(20*QuestHelper_Pref.scale)
757 self:SetWidth(20*QuestHelper_Pref.scale)
759 if objective ~= self.objective then
760 if objective and not QuestHelper_Pref.hide then
761 self:Show()
762 else
763 QuestHelper:InvokeWaypointCallbacks()
764 self:Hide()
767 self.objective = objective
768 self.recalc_timeout = 0
772 function icon:OnEnter()
773 if self.objective then
774 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
775 QuestHelper.tooltip:ClearLines()
777 if self.target[5] then
778 QuestHelper.tooltip:AddLine(QHFormat("WAYPOINT_REASON", self.target[5]), unpack(QuestHelper:GetColourTheme().tooltip))
779 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.serif, 14)
782 QuestHelper:AppendObjectiveToTooltip(self.objective)
783 QuestHelper.tooltip:Show()
787 function icon:OnLeave()
788 QuestHelper.tooltip:Hide()
791 function icon:OnClick()
792 if self.objective then
793 local menu = QuestHelper:CreateMenu()
794 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
795 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
796 menu:ShowAtCursor()
800 function icon:OnEvent()
801 if self.objective and self.objective.pos then
802 self:Show()
803 else
804 self:Hide()
808 icon:SetScript("OnUpdate", icon.OnUpdate)
809 icon:SetScript("OnEnter", icon.OnEnter)
810 icon:SetScript("OnLeave", icon.OnLeave)
811 icon:SetScript("OnEvent", icon.OnEvent)
812 icon:SetScript("OnClick", icon.OnClick)
814 icon:RegisterForClicks("RightButtonUp")
815 icon:RegisterEvent("PLAYER_ENTERING_WORLD")
817 return icon