Merge branch 'master' into translations
[QuestHelper.git] / dodads.lua
blob3ad2897a76086533be03a9a06ec6f2b5e7de3970
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 QH_Event("WORLD_MAP_UPDATE", function () walker:RouteChanged() end)
233 QH_Hook(walker, "OnUpdate", walker.OnUpdate)
235 return walker
238 function QuestHelper:GetOverlapObjectives(obj)
239 local w, h = self.map_overlay:GetWidth(), self.map_overlay:GetHeight()
240 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
242 local list = self.overlap_list
244 if not list then
245 list = {}
246 self.overlap_list = list
247 else
248 while table.remove(list) do end
251 local cx, cy = GetCursorPosition()
253 local es = QuestHelper.map_overlay:GetEffectiveScale()
254 local ies = 1/es
256 cx, cy = (cx-self.map_overlay:GetLeft()*es)*ies, (self.map_overlay:GetTop()*es-cy)*ies
258 local s = 10*QuestHelper_Pref.scale
260 for i, o in ipairs(walker_loc.route) do
261 --QuestHelper: Assert(o, string.format("nil dodads pos issue, o %s", tostring(o)))
262 --QuestHelper: Assert(o.pos, string.format("nil dodads pos issue, pos %s", QuestHelper:StringizeTable(o)))
263 if not o.ignore then
264 if o == obj then
265 table.insert(list, o)
266 else
267 local x, y = convertLocationToScreen(o.loc, c, z)
269 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
270 x, y = x*w, y*h
272 if cx >= x-s and cy >= y-s and cx <= x+s and cy <= y+s then
273 table.insert(list, o)
280 table.sort(list, function(a, b) return (a.distance or 0) < (b.distance or 0) end)
282 return list
285 function QuestHelper:AppendObjectiveProgressToTooltip(o, tooltip, font, depth)
286 if o.progress then
287 local prog_sort_table = {}
289 local theme = self:GetColourTheme()
291 local indent = (" "):rep(depth or 0)
293 for user, progress in pairs(o.progress) do
294 table.insert(prog_sort_table, user)
297 table.sort(prog_sort_table, function(a, b)
298 if o.progress[a][3] < o.progress[b][3] then
299 return true
300 elseif o.progress[a][3] == o.progress[b][3] then
301 return a < b
303 return false
304 end)
306 for i, u in ipairs(prog_sort_table) do
307 tooltip:AddDoubleLine(indent..QHFormat("PEER_PROGRESS", u),
308 self:ProgressString(o.progress[u][1].."/"..o.progress[u][2],
309 o.progress[u][3]), unpack(theme.tooltip))
311 if font then
312 local last, name = tooltip:NumLines(), tooltip:GetName()
313 local left, right = _G[name.."TextLeft"..last], _G[name.."TextRight"..last]
315 left:SetFont(font, 13)
316 right:SetFont(font, 13)
320 while table.remove(prog_sort_table) do end
324 function QuestHelper:AppendObjectiveToTooltip(o)
325 local theme = self:GetColourTheme()
327 QuestHelper: Assert(o.map_desc)
328 for _, v in ipairs(o.map_desc) do
329 self.tooltip:AddLine(v, unpack(theme.tooltip))
330 self.tooltip:GetPrevLines():SetFont(self.font.serif, 14)
333 if o.map_desc_chain then
334 self:AppendObjectiveToTooltip(o.map_desc_chain)
335 else
336 self:AppendObjectiveProgressToTooltip(o, self.tooltip, QuestHelper.font.sans)
338 self.tooltip:AddDoubleLine(QHText("TRAVEL_ESTIMATE"), QHFormat("TRAVEL_ESTIMATE_VALUE", o.distance or 0), unpack(theme.tooltip))
339 self.tooltip:GetPrevLines():SetFont(self.font.sans, 11)
340 select(2, self.tooltip:GetPrevLines()):SetFont(self.font.sans, 11)
344 globx = 0.5
345 globy = 0.5
347 local function rightclick_menu(obj)
348 if obj then
349 local menu = QuestHelper:CreateMenu()
350 local list = QuestHelper:GetOverlapObjectives(obj)
351 local item
353 if #list > 1 then
354 QuestHelper:CreateMenuTitle(menu, "Objectives")
356 for i, o in ipairs(list) do
357 local submenu = QuestHelper:CreateMenu()
358 item = QuestHelper:CreateMenuItem(menu, o.map_desc[1])
359 item:SetSubmenu(submenu)
360 item:AddTexture(QuestHelper:CreateIconTexture(item, o.icon_id or 8), true)
361 QuestHelper:AddObjectiveOptionsToMenu(o, submenu)
363 else
364 QuestHelper:CreateMenuTitle(menu, obj.map_desc[1])
365 QuestHelper:AddObjectiveOptionsToMenu(obj, menu)
368 menu:ShowAtCursor()
372 function QuestHelper:CreateWorldMapDodad(objective, nxt)
373 local icon = CreateFrame("Button", nil, QuestHelper.map_overlay)
374 icon:SetFrameStrata("FULLSCREEN")
376 function icon:SetTooltip(list)
377 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
378 QuestHelper.tooltip:ClearLines()
380 local first = true
382 for i, o in ipairs(list) do
383 if first then
384 first = false
385 else
386 QuestHelper.tooltip:AddLine("|c80ff0000 . . . . . .|r")
387 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.sans, 8)
390 QuestHelper:AppendObjectiveToTooltip(o)
393 QuestHelper.tooltip:Show()
396 function icon:SetObjective(objective, nxt)
397 self:SetHeight(20*QuestHelper_Pref.scale)
398 self:SetWidth(20*QuestHelper_Pref.scale)
400 if self.dot then
401 QuestHelper:ReleaseTexture(self.dot)
402 self.dot = nil
405 if self.bg then
406 QuestHelper:ReleaseTexture(self.bg)
407 self.bg = nil
410 if objective then
411 self.objective = objective
413 if nxt then
414 self.bg = QuestHelper:CreateIconTexture(self, 13)
415 elseif objective.map_highlight then
416 self.bg = QuestHelper:CreateIconTexture(self, 14)
417 else
418 self.bg = QuestHelper:CreateIconTexture(self, 16)
421 self.dot = QuestHelper:CreateIconTexture(self, objective.icon_id or 8)
423 self.bg:SetDrawLayer("BACKGROUND")
424 self.bg:SetAllPoints()
425 self.dot:SetPoint("TOPLEFT", self, "TOPLEFT", 3*QuestHelper_Pref.scale, -3*QuestHelper_Pref.scale)
426 self.dot:SetPoint("BOTTOMRIGHT", self, "BOTTOMRIGHT", -3*QuestHelper_Pref.scale, 3*QuestHelper_Pref.scale)
428 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(objective.loc))
429 --QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, 0, 0, globx, globy)
430 else
431 self.objective = nil
432 self:Hide()
436 function icon:SetGlow(list)
437 local w, h = QuestHelper.map_overlay:GetWidth(), QuestHelper.map_overlay:GetHeight()
438 local c, z = GetCurrentMapContinent(), GetCurrentMapZone()
440 local nodes = {}
442 for _, v in ipairs(list) do
443 if v.cluster then
444 for _, i in ipairs(v.cluster) do
445 nodes[i] = true
447 else
448 nodes[v] = true
453 local out = 1
454 for obj, _ in pairs(nodes) do
455 local x, y = convertLocationToScreen(obj.loc, c, z)
456 if x and y and x > 0 and y > 0 and x < 1 and y < 1 then
457 if not self.glow_list then
458 self.glow_list = QuestHelper:CreateTable()
461 tex = self.glow_list[out]
462 if not tex then
463 tex = QuestHelper:CreateGlowTexture(self)
464 table.insert(self.glow_list, tex)
466 out = out + 1
468 tex:SetPoint("CENTER", QuestHelper.map_overlay, "TOPLEFT", x*w, -y*h)
469 tex:SetVertexColor(1,1,1,0)
470 tex:SetWidth(h / 4) -- we want it to be a circle
471 tex:SetHeight(h / 4)
472 tex:Show()
473 tex.max_alpha = 1
477 if self.glow_list then
478 while #self.glow_list >= out do
479 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
482 if #self.glow_list == 0 then
483 QuestHelper:ReleaseTable(self.glow_list)
484 self.glow_list = nil
489 icon.show_glow = false
490 icon.glow_pct = 0.0
491 icon.phase = 0.0
492 icon.old_count = 0
494 function icon:OnUpdate(elapsed)
495 self.phase = (self.phase + elapsed)%6.283185307179586476925286766559005768394338798750211641949889185
497 if self.old_count > 0 then
498 local list = QuestHelper:GetOverlapObjectives(self.objective)
500 if #list ~= self.old_count then
501 self:SetTooltip(list)
502 self.old_count = #list
503 self:SetGlow(list)
507 if self.show_glow then
508 self.glow_pct = math.min(1, self.glow_pct+elapsed*1.5)
509 else
510 self.glow_pct = math.max(0, self.glow_pct-elapsed*0.5)
512 if self.glow_pct == 0 then
513 if self.glow_list then
514 while #self.glow_list > 0 do
515 QuestHelper:ReleaseTexture(table.remove(self.glow_list))
517 QuestHelper:ReleaseTable(self.glow_list)
518 self.glow_list = nil
521 QH_Hook(self, "OnUpdate", nil)
522 return
526 if self.glow_list then
527 -- You know, these numbers are harmonics of pi. Would SETI detected them, or would they just be seen as noise?
528 -- I'd vote for the later.
530 -- Pi - circumference over diameter - when was the last time you actually cared about diameters in math?
532 -- Pretty much everything in computer geometry depends on the pythagorean theorem, which you can use for
533 -- circles, spheres, and hyper-spheres, if you use radius.
535 -- It's even the basis of special relativity, with time being multiplied by c so that you get a distance
536 -- that you can use with the spatial dimensions. We're all in agreement that space traveling aliens are
537 -- going to know about relativity, right?
539 -- And if you ever do trig, a full circle would be exactly (circumference over radius) radians instead of
540 -- (circumference over diameter)*2 radians.
542 -- Obviously aliens are much more likely to prefer 6.283185307179586... as constant than our pi.
544 -- Important update: I just noticed that large factorials can be approximated using (2*pi*n)^.5*(n/e)^n
545 -- There's that 2 times pi thing again.
546 local r, g, b = math.sin(self.phase)*0.25+0.75,
547 math.sin(self.phase+2.094395102393195492308428922186335256131446266250070547316629728)*0.25+0.75,
548 math.sin(self.phase+4.188790204786390984616857844372670512262892532500141094633259456)*0.25+0.75
550 for i, tex in ipairs(self.glow_list) do
551 tex:SetVertexColor(r, g, b, self.glow_pct*tex.max_alpha)
556 function icon:OnEnter()
557 local list = QuestHelper:GetOverlapObjectives(self.objective)
558 self:SetTooltip(list)
559 self.old_count = #list
561 icon.show_glow = true
563 self:SetGlow(list)
565 QH_Hook(self, "OnUpdate", self.OnUpdate)
568 function icon:OnLeave()
569 QuestHelper.tooltip:Hide()
570 self.show_glow = false
571 self.old_count = 0
574 function icon:OnEvent()
575 if self.objective then
576 QuestHelper.Astrolabe:PlaceIconOnWorldMap(QuestHelper.map_overlay, self, convertLocation(self.objective.loc))
577 else
578 self.objective = nil
579 self:Hide()
583 function icon:OnClick()
584 rightclick_menu(self.objective)
587 QH_Hook(icon, "OnClick", icon.OnClick)
588 QH_Hook(icon, "OnEnter", icon.OnEnter)
589 QH_Hook(icon, "OnLeave", icon.OnLeave)
590 QH_Hook(icon, "OnEvent", icon.OnEvent)
592 icon:RegisterForClicks("RightButtonUp")
594 QH_Event("WORLD_MAP_UPDATE", function () icon:OnEvent() end)
596 icon:SetObjective(objective, nxt)
597 return icon
600 local callbacks = {}
601 local last_c, last_z, last_x, last_y, last_desc
603 function QuestHelper:AddWaypointCallback(func, ...)
604 local cb = self:CreateTable()
605 callbacks[cb] = true
606 local len = select("#", ...)
607 cb.len = len
608 cb.func = func
609 for i = 1,len do cb[i] = select(i, ...) end
610 cb[len+1] = last_c
611 cb[len+2] = last_z
612 cb[len+3] = last_x
613 cb[len+4] = last_y
614 cb[len+5] = last_desc
616 if last_c then
617 func(unpack(cb, 1, len+5))
620 return cb
623 function QuestHelper:RemoveWaypointCallback(cb)
624 callbacks[cb] = nil
625 self:ReleaseTable(cb)
628 function QuestHelper:InvokeWaypointCallbacks(c, z, x, y, desc)
629 QuestHelper: Assert(not c or type(c) == "number")
630 QuestHelper: Assert(not z or type(z) == "number")
631 QuestHelper: Assert(not x or type(x) == "number")
632 QuestHelper: Assert(not y or type(y) == "number")
633 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
635 if not c or (x and y) then
636 if c ~= last_c or z ~= last_z or x ~= last_x or y ~= last_y or desc ~= last_desc then
637 last_c, last_z, last_x, last_y, last_desc = c, z, x, y, desc
638 for cb in pairs(callbacks) do
639 local len = cb.len
640 cb[len+1] = c
641 cb[len+2] = z
642 cb[len+3] = x
643 cb[len+4] = y
644 cb[len+5] = desc
645 cb.func(unpack(cb, 1, len+5))
651 function QuestHelper:SetMinimapObject(minimap)
652 Minimap = minimap
653 QuestHelper.Astrolabe:SetMinimapObject(minimap)
654 QuestHelper.minimap_marker:SetParent(minimap)
655 QuestHelper.Astrolabe.processingFrame:SetParent(minimap)
658 --[[ Small parts of the arrow rendering code are thanks to Tomtom, with the following license:
660 -------------------------------------------------------------------------
661 Copyright (c) 2006-2007, James N. Whitehead II
662 All rights reserved.
664 Redistribution and use in source and binary forms, with or without
665 modification, are permitted provided that the following conditions are
666 met:
668 * Redistributions of source code must retain the above copyright
669 notice, this list of conditions and the following disclaimer.
670 * Redistributions in binary form must reproduce the above
671 copyright notice, this list of conditions and the following
672 disclaimer in the documentation and/or other materials provided
673 with the distribution.
674 * The name or alias of the copyright holder may not be used to endorse
675 or promote products derived from this software without specific prior
676 written permission.
678 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
679 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
680 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
681 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
682 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
683 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
684 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
685 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
686 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
687 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
688 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
689 ---------------------------------------------------------------------------]]
691 function QuestHelper:CreateMipmapDodad()
692 local icon = CreateFrame("Button", nil, Minimap)
693 icon:Hide()
694 icon.recalc_timeout = 0
696 icon.arrow = icon:CreateTexture("BACKGROUND")
697 icon.arrow:SetHeight(40)
698 icon.arrow:SetWidth(40)
699 icon.arrow:SetPoint("CENTER", 0, 0)
700 icon.arrow:SetTexture("Interface\\AddOns\\QuestHelper\\MinimapArrow")
701 icon.arrow:Hide()
703 icon.phase = 0
704 icon.target = {0, 0, 0, 0}
706 icon.bg = QuestHelper:CreateIconTexture(icon, 16)
707 icon.bg:SetDrawLayer("BACKGROUND")
708 icon.bg:SetAllPoints()
710 function icon:OnUpdate(elapsed)
711 local c, z, x, y, textdesc
712 if self.obj then
713 c, z = QuestHelper.collect_rc, QuestHelper.collect_rz
714 if c and z then
715 x, y = convertLocationToScreen(self.obj.loc, c, z)
718 if self.obj.map_desc_chain then
719 -- the first line will just be an "enroute" line
720 textdesc = self.obj.map_desc[1] .. "\n" .. self.obj.map_desc_chain.map_desc[1]
721 else
722 textdesc = self.obj.map_desc[1]
726 QuestHelper: Assert(not c or type(c) == "number")
727 QuestHelper: Assert(not z or type(z) == "number")
729 -- Deal with waypoint callbacks
730 if QuestHelper_Pref.hide or UnitIsDeadOrGhost("player") and not QuestHelper.InBrokenInstance then
731 QuestHelper:InvokeWaypointCallbacks()
732 else
733 QuestHelper:InvokeWaypointCallbacks(c, z, x, y, textdesc)
736 if self.obj and not QuestHelper.InBrokenInstance then
737 self:Show() -- really only triggers if the non-broken-instance code is being poked
739 if not QuestHelper_Pref.hide and QuestHelper.Astrolabe:PlaceIconOnMinimap(self, convertLocation(self.obj.loc)) ~= -1 then
740 local edge = QuestHelper.Astrolabe:IsIconOnEdge(self)
742 if edge then
743 self.arrow:Show()
744 self.dot:Hide()
745 self.bg:Hide()
746 else
747 self.arrow:Hide()
748 self.dot:Show()
749 self.bg:Show()
752 if edge then
753 local angle = QuestHelper.Astrolabe:GetDirectionToIcon(self)
754 if GetCVar("rotateMinimap") == "1" then
755 angle = angle + QuestHelper.Astrolabe:GetFacing()
758 if elapsed then
759 if self.phase > 6.283185307179586476925 then
760 self.phase = self.phase-6.283185307179586476925+elapsed*3.5
761 else
762 self.phase = self.phase+elapsed*3.5
766 local scale = 1.0 + 0.1 * math.sin(self.phase)
768 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)
769 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)
771 else
772 self:Hide()
774 else
775 self:Hide()
779 function icon:SetObjective(obj)
780 self:SetHeight(20*QuestHelper_Pref.scale)
781 self:SetWidth(20*QuestHelper_Pref.scale)
783 if obj ~= self.obj then
784 self.obj = obj
786 self.recalc_timeout = 0
788 if self.dot then QuestHelper:ReleaseTexture(self.dot) self.dot = nil end
790 if self.obj then
791 self.dot = QuestHelper:CreateIconTexture(self, self.obj.icon_id or 8)
792 self.dot:SetPoint("TOPLEFT", icon, "TOPLEFT", 2, -2)
793 self.dot:SetPoint("BOTTOMRIGHT", icon, "BOTTOMRIGHT", -2, 2)
796 self:OnUpdate()
800 function icon:OnEnter()
801 if self.obj then
802 QuestHelper.tooltip:SetOwner(self, "ANCHOR_CURSOR")
803 QuestHelper.tooltip:ClearLines()
805 --[[if self.target[5] then
806 QuestHelper.tooltip:AddLine(QHFormat("WAYPOINT_REASON", self.target[5]), unpack(QuestHelper:GetColourTheme().tooltip))
807 QuestHelper.tooltip:GetPrevLines():SetFont(QuestHelper.font.serif, 14)
808 end]]
810 QuestHelper:AppendObjectiveToTooltip(self.obj)
811 QuestHelper.tooltip:Show()
815 function icon:OnLeave()
816 QuestHelper.tooltip:Hide()
819 function icon:OnClick()
820 rightclick_menu(self.obj)
823 function icon:OnEvent()
824 if self.obj then
825 self:Show()
826 else
827 self:Hide()
831 QH_Hook(icon, "OnUpdate", icon.OnUpdate)
832 QH_Hook(icon, "OnEnter", icon.OnEnter)
833 QH_Hook(icon, "OnLeave", icon.OnLeave)
834 QH_Hook(icon, "OnClick", icon.OnClick)
836 icon:RegisterForClicks("RightButtonUp")
838 QH_Event("PLAYER_ENTERING_WORLD", function () icon:OnEvent() end)
840 return icon