remove extra +x
[QuestHelper.git] / dodads.lua
blobf24477833f7d5b38d4997060f9bee00157fa28ee
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 for i, obj in pairs(self.frame.route) do
159 if not obj.pos then
160 -- No. Just no.
161 QuestHelper:AppendNotificationError("10-10-2008 pathfinding/dodads nil coroutine race condition bug")
162 return -- return "failure :("
166 local points = self.points
167 local cur = self.frame.pos
169 while #points > 0 do self.frame:ReleaseTable(table.remove(points)) end
171 local travel_time = 0.0
173 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
175 if self.frame.target then
176 travel_time = math.max(0, self.frame.target_time-time())
177 cur = self.frame.target
178 local t = self.frame:CreateTable()
179 t[1], t[2] = convertLocationToScreen(cur, c, z)
180 table.insert(points, t)
183 for i, obj in pairs(self.frame.route) do
184 local path, d = self.frame:ComputeRoute(cur, obj.pos)
186 pushPath(points, path, c, z)
188 travel_time = travel_time + d
189 obj.travel_time = travel_time
191 cur = obj.pos
193 local t = self.frame:CreateTable()
194 t[1], t[2] = convertLocationToScreen(cur, c, z)
196 table.insert(points, t)
199 for i = 1, #self.frame.route do
200 local dodad = self.map_dodads[i]
201 if not dodad then
202 self.map_dodads[i] = self.frame:CreateWorldMapDodad(self.frame.route[i], i)
203 else
204 self.map_dodads[i]:SetObjective(self.frame.route[i], i)
208 for i = #self.frame.route+1,self.used_map_dodads do
209 self.map_dodads[i]:SetObjective(nil, 0)
212 self.used_map_dodads = #self.frame.route
216 walker:SetScript("OnEvent", walker.RouteChanged)
217 walker:RegisterEvent("WORLD_MAP_UPDATE")
219 walker:SetScript("OnUpdate", walker.OnUpdate)
221 return walker
224 function QuestHelper:GetOverlapObjectives(obj)
225 local w, h = self.map_overlay:GetWidth(), self.map_overlay:GetHeight()
226 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
228 local list = self.overlap_list
230 if not list then
231 list = {}
232 self.overlap_list = list
233 else
234 while table.remove(list) do end
237 local cx, cy = GetCursorPosition()
239 local es = QuestHelper.map_overlay:GetEffectiveScale()
240 local ies = 1/es
242 cx, cy = (cx-self.map_overlay:GetLeft()*es)*ies, (self.map_overlay:GetTop()*es-cy)*ies
244 local s = 10*QuestHelper_Pref.scale
246 for i, o in ipairs(self.route) do
247 QuestHelper: Assert(o, "nil dodads pos issue, o")
248 QuestHelper: Assert(o.pos, "nil dodads pos issue, pos")
249 if o == obj then
250 table.insert(list, o)
251 else
252 local x, y = o.pos[3], o.pos[4]
253 x, y = x / self.continent_scales_x[o.pos[1].c], y / self.continent_scales_y[o.pos[1].c]
254 x, y = self.Astrolabe:TranslateWorldMapPosition(o.pos[1].c, 0, x, y, c, z)
256 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
257 x, y = x*w, y*h
259 if cx >= x-s and cy >= y-s and cx <= x+s and cy <= y+s then
260 table.insert(list, o)
266 table.sort(list, function(a, b) return (a.travel_time or 0) < (b.travel_time or 0) end)
268 return list
271 local prog_sort_table = {}
273 function QuestHelper:AppendObjectiveProgressToTooltip(o, tooltip, font, depth)
274 if o.progress then
275 local theme = self:GetColourTheme()
277 local indent = (" "):rep(depth or 0)
279 for user, progress in pairs(o.progress) do
280 table.insert(prog_sort_table, user)
283 table.sort(prog_sort_table, function(a, b)
284 if o.progress[a][3] < o.progress[b][3] then
285 return true
286 elseif o.progress[a][3] == o.progress[b][3] then
287 return a < b
289 return false
290 end)
292 for i, u in ipairs(prog_sort_table) do
293 tooltip:AddDoubleLine(indent..QHFormat("PEER_PROGRESS", u),
294 self:ProgressString(o.progress[u][1].."/"..o.progress[u][2],
295 o.progress[u][3]), unpack(theme.tooltip))
297 if font then
298 local last, name = tooltip:NumLines(), tooltip:GetName()
299 local left, right = _G[name.."TextLeft"..last], _G[name.."TextRight"..last]
301 left:SetFont(font, 13)
302 right:SetFont(font, 13)
306 while table.remove(prog_sort_table) do end
310 function QuestHelper:AppendObjectiveToTooltip(o)
311 local theme = self:GetColourTheme()
313 self.tooltip:AddLine(o:Reason(), unpack(theme.tooltip))
314 self.tooltip:GetPrevLines():SetFont(self.font.serif, 14)
316 self:AppendObjectiveProgressToTooltip(o, self.tooltip, QuestHelper.font.sans)
318 self.tooltip:AddDoubleLine(QHText("TRAVEL_ESTIMATE"), QHFormat("TRAVEL_ESTIMATE_VALUE", o.travel_time or 0), unpack(theme.tooltip))
319 self.tooltip:GetPrevLines():SetFont(self.font.sans, 11)
320 select(2, self.tooltip:GetPrevLines()):SetFont(self.font.sans, 11)
323 function QuestHelper:CreateWorldMapDodad(objective, index)
324 local icon = CreateFrame("Button", nil, QuestHelper.map_overlay)
325 icon:SetFrameStrata("FULLSCREEN")
327 function icon:SetTooltip(list)
328 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
329 QuestHelper.tooltip:ClearLines()
331 local first = true
333 for i, o in ipairs(list) do
334 if first then
335 first = false
336 else
337 QuestHelper.tooltip:AddLine("|c80ff0000 . . . . . .|r")
338 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.sans, 8)
341 QuestHelper:AppendObjectiveToTooltip(o)
344 QuestHelper.tooltip:Show()
347 function icon:SetObjective(objective, i)
348 self:SetHeight(20*QuestHelper_Pref.scale)
349 self:SetWidth(20*QuestHelper_Pref.scale)
351 if self.dot then
352 QuestHelper:ReleaseTexture(self.dot)
353 self.dot = nil
356 if self.bg then
357 QuestHelper:ReleaseTexture(self.bg)
358 self.bg = nil
361 if objective then
362 self.objective = objective
363 self.index = i
365 if i == 1 then
366 -- if it's the very next objective, give it the green background
367 self.bg = QuestHelper:CreateIconTexture(self, 13)
368 elseif objective.filter_blocked then
369 -- if there are still prerequisites, make it grey
370 -- filter_blocked is updated by [Add|Remove]ObjectiveWatch and ObjectiveObjectDependsOn,
371 -- and will be true if there are other objectives that need to be completed before this one.
372 self.bg = QuestHelper:CreateIconTexture(self, 16)
373 else
374 -- otherwise give it the background selected by the objective
375 self.bg = QuestHelper:CreateIconTexture(self, objective.icon_bg)
378 self.dot = QuestHelper:CreateIconTexture(self, objective.icon_id)
380 self.bg:SetDrawLayer("BACKGROUND")
381 self.bg:SetAllPoints()
382 self.dot:SetPoint("TOPLEFT", self, "TOPLEFT", 3*QuestHelper_Pref.scale, -3*QuestHelper_Pref.scale)
383 self.dot:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -3*QuestHelper_Pref.scale, 3*QuestHelper_Pref.scale)
385 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(objective.pos))
386 else
387 self.objective = nil
388 self:Hide()
392 function icon:SetGlow(list)
393 local w, h = QuestHelper.map_overlay:GetWidth(), QuestHelper.map_overlay:GetHeight()
394 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
395 local _, x_size, y_size = QuestHelper.Astrolabe:ComputeDistance(c, z, 0.25, 0.25, c, z, 0.75, 0.75)
397 x_size = math.max(25, 200 / x_size * w)
398 y_size = math.max(25, 200 / y_size * h)
400 local out = 1
401 for _, objective in ipairs(list) do
402 if objective.p then for _, list in pairs(objective.p) do
403 for _, p in ipairs(list) do
404 local x, y = p[3], p[4]
405 x, y = x / QuestHelper.continent_scales_x[p[1].c], y / QuestHelper.continent_scales_y[p[1].c]
406 x, y = QuestHelper.Astrolabe:TranslateWorldMapPosition(p[1].c, 0, x, y, c, z)
407 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
408 if not self.glow_list then
409 self.glow_list = QuestHelper:CreateTable()
412 tex = self.glow_list[out]
413 if not tex then
414 tex = QuestHelper:CreateGlowTexture(self)
415 table.insert(self.glow_list, tex)
417 out = out + 1
419 tex:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x*w, -y*h)
420 tex:SetVertexColor(1,1,1,0)
421 tex:SetWidth(x_size)
422 tex:SetHeight(y_size)
423 tex:Show()
424 tex.max_alpha = 1/p[5]
426 end end
430 if self.glow_list then
431 for i = out,#self.glow_list do
432 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
435 if #self.glow_list == 0 then
436 QuestHelper:ReleaseTable(self.glow_list)
437 self.glow_list = nil
442 icon.show_glow = false
443 icon.glow_pct = 0.0
444 icon.phase = 0.0
445 icon.old_count = 0
447 function icon:OnUpdate(elapsed)
448 self.phase = (self.phase + elapsed)%6.283185307179586476925286766559005768394338798750211641949889185
450 if self.old_count > 0 then
451 local list = QuestHelper:GetOverlapObjectives(self.objective)
452 if #list ~= self.old_count then
453 self:SetTooltip(list)
454 self.old_count = #list
455 self:SetGlow(list)
459 if self.show_glow then
460 self.glow_pct = math.min(1, self.glow_pct+elapsed*1.5)
461 else
462 self.glow_pct = math.max(0, self.glow_pct-elapsed*0.5)
464 if self.glow_pct == 0 then
465 if self.glow_list then
466 while #self.glow_list > 0 do
467 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
469 QuestHelper:ReleaseTable(self.glow_list)
470 self.glow_list = nil
473 self:SetScript("OnUpdate", nil)
474 return
478 if self.glow_list then
479 -- You know, these numbers are harmonics of pi. Would SETI detected them, or would they just be seen as noise?
480 -- I'd vote for the later.
482 -- Pi - circumference over diameter - when was the last time you actually cared about diameters in math?
484 -- Pretty much everything in computer geometry depends on the pythagorean theorem, which you can use for
485 -- circles, spheres, and hyper-spheres, if you use radius.
487 -- It's even the basis of special relativity, with time being multiplied by c so that you get a distance
488 -- that you can use with the spatial dimensions. We're all in agreement that space traveling aliens are
489 -- going to know about relativity, right?
491 -- And if you ever do trig, a full circle would be exactly (circumference over radius) radians instead of
492 -- (circumference over diameter)*2 radians.
494 -- Obviously aliens are much more likely to prefer 6.283185307179586... as constant than our pi.
496 -- Important update: I just noticed that large factorials can be approximated using (2*pi*n)^.5*(n/e)^n
497 -- There's that 2 times pi thing again.
498 local r, g, b = math.sin(self.phase)*0.25+0.75,
499 math.sin(self.phase+2.094395102393195492308428922186335256131446266250070547316629728)*0.25+0.75,
500 math.sin(self.phase+4.188790204786390984616857844372670512262892532500141094633259456)*0.25+0.75
502 for i, tex in ipairs(self.glow_list) do
503 tex:SetVertexColor(r, g, b, self.glow_pct*tex.max_alpha)
508 function icon:OnEnter()
509 local list = QuestHelper:GetOverlapObjectives(self.objective)
510 self:SetTooltip(list)
511 self.old_count = #list
513 icon.show_glow = true
515 self:SetGlow(list)
517 self:SetScript("OnUpdate", self.OnUpdate)
520 function icon:OnLeave()
521 QuestHelper.tooltip:Hide()
522 self.show_glow = false
523 self.old_count = 0
526 function icon:OnEvent(event)
527 if self.objective and self.objective.pos then
528 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(self.objective.pos))
529 else
530 self.objective = nil
531 self:Hide()
535 function icon:OnClick()
536 if self.objective then
537 local menu = QuestHelper:CreateMenu()
538 local list = QuestHelper:GetOverlapObjectives(self.objective)
539 local item
541 if #list > 1 then
542 QuestHelper:CreateMenuTitle(menu, "Objectives")
544 for i, o in ipairs(list) do
545 local submenu = QuestHelper:CreateMenu()
546 item = QuestHelper:CreateMenuItem(menu, o:Reason(true))
547 item:SetSubmenu(submenu)
548 item:AddTexture(QuestHelper:CreateIconTexture(item, o.icon_id), true)
549 QuestHelper:AddObjectiveOptionsToMenu(o, submenu)
551 else
552 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
553 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
556 menu:ShowAtCursor()
560 icon:SetScript("OnClick", icon.OnClick)
561 icon:SetScript("OnEnter", icon.OnEnter)
562 icon:SetScript("OnLeave", icon.OnLeave)
563 icon:SetScript("OnEvent", icon.OnEvent)
565 icon:RegisterForClicks("RightButtonUp")
567 icon:RegisterEvent("WORLD_MAP_UPDATE")
569 icon:SetObjective(objective, index)
570 return icon
573 local callbacks = {}
574 local last_c, last_z, last_x, last_y, last_desc
576 function QuestHelper:AddWaypointCallback(func, ...)
577 local cb = self:CreateTable()
578 callbacks[cb] = true
579 local len = select("#", ...)
580 cb.len = len
581 cb.func = func
582 for i = 1,len do cb[i] = select(i, ...) end
583 cb[len+1] = last_c
584 cb[len+2] = last_z
585 cb[len+3] = last_x
586 cb[len+4] = last_y
587 cb[len+5] = last_desc
589 if last_c then
590 func(unpack(cb, 1, len+5))
593 return cb
596 function QuestHelper:RemoveWaypointCallback(cb)
597 callbacks[cb] = nil
598 self:ReleaseTable(cb)
601 function QuestHelper:InvokeWaypointCallbacks(c, z, x, y, desc)
602 if c ~= last_c or z ~= last_z or x ~= last_x or y ~= last_y or desc ~= last_desc then
603 last_c, last_z, last_x, last_y, last_desc = c, z, x, y, desc
604 for cb in pairs(callbacks) do
605 local len = cb.len
606 cb[len+1] = c
607 cb[len+2] = z
608 cb[len+3] = x
609 cb[len+4] = y
610 cb[len+5] = desc
611 cb.func(unpack(cb, 1, len+5))
616 function QuestHelper:CreateMipmapDodad()
617 local icon = CreateFrame("Button", nil, Minimap)
618 icon:Hide()
619 icon.recalc_timeout = 0
621 icon.arrow = CreateFrame("Model", nil, icon)
622 icon.arrow:SetHeight(140.8)
623 icon.arrow:SetWidth(140.8)
624 icon.arrow:SetPoint("CENTER", Minimap, "CENTER", 0, 0)
625 icon.arrow:SetModel("Interface\\Minimap\\Rotating-MinimapArrow.mdx")
626 icon.arrow:Hide()
628 icon.phase = 0
629 icon.target = {0, 0, 0, 0}
630 icon.icon_id = 7
632 icon.bg = QuestHelper:CreateIconTexture(icon, 16)
633 icon.bg:SetDrawLayer("BACKGROUND")
634 icon.bg:SetAllPoints()
636 function icon:NextObjective()
637 for i, o in ipairs(QuestHelper.route) do
638 if not QuestHelper.to_remove[o] and o.pos and not o.filter_blocked then
639 return o
643 return nil
646 function icon:OnUpdate(elapsed)
647 if self.objective then
648 if not self.objective.pos then
649 self.objective = self:NextObjective()
650 if not self.objective then
651 self:Hide()
652 return
656 self:Show()
658 if self.recalc_timeout <= 0 and not QuestHelper.graph_in_limbo then
659 self.recalc_timeout = 50
661 self.objective = self:NextObjective()
663 if not self.objective then
664 self:Hide()
665 return
668 local path, travel_time
670 if QuestHelper.target then
671 for i in ipairs(QuestHelper.target[1]) do QuestHelper: Assert(QuestHelper.target[2][i], "nil flightpath error resurgence!") end
672 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.target, self.objective.pos)
673 travel_time = travel_time + math.max(0, QuestHelper.target_time-time())
674 else
675 path, travel_time = QuestHelper:ComputeRoute(QuestHelper.pos, self.objective.pos)
678 local t = self.target
679 local id = self.objective.icon_id
680 t[1], t[2], t[3], t[4] = convertLocation(self.objective.pos)
681 t[5] = nil
683 self.objective.travel_time = travel_time
685 while path do
686 if path.g > 10.0 then
687 id = 8
688 t[1] = path.c
689 t[2] = 0
690 t[3] = path.x / QuestHelper.continent_scales_x[path.c]
691 t[4] = path.y / QuestHelper.continent_scales_y[path.c]
692 t[5] = path.name or "waypoint"
694 path = path.p
697 if not self.dot or id ~= self.icon_id then
698 self.icon_id = id
699 if self.dot then QuestHelper:ReleaseTexture(self.dot) end
700 self.dot = QuestHelper:CreateIconTexture(self, self.icon_id)
701 self.dot:SetPoint("TOPLEFT", icon, "TOPLEFT", 2, -2)
702 self.dot:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
705 if UnitIsDeadOrGhost("player") then
706 QuestHelper:InvokeWaypointCallbacks()
707 else
708 local reason = (t[5] and (QHFormat("WAYPOINT_REASON", t[5]).."\n"..self.objective:Reason(true)))
709 or self.objective:Reason(true)
711 if QuestHelper.c == t[1] then
712 -- Translate the position to the zone the player is standing in.
713 local c, z = QuestHelper.c, QuestHelper.z
714 local x, y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], c, z)
715 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
716 else
717 -- Try to find the nearest zone on the continent the objective is in.
718 local index, distsqr, x, y
719 for z, i in pairs(QuestHelper_IndexLookup[t[1]]) do
720 local _x, _y = QuestHelper.Astrolabe:TranslateWorldMapPosition(t[1], t[2], t[3], t[4], t[1], z)
721 local d = (_x-0.5)*(_x-0.5)+(_y-0.5)*(_y-0.5)
722 if not index or d < distsqr then
723 index, distsqr, x, y = i, d, _x, _y
726 local c, z = QuestHelper_IndexLookup[index]
727 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, reason)
731 QuestHelper.Astrolabe:PlaceIconOnMinimap(self, unpack(self.target))
732 else
733 self.recalc_timeout = self.recalc_timeout - 1
736 local edge = QuestHelper.Astrolabe:IsIconOnEdge(self)
738 if edge then
739 self.arrow:Show()
740 self.dot:Hide()
741 self.bg:Hide()
742 else
743 self.arrow:Hide()
744 self.dot:Show()
745 self.bg:Show()
748 if edge then
749 local angle = QuestHelper.Astrolabe:GetDirectionToIcon(self)
750 if GetCVar("rotateMinimap") == "1" then
751 angle = angle + MiniMapCompassRing:GetFacing()
754 self.arrow:SetFacing(angle)
755 self.arrow:SetPosition(ofs * (137 / 140) - radius * math.sin(angle),
756 ofs + radius * math.cos(angle), 0);
758 if self.phase > 6.283185307179586476925 then
759 self.phase = self.phase-6.283185307179586476925+elapsed*3.5
760 else
761 self.phase = self.phase+elapsed*3.5
763 self.arrow:SetModelScale(0.600000023841879+0.1*math.sin(self.phase))
765 else
766 self:Hide()
770 function icon:SetObjective(objective)
771 self:SetHeight(20*QuestHelper_Pref.scale)
772 self:SetWidth(20*QuestHelper_Pref.scale)
774 if objective ~= self.objective then
775 if objective and not QuestHelper_Pref.hide then
776 self:Show()
777 else
778 QuestHelper:InvokeWaypointCallbacks()
779 self:Hide()
782 self.objective = objective
783 self.recalc_timeout = 0
787 function icon:OnEnter()
788 if self.objective then
789 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
790 QuestHelper.tooltip:ClearLines()
792 if self.target[5] then
793 QuestHelper.tooltip:AddLine(QHFormat("WAYPOINT_REASON", self.target[5]), unpack(QuestHelper:GetColourTheme().tooltip))
794 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.serif, 14)
797 QuestHelper:AppendObjectiveToTooltip(self.objective)
798 QuestHelper.tooltip:Show()
802 function icon:OnLeave()
803 QuestHelper.tooltip:Hide()
806 function icon:OnClick()
807 if self.objective then
808 local menu = QuestHelper:CreateMenu()
809 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
810 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
811 menu:ShowAtCursor()
815 function icon:OnEvent()
816 if self.objective and self.objective.pos then
817 self:Show()
818 else
819 self:Hide()
823 icon:SetScript("OnUpdate", icon.OnUpdate)
824 icon:SetScript("OnEnter", icon.OnEnter)
825 icon:SetScript("OnLeave", icon.OnLeave)
826 icon:SetScript("OnEvent", icon.OnEvent)
827 icon:SetScript("OnClick", icon.OnClick)
829 icon:RegisterForClicks("RightButtonUp")
830 icon:RegisterEvent("PLAYER_ENTERING_WORLD")
832 return icon