loud in debug mode
[QuestHelper.git] / dodads.lua
blob32076cd13a9c9cce4a9acf1eee0e584b43e35190
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;
6 local Minimap = _G.Minimap
8 -- These conversions are nasty, and this entire section needs a serious cleanup.
9 local function convertLocation(p)
10 local c, x, y = QuestHelper.Astrolabe:FromAbsoluteContinentPosition(p.c, p.x, p.y)
11 return c, 0, x, y
12 end
14 local function convertLocationToScreen(p, c, z)
15 local pc, _, px, py = convertLocation(p)
16 local ox, oy = QuestHelper.Astrolabe:TranslateWorldMapPosition(pc, 0, px, py, c, z)
17 --QuestHelper:TextOut(string.format("%f/%f/%f to %f/%f/%f to %f/%f %f/%f", p.c, p.x, p.y, pc, px, py, c, z, ox, oy))
18 return ox, oy
19 end
21 local function convertNodeToScreen(n, c, z)
22 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)
23 end
25 QuestHelper.map_overlay = CreateFrame("FRAME", nil, WorldMapButton)
26 QuestHelper.map_overlay:SetFrameLevel(WorldMapButton:GetFrameLevel()+1)
27 QuestHelper.map_overlay:SetAllPoints()
28 QuestHelper.map_overlay:SetFrameStrata("FULLSCREEN")
30 local function ClampLine(x1, y1, x2, y2)
31 if x1 and y1 and x2 and y2 then
32 local x_div, y_div = (x2-x1), (y2-y1)
33 local x_0 = y1-x1/x_div*y_div
34 local x_1 = y1+(1-x1)/x_div*y_div
35 local y_0 = x1-y1/y_div*x_div
36 local y_1 = x1+(1-y1)/y_div*x_div
38 if y1 < 0 then
39 x1 = y_0
40 y1 = 0
41 end
43 if y2 < 0 then
44 x2 = y_0
45 y2 = 0
46 end
48 if y1 > 1 then
49 x1 = y_1
50 y1 = 1
51 end
53 if y2 > 1 then
54 x2 = y_1
55 y2 = 1
56 end
58 if x1 < 0 then
59 y1 = x_0
60 x1 = 0
61 end
63 if x2 < 0 then
64 y2 = x_0
65 x2 = 0
66 end
68 if x1 > 1 then
69 y1 = x_1
70 x1 = 1
71 end
73 if x2 > 1 then
74 y2 = x_1
75 x2 = 1
76 end
78 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
79 return x1, y1, x2, y2
80 end
81 end
82 end
84 local walker_loc
86 function QuestHelper:CreateWorldMapWalker()
87 local walker = CreateFrame("Button", nil, QuestHelper.map_overlay)
88 walker_loc = walker
89 walker:SetWidth(0)
90 walker:SetHeight(0)
91 walker:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", 0, 0)
92 walker:Show()
94 walker.phase = 0.0
95 walker.dots = {}
96 walker.points = {}
97 walker.origin = {}
98 walker.frame = self
99 walker.map_dodads = {}
100 walker.used_map_dodads = 0
102 QuestHelper: Assert(self == QuestHelper)
103 QuestHelper: Assert(self.Astrolabe)
105 function walker:OnUpdate(elapsed)
106 local out = 0
108 if QuestHelper_Pref.show_ants then
109 local points = self.points
111 self.phase = self.phase + elapsed * 0.66
112 while self.phase > 1 do self.phase = self.phase - 1 end
114 local w, h = QuestHelper.map_overlay:GetWidth(), -QuestHelper.map_overlay:GetHeight()
116 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
118 local last_x, last_y = self.frame.Astrolabe:TranslateWorldMapPosition(self.frame.c, self.frame.z, self.frame.x, self.frame.y, c, z)
119 local remainder = self.phase
121 for i, pos in ipairs(points) do
122 local new_x, new_y = unpack(pos)
123 local x1, y1, x2, y2 = ClampLine(last_x, last_y, new_x, new_y)
124 last_x, last_y = new_x, new_y
126 if x1 then
127 local len = math.sqrt((x1-x2)*(x1-x2)*16/9+(y1-y2)*(y1-y2))
129 if len > 0.0001 then
130 local interval = .025/len
131 local p = remainder*interval
133 while p < 1 do
134 out = out + 1
135 local dot = self.dots[out]
136 if not dot then
137 dot = QuestHelper:CreateDotTexture(self)
138 dot:SetDrawLayer("BACKGROUND")
139 self.dots[out] = dot
142 dot:ClearAllPoints()
143 dot:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x1*w*(1-p)+x2*w*p, y1*h*(1-p)+y2*h*p)
145 p = p + interval
148 remainder = (p-1)/interval
154 while #self.dots > out do
155 QuestHelper:ReleaseTexture(table.remove(self.dots))
159 function walker:RouteChanged(route)
160 if route then self.route = route end -- we cache it so we can refer to it later when the world map changes
161 if not self.route then return end
163 local dbgstr = string.format("%s %s %s %s", tostring(self), tostring(self.frame), tostring(QuestHelper), tostring(QuestHelper and QuestHelper.Astrolabe))
164 QuestHelper: Assert(self.frame == QuestHelper, dbgstr)
165 QuestHelper: Assert(QuestHelper.Astrolabe, dbgstr)
167 if self.frame.Astrolabe.WorldMapVisible then
168 local points = self.points
169 local cur = self.frame.pos
171 while #points > 0 do self.frame:ReleaseTable(table.remove(points)) end
173 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
175 -- I'm not quite sure what the point of this is.
176 --[[
177 if self.frame.target then
178 travel_time = math.max(0, self.frame.target_time-time())
179 cur = self.frame.target
180 local t = self.frame:CreateTable()
181 t[1], t[2] = convertLocationToScreen(cur, c, z)
182 table.insert(points, t)
183 end]]
185 for i, obj in ipairs(self.route) do
186 --QuestHelper:TextOut(string.format("%s", tostring(obj)))
188 --[[
189 local t = QuestHelper:CreateTable()
190 t[1], t[2] = convertLocationToScreen(obj.loc, c, z)
192 table.insert(list, t)]]
194 -- We're ignoring travel time for now.
195 --[[
196 travel_time = travel_time + 60
197 obj.travel_time = travel_time]]
198 if i > 1 then -- skip the start location
199 local t = self.frame:CreateTable()
200 t[1], t[2] = convertLocationToScreen(obj.loc, c, z)
202 table.insert(points, t)
204 --if lotsup then print(obj.ignore, obj.loc.x, obj.loc.y, obj.loc.c) end
206 --QuestHelper:TextOut(string.format("%s/%s/%s to %s/%s", tostring(obj.c), tostring(obj.x), tostring(obj.y), tostring(t[1]), tostring(t[2])))
208 --lotsup = false
210 local cur_dodad = 1
211 for i = 2, #self.route do -- 2 because we're skipping the player
212 if not self.route[i].ignore then
213 local dodad = self.map_dodads[cur_dodad]
214 if not dodad then
215 self.map_dodads[cur_dodad] = self.frame:CreateWorldMapDodad(self.route[i], i == 2)
216 else
217 self.map_dodads[cur_dodad]:SetObjective(self.route[i], i == 2)
219 cur_dodad = cur_dodad + 1
223 if cur_dodad <= self.used_map_dodads then for i = cur_dodad,self.used_map_dodads do
224 self.map_dodads[i]:SetObjective(nil, false)
225 end end
227 self.used_map_dodads = cur_dodad - 1
231 walker:SetScript("OnEvent", function () walker:RouteChanged() end) -- we do this just to strip the parameters out
232 walker:RegisterEvent("WORLD_MAP_UPDATE")
234 walker:SetScript("OnUpdate", walker.OnUpdate)
236 return walker
239 function QuestHelper:GetOverlapObjectives(obj)
240 local w, h = self.map_overlay:GetWidth(), self.map_overlay:GetHeight()
241 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
243 local list = self.overlap_list
245 if not list then
246 list = {}
247 self.overlap_list = list
248 else
249 while table.remove(list) do end
252 local cx, cy = GetCursorPosition()
254 local es = QuestHelper.map_overlay:GetEffectiveScale()
255 local ies = 1/es
257 cx, cy = (cx-self.map_overlay:GetLeft()*es)*ies, (self.map_overlay:GetTop()*es-cy)*ies
259 local s = 10*QuestHelper_Pref.scale
261 for i, o in ipairs(walker_loc.route) do
262 --QuestHelper: Assert(o, string.format("nil dodads pos issue, o %s", tostring(o)))
263 --QuestHelper: Assert(o.pos, string.format("nil dodads pos issue, pos %s", QuestHelper:StringizeTable(o)))
264 if not o.ignore then
265 if o == obj then
266 table.insert(list, o)
267 else
268 local x, y = convertLocationToScreen(o.loc, c, z)
270 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
271 x, y = x*w, y*h
273 if cx >= x-s and cy >= y-s and cx <= x+s and cy <= y+s then
274 table.insert(list, o)
281 table.sort(list, function(a, b) return (a.distance or 0) < (b.distance or 0) end)
283 return list
286 function QuestHelper:AppendObjectiveProgressToTooltip(o, tooltip, font, depth)
287 if o.progress then
288 local prog_sort_table = {}
290 local theme = self:GetColourTheme()
292 local indent = (" "):rep(depth or 0)
294 for user, progress in pairs(o.progress) do
295 table.insert(prog_sort_table, user)
298 table.sort(prog_sort_table, function(a, b)
299 if o.progress[a][3] < o.progress[b][3] then
300 return true
301 elseif o.progress[a][3] == o.progress[b][3] then
302 return a < b
304 return false
305 end)
307 for i, u in ipairs(prog_sort_table) do
308 tooltip:AddDoubleLine(indent..QHFormat("PEER_PROGRESS", u),
309 self:ProgressString(o.progress[u][1].."/"..o.progress[u][2],
310 o.progress[u][3]), unpack(theme.tooltip))
312 if font then
313 local last, name = tooltip:NumLines(), tooltip:GetName()
314 local left, right = _G[name.."TextLeft"..last], _G[name.."TextRight"..last]
316 left:SetFont(font, 13)
317 right:SetFont(font, 13)
321 while table.remove(prog_sort_table) do end
325 function QuestHelper:AppendObjectiveToTooltip(o)
326 local theme = self:GetColourTheme()
328 QuestHelper: Assert(o.map_desc)
329 for _, v in ipairs(o.map_desc) do
330 self.tooltip:AddLine(v, unpack(theme.tooltip))
331 self.tooltip:GetPrevLines():SetFont(self.font.serif, 14)
334 if o.map_desc_chain then
335 self:AppendObjectiveToTooltip(o.map_desc_chain)
336 else
337 self:AppendObjectiveProgressToTooltip(o, self.tooltip, QuestHelper.font.sans)
339 self.tooltip:AddDoubleLine(QHText("TRAVEL_ESTIMATE"), QHFormat("TRAVEL_ESTIMATE_VALUE", o.distance or 0), unpack(theme.tooltip))
340 self.tooltip:GetPrevLines():SetFont(self.font.sans, 11)
341 select(2, self.tooltip:GetPrevLines()):SetFont(self.font.sans, 11)
345 globx = 0.5
346 globy = 0.5
348 function QuestHelper:CreateWorldMapDodad(objective, nxt)
349 local icon = CreateFrame("Button", nil, QuestHelper.map_overlay)
350 icon:SetFrameStrata("FULLSCREEN")
352 function icon:SetTooltip(list)
353 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
354 QuestHelper.tooltip:ClearLines()
356 local first = true
358 for i, o in ipairs(list) do
359 if first then
360 first = false
361 else
362 QuestHelper.tooltip:AddLine("|c80ff0000 . . . . . .|r")
363 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.sans, 8)
366 QuestHelper:AppendObjectiveToTooltip(o)
369 QuestHelper.tooltip:Show()
372 function icon:SetObjective(objective, nxt)
373 self:SetHeight(20*QuestHelper_Pref.scale)
374 self:SetWidth(20*QuestHelper_Pref.scale)
376 if self.dot then
377 QuestHelper:ReleaseTexture(self.dot)
378 self.dot = nil
381 if self.bg then
382 QuestHelper:ReleaseTexture(self.bg)
383 self.bg = nil
386 if objective then
387 self.objective = objective
389 if nxt then
390 self.bg = QuestHelper:CreateIconTexture(self, 13)
391 elseif objective.map_highlight then
392 self.bg = QuestHelper:CreateIconTexture(self, 14)
393 else
394 self.bg = QuestHelper:CreateIconTexture(self, 16)
397 self.dot = QuestHelper:CreateIconTexture(self, objective.icon_id or 8)
399 self.bg:SetDrawLayer("BACKGROUND")
400 self.bg:SetAllPoints()
401 self.dot:SetPoint("TOPLEFT", self, "TOPLEFT", 3*QuestHelper_Pref.scale, -3*QuestHelper_Pref.scale)
402 self.dot:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -3*QuestHelper_Pref.scale, 3*QuestHelper_Pref.scale)
404 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(objective.loc))
405 --QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, 0, 0, globx, globy)
406 else
407 self.objective = nil
408 self:Hide()
412 function icon:SetGlow(list)
413 local w, h = QuestHelper.map_overlay:GetWidth(), QuestHelper.map_overlay:GetHeight()
414 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
416 local nodes = {}
418 for _, v in ipairs(list) do
419 if v.cluster then
420 for _, i in ipairs(v.cluster) do
421 nodes[i] = true
423 else
424 nodes[v] = true
429 local out = 1
430 for obj, _ in pairs(nodes) do
431 local x, y = convertLocationToScreen(obj.loc, c, z)
432 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
433 if not self.glow_list then
434 self.glow_list = QuestHelper:CreateTable()
437 tex = self.glow_list[out]
438 if not tex then
439 tex = QuestHelper:CreateGlowTexture(self)
440 table.insert(self.glow_list, tex)
442 out = out + 1
444 tex:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x*w, -y*h)
445 tex:SetVertexColor(1,1,1,0)
446 tex:SetWidth(h / 4) -- we want it to be a circle
447 tex:SetHeight(h / 4)
448 tex:Show()
449 tex.max_alpha = 1
453 if self.glow_list then
454 while #self.glow_list >= out do
455 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
458 if #self.glow_list == 0 then
459 QuestHelper:ReleaseTable(self.glow_list)
460 self.glow_list = nil
465 icon.show_glow = false
466 icon.glow_pct = 0.0
467 icon.phase = 0.0
468 icon.old_count = 0
470 function icon:OnUpdate(elapsed)
471 self.phase = (self.phase + elapsed)%6.283185307179586476925286766559005768394338798750211641949889185
473 if self.old_count > 0 then
474 local list = QuestHelper:GetOverlapObjectives(self.objective)
476 if #list ~= self.old_count then
477 self:SetTooltip(list)
478 self.old_count = #list
479 self:SetGlow(list)
483 if self.show_glow then
484 self.glow_pct = math.min(1, self.glow_pct+elapsed*1.5)
485 else
486 self.glow_pct = math.max(0, self.glow_pct-elapsed*0.5)
488 if self.glow_pct == 0 then
489 if self.glow_list then
490 while #self.glow_list > 0 do
491 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
493 QuestHelper:ReleaseTable(self.glow_list)
494 self.glow_list = nil
497 self:SetScript("OnUpdate", nil)
498 return
502 if self.glow_list then
503 -- You know, these numbers are harmonics of pi. Would SETI detected them, or would they just be seen as noise?
504 -- I'd vote for the later.
506 -- Pi - circumference over diameter - when was the last time you actually cared about diameters in math?
508 -- Pretty much everything in computer geometry depends on the pythagorean theorem, which you can use for
509 -- circles, spheres, and hyper-spheres, if you use radius.
511 -- It's even the basis of special relativity, with time being multiplied by c so that you get a distance
512 -- that you can use with the spatial dimensions. We're all in agreement that space traveling aliens are
513 -- going to know about relativity, right?
515 -- And if you ever do trig, a full circle would be exactly (circumference over radius) radians instead of
516 -- (circumference over diameter)*2 radians.
518 -- Obviously aliens are much more likely to prefer 6.283185307179586... as constant than our pi.
520 -- Important update: I just noticed that large factorials can be approximated using (2*pi*n)^.5*(n/e)^n
521 -- There's that 2 times pi thing again.
522 local r, g, b = math.sin(self.phase)*0.25+0.75,
523 math.sin(self.phase+2.094395102393195492308428922186335256131446266250070547316629728)*0.25+0.75,
524 math.sin(self.phase+4.188790204786390984616857844372670512262892532500141094633259456)*0.25+0.75
526 for i, tex in ipairs(self.glow_list) do
527 tex:SetVertexColor(r, g, b, self.glow_pct*tex.max_alpha)
532 function icon:OnEnter()
533 local list = QuestHelper:GetOverlapObjectives(self.objective)
534 self:SetTooltip(list)
535 self.old_count = #list
537 icon.show_glow = true
539 self:SetGlow(list)
541 self:SetScript("OnUpdate", self.OnUpdate)
544 function icon:OnLeave()
545 QuestHelper.tooltip:Hide()
546 self.show_glow = false
547 self.old_count = 0
550 function icon:OnEvent(event)
551 if self.objective then
552 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(self.objective.loc))
553 else
554 self.objective = nil
555 self:Hide()
559 function icon:OnClick()
560 if self.objective then
561 local menu = QuestHelper:CreateMenu()
562 local list = QuestHelper:GetOverlapObjectives(self.objective)
563 local item
565 if #list > 1 then
566 QuestHelper:CreateMenuTitle(menu, "Objectives")
568 for i, o in ipairs(list) do
569 local submenu = QuestHelper:CreateMenu()
570 item = QuestHelper:CreateMenuItem(menu, o.map_desc[1])
571 item:SetSubmenu(submenu)
572 item:AddTexture(QuestHelper:CreateIconTexture(item, o.icon_id), true)
573 QuestHelper:AddObjectiveOptionsToMenu(o, submenu)
575 else
576 QuestHelper:CreateMenuTitle(menu, self.objective.map_desc[1])
577 QuestHelper:AddObjectiveOptionsToMenu(self.objective, menu)
580 menu:ShowAtCursor()
584 icon:SetScript("OnClick", icon.OnClick)
585 icon:SetScript("OnEnter", icon.OnEnter)
586 icon:SetScript("OnLeave", icon.OnLeave)
587 icon:SetScript("OnEvent", icon.OnEvent)
589 icon:RegisterForClicks("RightButtonUp")
591 icon:RegisterEvent("WORLD_MAP_UPDATE")
593 icon:SetObjective(objective, nxt)
594 return icon
597 local callbacks = {}
598 local last_c, last_z, last_x, last_y, last_desc
600 function QuestHelper:AddWaypointCallback(func, ...)
601 local cb = self:CreateTable()
602 callbacks[cb] = true
603 local len = select("#", ...)
604 cb.len = len
605 cb.func = func
606 for i = 1,len do cb[i] = select(i, ...) end
607 cb[len+1] = last_c
608 cb[len+2] = last_z
609 cb[len+3] = last_x
610 cb[len+4] = last_y
611 cb[len+5] = last_desc
613 if last_c then
614 func(unpack(cb, 1, len+5))
617 return cb
620 function QuestHelper:RemoveWaypointCallback(cb)
621 callbacks[cb] = nil
622 self:ReleaseTable(cb)
625 function QuestHelper:InvokeWaypointCallbacks(c, z, x, y, desc)
626 QuestHelper: Assert(not c or type(c) == "number")
627 QuestHelper: Assert(not z or type(z) == "number")
628 QuestHelper: Assert(not x or type(x) == "number")
629 QuestHelper: Assert(not y or type(y) == "number")
630 if c == last_c and z == last_z and desc == last_desc and not x and not y then x, y = last_x, last_y end -- sometimes we may not have up-to-date location, but could still in theory be pointing at the same spot
632 if not c or (x and y) then
633 if c ~= last_c or z ~= last_z or x ~= last_x or y ~= last_y or desc ~= last_desc then
634 last_c, last_z, last_x, last_y, last_desc = c, z, x, y, desc
635 for cb in pairs(callbacks) do
636 local len = cb.len
637 cb[len+1] = c
638 cb[len+2] = z
639 cb[len+3] = x
640 cb[len+4] = y
641 cb[len+5] = desc
642 cb.func(unpack(cb, 1, len+5))
648 function QuestHelper:SetMinimapObject(minimap)
649 Minimap = minimap
650 QuestHelper.Astrolabe:SetMinimapObject(minimap)
651 QuestHelper.minimap_marker:SetParent(minimap)
652 QuestHelper.Astrolabe.processingFrame:SetParent(minimap)
655 --[[ Small parts of the arrow rendering code are thanks to Tomtom, with the following license:
657 -------------------------------------------------------------------------
658 Copyright (c) 2006-2007, James N. Whitehead II
659 All rights reserved.
661 Redistribution and use in source and binary forms, with or without
662 modification, are permitted provided that the following conditions are
663 met:
665 * Redistributions of source code must retain the above copyright
666 notice, this list of conditions and the following disclaimer.
667 * Redistributions in binary form must reproduce the above
668 copyright notice, this list of conditions and the following
669 disclaimer in the documentation and/or other materials provided
670 with the distribution.
671 * The name or alias of the copyright holder may not be used to endorse
672 or promote products derived from this software without specific prior
673 written permission.
675 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
676 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
677 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
678 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
679 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
680 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
681 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
682 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
683 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
684 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
685 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
686 ---------------------------------------------------------------------------]]
688 function QuestHelper:CreateMipmapDodad()
689 local icon = CreateFrame("Button", nil, Minimap)
690 icon:Hide()
691 icon.recalc_timeout = 0
693 icon.arrow = icon:CreateTexture("BACKGROUND")
694 icon.arrow:SetHeight(40)
695 icon.arrow:SetWidth(40)
696 icon.arrow:SetPoint("CENTER", 0, 0)
697 icon.arrow:SetTexture("Interface\\AddOns\\QuestHelper\\MinimapArrow")
698 icon.arrow:Hide()
700 icon.phase = 0
701 icon.target = {0, 0, 0, 0}
703 icon.bg = QuestHelper:CreateIconTexture(icon, 16)
704 icon.bg:SetDrawLayer("BACKGROUND")
705 icon.bg:SetAllPoints()
707 function icon:OnUpdate(elapsed)
708 local c, z, x, y, textdesc
709 if self.obj then
710 c, z = QuestHelper.collect_rc, QuestHelper.collect_rz
711 if c and z then
712 x, y = convertLocationToScreen(self.obj.loc, c, z)
715 if self.obj.map_desc_chain then
716 -- the first line will just be an "enroute" line
717 textdesc = self.obj.map_desc[1] .. "\n" .. self.obj.map_desc_chain.map_desc[1]
718 else
719 textdesc = self.obj.map_desc[1]
723 QuestHelper: Assert(not c or type(c) == "number")
724 QuestHelper: Assert(not z or type(z) == "number")
726 -- Deal with waypoint callbacks
727 if QuestHelper_Pref.hide or UnitIsDeadOrGhost("player") and not QuestHelper.InBrokenInstance then
728 QuestHelper:InvokeWaypointCallbacks()
729 else
730 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, textdesc)
733 if self.obj and not QuestHelper.InBrokenInstance then
734 self:Show() -- really only triggers if the non-broken-instance code is being poked
736 if not QuestHelper_Pref.hide and QuestHelper.Astrolabe:PlaceIconOnMinimap(self, convertLocation(self.obj.loc)) ~= -1 then
737 local edge = QuestHelper.Astrolabe:IsIconOnEdge(self)
739 if edge then
740 self.arrow:Show()
741 self.dot:Hide()
742 self.bg:Hide()
743 else
744 self.arrow:Hide()
745 self.dot:Show()
746 self.bg:Show()
749 if edge then
750 local angle = QuestHelper.Astrolabe:GetDirectionToIcon(self)
751 if GetCVar("rotateMinimap") == "1" then
752 angle = angle + QuestHelper.Astrolabe:GetFacing()
755 if elapsed then
756 if self.phase > 6.283185307179586476925 then
757 self.phase = self.phase-6.283185307179586476925+elapsed*3.5
758 else
759 self.phase = self.phase+elapsed*3.5
763 local scale = 1.0 + 0.1 * math.sin(self.phase)
765 local x, y = scale * math.sin(angle + 3.14159 * 0.75) * math.sqrt(0.5), scale * math.cos(angle + 3.14159 * 0.75) * math.sqrt(0.5)
766 self.arrow:SetTexCoord(0.5 - x, 0.5 + y, 0.5 + y, 0.5 + x, 0.5 - y, 0.5 - x, 0.5 + x, 0.5 - y)
768 else
769 self:Hide()
771 else
772 self:Hide()
776 function icon:SetObjective(obj)
777 self:SetHeight(20*QuestHelper_Pref.scale)
778 self:SetWidth(20*QuestHelper_Pref.scale)
780 if obj ~= self.obj then
781 self.obj = obj
783 self.recalc_timeout = 0
785 if self.dot then QuestHelper:ReleaseTexture(self.dot) self.dot = nil end
787 if self.obj then
788 self.dot = QuestHelper:CreateIconTexture(self, self.obj.icon_id or 8)
789 self.dot:SetPoint("TOPLEFT", icon, "TOPLEFT", 2, -2)
790 self.dot:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
793 self:OnUpdate()
797 function icon:OnEnter()
798 if self.obj then
799 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
800 QuestHelper.tooltip:ClearLines()
802 --[[if self.target[5] then
803 QuestHelper.tooltip:AddLine(QHFormat("WAYPOINT_REASON", self.target[5]), unpack(QuestHelper:GetColourTheme().tooltip))
804 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.serif, 14)
805 end]]
807 QuestHelper:AppendObjectiveToTooltip(self.obj)
808 QuestHelper.tooltip:Show()
812 function icon:OnLeave()
813 QuestHelper.tooltip:Hide()
816 function icon:OnClick()
817 if self.objective then
818 local menu = QuestHelper:CreateMenu()
819 QuestHelper:CreateMenuTitle(menu, self.objective:Reason(true))
820 QuestHelper:AddObjectiveOptionsToMenu(self.obj, menu)
821 menu:ShowAtCursor()
825 function icon:OnEvent()
826 if self.obj then
827 self:Show()
828 else
829 self:Hide()
833 icon:SetScript("OnUpdate", icon.OnUpdate)
834 icon:SetScript("OnEnter", icon.OnEnter)
835 icon:SetScript("OnLeave", icon.OnLeave)
836 icon:SetScript("OnEvent", icon.OnEvent)
837 icon:SetScript("OnClick", icon.OnClick)
839 icon:RegisterForClicks("RightButtonUp")
840 icon:RegisterEvent("PLAYER_ENTERING_WORLD")
842 return icon