this will almost certainly break something
[QuestHelper.git] / arrow.lua
blobf4fb40819517c1f89707d972967fcdfe019dfdc1
1 QuestHelper_File["arrow.lua"] = "Development Version"
2 QuestHelper_Loadtime["arrow.lua"] = GetTime()
4 --[[ This entire file is pretty liberally ganked from TomTom (and then modified) under the following license:
6 -------------------------------------------------------------------------
7 Copyright (c) 2006-2007, James N. Whitehead II
8 All rights reserved.
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are
12 met:
14 * Redistributions of source code must retain the above copyright
15 notice, this list of conditions and the following disclaimer.
16 * Redistributions in binary form must reproduce the above
17 copyright notice, this list of conditions and the following
18 disclaimer in the documentation and/or other materials provided
19 with the distribution.
20 * The name or alias of the copyright holder may not be used to endorse
21 or promote products derived from this software without specific prior
22 written permission.
24 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
27 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
30 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
31 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
32 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
33 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
34 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 ---------------------------------------------------------------------------
37 Thanks, James! <3 ]]
39 local function ColorGradient(perc, ...)
40 local num = select("#", ...)
41 local hexes = type(select(1, ...)) == "string"
43 if perc == 1 then
44 return select(num-2, ...), select(num-1, ...), select(num, ...)
45 end
47 num = num / 3
49 local segment, relperc = math.modf(perc*(num-1))
50 local r1, g1, b1, r2, g2, b2
51 r1, g1, b1 = select((segment*3)+1, ...), select((segment*3)+2, ...), select((segment*3)+3, ...)
52 r2, g2, b2 = select((segment*3)+4, ...), select((segment*3)+5, ...), select((segment*3)+6, ...)
54 if not r2 or not g2 or not b2 then
55 return r1, g1, b1
56 else
57 return r1 + (r2-r1)*relperc,
58 g1 + (g2-g1)*relperc,
59 b1 + (b2-b1)*relperc
60 end
61 end
63 local wayframe = CreateFrame("Button", "QHArrowFrame", UIParent)
64 wayframe:SetPoint("CENTER", -300, 300)
65 wayframe:EnableMouse(true)
66 wayframe:SetMovable(true)
67 wayframe:SetUserPlaced(true)
68 wayframe:Hide()
70 wif = wayframe
72 -- Frame used to control the scaling of the title and friends
73 local titleframe = CreateFrame("Frame", nil, wayframe)
75 wayframe.title = titleframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall")
76 wayframe.status = titleframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall")
77 wayframe.tta = titleframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall")
78 wayframe.title:SetPoint("TOP", wayframe, "BOTTOM", 0, 0)
79 wayframe.status:SetPoint("TOP", wayframe.title, "BOTTOM", 0, 0)
80 wayframe.tta:SetPoint("TOP", wayframe.status, "BOTTOM", 0, 0)
81 local default_font_name, default_font_size, default_font_flags = wayframe.title:GetFont()
84 local r, g, b, a = wayframe.status:GetTextColor()
85 r, g, b = r - 0.2, g - 0.2, b - 0.2
86 wayframe.status:SetTextColor(r, g, b, a)
87 end
89 local OnUpdate
91 local function OnDragStart(self, button)
92 if not QuestHelper_Pref.arrow_locked then -- TODO TWEAKERY
93 self:StartMoving()
94 end
95 end
97 local function OnDragStop(self, button)
98 self:StopMovingOrSizing()
99 end
101 local function OnEvent(self, event, ...)
102 if event == "ZONE_CHANGED_NEW_AREA" and QuestHelper_Pref.arrow and not QuestHelper_Pref.hide then -- TODO TWEAKERY
103 self:Show()
104 OnUpdate(self, nil)
108 wayframe:SetScript("OnDragStart", OnDragStart)
109 wayframe:SetScript("OnDragStop", OnDragStop)
110 wayframe:RegisterForDrag("LeftButton")
111 wayframe:RegisterEvent("ZONE_CHANGED_NEW_AREA")
112 wayframe:SetScript("OnEvent", OnEvent)
114 wayframe.arrow = wayframe:CreateTexture("OVERLAY")
115 --wayframe.arrow:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image_down") -- if we don't do this, the image doesn't seem to end up cached. :blizzard:
116 wayframe.arrow:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image")
117 wayframe.arrow:SetAllPoints()
119 local active_point, arrive_distance, showDownArrow, point_title
120 active_point = {}
122 function QH_Arrow_Show()
123 wayframe:Show()
126 function QH_Arrow_Reset()
127 wayframe:ClearAllPoints()
128 wayframe:SetPoint("CENTER", 0, 0)
129 QuestHelper_Pref.arrow_locked = false -- they're probably going to want to move it
132 function QH_Arrow_SetScale(scale)
133 if scale then
134 QuestHelper_Pref.arrow_arrowsize = scale
135 else
136 scale = QuestHelper_Pref.arrow_arrowsize
139 if not showDownArrow then
140 wayframe:SetHeight(42 * scale)
141 wayframe:SetWidth(56 * scale)
142 else
143 scale = scale * 0.8
144 wayframe:SetHeight(70 * scale)
145 wayframe:SetWidth(53 * scale)
148 QH_Arrow_SetScale()
150 function QH_Arrow_SetTextScale(scale)
151 wayframe.title:SetFont(default_font_name, default_font_size * scale, default_font_flags)
152 wayframe.status:SetFont(default_font_name, default_font_size * scale, default_font_flags)
153 wayframe.tta:SetFont(default_font_name, default_font_size * scale, default_font_flags)
154 QuestHelper_Pref.arrow_textsize = scale
155 --wayframe:SetScale(scale)
157 QH_Arrow_SetTextScale(QuestHelper_Pref.arrow_textsize or 1)
159 local function wpupdate(c, z, x, y, desc)
160 active_point.c, active_point.z, active_point.x, active_point.y = c, z, x, y
161 wayframe.title:SetText(desc)
162 wayframe:Show()
163 OnUpdate(wayframe, nil)
166 QuestHelper:AddWaypointCallback(wpupdate)
168 local status = wayframe.status
169 local tta = wayframe.tta
170 local arrow = wayframe.arrow
171 local last_distance = 0
172 local tta_throttle = 0
173 local speed = 0
174 local speed_count = 0
176 OnUpdate = function(self, elapsed)
177 QuestHelper: Assert(self)
179 if not active_point.c or QuestHelper.collect_rc ~= active_point.c or QuestHelper.collect_delayed or QuestHelper.InBrokenInstance or not QuestHelper_Pref.arrow then
180 self:Hide()
181 return
184 local dist, dx, dy = QuestHelper.Astrolabe:ComputeDistance(QuestHelper.collect_rc, QuestHelper.collect_rz, QuestHelper.collect_rx, QuestHelper.collect_ry, active_point.c, active_point.z, active_point.x, active_point.y)
186 if dist then
187 status:SetText(QHFormat("DISTANCE", math.floor(dist + 0.5)))
188 else
189 status:SetText("")
192 -- Showing the arrival arrow?
193 if dist and dist <= 10 then
194 if not showDownArrow then
195 showDownArrow = true
196 QH_Arrow_SetScale()
197 arrow:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image_down")
198 arrow:SetVertexColor(0, 1, 0)
201 local cell = math.floor(mod(GetTime() * 20, 55)) -- 20 fps seems to be around the right number
203 local column = cell % 9
204 local row = floor(cell / 9)
206 local xstart = (column * 53) / 512
207 local ystart = (row * 70) / 512
208 local xend = ((column + 1) * 53) / 512
209 local yend = ((row + 1) * 70) / 512
210 arrow:SetTexCoord(xstart,xend,ystart,yend)
211 else
212 if showDownArrow then
213 showDownArrow = false
214 QH_Arrow_SetScale()
215 arrow:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image")
216 showDownArrow = false
219 local angle = atan2(-dx, -dy) / 360 * (math.pi * 2) -- degrees. seriously what
220 --if angle < 0 then angle = angle + math.pi * 2 end
221 local player = GetPlayerFacing()
222 angle = angle - player
224 local perc = math.abs((math.pi - math.abs(angle)) / math.pi)
225 if perc > 1 then perc = 2 - perc end -- siiigh
227 local gr,gg,gb = 0, 1, 0
228 local mr,mg,mb = 1, 1, 0
229 local br,bg,bb = 1, 0, 0
230 local r,g,b = ColorGradient(perc, br, bg, bb, mr, mg, mb, gr, gg, gb)
231 arrow:SetVertexColor(r,g,b)
234 local cell = floor(angle / (math.pi * 2) * 108 + 0.5) % 108
235 local column = cell % 9
236 local row = floor(cell / 9)
238 local xstart = (column * 56) / 512
239 local ystart = (row * 42) / 512
240 local xend = ((column + 1) * 56) / 512
241 local yend = ((row + 1) * 42) / 512
242 arrow:SetTexCoord(xstart,xend,ystart,yend)
245 -- Calculate the TTA every second (%01d:%02d)
247 --[[
248 if elapsed then
249 tta_throttle = tta_throttle + elapsed
251 if tta_throttle >= 1.0 then
252 -- Calculate the speed in yards per sec at which we're moving
253 local current_speed = (last_distance - dist) / tta_throttle
255 if last_distance == 0 then
256 current_speed = 0
259 if speed_count < 2 then
260 speed = (speed + current_speed) / 2
261 speed_count = speed_count + 1
262 else
263 speed_count = 0
264 speed = current_speed
267 if speed > 0 then
268 local eta = math.abs(dist / speed)
269 tta:SetFormattedText("%01d:%02d", eta / 60, eta % 60)
270 else
271 tta:SetText("")
274 last_distance = dist
275 tta_throttle = 0
281 wayframe:SetScript("OnUpdate", OnUpdate)
284 local function spacer()
285 local htex = QuestHelper:CreateIconTexture(item, 10)
286 htex:SetVertexColor(1, 1, 1, 0)
287 return htex
290 local function WayFrame_OnClick(self, button)
291 local menu = QuestHelper:CreateMenu()
293 QuestHelper:CreateMenuTitle(menu, "QuestHelper Arrow")
295 local hide = QuestHelper:CreateMenuItem(menu, "Hide")
296 hide:SetFunction(function () QuestHelper:ToggleArrow() end)
297 --hide:AddTexture(spacer(), true)
298 --hide:AddTexture(spacer(), false)
300 local lock = QuestHelper:CreateMenuItem(menu, "Lock")
301 local ltex = QuestHelper:CreateIconTexture(item, 10)
302 lock:SetFunction(function () QuestHelper_Pref.arrow_locked = not QuestHelper_Pref.arrow_locked end)
303 lock:AddTexture(ltex, true)
304 lock:AddTexture(spacer(), false)
305 ltex:SetVertexColor(1, 1, 1, QuestHelper_Pref.arrow_locked and 1 or 0)
307 local scale = QuestHelper:CreateMenuItem(menu, "Arrow Scale")
308 local scale_menu = QuestHelper:CreateMenu()
309 scale:SetSubmenu(scale_menu)
310 scale:AddTexture(spacer(), true)
311 for i = 5, 15 do
312 local it = QuestHelper:CreateMenuItem(scale_menu, string.format("%d%%", i * 10))
313 local ix = i
314 it:SetFunction(function () QH_Arrow_SetScale(ix / 10) end)
315 local icon = QuestHelper:CreateIconTexture(item, 10)
316 if QuestHelper_Pref.arrow_arrowsize == ix / 10 then
317 icon:SetVertexColor(1, 1, 1, 1)
318 else
319 icon:SetVertexColor(1, 1, 1, 0)
321 it:AddTexture(icon)
324 local tscale = QuestHelper:CreateMenuItem(menu, "Text Scale")
325 local tscale_menu = QuestHelper:CreateMenu()
326 tscale:SetSubmenu(tscale_menu)
327 tscale:AddTexture(spacer(), true)
328 for i = 5, 15 do
329 local it = QuestHelper:CreateMenuItem(tscale_menu, string.format("%d%%", i * 10))
330 local ix = i
331 it:SetFunction(function () QH_Arrow_SetTextScale(ix / 10) end)
332 local icon = QuestHelper:CreateIconTexture(item, 10)
333 if QuestHelper_Pref.arrow_textsize == ix / 10 then
334 icon:SetVertexColor(1, 1, 1, 1)
335 else
336 icon:SetVertexColor(1, 1, 1, 0)
338 it:AddTexture(icon)
341 menu:ShowAtCursor()
344 wayframe:RegisterForClicks("RightButtonUp")
345 wayframe:SetScript("OnClick", WayFrame_OnClick)