1 QuestHelper_File
["dodads.lua"] = "Development Version"
2 QuestHelper_Loadtime
["dodads.lua"] = GetTime()
4 local ofs
= 0.000723339 * (GetScreenHeight()/GetScreenWidth() + 1/3) * 70.4;
5 local radius
= ofs
/ 1.166666666666667;
7 local function convertLocation(p
)
8 local c
, x
, y
= p
[1].c
, p
[3], p
[4]
9 x
, y
= x
/QuestHelper
.continent_scales_x
[c
], y
/QuestHelper
.continent_scales_y
[c
]
13 local function convertLocationToScreen(p
, c
, z
)
14 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
)
17 local function convertNodeToScreen(n
, c
, z
)
18 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
)
21 QuestHelper
.map_overlay
= CreateFrame("FRAME", nil, WorldMapButton
)
22 QuestHelper
.map_overlay
:SetFrameLevel(WorldMapButton
:GetFrameLevel()+1)
23 QuestHelper
.map_overlay
:SetAllPoints()
24 QuestHelper
.map_overlay
:SetFrameStrata("FULLSCREEN")
26 local function ClampLine(x1
, y1
, x2
, y2
)
27 if x1
and y1
and x2
and y2
then
28 local x_div
, y_div
= (x2
-x1
), (y2
-y1
)
29 local x_0
= y1
-x1
/x_div
*y_div
30 local x_1
= y1
+(1-x1
)/x_div
*y_div
31 local y_0
= x1
-y1
/y_div
*x_div
32 local y_1
= x1
+(1-y1
)/y_div
*x_div
74 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
80 local function pushPath(list
, path
, c
, z
)
82 pushPath(list
, path
.p
, c
, z
)
83 local t
= QuestHelper
:CreateTable()
84 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
)
89 function QuestHelper
:CreateWorldMapWalker()
90 local walker
= CreateFrame("Button", nil, QuestHelper
.map_overlay
)
93 walker
:SetPoint("CENTER", QuestHelper
.map_overlay
, "TOPLEFT", 0, 0)
101 walker
.map_dodads
= {}
102 walker
.used_map_dodads
= 0
104 function walker
:OnUpdate(elapsed
)
107 if QuestHelper_Pref
.show_ants
then
108 local points
= self
.points
110 self
.phase
= self
.phase
+ elapsed
* 0.66
111 while self
.phase
> 1 do self
.phase
= self
.phase
- 1 end
113 local w
, h
= QuestHelper
.map_overlay
:GetWidth(), -QuestHelper
.map_overlay
:GetHeight()
115 local c
, z
= GetCurrentMapContinent(), GetCurrentMapZone()
117 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
119 for i
, pos
in ipairs(points
) do
120 local new_x
, new_y
= unpack(pos
)
121 local x1
, y1
, x2
, y2
= ClampLine(last_x
, last_y
, new_x
, new_y
)
122 last_x
, last_y
= new_x
, new_y
125 local len
= math
.sqrt((x1
-x2
)*(x1
-x2
)*16/9+(y1
-y2
)*(y1
-y2
))
128 local interval
= .025/len
129 local p
= remainder
*interval
133 local dot
= self
.dots
[out
]
135 dot
= QuestHelper
:CreateDotTexture(self
)
136 dot
:SetDrawLayer("BACKGROUND")
141 dot
:SetPoint("CENTER", QuestHelper
.map_overlay
, "TOPLEFT", x1
*w
*(1-p
)+x2
*w
*p
, y1
*h
*(1-p
)+y2
*h
*p
)
146 remainder
= (p
-1)/interval
152 while #self
.dots
> out
do
153 QuestHelper
:ReleaseTexture(table.remove(self
.dots
))
157 function walker
:RouteChanged()
158 if self
.frame
.Astrolabe
.WorldMapVisible
then
159 for i
, obj
in pairs(self
.frame
.route
) do
162 --QuestHelper:AppendNotificationError("10-10-2008 pathfinding/dodads nil coroutine race condition bug")
163 return -- return "failure :("
167 local points
= self
.points
168 local cur
= self
.frame
.pos
170 while #points
> 0 do self
.frame
:ReleaseTable(table.remove(points
)) end
172 local travel_time
= 0.0
174 local c
, z
= GetCurrentMapContinent(), GetCurrentMapZone()
176 if self
.frame
.target
then
177 travel_time
= math
.max(0, self
.frame
.target_time
-time())
178 cur
= self
.frame
.target
179 local t
= self
.frame
:CreateTable()
180 t
[1], t
[2] = convertLocationToScreen(cur
, c
, z
)
181 table.insert(points
, t
)
184 for i
, obj
in pairs(self
.frame
.route
) do
185 local path
, d
= self
.frame
:ComputeRoute(cur
, obj
.pos
)
187 pushPath(points
, path
, c
, z
)
189 travel_time
= travel_time
+ d
190 obj
.travel_time
= travel_time
194 local t
= self
.frame
:CreateTable()
195 t
[1], t
[2] = convertLocationToScreen(cur
, c
, z
)
197 table.insert(points
, t
)
200 for i
= 1, #self
.frame
.route
do
201 local dodad
= self
.map_dodads
[i
]
203 self
.map_dodads
[i
] = self
.frame
:CreateWorldMapDodad(self
.frame
.route
[i
], i
)
205 self
.map_dodads
[i
]:SetObjective(self
.frame
.route
[i
], i
)
209 for i
= #self
.frame
.route
+1,self
.used_map_dodads
do
210 self
.map_dodads
[i
]:SetObjective(nil, 0)
213 self
.used_map_dodads
= #self
.frame
.route
217 walker
:SetScript("OnEvent", walker
.RouteChanged
)
218 walker
:RegisterEvent("WORLD_MAP_UPDATE")
220 walker
:SetScript("OnUpdate", walker
.OnUpdate
)
225 function QuestHelper
:GetOverlapObjectives(obj
)
226 local w
, h
= self
.map_overlay
:GetWidth(), self
.map_overlay
:GetHeight()
227 local c
, z
= GetCurrentMapContinent(), GetCurrentMapZone()
229 local list
= self
.overlap_list
233 self
.overlap_list
= list
235 while table.remove(list
) do end
238 local cx
, cy
= GetCursorPosition()
240 local es
= QuestHelper
.map_overlay
:GetEffectiveScale()
243 cx
, cy
= (cx
-self
.map_overlay
:GetLeft()*es
)*ies
, (self
.map_overlay
:GetTop()*es
-cy
)*ies
245 local s
= 10*QuestHelper_Pref
.scale
247 for i
, o
in ipairs(self
.route
) do
248 --QuestHelper: Assert(o, string.format("nil dodads pos issue, o %s", tostring(o)))
249 --QuestHelper: Assert(o.pos, string.format("nil dodads pos issue, pos %s", QuestHelper:StringizeTable(o)))
251 table.insert(list
, o
)
252 elseif o
.pos
then -- as near as I can tell, there's some curious coroutine contention going on here, and it's possible that things don't have a position even though they're in the route. If they don't have a position, we don't need to add them to a list - this function is (I think) only called for the tooltips. Therefore, either it no longer exists on the main map, or it's about to vanish from the main map. Go go gadget someone-else's-problem-field!
253 local x
, y
= o
.pos
[3], o
.pos
[4]
254 x
, y
= x
/ self
.continent_scales_x
[o
.pos
[1].c
], y
/ self
.continent_scales_y
[o
.pos
[1].c
]
255 x
, y
= self
.Astrolabe
:TranslateWorldMapPosition(o
.pos
[1].c
, 0, x
, y
, c
, z
)
257 if x
and y
and x
> 0 and y
> 0 and x
< 1 and y
< 1 then
260 if cx
>= x
-s
and cy
>= y
-s
and cx
<= x
+s
and cy
<= y
+s
then
261 table.insert(list
, o
)
267 table.sort(list
, function(a
, b
) return (a
.travel_time
or 0) < (b
.travel_time
or 0) end)
272 local prog_sort_table
= {}
274 function QuestHelper
:AppendObjectiveProgressToTooltip(o
, tooltip
, font
, depth
)
276 local theme
= self
:GetColourTheme()
278 local indent
= (" "):rep(depth
or 0)
280 for user
, progress
in pairs(o
.progress
) do
281 table.insert(prog_sort_table
, user
)
284 table.sort(prog_sort_table
, function(a
, b
)
285 if o
.progress
[a
][3] < o
.progress
[b
][3] then
287 elseif o
.progress
[a
][3] == o
.progress
[b
][3] then
293 for i
, u
in ipairs(prog_sort_table
) do
294 tooltip
:AddDoubleLine(indent
..QHFormat("PEER_PROGRESS", u
),
295 self
:ProgressString(o
.progress
[u
][1].."/"..o
.progress
[u
][2],
296 o
.progress
[u
][3]), unpack(theme
.tooltip
))
299 local last
, name
= tooltip
:NumLines(), tooltip
:GetName()
300 local left
, right
= _G
[name
.."TextLeft"..last
], _G
[name
.."TextRight"..last
]
302 left
:SetFont(font
, 13)
303 right
:SetFont(font
, 13)
307 while table.remove(prog_sort_table
) do end
311 function QuestHelper
:AppendObjectiveToTooltip(o
)
312 local theme
= self
:GetColourTheme()
314 self
.tooltip
:AddLine(o
:Reason(), unpack(theme
.tooltip
))
315 self
.tooltip
:GetPrevLines():SetFont(self
.font
.serif
, 14)
317 self
:AppendObjectiveProgressToTooltip(o
, self
.tooltip
, QuestHelper
.font
.sans
)
319 self
.tooltip
:AddDoubleLine(QHText("TRAVEL_ESTIMATE"), QHFormat("TRAVEL_ESTIMATE_VALUE", o
.travel_time
or 0), unpack(theme
.tooltip
))
320 self
.tooltip
:GetPrevLines():SetFont(self
.font
.sans
, 11)
321 select(2, self
.tooltip
:GetPrevLines()):SetFont(self
.font
.sans
, 11)
324 function QuestHelper
:CreateWorldMapDodad(objective
, index
)
325 local icon
= CreateFrame("Button", nil, QuestHelper
.map_overlay
)
326 icon
:SetFrameStrata("FULLSCREEN")
328 function icon
:SetTooltip(list
)
329 QuestHelper
.tooltip
:SetOwner(self
, "ANCHOR_CURSOR")
330 QuestHelper
.tooltip
:ClearLines()
334 for i
, o
in ipairs(list
) do
338 QuestHelper
.tooltip
:AddLine("|c80ff0000 . . . . . .|r")
339 QuestHelper
.tooltip
:GetPrevLines():SetFont(QuestHelper
.font
.sans
, 8)
342 QuestHelper
:AppendObjectiveToTooltip(o
)
345 QuestHelper
.tooltip
:Show()
348 function icon
:SetObjective(objective
, i
)
349 self
:SetHeight(20*QuestHelper_Pref
.scale
)
350 self
:SetWidth(20*QuestHelper_Pref
.scale
)
353 QuestHelper
:ReleaseTexture(self
.dot
)
358 QuestHelper
:ReleaseTexture(self
.bg
)
363 self
.objective
= objective
367 -- if it's the very next objective, give it the green background
368 self
.bg
= QuestHelper
:CreateIconTexture(self
, 13)
369 elseif objective
.filter_blocked
then
370 -- if there are still prerequisites, make it grey
371 -- filter_blocked is updated by [Add|Remove]ObjectiveWatch and ObjectiveObjectDependsOn,
372 -- and will be true if there are other objectives that need to be completed before this one.
373 self
.bg
= QuestHelper
:CreateIconTexture(self
, 16)
375 -- otherwise give it the background selected by the objective
376 self
.bg
= QuestHelper
:CreateIconTexture(self
, objective
.icon_bg
)
379 self
.dot
= QuestHelper
:CreateIconTexture(self
, objective
.icon_id
)
381 self
.bg
:SetDrawLayer("BACKGROUND")
382 self
.bg
:SetAllPoints()
383 self
.dot
:SetPoint("TOPLEFT", self
, "TOPLEFT", 3*QuestHelper_Pref
.scale
, -3*QuestHelper_Pref
.scale
)
384 self
.dot
:SetPoint("BOTTOMRIGHT", self
, "BOTTOMRIGHT", -3*QuestHelper_Pref
.scale
, 3*QuestHelper_Pref
.scale
)
386 QuestHelper
.Astrolabe
:PlaceIconOnWorldMap(QuestHelper
.map_overlay
, self
, convertLocation(objective
.pos
))
393 function icon
:SetGlow(list
)
394 local w
, h
= QuestHelper
.map_overlay
:GetWidth(), QuestHelper
.map_overlay
:GetHeight()
395 local c
, z
= GetCurrentMapContinent(), GetCurrentMapZone()
396 local _
, x_size
, y_size
= QuestHelper
.Astrolabe
:ComputeDistance(c
, z
, 0.25, 0.25, c
, z
, 0.75, 0.75)
398 x_size
= math
.max(25, 200 / x_size
* w
)
399 y_size
= math
.max(25, 200 / y_size
* h
)
402 for _
, objective
in ipairs(list
) do
403 if objective
.p
then for _
, list
in pairs(objective
.p
) do
404 for _
, p
in ipairs(list
) do
405 local x
, y
= p
[3], p
[4]
406 x
, y
= x
/ QuestHelper
.continent_scales_x
[p
[1].c
], y
/ QuestHelper
.continent_scales_y
[p
[1].c
]
407 x
, y
= QuestHelper
.Astrolabe
:TranslateWorldMapPosition(p
[1].c
, 0, x
, y
, c
, z
)
408 if x
and y
and x
> 0 and y
> 0 and x
< 1 and y
< 1 then
409 if not self
.glow_list
then
410 self
.glow_list
= QuestHelper
:CreateTable()
413 tex
= self
.glow_list
[out
]
415 tex
= QuestHelper
:CreateGlowTexture(self
)
416 table.insert(self
.glow_list
, tex
)
420 tex
:SetPoint("CENTER", QuestHelper
.map_overlay
, "TOPLEFT", x
*w
, -y
*h
)
421 tex
:SetVertexColor(1,1,1,0)
423 tex
:SetHeight(y_size
)
425 tex
.max_alpha
= 1/p
[5]
431 if self
.glow_list
then
432 for i
= out
,#self
.glow_list
do
433 QuestHelper
:ReleaseTexture(table.remove(self
.glow_list
))
436 if #self
.glow_list
== 0 then
437 QuestHelper
:ReleaseTable(self
.glow_list
)
443 icon
.show_glow
= false
448 function icon
:OnUpdate(elapsed
)
449 self
.phase
= (self
.phase
+ elapsed
)%6.283185307179586476925286766559005768394338798750211641949889185
451 if self
.old_count
> 0 then
452 local list
= QuestHelper
:GetOverlapObjectives(self
.objective
)
453 if #list
~= self
.old_count
then
454 self
:SetTooltip(list
)
455 self
.old_count
= #list
460 if self
.show_glow
then
461 self
.glow_pct
= math
.min(1, self
.glow_pct
+elapsed
*1.5)
463 self
.glow_pct
= math
.max(0, self
.glow_pct
-elapsed
*0.5)
465 if self
.glow_pct
== 0 then
466 if self
.glow_list
then
467 while #self
.glow_list
> 0 do
468 QuestHelper
:ReleaseTexture(table.remove(self
.glow_list
))
470 QuestHelper
:ReleaseTable(self
.glow_list
)
474 self
:SetScript("OnUpdate", nil)
479 if self
.glow_list
then
480 -- You know, these numbers are harmonics of pi. Would SETI detected them, or would they just be seen as noise?
481 -- I'd vote for the later.
483 -- Pi - circumference over diameter - when was the last time you actually cared about diameters in math?
485 -- Pretty much everything in computer geometry depends on the pythagorean theorem, which you can use for
486 -- circles, spheres, and hyper-spheres, if you use radius.
488 -- It's even the basis of special relativity, with time being multiplied by c so that you get a distance
489 -- that you can use with the spatial dimensions. We're all in agreement that space traveling aliens are
490 -- going to know about relativity, right?
492 -- And if you ever do trig, a full circle would be exactly (circumference over radius) radians instead of
493 -- (circumference over diameter)*2 radians.
495 -- Obviously aliens are much more likely to prefer 6.283185307179586... as constant than our pi.
497 -- Important update: I just noticed that large factorials can be approximated using (2*pi*n)^.5*(n/e)^n
498 -- There's that 2 times pi thing again.
499 local r
, g
, b
= math
.sin(self
.phase
)*0.25+0.75,
500 math
.sin(self
.phase
+2.094395102393195492308428922186335256131446266250070547316629728)*0.25+0.75,
501 math
.sin(self
.phase
+4.188790204786390984616857844372670512262892532500141094633259456)*0.25+0.75
503 for i
, tex
in ipairs(self
.glow_list
) do
504 tex
:SetVertexColor(r
, g
, b
, self
.glow_pct
*tex
.max_alpha
)
509 function icon
:OnEnter()
510 local list
= QuestHelper
:GetOverlapObjectives(self
.objective
)
511 self
:SetTooltip(list
)
512 self
.old_count
= #list
514 icon
.show_glow
= true
518 self
:SetScript("OnUpdate", self
.OnUpdate
)
521 function icon
:OnLeave()
522 QuestHelper
.tooltip
:Hide()
523 self
.show_glow
= false
527 function icon
:OnEvent(event
)
528 if self
.objective
and self
.objective
.pos
then
529 QuestHelper
.Astrolabe
:PlaceIconOnWorldMap(QuestHelper
.map_overlay
, self
, convertLocation(self
.objective
.pos
))
536 function icon
:OnClick()
537 if self
.objective
then
538 local menu
= QuestHelper
:CreateMenu()
539 local list
= QuestHelper
:GetOverlapObjectives(self
.objective
)
543 QuestHelper
:CreateMenuTitle(menu
, "Objectives")
545 for i
, o
in ipairs(list
) do
546 local submenu
= QuestHelper
:CreateMenu()
547 item
= QuestHelper
:CreateMenuItem(menu
, o
:Reason(true))
548 item
:SetSubmenu(submenu
)
549 item
:AddTexture(QuestHelper
:CreateIconTexture(item
, o
.icon_id
), true)
550 QuestHelper
:AddObjectiveOptionsToMenu(o
, submenu
)
553 QuestHelper
:CreateMenuTitle(menu
, self
.objective
:Reason(true))
554 QuestHelper
:AddObjectiveOptionsToMenu(self
.objective
, menu
)
561 icon
:SetScript("OnClick", icon
.OnClick
)
562 icon
:SetScript("OnEnter", icon
.OnEnter
)
563 icon
:SetScript("OnLeave", icon
.OnLeave
)
564 icon
:SetScript("OnEvent", icon
.OnEvent
)
566 icon
:RegisterForClicks("RightButtonUp")
568 icon
:RegisterEvent("WORLD_MAP_UPDATE")
570 icon
:SetObjective(objective
, index
)
575 local last_c
, last_z
, last_x
, last_y
, last_desc
577 function QuestHelper
:AddWaypointCallback(func
, ...)
578 local cb
= self
:CreateTable()
580 local len
= select("#", ...)
583 for i
= 1,len
do cb
[i
] = select(i
, ...) end
588 cb
[len
+5] = last_desc
591 func(unpack(cb
, 1, len
+5))
597 function QuestHelper
:RemoveWaypointCallback(cb
)
599 self
:ReleaseTable(cb
)
602 function QuestHelper
:InvokeWaypointCallbacks(c
, z
, x
, y
, desc
)
603 if c
~= last_c
or z
~= last_z
or x
~= last_x
or y
~= last_y
or desc
~= last_desc
then
604 last_c
, last_z
, last_x
, last_y
, last_desc
= c
, z
, x
, y
, desc
605 for cb
in pairs(callbacks
) do
612 cb
.func(unpack(cb
, 1, len
+5))
617 function QuestHelper
:CreateMipmapDodad()
618 local icon
= CreateFrame("Button", nil, Minimap
)
620 icon
.recalc_timeout
= 0
622 icon
.arrow
= CreateFrame("Model", nil, icon
)
623 icon
.arrow
:SetHeight(140.8)
624 icon
.arrow
:SetWidth(140.8)
625 icon
.arrow
:SetPoint("CENTER", Minimap
, "CENTER", 0, 0)
626 icon
.arrow
:SetModel("Interface\\Minimap\\Rotating-MinimapArrow.mdx")
630 icon
.target
= {0, 0, 0, 0}
633 icon
.bg
= QuestHelper
:CreateIconTexture(icon
, 16)
634 icon
.bg
:SetDrawLayer("BACKGROUND")
635 icon
.bg
:SetAllPoints()
637 function icon
:NextObjective()
638 for i
, o
in ipairs(QuestHelper
.route
) do
639 if not QuestHelper
.to_remove
[o
] and o
.pos
and not o
.filter_blocked
then
647 function icon
:OnUpdate(elapsed
)
648 if self
.objective
then
649 if not self
.objective
.pos
then
650 self
.objective
= self
:NextObjective()
651 if not self
.objective
then
659 if self
.recalc_timeout
<= 0 and not QuestHelper
.graph_in_limbo
and QuestHelper
.Routing
.map_walker
then
660 self
.recalc_timeout
= 50
662 self
.objective
= self
:NextObjective()
664 if not self
.objective
then
669 local path
, travel_time
671 if QuestHelper
.target
then
673 -- Okay, this is another "fix the symptom without fixing the cause" hack. Not good, but a lot of this is going away anyway.
674 local has_path
= true
675 for i
in ipairs(QuestHelper
.target
[1]) do if not QuestHelper
.target
[2][i
] then has_path
= false end end
677 path
, travel_time
= QuestHelper
:ComputeRoute(QuestHelper
.target
, self
.objective
.pos
)
678 travel_time
= travel_time
+ math
.max(0, QuestHelper
.target_time
-time())
680 --QuestHelper:TextOut("yes here is the nil bug")
683 path
, travel_time
= QuestHelper
:ComputeRoute(QuestHelper
.pos
, self
.objective
.pos
)
686 local t
= self
.target
687 local id
= self
.objective
.icon_id
688 t
[1], t
[2], t
[3], t
[4] = convertLocation(self
.objective
.pos
)
691 self
.objective
.travel_time
= travel_time
694 if path
.g
> 10.0 then
698 t
[3] = path
.x
/ QuestHelper
.continent_scales_x
[path
.c
]
699 t
[4] = path
.y
/ QuestHelper
.continent_scales_y
[path
.c
]
700 t
[5] = path
.name
or "waypoint"
705 if not self
.dot
or id
~= self
.icon_id
then
707 if self
.dot
then QuestHelper
:ReleaseTexture(self
.dot
) end
708 self
.dot
= QuestHelper
:CreateIconTexture(self
, self
.icon_id
)
709 self
.dot
:SetPoint("TOPLEFT", icon
, "TOPLEFT", 2, -2)
710 self
.dot
:SetPoint("BOTTOMRIGHT", icon
, "BOTTOMRIGHT", -2, 2)
713 if UnitIsDeadOrGhost("player") then
714 QuestHelper
:InvokeWaypointCallbacks()
716 local reason
= (t
[5] and (QHFormat("WAYPOINT_REASON", t
[5]).."\n"..self
.objective
:Reason(true)))
717 or self
.objective
:Reason(true)
719 if QuestHelper
.c
== t
[1] then
720 -- Translate the position to the zone the player is standing in.
721 local c
, z
= QuestHelper
.c
, QuestHelper
.z
722 local x
, y
= QuestHelper
.Astrolabe
:TranslateWorldMapPosition(t
[1], t
[2], t
[3], t
[4], c
, z
)
723 QuestHelper
:InvokeWaypointCallbacks(c
, z
, x
, y
, reason
)
725 -- Try to find the nearest zone on the continent the objective is in.
726 local index
, distsqr
, x
, y
727 for z
, i
in pairs(QuestHelper_IndexLookup
[t
[1]]
) do
728 local _x
, _y
= QuestHelper
.Astrolabe
:TranslateWorldMapPosition(t
[1], t
[2], t
[3], t
[4], t
[1], z
)
729 local d
= (_x
-0.5)*(_x
-0.5)+(_y
-0.5)*(_y
-0.5)
730 if not index
or d
< distsqr
then
731 index
, distsqr
, x
, y
= i
, d
, _x
, _y
734 local c
, z
= QuestHelper_IndexLookup
[index
]
735 QuestHelper
:InvokeWaypointCallbacks(c
, z
, x
, y
, reason
)
739 QuestHelper
.Astrolabe
:PlaceIconOnMinimap(self
, unpack(self
.target
))
741 self
.recalc_timeout
= self
.recalc_timeout
- 1
744 local edge
= QuestHelper
.Astrolabe
:IsIconOnEdge(self
)
757 local angle
= QuestHelper
.Astrolabe
:GetDirectionToIcon(self
)
758 if GetCVar("rotateMinimap") == "1" then
759 angle
= angle
+ QuestHelper
.Astrolabe
:GetFacing()
762 self
.arrow
:SetFacing(angle
)
763 self
.arrow
:SetPosition(ofs
* (137 / 140) - radius
* math
.sin(angle
),
764 ofs
+ radius
* math
.cos(angle
), 0);
766 if self
.phase
> 6.283185307179586476925 then
767 self
.phase
= self
.phase
-6.283185307179586476925+elapsed
*3.5
769 self
.phase
= self
.phase
+elapsed
*3.5
771 self
.arrow
:SetModelScale(0.600000023841879+0.1*math
.sin(self
.phase
))
778 function icon
:SetObjective(objective
)
779 self
:SetHeight(20*QuestHelper_Pref
.scale
)
780 self
:SetWidth(20*QuestHelper_Pref
.scale
)
782 if objective
~= self
.objective
then
783 if objective
and not QuestHelper_Pref
.hide
then
786 QuestHelper
:InvokeWaypointCallbacks()
790 self
.objective
= objective
791 self
.recalc_timeout
= 0
795 function icon
:OnEnter()
796 if self
.objective
then
797 QuestHelper
.tooltip
:SetOwner(self
, "ANCHOR_CURSOR")
798 QuestHelper
.tooltip
:ClearLines()
800 if self
.target
[5] then
801 QuestHelper
.tooltip
:AddLine(QHFormat("WAYPOINT_REASON", self
.target
[5]), unpack(QuestHelper
:GetColourTheme().tooltip
))
802 QuestHelper
.tooltip
:GetPrevLines():SetFont(QuestHelper
.font
.serif
, 14)
805 QuestHelper
:AppendObjectiveToTooltip(self
.objective
)
806 QuestHelper
.tooltip
:Show()
810 function icon
:OnLeave()
811 QuestHelper
.tooltip
:Hide()
814 function icon
:OnClick()
815 if self
.objective
then
816 local menu
= QuestHelper
:CreateMenu()
817 QuestHelper
:CreateMenuTitle(menu
, self
.objective
:Reason(true))
818 QuestHelper
:AddObjectiveOptionsToMenu(self
.objective
, menu
)
823 function icon
:OnEvent()
824 if self
.objective
and self
.objective
.pos
then
831 icon
:SetScript("OnUpdate", icon
.OnUpdate
)
832 icon
:SetScript("OnEnter", icon
.OnEnter
)
833 icon
:SetScript("OnLeave", icon
.OnLeave
)
834 icon
:SetScript("OnEvent", icon
.OnEvent
)
835 icon
:SetScript("OnClick", icon
.OnClick
)
837 icon
:RegisterForClicks("RightButtonUp")
838 icon
:RegisterEvent("PLAYER_ENTERING_WORLD")