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
10 Redistribution and use in source and binary forms, with or without
11 modification, are permitted provided that the following conditions are
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
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 ---------------------------------------------------------------------------
39 local function ColorGradient(perc
, ...)
40 local num
= select("#", ...)
41 local hexes
= type(select(1, ...)) == "string"
44 return select(num
-2, ...), select(num
-1, ...), select(num
, ...)
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
57 return r1
+ (r2
-r1
)*relperc
,
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)
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
)
91 local function OnDragStart(self
, button
)
92 if not QuestHelper_Pref
.arrow_locked
then -- TODO TWEAKERY
97 local function OnDragStop(self
, button
)
98 self
:StopMovingOrSizing()
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
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
122 function QH_Arrow_Show()
126 function QH_Arrow_Reset()
127 QuestHelper_Pref
.arrow
= true
128 wayframe
:ClearAllPoints()
129 wayframe
:SetPoint("CENTER", 0, 0)
130 QuestHelper_Pref
.arrow_locked
= false -- they're probably going to want to move it
134 function QH_Arrow_SetScale(scale
)
136 QuestHelper_Pref
.arrow_arrowsize
= scale
138 scale
= QuestHelper_Pref
.arrow_arrowsize
141 if not showDownArrow
then
142 wayframe
:SetHeight(42 * scale
)
143 wayframe
:SetWidth(56 * scale
)
146 wayframe
:SetHeight(70 * scale
)
147 wayframe
:SetWidth(53 * scale
)
152 function QH_Arrow_SetTextScale(scale
)
153 wayframe
.title
:SetFont(default_font_name
, default_font_size
* scale
, default_font_flags
)
154 wayframe
.status
:SetFont(default_font_name
, default_font_size
* scale
, default_font_flags
)
155 wayframe
.tta
:SetFont(default_font_name
, default_font_size
* scale
, default_font_flags
)
156 QuestHelper_Pref
.arrow_textsize
= scale
157 --wayframe:SetScale(scale)
159 QH_Arrow_SetTextScale(QuestHelper_Pref
.arrow_textsize
or 1)
161 local function wpupdate(c
, z
, x
, y
, desc
)
163 QuestHelper
: Assert(z
)
164 QuestHelper
: Assert(x
)
165 QuestHelper
: Assert(y
)
167 QuestHelper
: Assert(not z
)
168 QuestHelper
: Assert(not x
)
169 QuestHelper
: Assert(not y
)
171 active_point
.c
, active_point
.z
, active_point
.x
, active_point
.y
= c
, z
, x
, y
172 wayframe
.title
:SetText(desc
)
174 OnUpdate(wayframe
, nil)
177 QuestHelper
:AddWaypointCallback(wpupdate
)
179 local status
= wayframe
.status
180 local tta
= wayframe
.tta
181 local arrow
= wayframe
.arrow
182 local last_distance
= 0
183 local tta_throttle
= 0
185 local speed_count
= 0
187 OnUpdate
= function(self
, elapsed
)
188 QuestHelper
: Assert(self
)
190 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
195 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
)
198 status
:SetText(QHFormat("DISTANCE", math
.floor(dist
+ 0.5)))
203 -- Showing the arrival arrow?
204 if dist
and dist
<= 10 then
205 if not showDownArrow
then
208 arrow
:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image_down")
209 arrow
:SetVertexColor(0, 1, 0)
212 local cell
= math
.floor(mod(GetTime() * 20, 55)) -- 20 fps seems to be around the right number
214 local column
= cell
% 9
215 local row
= floor(cell
/ 9)
217 local xstart
= (column
* 53) / 512
218 local ystart
= (row
* 70) / 512
219 local xend
= ((column
+ 1) * 53) / 512
220 local yend
= ((row
+ 1) * 70) / 512
221 arrow
:SetTexCoord(xstart
,xend
,ystart
,yend
)
223 if showDownArrow
then
224 showDownArrow
= false
226 arrow
:SetTexture("Interface\\AddOns\\QuestHelper\\arrow_image")
227 showDownArrow
= false
230 local angle
= atan2(-dx
, -dy
) / 360 * (math
.pi
* 2) -- degrees. seriously what
231 --if angle < 0 then angle = angle + math.pi * 2 end
232 local player
= GetPlayerFacing()
233 angle
= angle
- player
235 local perc
= math
.abs((math
.pi
- math
.abs(angle
)) / math
.pi
)
236 if perc
> 1 then perc
= 2 - perc
end -- siiigh
238 local gr
,gg
,gb
= 0, 1, 0
239 local mr
,mg
,mb
= 1, 1, 0
240 local br
,bg
,bb
= 1, 0, 0
241 local r
,g
,b
= ColorGradient(perc
, br
, bg
, bb
, mr
, mg
, mb
, gr
, gg
, gb
)
242 arrow
:SetVertexColor(r
,g
,b
)
245 local cell
= floor(angle
/ (math
.pi
* 2) * 108 + 0.5) % 108
246 local column
= cell
% 9
247 local row
= floor(cell
/ 9)
249 local xstart
= (column
* 56) / 512
250 local ystart
= (row
* 42) / 512
251 local xend
= ((column
+ 1) * 56) / 512
252 local yend
= ((row
+ 1) * 42) / 512
253 arrow
:SetTexCoord(xstart
,xend
,ystart
,yend
)
256 -- Calculate the TTA every second (%01d:%02d)
260 tta_throttle = tta_throttle + elapsed
262 if tta_throttle >= 1.0 then
263 -- Calculate the speed in yards per sec at which we're moving
264 local current_speed = (last_distance - dist) / tta_throttle
266 if last_distance == 0 then
270 if speed_count < 2 then
271 speed = (speed + current_speed) / 2
272 speed_count = speed_count + 1
275 speed = current_speed
279 local eta = math.abs(dist / speed)
280 tta:SetFormattedText("%01d:%02d", eta / 60, eta % 60)
292 wayframe
:SetScript("OnUpdate", OnUpdate
)
295 local function spacer()
296 local htex
= QuestHelper
:CreateIconTexture(item
, 10)
297 htex
:SetVertexColor(1, 1, 1, 0)
301 function QH_Arrow_PopulateMenu(menu
)
302 local hide
= QuestHelper
:CreateMenuItem(menu
, QuestHelper_Pref
.arrow
and QHText("QH_BUTTON_HIDE") or QHText("QH_BUTTON_SHOW"))
303 hide
:SetFunction(function () QuestHelper
:ToggleArrow() end)
304 --hide:AddTexture(spacer(), true)
305 --hide:AddTexture(spacer(), false)
307 local lock
= QuestHelper
:CreateMenuItem(menu
, "Lock")
308 local ltex
= QuestHelper
:CreateIconTexture(item
, 10)
309 lock
:SetFunction(function () QuestHelper_Pref
.arrow_locked
= not QuestHelper_Pref
.arrow_locked
end)
310 lock
:AddTexture(ltex
, true)
311 lock
:AddTexture(spacer(), false)
312 ltex
:SetVertexColor(1, 1, 1, QuestHelper_Pref
.arrow_locked
and 1 or 0)
314 local scale
= QuestHelper
:CreateMenuItem(menu
, "Arrow Scale")
315 local scale_menu
= QuestHelper
:CreateMenu()
316 scale
:SetSubmenu(scale_menu
)
317 scale
:AddTexture(spacer(), true)
319 local it
= QuestHelper
:CreateMenuItem(scale_menu
, string.format("%d%%", i
* 10))
321 it
:SetFunction(function () QH_Arrow_SetScale(ix
/ 10) end)
322 local icon
= QuestHelper
:CreateIconTexture(item
, 10)
323 if QuestHelper_Pref
.arrow_arrowsize
== ix
/ 10 then
324 icon
:SetVertexColor(1, 1, 1, 1)
326 icon
:SetVertexColor(1, 1, 1, 0)
331 local tscale
= QuestHelper
:CreateMenuItem(menu
, "Text Scale")
332 local tscale_menu
= QuestHelper
:CreateMenu()
333 tscale
:SetSubmenu(tscale_menu
)
334 tscale
:AddTexture(spacer(), true)
336 local it
= QuestHelper
:CreateMenuItem(tscale_menu
, string.format("%d%%", i
* 10))
338 it
:SetFunction(function () QH_Arrow_SetTextScale(ix
/ 10) end)
339 local icon
= QuestHelper
:CreateIconTexture(item
, 10)
340 if QuestHelper_Pref
.arrow_textsize
== ix
/ 10 then
341 icon
:SetVertexColor(1, 1, 1, 1)
343 icon
:SetVertexColor(1, 1, 1, 0)
348 local reset
= QuestHelper
:CreateMenuItem(menu
, QHText("SETTINGS_MENU_ARROW_RESET"))
349 reset
:SetFunction(function () QH_Arrow_Reset() end)
352 local function WayFrame_OnClick(self
, button
)
353 local menu
= QuestHelper
:CreateMenu()
354 QuestHelper
:CreateMenuTitle(menu
, QHText("SETTINGS_ARROWLINK_ARROW"))
356 QH_Arrow_PopulateMenu(menu
)
361 wayframe
:RegisterForClicks("RightButtonUp")
362 wayframe
:SetScript("OnClick", WayFrame_OnClick
)