vanilla-wow-addons – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | -- Utility functions for FlightMap |
2 | |||
3 | FlightMapUtil = {}; |
||
4 | |||
5 | ------- Data access functions |
||
6 | |||
7 | -- Break up a "Town, Zone" string into town and zone components. If |
||
8 | -- there's no comma, ie, Moonglade, the string will be returned for |
||
9 | -- both town and zone. |
||
10 | FlightMapUtil.getNameAndZone = function(taxipath) |
||
11 | local comma = string.find(taxipath, FLIGHTMAP_SEP_STRING, 1, true); |
||
12 | if (comma) then |
||
13 | local name = string.sub(taxipath, 1, comma - 1); |
||
14 | local zone = string.sub(taxipath, |
||
15 | comma + string.len(FLIGHTMAP_SEP_STRING), |
||
16 | -1 - string.len(FLIGHTMAP_SEP_POSTAMBLE)); |
||
17 | return name, zone; |
||
18 | else |
||
19 | return taxipath, taxipath; |
||
20 | end |
||
21 | end |
||
22 | |||
23 | -- Construct a node name from its continent and taxi coordinates |
||
24 | FlightMapUtil.makeNodeName = function(continent, taxiX, taxiY) |
||
25 | return string.format("%d:%d:%d", continent, taxiX * 1000, taxiY * 1000); |
||
26 | end |
||
27 | |||
28 | -- Return the flight map data appropriate to the current character |
||
29 | FlightMapUtil.getFlightMap = function() |
||
30 | -- Return default flight data for the specified faction |
||
31 | local function lGetFactionDefaults(faction) |
||
32 | if faction == FLIGHTMAP_ALLIANCE then |
||
33 | return FLIGHTMAP_ALLIANCE_FLIGHTS; |
||
34 | elseif faction == FLIGHTMAP_HORDE then |
||
35 | return FLIGHTMAP_HORDE_FLIGHTS; |
||
36 | end |
||
37 | return {}; -- Catch all |
||
38 | end |
||
39 | |||
40 | local _, faction = UnitFactionGroup("player"); |
||
41 | if not faction then return {}; end |
||
42 | if not FlightMap[faction] then |
||
43 | FlightMap[faction] = lGetFactionDefaults(faction); |
||
44 | end |
||
45 | return FlightMap[faction]; |
||
46 | end |
||
47 | |||
48 | -- Returns true if the current character has seen a given node; |
||
49 | -- if the second argument is a true value, teaches the character of |
||
50 | -- the node's existence. |
||
51 | FlightMapUtil.knownNode = function(node, learning) |
||
52 | local name = UnitName("player"); |
||
53 | local realm = GetCVar("realmName"); |
||
54 | |||
55 | -- Conglomerate key |
||
56 | local key = name .. "@" .. realm; |
||
57 | |||
58 | -- If nothing is known for this character, make it known! |
||
59 | if not FlightMap.Knowledge[key] then |
||
60 | FlightMap.Knowledge[key] = {}; |
||
61 | end |
||
62 | |||
63 | if learning then |
||
64 | FlightMap.Knowledge[key][node] = true; |
||
65 | end |
||
66 | |||
67 | return FlightMap.Knowledge[key][node]; |
||
68 | end |
||
69 | |||
70 | -- TODO: put elsewhere |
||
71 | FlightMapUtil.lZoneNameMap = {}; |
||
72 | FlightMapUtil.lContinentNameMap = {}; |
||
73 | |||
74 | local function LoadNames(map, ...) |
||
75 | for i=1, arg.n, 1 do |
||
76 | map[i] = arg[i]; |
||
77 | end |
||
78 | end |
||
79 | |||
80 | FlightMapUtil.getContinentName = function(c) |
||
81 | if not FlightMapUtil.lContinentNameMap[c] then |
||
82 | LoadNames(FlightMapUtil.lContinentNameMap, GetMapContinents()); |
||
83 | end |
||
84 | |||
85 | return FlightMapUtil.lContinentNameMap[c]; |
||
86 | end |
||
87 | |||
88 | -- Return the name of the current map zone |
||
89 | FlightMapUtil.getZoneName = function() |
||
90 | local cNum = GetCurrentMapContinent(); |
||
91 | local zNum = GetCurrentMapZone(); |
||
92 | if not FlightMapUtil.lZoneNameMap[cNum] then |
||
93 | FlightMapUtil.lZoneNameMap[cNum] = {}; |
||
94 | LoadNames(FlightMapUtil.lZoneNameMap[cNum], GetMapZones(cNum)); |
||
95 | end |
||
96 | |||
97 | return FlightMapUtil.lZoneNameMap[cNum][zNum]; |
||
98 | end |
||
99 | |||
100 | -- Returns a table of nodes in a given zone; if second optional |
||
101 | -- argument is present and true, also returns subzone nodes. |
||
102 | FlightMapUtil.getNodesInZone = function(zone, subZones) |
||
103 | local map = FlightMapUtil.getFlightMap(); |
||
104 | local nodes = {}; |
||
105 | for k, v in map do |
||
106 | if v.Zone == zone then |
||
107 | nodes[k] = v; |
||
108 | elseif subZones and FLIGHTMAP_SUBZONES[v.Zone] == zone then |
||
109 | nodes[k] = v; |
||
110 | end |
||
111 | end |
||
112 | |||
113 | return nodes; |
||
114 | end |
||
115 | |||
116 | -- Get the current continent number |
||
117 | FlightMapUtil.getContinent = function() |
||
118 | SetMapToCurrentZone(); |
||
119 | return GetCurrentMapContinent(); |
||
120 | end |
||
121 | |||
122 | ------- Format and display functions |
||
123 | |||
124 | -- Format a second amount into m:ss, returning "-:--" for zero seconds |
||
125 | -- unless the "showZero" argument is true |
||
126 | FlightMapUtil.formatTime = function(secs, showZero) |
||
127 | if secs == 0 and not showZero then return "-:--"; end |
||
128 | |||
129 | return string.format("%d:%02d", secs / 60, math.mod(secs, 60)); |
||
130 | end |
||
131 | |||
132 | -- Format a copper amount into a gold, silver, copper string |
||
133 | FlightMapUtil.formatMoney = function(amount) |
||
134 | local FORMAT_GOLD = "|cffddbb00%d%s|r"; |
||
135 | local FORMAT_SILVER = "|cffcccccc%d%s|r"; |
||
136 | local FORMAT_COPPER = "|cffcc9010%d%s|r"; |
||
137 | |||
138 | local copper = math.mod(amount, 100); |
||
139 | local silver = math.mod(math.floor(amount/100), 100); |
||
140 | local gold = math.floor(amount/10000); |
||
141 | |||
142 | local result = ""; |
||
143 | local pad = ""; |
||
144 | |||
145 | -- Only show gold and silver if they are non-zero |
||
146 | if gold > 0 then |
||
147 | local s = string.format(FORMAT_GOLD, gold, FLIGHTMAP_MONEY_GOLD); |
||
148 | result = result .. s; |
||
149 | pad = " "; |
||
150 | end |
||
151 | if silver > 0 then |
||
152 | local s = string.format(FORMAT_SILVER, silver, FLIGHTMAP_MONEY_SILVER); |
||
153 | result = result .. pad .. s; |
||
154 | pad = " "; |
||
155 | end |
||
156 | |||
157 | -- But show copper anyway if there's neither gold nor silver.. |
||
158 | if (gold == 0 and silver == 0) or copper > 0 then |
||
159 | local s = string.format(FORMAT_COPPER, copper, FLIGHTMAP_MONEY_COPPER); |
||
160 | result = result .. pad .. s; |
||
161 | end |
||
162 | |||
163 | return result; |
||
164 | end |
||
165 | |||
166 | -- Draw a line by stretching the texture widget given in texture |
||
167 | -- across the parent frame given in parent. The coordinates |
||
168 | -- should be expressed as a number between 0 and 1, representing |
||
169 | -- the homogenized space of the parent. (0, 0) is the lower left |
||
170 | -- corner. |
||
171 | FlightMapUtil.drawLine = function(parent, texture, x1, y1, x2, y2) |
||
172 | texture:ClearAllPoints(); |
||
173 | |||
174 | -- Get the line deltas in pixels |
||
175 | local dx = abs((x1 - x2) * parent:GetWidth()); |
||
176 | local dy = abs((y1 - y2) * parent:GetHeight()); |
||
177 | |||
178 | -- Seven possible cases: |
||
179 | -- 1) Horizontal line (dy = 0) |
||
180 | -- 2) Vertical line (dx = 0) |
||
181 | -- 3) source is ABOVE and RIGHT of dest |
||
182 | -- 4) source is BELOW and RIGHT of dest |
||
183 | -- 5) source is ABOVE and LEFT of dest |
||
184 | -- 6) source is BELOW and LEFT of dest |
||
185 | -- 7) Source and destination are equal |
||
186 | |||
187 | -- Equal points is the easiest case. |
||
188 | if dx == 0 and dy == 0 then |
||
189 | texture:Hide(); |
||
190 | return false; |
||
191 | end |
||
192 | |||
193 | -- The remaining cases can be reduced to four by swapping the |
||
194 | -- source and destination points to ensure the source point is |
||
195 | -- always to the left of the destination point: |
||
196 | if x1 > x2 then |
||
197 | local tmpX = x1; |
||
198 | local tmpY = y1; |
||
199 | x1 = x2; x2 = tmpX; |
||
200 | y1 = y2; y2 = tmpY; |
||
201 | end |
||
202 | |||
203 | -- And then further reduced to two by making sure no lines really |
||
204 | -- are horizontal or vertical |
||
205 | if dy < 1 then dy = 1; end |
||
206 | if dx < 1 then dx = 1; end |
||
207 | |||
208 | -- Clip the texture if either delta is smaller than the base size |
||
209 | -- This prevents the texture from being scaled down, which could result |
||
210 | -- in parts of the line vanishing during interpolation. |
||
211 | local clipsize = dx; |
||
212 | if dy < dx then clipsize = dy; end |
||
213 | |||
214 | -- Now normalize the clipping size to 0-1 |
||
215 | clipsize = clipsize / FLIGHTMAP_LINE_SIZE; |
||
216 | if clipsize > 1 then clipsize = 1; end |
||
217 | |||
218 | local anchorPoint = "NONE"; |
||
219 | if y1 > y2 then -- Case 1: source ABOVE dest |
||
220 | -- Set correct texture |
||
221 | texture:SetTexture(FLIGHTMAP_TEX_UP); |
||
222 | -- Use the bottom left corner of it |
||
223 | texture:SetTexCoord(0, clipsize, 1 - clipsize, 1); |
||
224 | -- Place the bottom left corner |
||
225 | anchorPoint = "BOTTOMLEFT"; |
||
226 | else -- Case 2: source BELOW dest |
||
227 | -- Set correct texture |
||
228 | texture:SetTexture(FLIGHTMAP_TEX_DOWN); |
||
229 | -- Use the top left corner of it |
||
230 | texture:SetTexCoord(0, clipsize, 0, clipsize); |
||
231 | -- Place the top left corner |
||
232 | anchorPoint = "TOPLEFT"; |
||
233 | end |
||
234 | |||
235 | -- Set the origin, using whichever anchor point is appropriate |
||
236 | texture:SetPoint(anchorPoint, parent, "TOPLEFT", |
||
237 | x1 * parent:GetWidth(), |
||
238 | -y1 * parent:GetHeight()); |
||
239 | |||
240 | -- Set the texture's width and height |
||
241 | texture:SetWidth(dx); |
||
242 | texture:SetHeight(dy); |
||
243 | |||
244 | -- Show the texture |
||
245 | texture:Show(); |
||
246 | |||
247 | -- Success :) |
||
248 | return true; |
||
249 | end |