vanilla-wow-addons – Blame information for rev 1

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 ----------------------------------------------------------------------------
2 -- TomTom: A navigational assistant for World of Warcraft
3 -- CrazyTaxi: A crazy-taxi style arrow used for waypoint navigation.
4 -- concept taken from MapNotes2 (Thanks to Mery for the idea, along
5 -- with the artwork.)
6 ----------------------------------------------------------------------------
7 local function log(msg) DEFAULT_CHAT_FRAME:AddMessage(msg) end -- alias for convenience
8 ---------------------------------------------------------------------------------------------------
9 math.modf = function(number)
10 local fractional = Questie:Modulo(number, 1)
11 local integral = number - fractional
12 return integral, fractional
13 end
14 ---------------------------------------------------------------------------------------------------
15 function GetPlayerFacing()
16 local p = Minimap
17 local m = ({p:GetChildren()})[9]
18 return m:GetFacing()
19 end
20 ---------------------------------------------------------------------------------------------------
21 local sformat = string.format
22 local function ColorGradient(perc, tablee)
23 local num = table.getn(tablee)
24 local hexes = tablee[1] == "string"
25 if perc == 1 then
26 return tablee[num-2], tablee[num-1], tablee[num]
27 end
28 num = num / 3
29 local segment, relperc = math.modf(perc*(num-1))
30 local r1, g1, b1, r2, g2, b2
31 r1, g1, b1 = tablee[(segment*3)+1], tablee[(segment*3)+2], tablee[(segment*3)+3]
32 r2, g2, b2 = tablee[(segment*3)+4], tablee[(segment*3)+5], tablee[(segment*3)+6]
33 if not r1 then return end
34 if not r2 or not g2 or not b2 then
35 return r1, g1, b1
36 else
37 return r1 + (r2-r1)*relperc,
38 g1 + (g2-g1)*relperc,
39 b1 + (b2-b1)*relperc
40 end
41 end
42 ---------------------------------------------------------------------------------------------------
43 local twopi = math.pi * 2
44 function WayFrame_OnClick()
45 if (MouseIsOver(TomTomCrazyArrow) ~= nil) and (arg1 == "RightButton") then
46 TomTomCrazyArrow:Hide()
47 end
48 end
49 ---------------------------------------------------------------------------------------------------
50 local wayframe = CreateFrame("Button", "TomTomCrazyArrow", UIParent)
51 wayframe:SetHeight(42)
52 wayframe:SetWidth(56)
53 wayframe:SetPoint("CENTER", 0, 0)
54 wayframe:EnableMouse(true)
55 wayframe:SetMovable(true)
56 wayframe:Hide()
57 -- Frame used to control the scaling of the title and friends
58 local titleframe = CreateFrame("Frame", nil, wayframe)
59 wayframe.title = titleframe:CreateFontString("OVERLAY", nil, "GameFontHighlightSmall")
60 wayframe.status = titleframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall")
61 wayframe.tta = titleframe:CreateFontString("OVERLAY", nil, "GameFontNormalSmall")
62 wayframe.title:SetPoint("TOP", wayframe, "BOTTOM", 0, 0)
63 wayframe.status:SetPoint("TOP", wayframe.title, "BOTTOM", 0, 0)
64 wayframe.tta:SetPoint("TOP", wayframe.status, "BOTTOM", 0, 0)
65 ---------------------------------------------------------------------------------------------------
66 local function OnDragStart(self, button)
67 if IsControlKeyDown() and IsShiftKeyDown() then
68 this:StartMoving()
69 wayframe:SetClampedToScreen(true);
70 end
71 end
72 ---------------------------------------------------------------------------------------------------
73 local function OnDragStop(self, button)
74 this:StopMovingOrSizing()
75 end
76 ---------------------------------------------------------------------------------------------------
77 local function OnEvent(self, event, ...)
78 if event == "ZONE_CHANGED_NEW_AREA" then
79 self:Show()
80 end
81 end
82 ---------------------------------------------------------------------------------------------------
83 wayframe:SetScript("OnDragStart", OnDragStart)
84 wayframe:SetScript("OnDragStop", OnDragStop)
85 wayframe:RegisterForDrag("LeftButton")
86 wayframe:RegisterEvent("ZONE_CHANGED_NEW_AREA")
87 wayframe:SetScript("OnEvent", OnEvent)
88 wayframe.arrow = wayframe:CreateTexture("OVERLAY")
89 wayframe.arrow:SetTexture("Interface\\AddOns\\!Questie\\Images\\Arrow")
90 wayframe.arrow:SetAllPoints()
91 ---------------------------------------------------------------------------------------------------
92 local active_point, arrive_distance, showDownArrow, point_title, arrow_objective, isHide
93 function SetCrazyArrow(point, dist, title)
94 active_point = point
95 arrive_distance = dist
96 point_title = title
97 if active_point and not isHide then
98 wayframe.title:SetText(point_title or "Unknown waypoint")
99 wayframe:Show()
100 else
101 wayframe:Hide()
102 end
103 end
104 ---------------------------------------------------------------------------------------------------
105 function SetArrowFromIcon(icon)
106 local targetPoint = {
107 ["c"] = icon.data.continent,
108 ["z"] = icon.data.zoneid,
109 ["x"] = icon.averageX,
110 ["y"] = icon.averageY
111 }
112 local quest = QuestieHashMap[icon.data.questHash]
113 local data = {
114 ["point"] = targetPoint,
115 ["questName"] = quest.name,
116 ["questLevel"] = quest.questLevel
117 }
118 SetArrowFromData(data)
119 end
120 ---------------------------------------------------------------------------------------------------
121 function SetArrowFromData(data)
122 local colorString = "|c" .. QuestieTracker:GetDifficultyColor(data.questLevel)
123 local title = colorString
124 title = title .. "[" .. data.questLevel .. "] "
125 if QuestieConfig.boldColors then
126 title = title .. "|r|cFFFFFFFF" .. data.questName .. "|r"
127 else
128 title = title .. data.questName .. "|r"
129 end
130 SetCrazyArrow(data.point, 0, title)
131 arrow_objective = nil
132 arrow_data = data
133 end
134 ---------------------------------------------------------------------------------------------------
135 function SetArrowObjective(hash)
136 if arrow_objective == hash then
137 wayframe:Hide();
138 arrow_objective = 0;
139 return;
140 end
141 arrow_objective = hash
142 arrow_data = nil
143 if not QuestieCachedQuests[hash] or not QuestieCachedQuests[hash]["arrowPoint"] then return end
144 local objective = QuestieCachedQuests[hash]["arrowPoint"]
145 SetCrazyArrow(objective, objective.dist, objective.title)
146 end
147 ---------------------------------------------------------------------------------------------------
148 function RemoveCrazyArrow(hash)
149 if hash then
150 if (TomTomCrazyArrow:IsVisible() ~= nil) and (arrow_objective == hash or arrow_data) then
151 TomTomCrazyArrow:Hide()
152 end
153 end
154 if (QuestieConfig.arrowEnabled == false) then
155 TomTomCrazyArrow:Hide()
156 end
157 end
158 ---------------------------------------------------------------------------------------------------
159 local status = wayframe.status;
160 local tta = wayframe.tta;
161 local arrow = wayframe.arrow;
162 local arrowLastUpdate = 0;
163 local LastPlayerPosition = {};
164 local count = 0;
165 local last_distance = 0;
166 local tta_throttle = 0;
167 local speed = 0;
168 local speed_count = 0;
169 local function OnUpdate(self, elapsed)
170 local self = this
171 local elapsed = 1/GetFramerate()
172 local dist,x,y
173 if not UnitIsDeadOrGhost("player") then
174 if arrow_objective then
175 if QuestieCachedQuests[arrow_objective] then
176 local objective = QuestieCachedQuests[arrow_objective]["arrowPoint"]
177 if objective then
178 SetCrazyArrow(objective, objective.dist, objective.title)
179 end
180 else
181 self:Hide()
182 end
183 elseif arrow_data then
184 SetArrowFromData(arrow_data)
185 end
186 if not active_point then
187 self:Hide()
188 return
189 end
190 end
191 --While dead this maintains the corpseArrow
192 if UnitIsDeadOrGhost("player") and (UnitIsDead("player") ~= 1) and (bgactive == false) then
193 Questie:OnUpdate(elapsed)
194 end
195 local dist,x,y = GetDistanceToIcon(active_point)
196 if GetTime() - arrowLastUpdate >= .04 then
197 if (TomTomCrazyArrow:IsVisible() ~= nil) then
198 if not dist or IsInInstance() then
199 if not active_point.x and not active_point.y then
200 active_point = nil
201 end
202 self:Hide()
203 return
204 end
205 status:SetText(sformat("%d yards", dist))
206 local cell
207 -- Showing the arrival arrow?
208 if dist <= 5 then
209 if not showDownArrow then
210 arrow:SetHeight(70)
211 arrow:SetWidth(53)
212 arrow:SetTexture("Interface\\AddOns\\!Questie\\Images\\Arrow-UP")
213 arrow:SetVertexColor(0, 1, 0)
214 showDownArrow = true
215 end
216 count = count + 1
217 if count >= 55 then
218 count = 0
219 end
220 cell = count
221 local column = Questie:Modulo(cell, 9)
222 local row = floor(cell / 9)
223 local xstart = (column * 53) / 512
224 local ystart = (row * 70) / 512
225 local xend = ((column + 1) * 53) / 512
226 local yend = ((row + 1) * 70) / 512
227 arrow:SetTexCoord(xstart,xend,ystart,yend)
228 else
229 if showDownArrow then
230 arrow:SetHeight(56)
231 arrow:SetWidth(42)
232 arrow:SetTexture("Interface\\AddOns\\!Questie\\Images\\Arrow")
233 showDownArrow = false
234 end
235 local degtemp = GetDirectionToIcon(active_point);
236 if degtemp < 0 then degtemp = degtemp + 360; end
237 local angle = math.rad(degtemp)
238 local player = GetPlayerFacing() + 0.1
239 angle = angle - player
240 local perc = 1- math.abs(((math.pi - math.abs(angle)) / math.pi))
241 local gr,gg,gb = 1, 1, 1
242 local mr,mg,mb = 0.75, 0.75, 0.75
243 local br,bg,bb = 0.5, 0.5, 0.5
244 local tablee = {};
245 table.insert(tablee, gr)
246 table.insert(tablee, gg)
247 table.insert(tablee, gb)
248 table.insert(tablee, mr)
249 table.insert(tablee, mg)
250 table.insert(tablee, mb)
251 table.insert(tablee, br)
252 table.insert(tablee, bg)
253 table.insert(tablee, bb)
254 local r,g,b = ColorGradient(perc,tablee)
255 if not g then
256 g = 0;
257 end
258 arrow:SetVertexColor(1-g,-1+g*2,0)
259 cell = Questie:Modulo(floor(angle / twopi * 108 + 0.5), 108);
260 local column = Questie:Modulo(cell, 9)
261 local row = floor(cell / 9)
262 local xstart = (column * 56) / 512
263 local ystart = (row * 42) / 512
264 local xend = ((column + 1) * 56) / 512
265 local yend = ((row + 1) * 42) / 512
266 arrow:SetTexCoord(xstart,xend,ystart,yend)
267 end
268 arrowLastUpdate = GetTime()
269 end
270 end
271 if (QuestieConfig.arrowTime == true) then
272 -- Calculate the TTA every second (%01d:%02d)
273 tta_throttle = tta_throttle + elapsed
274 if tta_throttle >= 1 then
275 -- Calculate the speed in yards per sec at which we're moving
276 local current_speed = (last_distance - dist) / tta_throttle
277 if last_distance == 0 then
278 current_speed = 0
279 end
280 if speed_count < 2 then
281 speed = (speed + current_speed) / 2
282 speed_count = speed_count + 1
283 else
284 speed_count = 0
285 speed = current_speed
286 end
287 if speed > 0 then
288 local eta = math.abs(dist / speed)
289 local text = string.format("%01d:%02d", eta / 60, Questie:Modulo(eta, 60))
290 tta:SetText(text)
291 else
292 tta:SetText("***")
293 end
294 last_distance = dist
295 tta_throttle = 0
296 end
297 end
298 end
299 ---------------------------------------------------------------------------------------------------
300 function ShowHideCrazyArrow()
301 if wayframe:IsShown() then
302 wayframe:Show()
303 if true then
304 wayframe:EnableMouse(false)
305 else
306 wayframe:EnableMouse(true)
307 end
308 -- Set the scale and alpha
309 wayframe:SetScale(1)
310 wayframe:SetAlpha(1)
311 local width = 80
312 local height = 80
313 local scale = 1
314 wayframe.title:SetWidth(width)
315 wayframe.title:SetHeight(height)
316 titleframe:SetScale(scale)
317 titleframe:SetAlpha(1)
318 if true then
319 tta:Show()
320 else
321 tta:Hide()
322 end
323 else
324 wayframe:Hide()
325 end
326 end
327 ---------------------------------------------------------------------------------------------------
328 function ArrowHidden()
329 isHide = true
330 end
331 ---------------------------------------------------------------------------------------------------
332 function ArrowShown()
333 isHide = false
334 end
335 ---------------------------------------------------------------------------------------------------
336 wayframe:SetScript("OnUpdate", OnUpdate)
337 wayframe:RegisterForClicks("RightButtonUp")
338 wayframe:SetScript("OnClick", WayFrame_OnClick)
339 local function getCoords(column, row)
340 local xstart = (column * 56) / 512
341 local ystart = (row * 42) / 512
342 local xend = ((column + 1) * 56) / 512
343 local yend = ((row + 1) * 42) / 512
344 return xstart, xend, ystart, yend
345 end
346 ---------------------------------------------------------------------------------------------------
347 --this is where texcoords are extracted incorrectly (I think), leading the arrow to not point in the correct direction
348 local texcoords = setmetatable({}, {__index = function(t, k)
349 -- this was k:match("(%d+):(%d+)") - so we need string.match, but that's not in Lua 5.0
350 local fIndex, lIndex = string.find(k, "(%d+)")
351 local col = string.sub(k, fIndex, lIndex)
352 fIndex2, lIndex2 = string.find(k, ":(%d+)")
353 local row = string.sub(k, fIndex2+1, lIndex2)
354 col,row = tonumber(col), tonumber(row)
355 local obj = {getCoords(col, row)}
356 rawset(t, k, obj)
357 return obj
358 end})
359 ---------------------------------------------------------------------------------------------------
360 wayframe:RegisterEvent("ADDON_LOADED")
361 local runonce = true
362 wayframe:SetScript("OnEvent", function(self, event, arg1, ...)
363 if runonce == true then
364 local feed_crazy = CreateFrame("Frame")
365 local crazyFeedFrame = CreateFrame("Frame")
366 local throttle = 1
367 local counter = 0
368 crazyFeedFrame:SetScript("OnUpdate", function(self, elapsed)
369 elapsed = 1/GetFramerate()
370 counter = counter + elapsed
371 if counter < throttle then
372 return
373 end
374 counter = 0
375 local angle = GetDirectionToIcon(active_point)
376 local player = GetPlayerFacing()
377 if not angle or not player then
378 feed_crazy.iconCoords = texcoords["1:1"]
379 feed_crazy.iconR = 0.2
380 feed_crazy.iconG = 1.0
381 feed_crazy.iconB = 0.2
382 feed_crazy.text = "No waypoint"
383 return
384 end
385 angle = angle - player
386 local perc = math.abs((math.pi - math.abs(angle)) / math.pi)
387 local gr,gg,gb = 1, 1, 1
388 local mr,mg,mb = 0.75, 0.75, 0.75
389 local br,bg,bb = 0.5, 0.5, 0.5
390 local tablee = {};
391 table.insert(tablee, gr)
392 table.insert(tablee, gg)
393 table.insert(tablee, gb)
394 table.insert(tablee, mr)
395 table.insert(tablee, mg)
396 table.insert(tablee, mb)
397 table.insert(tablee, br)
398 table.insert(tablee, bg)
399 table.insert(tablee, bb)
400 local r,g,b = ColorGradient(perc, tablee)
401 feed_crazy.iconR = r
402 feed_crazy.iconG = g
403 feed_crazy.iconB = b
404 cell = Questie:Modulo(floor(angle / twopi * 108 + 0.5) ,108)
405 local column = Questie:Modulo(cell, 9)
406 local row = floor(cell / 9)
407 local key = column .. ":" .. row
408 feed_crazy.iconCoords = texcoords[key]
409 feed_crazy.text = point_title or "Unknown waypoint"
410 end)
411 end
412 runonce = false
413 end)
414 ---------------------------------------------------------------------------------------------------
415 -- calculations have to be redone - we are NOT actually working with Astrolabe "icons" here as TomTom did and want the arrow API
416 -- to be accessible to everyone
417 function GetDirectionToIcon( point )
418 if not point then return end
419 local C,Z,X,Y = Astrolabe:GetCurrentPlayerPosition() -- continent, zone, x, y
420 local dist, xDelta, yDelta = Astrolabe:ComputeDistance( C, Z, X, Y, point.c, point.z, point.x, point.y )
421 if not xDelta or not yDelta then return end
422 local dir = atan2(xDelta, -(yDelta))
423 if ( dir > 0 ) then
424 return twopi - dir;
425 else
426 return -dir;
427 end
428 end
429 ---------------------------------------------------------------------------------------------------
430 function GetDistanceToIcon( point )
431 local C,Z,X,Y = Astrolabe:GetCurrentPlayerPosition() -- continent, zone, x, y
432 local dist, xDelta, yDelta = Astrolabe:ComputeDistance( C, Z, X, Y, point.c, point.z, point.x, point.y )
433 return dist, xDelta, yDelta
434 end