List of commits:
Subject Hash Author Date (UTC)
feat!: Redo the core functionality 085af1bc403b3a9d2d4b99ec460d67889239fabd Vladyslav Bondarenko 2021-07-09 11:15:31
feat: Track additional auras 958e52f9808d64ebb816663d2aa22a4eb39a2068 Vladyslav Bondarenko 2021-01-22 20:28:13
fix!: No longer crash on unknown spell 65061085f0f55b75910c9ed4d8249b1e8e30f9ee Vladyslav Bondarenko 2020-12-11 17:31:16
fix: Render indicators properly on first login bf102cc749cc23d3769a82f10fe93a05afc5277f Vladyslav Bondarenko 2020-12-11 14:25:11
feat: Add Serendipity and Surge of Light indicators ba1d0f32a4b8f4f5d4e2730f0a4e409e23b52974 Vladyslav Bondarenko 2020-12-10 16:19:55
Initial commit 9b3df418e373218125fec12271084afebb11cfc2 Vladyslav Bondarenko 2020-12-04 10:27:24
Commit 085af1bc403b3a9d2d4b99ec460d67889239fabd - feat!: Redo the core functionality
Re-create the basic funcionality of spell activation overlay
from scratch. This new implementation is hopefully more efficient.

Remove the dependency on a complex build tool that is Gradle.

Remove internal reliance on heuristics in code.
Author: Vladyslav Bondarenko
Author date (UTC): 2021-07-09 11:15
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2021-07-09 11:15
Parent(s): 958e52f9808d64ebb816663d2aa22a4eb39a2068
Signing key:
Tree: 76c58c24d04b44954265f915493a1f2aa9d84be5
File Lines added Lines deleted
.luacheckrc 18 14
build.gradle 0 69
clearcasting.lua 544 0
clearcasting.toc 1 1
gradle.properties 0 1
share/Interface/FrameXML/UI.xsd 0 1414
src/ClearcastingFrame.lua 0 467
File .luacheckrc renamed from conf/luacheckrc.lua (similarity 78%) (mode: 100644) (index 600f4b1..c9be551)
1 1 -- http://luacheck.readthedocs.io/en/stable/config.html -- http://luacheck.readthedocs.io/en/stable/config.html
2 2 stds.wow = { stds.wow = {
3 globals = {
4 "SlashCmdList",
5 }, -- these globals can be set and accessed.
3 globals = {}, -- these globals can be set and accessed.
6 4 read_globals = { read_globals = {
7 5 "CreateFrame", "CreateFrame",
8 "DismissCompanion",
9 "DoEmote",
6 "DEFAULT_CHAT_FRAME",
10 7 "GameFontNormal", "GameFontNormal",
11 8 "GameMenuFrame", "GameMenuFrame",
12 9 "GetBinding", "GetBinding",
13 "GetCompanionInfo",
10 "GetChatWindowInfo",
14 11 "GetContainerItemID", "GetContainerItemID",
15 12 "GetContainerItemInfo", "GetContainerItemInfo",
16 13 "GetContainerNumSlots", "GetContainerNumSlots",
 
... ... stds.wow = {
24 21 "GetMacroInfo", "GetMacroInfo",
25 22 "GetMoney", "GetMoney",
26 23 "GetNumBindings", "GetNumBindings",
27 "GetNumCompanions",
28 24 "GetNumLootItems", "GetNumLootItems",
29 25 "GetNumPartyMembers", "GetNumPartyMembers",
30 26 "GetNumRaidMembers", "GetNumRaidMembers",
31 27 "GetNumTalentTabs", "GetNumTalentTabs",
32 28 "GetNumTalents", "GetNumTalents",
33 29 "GetPartyMember", "GetPartyMember",
30 "GetPrimaryTalentTree",
34 31 "GetRealmName", "GetRealmName",
35 "GetSPellLink",
36 32 "GetSpellCooldown", "GetSpellCooldown",
37 33 "GetSpellInfo", "GetSpellInfo",
38 34 "GetSpellLink", "GetSpellLink",
35 "GetSpellName",
39 36 "GetSpellTexture", "GetSpellTexture",
40 37 "GetSubZoneText", "GetSubZoneText",
41 38 "GetTalentInfo", "GetTalentInfo",
42 39 "GetTime", "GetTime",
43 "GetUnitName",
44 40 "GetZoneText", "GetZoneText",
45 41 "HideUIPanel", "HideUIPanel",
46 42 "IsSpellInRange", "IsSpellInRange",
47 "IsUsableSpell",
48 43 "LootSlotIsCoin", "LootSlotIsCoin",
49 44 "LootSlotIsItem", "LootSlotIsItem",
50 45 "MainMenuBar", "MainMenuBar",
51 46 "MerchantFrame", "MerchantFrame",
47 "NUM_CHAT_WINDOWS",
48 "NumberFont_Outline_Large",
52 49 "OpenAllBags", "OpenAllBags",
50 "PaladinPowerBar",
51 "PaladinPowerBarBG",
53 52 "QuestLogFrame", "QuestLogFrame",
54 "SendAddonMessage",
53 "SPELL_POWER_HOLY_POWER",
54 "SendChatMessage",
55 "SetCVar",
55 56 "ShowUIPanel", "ShowUIPanel",
56 57 "StaticPopup_Show", "StaticPopup_Show",
57 58 "ToggleAchievementFrame", "ToggleAchievementFrame",
 
... ... stds.wow = {
64 65 "ToggleSpellBook", "ToggleSpellBook",
65 66 "ToggleTalentFrame", "ToggleTalentFrame",
66 67 "UIParent", "UIParent",
68 "UnitAffectingCombat",
67 69 "UnitAura", "UnitAura",
70 "UnitBuff",
68 71 "UnitClass", "UnitClass",
69 "UnitExists",
70 72 "UnitFactionGroup", "UnitFactionGroup",
71 73 "UnitIsDead", "UnitIsDead",
72 "UnitIsPlayer",
73 74 "UnitName", "UnitName",
74 75 "UnitPlayerControlled", "UnitPlayerControlled",
76 "UnitPower",
77 "UnitSetRole",
78 "UnitIsEnemy",
75 79 "date", "date",
76 80 "difftime", "difftime",
77 81 "geterrorhandler", "geterrorhandler",
 
... ... stds.wow = {
79 83 "hooksecurefunc", "hooksecurefunc",
80 84 "strtrim", "strtrim",
81 85 "time", "time",
86 "ChatFrame1",
82 87 } -- these globals can only be accessed. } -- these globals can only be accessed.
83 88 } }
84 89
 
... ... stds.clearcasting = {
86 91 globals = { globals = {
87 92 }, },
88 93 read_globals = { read_globals = {
89 "ClearcastingFont",
90 94 } }
91 95 } }
92 96
File build.gradle deleted (index c9dc87c..0000000)
1 plugins {
2 id 'base'
3 }
4
5 /*
6 * Project version must be duplicated in the add-ons table-of-contents file (*.toc).
7 * No template manager or annotation parser is used for this purpose.
8 * That way, a ToC file with a placeholder for version that remains
9 * unprocessed will never be packaged and distributed.
10 */
11 /*version = '2.0.0wip'*/
12
13 tasks.create('ldoc', Exec) {
14 executable 'ldoc'
15 args "--dir=${projectDir}/doc/", "${projectDir}/src/"
16 }
17
18 tasks.create('luacheck', Exec) {
19 executable 'luacheck'
20 args "--config ${projectDir}/conf/luacheckrc.lua", "${projectDir}/src/"
21 }
22
23 tasks.create('xmllint', Exec) {
24 commandLine "xmllint", "--noout", "--schema", "${projectDir}/share/Interface/FrameXML/UI.xsd", "${projectDir}/${project.name}.xml"
25 }
26
27 /*
28 * The game client imposes a restriction on the add-on directory name.
29 * Specifically, only letters are allowed and no numbers or special characters.
30 * Therefore, version number is not included in the packaged add-on directory's name.
31 * However, the version number is still included in the distributed archive name.
32 */
33 tasks.create('distZip', Zip) {
34 from("$projectDir") {
35 include "${project.name}.toc"
36 include "${project.name}.xml"
37 include 'README.md'
38 include 'bindings.xml'
39 include 'build.gradle'
40 include 'gradle.properties'
41
42 into("${project.name}")
43 }
44
45 from("$projectDir/conf/") {
46 include 'luacheckrc.lua'
47
48 into("${project.name}/conf/")
49 }
50
51 from("$projectDir/src/") {
52 include '**/*.lua'
53
54 into("${project.name}/src/")
55 }
56
57 from("$projectDir/doc/") {
58 into("${project.name}/doc/")
59 }
60
61 from("$projectDir/share/") {
62 into("${project.name}/share/")
63 }
64 }
65
66 distZip.dependsOn(ldoc)
67 check.dependsOn(luacheck)
68 check.dependsOn(xmllint)
69 assemble.dependsOn(distZip)
File clearcasting.lua added (mode: 100644) (index 0000000..7c3e186)
1 --[[--
2 Clearcasting addon.
3
4 @script clearcasting
5 ]]
6
7 local function debug(...)
8 if true == ClearcastingDebugFlag then
9 print('[Clearcasting]: ', ...)
10 end
11 end
12
13 local function getAuraId(spellName, spellCategory)
14 local spellLink = GetSpellLink(spellName, spellCategory)
15 if spellLink then
16 return tonumber(spellLink:match("spell:(%d+)"))
17 else
18 return nil
19 end
20 end
21
22 local function updateEveryIndicator(rootFrame)
23 local t = rootFrame.indicatorTable
24 local i = #t
25 while (i > 0) do
26 local f = t[i]
27 assert (f ~= nil)
28 local auraId = f.auraId
29 local auraName = f.auraName
30 if auraId ~= nil then
31 assert (auraId >= 1)
32 local unitDesignation = f.unitDesignation
33 local remainingSecs, duration, stackQuantity = getUnitAuraRemainingSecs(unitDesignation, auraId)
34 if remainingSecs > 0 then
35 f:Show()
36 local t = ''
37 if stackQuantity > 1 then
38 t = string.format("%.0f\r\n%d*", remainingSecs, stackQuantity)
39 else
40 t = string.format("%.0f", remainingSecs)
41 end
42 f.text:SetText(t)
43 local r = remainingSecs / duration
44 local bleed = math.min(1.5 * r, 1)
45 f.background:SetVertexColor(1, bleed, bleed)
46 else
47 f:Hide()
48 f.text:SetText(nil)
49 end
50 end
51 i = i - 1
52 end
53 end
54
55 --[[--
56 Use unique aura identifier when possible.
57 Otherwise use aura name. Function may fail when given spell name.
58 An aura is either a spell in character spell book or talent effect.
59 Given unique identifier of a currently unavailable ability
60 the function produces an error.
61 ]]
62 local function isSpellAvailable(eitherSpellIdOrName)
63 local n = GetSpellInfo(eitherSpellIdOrName)
64 return n ~= nil
65 end
66
67 local function findFirstFilterName(unitDesignation, filterDescriptor, eitherTargetNameOrId)
68 assert (unitDesignation ~= nil)
69 assert ('string' == type(unitDesignation))
70 assert (string.len(unitDesignation) >= 4)
71 assert (string.len(unitDesignation) <= 32)
72
73 assert (filterDescriptor ~= nil)
74 assert ('string' == type(filterDescriptor))
75 assert (string.len(filterDescriptor) >= 4)
76 assert (string.len(filterDescriptor) <= 64)
77
78 assert (eitherTargetNameOrId ~= nil)
79 if 'string' == type(eitherTargetNameOrId) then
80 local targetName = eitherTargetNameOrId
81 assert (targetName ~= nil)
82 assert ('string' == type(targetName))
83 assert (string.len(targetName) >= 4)
84 assert (string.len(targetName) <= 256)
85 elseif 'number' == type(eitherTargetNameOrId) then
86 local targetId = eitherTargetNameOrId
87 assert (targetId ~= nil)
88 assert ('string' == type(targetId))
89 assert (targetId > 0)
90 else
91 return nil
92 --[[error('illegal argument')]]--
93 end
94
95 local i = 0
96 while (i < 64) do
97 i = i + 1
98 local name, rank, pictureFile, stackQuantity, category,
99 duration, expirationInstance,
100 caster, stealableFlag, consolidateFlag, id = UnitAura(unitDesignation, i, filterDescriptor)
101 if not name then
102 break
103 end
104 if eitherTargetNameOrId == name or eitherTargetNameOrId == id then
105 return name, rank, pictureFile, stackQuantity, category,
106 duration, expirationInstance,
107 caster, stealableFlag, consolidateFlag, id
108 end
109 end
110
111 return nil
112 end
113
114 local function findFirstFilterCategory(unitDesignation, filterDescriptor, targetCategory)
115 assert (unitDesignation ~= nil)
116 assert ('string' == type(unitDesignation))
117 assert (string.len(unitDesignation) >= 4)
118 assert (string.len(unitDesignation) <= 32)
119
120 assert (filterDescriptor ~= nil)
121 assert ('string' == type(filterDescriptor))
122 assert (string.len(filterDescriptor) >= 4)
123 assert (string.len(filterDescriptor) <= 64)
124
125 assert (targetCategory ~= nil)
126 if 'string' == type(targetCategory) then
127 assert (string.len(targetCategory) >= 4)
128 assert (string.len(targetCategory) <= 64)
129 else
130 return nil
131 --[[error('illegal argument')]]--
132 end
133
134 local i = 0
135 while (i < 64) do
136 i = i + 1
137 local name, rank, pictureFile, stackQuantity, category,
138 duration, expirationInstance,
139 caster, stealableFlag, consolidateFlag, id = UnitAura(unitDesignation, i, filterDescriptor)
140 if not name then
141 break
142 end
143 if targetCategory == category then
144 return name, rank, pictureFile, stackQuantity, category,
145 duration, expirationInstance,
146 caster, stealableFlag, consolidateFlag, id
147 end
148 end
149
150 return nil
151 end
152
153 local function findAnyFilterName(unitDesignation, filterDescriptor, targetSet)
154 assert (unitDesignation ~= nil)
155 assert ('string' == type(unitDesignation))
156 assert (string.len(unitDesignation) >= 4)
157 assert (string.len(unitDesignation) <= 32)
158
159 assert (filterDescriptor ~= nil)
160 assert ('string' == type(filterDescriptor))
161 assert (string.len(filterDescriptor) >= 4)
162 assert (string.len(filterDescriptor) <= 64)
163
164 if 'table' == type(targetSet) then
165 assert (targetSet ~= nil)
166 assert (#targetSet >= 1)
167 else
168 return nil
169 end
170
171 local i = 0
172 debug('#begin findAny')
173 while (i < 64) do
174 i = i + 1
175 local name, rank, pictureFile, stackQuantity, category,
176 duration, expirationInstance,
177 caster, stealableFlag, consolidateFlag, id = UnitAura(unitDesignation, i, filterDescriptor)
178 local j = 0
179 while (j < #targetSet) do
180 j = j + 1
181 local eitherTargetNameOrId = targetSet[j]
182 debug('expected: ', eitherTargetNameOrId, ', actual: ', name)
183 if eitherTargetNameOrId == name or eitherTargetNameOrId == id then
184 debug('return ', name)
185 return name, rank, pictureFile, stackQuantity, category,
186 duration, expirationInstance,
187 caster, stealableFlag, consolidateFlag, id
188 end
189 end
190 end
191 debug('-end findAny')
192
193 return nil
194 end
195
196 local function findAnyHarmful(unitDesignation, filterDescriptor, targetCategory)
197 assert (unitDesignation ~= nil)
198 assert ('string' == type(unitDesignation))
199 assert (string.len(unitDesignation) >= 4)
200 assert (string.len(unitDesignation) <= 32)
201
202 assert (filterDescriptor ~= nil)
203 assert ('string' == type(filterDescriptor))
204 assert (string.len(filterDescriptor) >= 4)
205 assert (string.len(filterDescriptor) <= 64)
206
207 assert (targetCategory ~= nil)
208 if 'string' == type(targetCategory) then
209 assert (string.len(targetCategory) >= 4)
210 assert (string.len(targetCategory) <= 64)
211 if 'HARMFUL' ~= targetCategory then
212 return nil
213 end
214 else
215 return nil
216 --[[error('illegal argument')]]--
217 end
218
219
220 local i = 0
221 while (i < 64) do
222 i = i + 1
223 local name, rank, pictureFile, stackQuantity, category,
224 duration, expirationInstance,
225 caster, stealableFlag, consolidateFlag, id = UnitAura(unitDesignation, i, filterDescriptor)
226 if name and nil == category then
227 return name, rank, pictureFile, stackQuantity, category,
228 duration, expirationInstance,
229 caster, stealableFlag, consolidateFlag, id
230 end
231 end
232
233 return nil
234 end
235
236 local function applyBackground(f, pictureFile)
237 assert (f ~= nil)
238
239 f:SetBackdrop({bgFile = pictureFile,
240 edgeFile = "Interface\\AddOns\\clearcasting\\share\\2px_tooltip_border",
241 tile = false, tileSize = 24, edgeSize = 8,
242 insets = { left = 2, right = 2, top = 2, bottom = 2 }})
243
244 --f:SetBackdropColor(0.5, 0.5, 0.5, 0.5)
245 end
246
247 local function applyBorder(f, category, caster)
248 local r, g, b, a
249 if 'Magic' == category then
250 r = 0 / 255
251 g = 153 / 255
252 b = 255 / 255
253 a = 255 / 255
254 elseif 'Disease' == category then
255 r = 204 / 255
256 g = 255 / 255
257 b = 0 / 255
258 a = 255 / 255
259 elseif 'Curse' == category then
260 r = 255 / 255
261 g = 51 / 255
262 b = 255 / 255
263 a = 255 / 255
264 elseif 'Poison' == category then
265 r = 0 / 255
266 g = 204 / 255
267 b = 51 / 255
268 a = 255 / 255
269 elseif 'player' == caster then
270 r = 255 / 255
271 g = 255 / 255
272 b = 255 / 255
273 a = 255 / 255
274 else
275 r = 255 / 255
276 g = 51 / 255
277 b = 0 / 255
278 a = 255 / 255
279 end
280 f:SetBackdropBorderColor(r, g, b, a)
281 end
282
283 local function formatIndicatorText(duration, expirationInstance, stackQuantity)
284 local now = GetTime()
285 duration = duration or 0
286 expirationInstance = expirationInstance or now
287 local remainingDurationSec = expirationInstance - now
288
289 local t
290 if remainingDurationSec <= 0 or remainingDurationSec >= 60 or 0 == duration then
291 t = nil
292 else
293 t = string.format("%.0f", remainingDurationSec)
294
295 stackQuantity = stackQuantity or 0
296 if stackQuantity >= 2 and stackQuantity <= 9 then
297 t = t .. ', ' .. tostring(math.ceil(stackQuantity))
298 end
299 end
300
301 return t
302 end
303
304 local function applyDuration(f, duration, expirationInstance, stackQuantity)
305 assert (f ~= nil)
306
307 local now = GetTime()
308 duration = duration or 0
309 expirationInstance = expirationInstance or now
310
311 local t = formatIndicatorText(duration, expirationInstance, stackQuantity)
312
313 local textHandle = f.text
314 textHandle:SetText(t)
315 f:Show()
316 f.expirationInstance = expirationInstance
317 f.duration = duration
318 f.stackQuantity = stackQuantity
319 end
320
321 local function applyIndicatorUpdate(f)
322 applyDuration(f, f.duration, f.expirationInstance, f.stackQuantity)
323 end
324
325 local function indicatorUpdateProcessor(rootFrame, elapsedSecs)
326 assert (rootFrame ~= nil)
327 assert (elapsedSecs ~= nil)
328 assert (type(elapsedSecs) == 'number')
329 elapsedSecs = math.min(math.max(0, elapsedSecs), 999)
330
331 local duration = rootFrame.elapsedSecs
332 if duration == nil then
333 duration = 0.0
334 elseif type(duration) ~= 'number' then
335 duration = 0.0
336 end
337 duration = math.min(math.max(0, duration + elapsedSecs), 999)
338 rootFrame.elapsedSecs = duration
339 if duration >= 0.08 then
340 applyIndicatorUpdate(rootFrame)
341 rootFrame.elapsedSecs = 0.0
342 end
343 end
344
345 local function attemptToApply(f, name, rank, pictureFile, stackQuantity, category,
346 duration, expirationInstance,
347 caster, stealableFlag, consolidateFlag, id)
348 assert (f ~= nil)
349
350 if not name then
351 f:Hide()
352 f:SetScript('OnUpdate', nil)
353 return
354 end
355
356 applyBackground(f, pictureFile)
357 applyBorder(f, category, caster)
358 applyDuration(f, duration, expirationInstance, stackQuantity)
359 f:Show()
360 f:SetScript('OnUpdate', indicatorUpdateProcessor)
361 end
362
363 local function indicatorEventProcessor(f)
364 assert (f ~= nil)
365
366 local unitDesignation = f.unit or 'player'
367 assert (unitDesignation ~= nil)
368 assert ('string' == type(unitDesignation))
369 assert (string.len(unitDesignation) >= 4)
370 assert (string.len(unitDesignation) <= 32)
371
372 local filterDescriptor = f.filter or 'HELPFUL'
373 assert (filterDescriptor ~= nil)
374 assert ('string' == type(filterDescriptor))
375 assert (string.len(filterDescriptor) >= 4)
376 assert (string.len(filterDescriptor) <= 64)
377
378 local target = f.spell
379 assert (target ~= nil)
380
381 local name, rank, pictureFile, stackQuantity, category,
382 duration, expirationInstance,
383 caster, stealableFlag, consolidateFlag, id
384
385 name, rank, pictureFile, stackQuantity, category,
386 duration, expirationInstance,
387 caster, stealableFlag, consolidateFlag, id = findFirstFilterName(unitDesignation, filterDescriptor, target)
388
389 if not name then
390 name, rank, pictureFile, stackQuantity, category,
391 duration, expirationInstance,
392 caster, stealableFlag, consolidateFlag, id = findFirstFilterCategory(unitDesignation, filterDescriptor, target)
393 end
394
395 if not name then
396 name, rank, pictureFile, stackQuantity, category,
397 duration, expirationInstance,
398 caster, stealableFlag, consolidateFlag, id = findAnyFilterName(unitDesignation, filterDescriptor, target)
399 end
400
401 if not name then
402 name, rank, pictureFile, stackQuantity, category,
403 duration, expirationInstance,
404 caster, stealableFlag, consolidateFlag, id = findAnyHarmful(unitDesignation, filterDescriptor, target)
405 end
406
407 attemptToApply(f, name, rank, pictureFile, stackQuantity, category,
408 duration, expirationInstance,
409 caster, stealableFlag, consolidateFlag, id)
410 end
411
412 local function createIndicator(parentFrame, target, unitDesignation, filterDescriptor)
413 assert (parentFrame ~= nil)
414
415 assert (target ~= nil)
416
417 local maxColumnQuantity = 4
418 local maxRowQuantity = 6
419
420 local p = parentFrame:GetName() or 'Clearcasting'
421 local siblingSet = {parentFrame:GetChildren()}
422 local siblingQuantity = #siblingSet or 0
423 assert (siblingQuantity >= 0)
424 assert (siblingQuantity <= maxRowQuantity * maxColumnQuantity)
425 local i = siblingQuantity + 1
426 local n = p .. 'SpellActivationOverlay' .. tostring(i)
427
428 local f = CreateFrame('FRAME', n, parentFrame)
429 local size = 24
430 local padding = 4
431 local paddedSize = size + padding
432 local y = math.floor(siblingQuantity / maxColumnQuantity)
433 local x = siblingQuantity - (maxColumnQuantity * y)
434 f:SetSize(size, size)
435 f:SetPoint('BOTTOMLEFT', x * paddedSize, y * paddedSize)
436
437 local t = f:CreateFontString(n .. 'Text', 'OVERLAY')
438 local fontObject = NumberFont_Outline_Large
439 assert (fontObject ~= nil)
440 t:SetFontObject(fontObject)
441 t:SetAllPoints()
442 t:SetText('?')
443 f.text = t
444
445 local a = f:CreateTexture(n .. 'Background', 'ARTWORK')
446 a:SetAllPoints()
447 f.background = a
448
449 f.filter = string.upper(filterDescriptor or 'HELPFUL')
450 f.spell = target
451 f:SetScript('OnEvent', indicatorEventProcessor)
452 f:SetScript('OnUpdate', indicatorUpdateProcessor)
453 f:RegisterEvent('UNIT_AURA')
454 f:RegisterEvent('PLAYER_ENTERING_WORLD')
455
456 return f
457 end
458
459 local function initSpellActivationOverlay(rootFrame)
460 local presenceSet = {
461 'Concentration Aura',
462 'Crusader Aura',
463 'Devotion Aura',
464 'Fire Resistance Aura',
465 'Frost Resistance Aura',
466 'Retribution Aura',
467 'Shadow Resistance Aura',
468 }
469 createIndicator(rootFrame, presenceSet, 'player', 'PLAYER HELPFUL')
470
471 local sealSet = {
472 'Seal of Command',
473 'Seal of Corruption',
474 'Seal of Light',
475 'Seal of Righetousness',
476 'Seal of Vengeance',
477 'Seal of Wisdom',
478 }
479 createIndicator(rootFrame, sealSet, 'player', 'PLAYER HELPFUL')
480
481 local blessingSet = {
482 'Blessing of Kings',
483 'Blessing of Might',
484 'Blessing of Sanctuary',
485 'Blessing of Wisdom',
486 'Greater Blessing of Kings',
487 'Greater Blessing of Might',
488 'Greater Blessing of Sanctuary',
489 'Greater Blessing of Wisdom',
490 }
491 createIndicator(rootFrame, blessingSet, 'player', 'PLAYER HELPFUL')
492
493 createIndicator(rootFrame, 'Divine Shield')
494 createIndicator(rootFrame, 'Divine Protection')
495 createIndicator(rootFrame, 'Hand of Protection')
496 createIndicator(rootFrame, 'Avenging Wrath')
497 createIndicator(rootFrame, 'Divine Favor')
498 createIndicator(rootFrame, 'Divine Plea')
499 createIndicator(rootFrame, 'Divine Illumination')
500 createIndicator(rootFrame, 'Light\'s Grace')
501 createIndicator(rootFrame, 'Hand of Freedom')
502
503 local margin = rootFrame:GetWidth() / 2 - 28 * 5 / 2
504 local d0 = createIndicator(rootFrame, 'Magic', 'player', 'HARMFUL')
505 d0:SetPoint('BOTTOMLEFT', margin + 28 * 0, 64)
506 local d1 = createIndicator(rootFrame, 'Poison', 'player', 'HARMFUL')
507 d1:SetPoint('BOTTOMLEFT', margin + 28 * 1, 64)
508 local d2 = createIndicator(rootFrame, 'Disease', 'player', 'HARMFUL')
509 d2:SetPoint('BOTTOMLEFT', margin + 28 * 2, 64)
510 local d3 = createIndicator(rootFrame, 'Curse', 'player', 'HARMFUL')
511 d3:SetPoint('BOTTOMLEFT', margin + 28 * 3, 64)
512 local d4 = createIndicator(rootFrame, 'HARMFUL', 'player', 'HARMFUL')
513 d4:SetPoint('BOTTOMLEFT', margin + 28 * 4, 64)
514
515 return {rootFrame:GetChildren()}
516 end
517
518 local function init(rootFrame)
519 rootFrame:UnregisterAllEvents()
520
521 local t = initSpellActivationOverlay(rootFrame)
522 assert (t ~= nil)
523 assert (#t >= 1)
524
525
526 --rootFrame:SetScript('OnEvent', eventProcessor)
527
528 rootFrame.elapsedSecs = 0.0
529 --rootFrame:SetScript('OnUpdate', updateProcessor)
530
531 --rootFrame:RegisterEvent('UNIT_AURA')
532 --rootFrame:RegisterEvent('SPELLS_CHANGED')
533 end
534
535 local function main()
536 assert ('enGB' == GetLocale() or 'enUS' == GetLocale())
537 local rootFrame = CreateFrame('FRAME', 'ClearcastingFrame', UIParent)
538 rootFrame:SetSize(384, 288)
539 rootFrame:SetPoint('CENTER', UIParent, 'CENTER', 0, 0)
540
541 rootFrame:SetScript('OnEvent', init)
542 rootFrame:RegisterEvent('VARIABLES_LOADED')
543 end
544 main()
File clearcasting.toc changed (mode: 100644) (index 6d4f9fb..e6fc22e)
4 4 ##Version: 0.0.1-SNAPSHOT ##Version: 0.0.1-SNAPSHOT
5 5 ##SavedVariablesPerCharacter: ClearcastingDebugFlag ##SavedVariablesPerCharacter: ClearcastingDebugFlag
6 6 clearcasting.xml clearcasting.xml
7 src\ClearcastingFrame.lua
7 clearcasting.lua
File gradle.properties deleted (index b00d4f1..0000000)
1 version=0.0.4-SNAPSHOT
File share/Interface/FrameXML/UI.xsd deleted (index 0cb09fc..0000000)
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!-- edited with XMLSpy v2005 sp2 U (http://www.altova.com) by Sam Lantinga (Blizzard Entertainment) -->
3 <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.blizzard.com/wow/ui/" xmlns:ui="http://www.blizzard.com/wow/ui/" targetNamespace="http://www.blizzard.com/wow/ui/" elementFormDefault="qualified" attributeFormDefault="unqualified">
4 <xs:simpleType name="FRAMEPOINT">
5 <xs:restriction base="xs:NMTOKEN">
6 <xs:enumeration value="TOPLEFT"/>
7 <xs:enumeration value="TOPRIGHT"/>
8 <xs:enumeration value="BOTTOMLEFT"/>
9 <xs:enumeration value="BOTTOMRIGHT"/>
10 <xs:enumeration value="TOP"/>
11 <xs:enumeration value="BOTTOM"/>
12 <xs:enumeration value="LEFT"/>
13 <xs:enumeration value="RIGHT"/>
14 <xs:enumeration value="CENTER"/>
15 </xs:restriction>
16 </xs:simpleType>
17
18 <xs:simpleType name="FRAMESTRATA">
19 <xs:restriction base="xs:NMTOKEN">
20 <xs:enumeration value="PARENT"/>
21 <xs:enumeration value="BACKGROUND"/>
22 <xs:enumeration value="LOW"/>
23 <xs:enumeration value="MEDIUM"/>
24 <xs:enumeration value="HIGH"/>
25 <xs:enumeration value="DIALOG"/>
26 <xs:enumeration value="FULLSCREEN"/>
27 <xs:enumeration value="FULLSCREEN_DIALOG"/>
28 <xs:enumeration value="TOOLTIP"/>
29 </xs:restriction>
30 </xs:simpleType>
31
32 <xs:simpleType name="DRAWLAYER">
33 <xs:restriction base="xs:NMTOKEN">
34 <xs:enumeration value="BACKGROUND"/>
35 <xs:enumeration value="BORDER"/>
36 <xs:enumeration value="ARTWORK"/>
37 <xs:enumeration value="OVERLAY"/>
38 <xs:enumeration value="HIGHLIGHT"/>
39 </xs:restriction>
40 </xs:simpleType>
41
42 <xs:simpleType name="ALPHAMODE">
43 <xs:restriction base="xs:NMTOKEN">
44 <xs:enumeration value="DISABLE"/>
45 <xs:enumeration value="BLEND"/>
46 <xs:enumeration value="ALPHAKEY"/>
47 <xs:enumeration value="ADD"/>
48 <xs:enumeration value="MOD"/>
49 </xs:restriction>
50 </xs:simpleType>
51
52 <xs:simpleType name="OUTLINETYPE">
53 <xs:restriction base="xs:NMTOKEN">
54 <xs:enumeration value="NONE"/>
55 <xs:enumeration value="NORMAL"/>
56 <xs:enumeration value="THICK"/>
57 </xs:restriction>
58 </xs:simpleType>
59
60 <xs:simpleType name="JUSTIFYVTYPE">
61 <xs:restriction base="xs:NMTOKEN">
62 <xs:enumeration value="TOP"/>
63 <xs:enumeration value="MIDDLE"/>
64 <xs:enumeration value="BOTTOM"/>
65 </xs:restriction>
66 </xs:simpleType>
67
68 <xs:simpleType name="JUSTIFYHTYPE">
69 <xs:restriction base="xs:NMTOKEN">
70 <xs:enumeration value="LEFT"/>
71 <xs:enumeration value="CENTER"/>
72 <xs:enumeration value="RIGHT"/>
73 </xs:restriction>
74 </xs:simpleType>
75
76 <xs:simpleType name="INSERTMODE">
77 <xs:restriction base="xs:NMTOKEN">
78 <xs:enumeration value="TOP"/>
79 <xs:enumeration value="BOTTOM"/>
80 </xs:restriction>
81 </xs:simpleType>
82
83 <xs:simpleType name="ORIENTATION">
84 <xs:restriction base="xs:NMTOKEN">
85 <xs:enumeration value="HORIZONTAL"/>
86 <xs:enumeration value="VERTICAL"/>
87 </xs:restriction>
88 </xs:simpleType>
89
90 <xs:simpleType name="ATTRIBUTETYPE">
91 <xs:restriction base="xs:NMTOKEN">
92 <xs:enumeration value="nil"/>
93 <xs:enumeration value="boolean"/>
94 <xs:enumeration value="number"/>
95 <xs:enumeration value="string"/>
96 </xs:restriction>
97 </xs:simpleType>
98
99 <xs:simpleType name="KEYVALUETYPE">
100 <xs:restriction base="xs:NMTOKEN">
101 <xs:enumeration value="nil"/>
102 <xs:enumeration value="boolean"/>
103 <xs:enumeration value="number"/>
104 <xs:enumeration value="string"/>
105 <xs:enumeration value="global"/>
106 </xs:restriction>
107 </xs:simpleType>
108
109 <xs:simpleType name="SCRIPTINHERITTYPE">
110 <xs:restriction base="xs:NMTOKEN">
111 <xs:enumeration value="prepend"/>
112 <xs:enumeration value="append"/>
113 <xs:enumeration value="none"/>
114 </xs:restriction>
115 </xs:simpleType>
116
117 <xs:simpleType name="SCRIPTINTRINSICORDERTYPE">
118 <xs:restriction base="xs:NMTOKEN">
119 <xs:enumeration value="precall"/>
120 <xs:enumeration value="postcall"/>
121 <xs:enumeration value="none"/>
122 </xs:restriction>
123 </xs:simpleType>
124
125 <xs:simpleType name="FONTALPHABET">
126 <xs:restriction base="xs:NMTOKEN">
127 <xs:enumeration value="roman"/>
128 <xs:enumeration value="korean"/>
129 <xs:enumeration value="simplifiedchinese"/>
130 <xs:enumeration value="traditionalchinese"/>
131 <xs:enumeration value="russian"/>
132 </xs:restriction>
133 </xs:simpleType>
134
135 <xs:simpleType name="WRAPMODE">
136 <xs:restriction base="xs:NMTOKEN">
137 <xs:enumeration value="CLAMP"/>
138 <xs:enumeration value="REPEAT"/>
139 <xs:enumeration value="CLAMPTOBLACK"/>
140 <xs:enumeration value="CLAMPTOBLACKADDITIVE"/>
141 <xs:enumeration value="CLAMPTOWHITE"/>
142 <xs:enumeration value="MIRROR"/>
143 </xs:restriction>
144 </xs:simpleType>
145
146 <xs:element name="AbsValue">
147 <xs:complexType>
148 <xs:attribute name="val" type="xs:int" use="required"/>
149 </xs:complexType>
150 </xs:element>
151
152 <xs:element name="RelValue">
153 <xs:complexType>
154 <xs:attribute name="val" type="xs:float" use="required"/>
155 </xs:complexType>
156 </xs:element>
157
158 <xs:complexType name="Value">
159 <xs:choice minOccurs="0">
160 <xs:element ref="AbsValue"/>
161 <xs:element ref="RelValue"/>
162 </xs:choice>
163 <xs:attribute name="val" type="xs:int" use="optional"/>
164 </xs:complexType>
165
166 <xs:element name="AbsDimension">
167 <xs:complexType>
168 <xs:attribute name="x" type="xs:float" use="required"/>
169 <xs:attribute name="y" type="xs:float" use="required"/>
170 </xs:complexType>
171 </xs:element>
172
173 <xs:element name="RelDimension">
174 <xs:complexType>
175 <xs:attribute name="x" type="xs:float" use="required"/>
176 <xs:attribute name="y" type="xs:float" use="required"/>
177 </xs:complexType>
178 </xs:element>
179
180 <xs:complexType name="Dimension">
181 <xs:choice minOccurs="0">
182 <xs:element ref="AbsDimension"/>
183 <xs:element ref="RelDimension"/>
184 </xs:choice>
185 <xs:attribute name="x" type="xs:float" use="optional"/>
186 <xs:attribute name="y" type="xs:float" use="optional"/>
187 </xs:complexType>
188
189 <xs:element name="AbsInset">
190 <xs:complexType>
191 <xs:attribute name="left" type="xs:float" use="optional"/>
192 <xs:attribute name="right" type="xs:float" use="optional"/>
193 <xs:attribute name="top" type="xs:float" use="optional"/>
194 <xs:attribute name="bottom" type="xs:float" use="optional"/>
195 </xs:complexType>
196 </xs:element>
197
198 <xs:element name="RelInset">
199 <xs:complexType>
200 <xs:attribute name="left" type="xs:float" use="required"/>
201 <xs:attribute name="right" type="xs:float" use="required"/>
202 <xs:attribute name="top" type="xs:float" use="required"/>
203 <xs:attribute name="bottom" type="xs:float" use="required"/>
204 </xs:complexType>
205 </xs:element>
206
207 <xs:complexType name="Inset">
208 <xs:choice minOccurs="0">
209 <xs:element ref="AbsInset"/>
210 <xs:element ref="RelInset"/>
211 </xs:choice>
212 <xs:attribute name="left" type="xs:int" use="optional"/>
213 <xs:attribute name="right" type="xs:int" use="optional"/>
214 <xs:attribute name="top" type="xs:int" use="optional"/>
215 <xs:attribute name="bottom" type="xs:int" use="optional"/>
216 </xs:complexType>
217
218 <xs:simpleType name="ColorFloat">
219 <xs:restriction base="xs:float">
220 <xs:minInclusive value="0.0"/>
221 <xs:maxInclusive value="1.0"/>
222 </xs:restriction>
223 </xs:simpleType>
224
225 <xs:complexType name="ColorType">
226 <xs:attribute name="r" type="ColorFloat" default="0.0"/>
227 <xs:attribute name="g" type="ColorFloat" default="0.0"/>
228 <xs:attribute name="b" type="ColorFloat" default="0.0"/>
229 <xs:attribute name="a" type="ColorFloat" default="1.0"/>
230 <xs:attribute name="color" type="xs:string"/>
231 </xs:complexType>
232
233 <xs:complexType name="ShadowType">
234 <xs:sequence minOccurs="0">
235 <xs:choice maxOccurs="unbounded">
236 <xs:element name="Color" type="ColorType"/>
237 <xs:element name="Offset" type="Dimension"/>
238 </xs:choice>
239 </xs:sequence>
240 <xs:attribute name="x" type="xs:float"/>
241 <xs:attribute name="y" type="xs:float"/>
242 </xs:complexType>
243
244 <xs:complexType name="GradientType">
245 <xs:sequence>
246 <xs:element name="MinColor" type="ColorType"/>
247 <xs:element name="MaxColor" type="ColorType"/>
248 </xs:sequence>
249 <xs:attribute name="orientation" type="ORIENTATION" default="HORIZONTAL"/>
250 </xs:complexType>
251
252 <xs:complexType name="KeyValueType">
253 <xs:attribute name="key" type="xs:string" use="required"/>
254 <xs:attribute name="value" type="xs:string" use="required"/>
255 <xs:attribute name="keyType" type="KEYVALUETYPE" use="optional" default="string"/>
256 <xs:attribute name="type" type="KEYVALUETYPE" use="optional" default="string"/>
257 </xs:complexType>
258
259 <xs:complexType name="KeyValuesType">
260 <xs:sequence>
261 <xs:choice maxOccurs="unbounded">
262 <xs:element name="KeyValue" type="KeyValueType"/>
263 </xs:choice>
264 </xs:sequence>
265 </xs:complexType>
266
267 <xs:complexType name="AttributeType">
268 <xs:attribute name="name" type="xs:string" use="required"/>
269 <xs:attribute name="type" type="ATTRIBUTETYPE" use="optional" default="string"/>
270 <xs:attribute name="value" type="xs:string" use="optional"/>
271 </xs:complexType>
272
273 <xs:complexType name="AttributesType">
274 <xs:sequence>
275 <xs:choice maxOccurs="unbounded">
276 <xs:element name="Attribute" type="AttributeType"/>
277 </xs:choice>
278 </xs:sequence>
279 </xs:complexType>
280
281 <xs:complexType name="ButtonStyleType">
282 <xs:attribute name="style" type="xs:string" use="required"/>
283 </xs:complexType>
284
285 <xs:complexType name="ScriptsType">
286 <xs:sequence>
287 <xs:choice maxOccurs="unbounded">
288 <xs:element name="OnLoad" type="ScriptType"/>
289 <xs:element name="OnAttributeChanged" type="ScriptType"/>
290 <xs:element name="OnSizeChanged" type="ScriptType"/>
291 <xs:element name="OnEvent" type="ScriptType"/>
292 <xs:element name="OnUpdate" type="ScriptType"/>
293 <xs:element name="OnShow" type="ScriptType"/>
294 <xs:element name="OnHide" type="ScriptType"/>
295 <xs:element name="OnEnter" type="ScriptType"/>
296 <xs:element name="OnLeave" type="ScriptType"/>
297 <xs:element name="OnMouseDown" type="ScriptType"/>
298 <xs:element name="OnMouseUp" type="ScriptType"/>
299 <xs:element name="OnMouseWheel" type="ScriptType"/>
300 <xs:element name="OnJoystickStickMotion" type="ScriptType"/>
301 <xs:element name="OnJoystickAxisMotion" type="ScriptType"/>
302 <xs:element name="OnJoystickButtonDown" type="ScriptType"/>
303 <xs:element name="OnJoystickButtonUp" type="ScriptType"/>
304 <xs:element name="OnJoystickHatMotion" type="ScriptType"/>
305 <xs:element name="OnDragStart" type="ScriptType"/>
306 <xs:element name="OnDragStop" type="ScriptType"/>
307 <xs:element name="OnReceiveDrag" type="ScriptType"/>
308 <xs:element name="PreClick" type="ScriptType"/>
309 <xs:element name="OnClick" type="ScriptType"/>
310 <xs:element name="PostClick" type="ScriptType"/>
311 <xs:element name="OnDoubleClick" type="ScriptType"/>
312 <xs:element name="OnValueChanged" type="ScriptType"/>
313 <xs:element name="OnMinMaxChanged" type="ScriptType"/>
314 <xs:element name="OnUpdateModel" type="ScriptType"/>
315 <xs:element name="OnModelLoaded" type="ScriptType"/>
316 <xs:element name="OnAnimStarted" type="ScriptType"/>
317 <xs:element name="OnAnimFinished" type="ScriptType"/>
318 <xs:element name="OnEnterPressed" type="ScriptType"/>
319 <xs:element name="OnEscapePressed" type="ScriptType"/>
320 <xs:element name="OnSpacePressed" type="ScriptType"/>
321 <xs:element name="OnTabPressed" type="ScriptType"/>
322 <xs:element name="OnTextChanged" type="ScriptType"/>
323 <xs:element name="OnTextSet" type="ScriptType"/>
324 <xs:element name="OnCursorChanged" type="ScriptType"/>
325 <xs:element name="OnInputLanguageChanged" type="ScriptType"/>
326 <xs:element name="OnEditFocusGained" type="ScriptType"/>
327 <xs:element name="OnEditFocusLost" type="ScriptType"/>
328 <xs:element name="OnHorizontalScroll" type="ScriptType"/>
329 <xs:element name="OnVerticalScroll" type="ScriptType"/>
330 <xs:element name="OnScrollRangeChanged" type="ScriptType"/>
331 <xs:element name="OnCharComposition" type="ScriptType"/>
332 <xs:element name="OnChar" type="ScriptType"/>
333 <xs:element name="OnKeyDown" type="ScriptType"/>
334 <xs:element name="OnKeyUp" type="ScriptType"/>
335 <xs:element name="OnColorSelect" type="ScriptType"/>
336 <xs:element name="OnHyperlinkEnter" type="ScriptType"/>
337 <xs:element name="OnHyperlinkLeave" type="ScriptType"/>
338 <xs:element name="OnHyperlinkClick" type="ScriptType"/>
339 <xs:element name="OnMessageScrollChanged" type="ScriptType"/>
340 <xs:element name="OnMovieFinished" type="ScriptType"/>
341 <xs:element name="OnMovieShowSubtitle" type="ScriptType"/>
342 <xs:element name="OnMovieHideSubtitle" type="ScriptType"/>
343 <xs:element name="OnTooltipSetDefaultAnchor" type="ScriptType"/>
344 <xs:element name="OnTooltipCleared" type="ScriptType"/>
345 <xs:element name="OnTooltipAddMoney" type="ScriptType"/>
346 <xs:element name="OnTooltipSetUnit" type="ScriptType"/>
347 <xs:element name="OnTooltipSetItem" type="ScriptType"/>
348 <xs:element name="OnTooltipSetSpell" type="ScriptType"/>
349 <xs:element name="OnTooltipSetQuest" type="ScriptType"/>
350 <xs:element name="OnTooltipSetAchievement" type="ScriptType"/>
351 <xs:element name="OnTooltipSetFramestack" type="ScriptType"/>
352 <xs:element name="OnTooltipSetEquipmentSet" type="ScriptType"/>
353 <xs:element name="OnEnable" type="ScriptType"/>
354 <xs:element name="OnDisable" type="ScriptType"/>
355 <xs:element name="OnArrowPressed" type="ScriptType"/>
356 <xs:element name="OnExternalLink" type="ScriptType"/>
357 <xs:element name="OnButtonUpdate" type="ScriptType"/>
358 <xs:element name="OnError" type="ScriptType"/>
359 <xs:element name="OnDressModel" type="ScriptType"/>
360 <xs:element name="OnCooldownDone" type="ScriptType"/>
361 <xs:element name="OnPanFinished" type="ScriptType"/>
362 <xs:element name="OnUiMapChanged" type="ScriptType"/>
363 <xs:element name="OnRequestNewSize" type="ScriptType"/>
364 </xs:choice>
365 </xs:sequence>
366 </xs:complexType>
367
368 <xs:complexType name="ScriptType">
369 <xs:simpleContent>
370 <xs:extension base="xs:string">
371 <xs:attribute name="function" type="xs:string"/>
372 <xs:attribute name="method" type="xs:string"/>
373 <xs:attribute name="inherit" type="SCRIPTINHERITTYPE" use="optional" default="none"/>
374 <xs:attribute name="intrinsicOrder" type="SCRIPTINTRINSICORDERTYPE" use="optional" default="none"/>
375 <xs:attribute name="autoEnableInput" type="xs:boolean" default="true"/>
376 </xs:extension>
377 </xs:simpleContent>
378 </xs:complexType>
379
380 <xs:complexType name="FontType">
381 <xs:sequence minOccurs="0">
382 <xs:choice maxOccurs="unbounded">
383 <xs:element name="FontHeight" type="Value"/>
384 <xs:element name="Color" type="ColorType"/>
385 <xs:element name="Shadow" type="ShadowType"/>
386 </xs:choice>
387 </xs:sequence>
388 <xs:attribute name="name" type="xs:string"/>
389 <xs:attribute name="inherits" type="xs:string"/>
390 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
391 <xs:attribute name="font" type="xs:string"/>
392 <xs:attribute name="spacing" type="xs:float" default="0"/>
393 <xs:attribute name="outline" type="OUTLINETYPE" default="NONE"/>
394 <xs:attribute name="monochrome" type="xs:boolean" default="false"/>
395 <xs:attribute name="justifyV" type="JUSTIFYVTYPE" default="MIDDLE"/>
396 <xs:attribute name="justifyH" type="JUSTIFYHTYPE" default="CENTER"/>
397 <xs:attribute name="height" type="xs:float"/>
398 <xs:attribute name="fixedSize" type="xs:boolean" default="false"/>
399 <xs:attribute name="filter" type="xs:boolean" default="false"/>
400 </xs:complexType>
401
402 <xs:element name="Font">
403 <xs:complexType>
404 <xs:complexContent>
405 <xs:extension base="FontType"/>
406 </xs:complexContent>
407 </xs:complexType>
408 </xs:element>
409
410 <xs:complexType name="FontMemberType">
411 <xs:sequence minOccurs="1" maxOccurs="1">
412 <xs:element name="Font" type="FontType"/>
413 </xs:sequence>
414 <xs:attribute name="alphabet" type="FONTALPHABET" use="required"/>
415 </xs:complexType>
416
417 <xs:complexType name="FontFamilyType">
418 <xs:sequence>
419 <xs:choice maxOccurs="unbounded">
420 <xs:element name="Member" type="FontMemberType"/>
421 </xs:choice>
422 </xs:sequence>
423 <xs:attribute name="name" type="xs:string" use="required"/>
424 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
425 </xs:complexType>
426
427 <xs:element name="FontFamily" type="FontFamilyType"/>
428
429 <xs:complexType name="LayoutFrameType">
430 <xs:sequence minOccurs="0">
431 <xs:choice maxOccurs="unbounded">
432 <xs:element name="Size" type="Dimension"/>
433 <xs:element name="Anchors">
434 <xs:complexType>
435 <xs:sequence>
436 <xs:element name="Anchor" maxOccurs="unbounded">
437 <xs:complexType>
438 <xs:sequence minOccurs="0">
439 <xs:element name="Offset" type="Dimension"/>
440 </xs:sequence>
441 <xs:attribute name="point" type="FRAMEPOINT" use="required"/>
442 <xs:attribute name="relativeKey" type="xs:string"/>
443 <xs:attribute name="relativeTo" type="xs:string"/>
444 <xs:attribute name="relativePoint" type="FRAMEPOINT"/>
445 <xs:attribute name="x" type="xs:float"/>
446 <xs:attribute name="y" type="xs:float"/>
447 </xs:complexType>
448 </xs:element>
449 </xs:sequence>
450 </xs:complexType>
451 </xs:element>
452 <xs:element name="KeyValues" type="KeyValuesType"/>
453 <xs:element name="Animations">
454 <xs:complexType>
455 <xs:sequence>
456 <xs:element ref="AnimationGroup" maxOccurs="unbounded"/>
457 </xs:sequence>
458 </xs:complexType>
459 </xs:element>
460 </xs:choice>
461 </xs:sequence>
462 <xs:attribute name="name" type="xs:string"/>
463 <xs:attribute name="parentKey" type="xs:string"/>
464 <xs:attribute name="parentArray" type="xs:string"/>
465 <xs:attribute name="inherits" type="xs:string"/>
466 <xs:attribute name="mixin" type="xs:string"/>
467 <xs:attribute name="secureMixin" type="xs:string"/>
468 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
469 <xs:attribute name="setAllPoints" type="xs:boolean" default="false"/>
470 <xs:attribute name="hidden" type="xs:boolean" default="false"/>
471 </xs:complexType>
472 <xs:element name="LayoutFrame" type="LayoutFrameType"/>
473
474 <xs:complexType name="BackdropType">
475 <xs:sequence minOccurs="0">
476 <xs:choice maxOccurs="unbounded">
477 <xs:element name="BackgroundInsets" type="Inset"/>
478 <xs:element name="TileSize" type="Value"/>
479 <xs:element name="EdgeSize" type="Value"/>
480 <xs:element name="Color" type="ColorType"/>
481 <xs:element name="BorderColor" type="ColorType"/>
482 </xs:choice>
483 </xs:sequence>
484 <xs:attribute name="bgFile" type="xs:string"/>
485 <xs:attribute name="edgeFile" type="xs:string"/>
486 <xs:attribute name="tile" type="xs:boolean" default="false"/>
487 <xs:attribute name="tileEdge" type="xs:boolean" default="false"/>
488 <xs:attribute name="alphaMode" type="ALPHAMODE" default="BLEND"/>
489 </xs:complexType>
490
491 <xs:complexType name="RectType">
492 <xs:attribute name="ULx" type="xs:float"/>
493 <xs:attribute name="ULy" type="xs:float"/>
494 <xs:attribute name="LLx" type="xs:float"/>
495 <xs:attribute name="LLy" type="xs:float"/>
496 <xs:attribute name="URx" type="xs:float"/>
497 <xs:attribute name="URy" type="xs:float"/>
498 <xs:attribute name="LRx" type="xs:float"/>
499 <xs:attribute name="LRy" type="xs:float"/>
500 </xs:complexType>
501
502 <xs:complexType name="TextureType">
503 <xs:complexContent>
504 <xs:extension base="LayoutFrameType">
505 <xs:sequence minOccurs="0">
506 <xs:choice maxOccurs="unbounded">
507 <xs:element name="TexCoords">
508 <xs:complexType>
509 <xs:sequence minOccurs="0" maxOccurs="1">
510 <xs:element name="Rect" type="RectType"/>
511 </xs:sequence>
512 <xs:attribute name="left" type="xs:float"/>
513 <xs:attribute name="right" type="xs:float"/>
514 <xs:attribute name="top" type="xs:float"/>
515 <xs:attribute name="bottom" type="xs:float"/>
516 </xs:complexType>
517 </xs:element>
518 <xs:element name="Color" type="ColorType"/>
519 <xs:element name="Gradient" type="GradientType"/>
520 </xs:choice>
521 </xs:sequence>
522 <xs:attribute name="file" type="xs:string"/>
523 <xs:attribute name="mask" type="xs:string"/>
524 <xs:attribute name="alphaMode" type="ALPHAMODE" default="BLEND"/>
525 <xs:attribute name="alpha" type="xs:float" default="1.0"/>
526 <xs:attribute name="scale" type="xs:float" default="1.0"/>
527 <xs:attribute name="rotation" type="xs:float" default="0.0"/>
528 <xs:attribute name="snapToPixelGrid" type="xs:boolean" default="true"/>
529 <xs:attribute name="texelSnappingBias" type="xs:float"/>
530 <xs:attribute name="hWrapMode" type="WRAPMODE" default="CLAMP"/>
531 <xs:attribute name="vWrapMode" type="WRAPMODE" default="CLAMP"/>
532 <xs:attribute name="ignoreParentAlpha" type="xs:boolean" default="false"/>
533 <xs:attribute name="ignoreParentScale" type="xs:boolean" default="false"/>
534 <xs:attribute name="nonBlocking" type="xs:boolean" default="false"/>
535 <xs:attribute name="horizTile" type="xs:boolean" default="false"/>
536 <xs:attribute name="vertTile" type="xs:boolean" default="false"/>
537 <xs:attribute name="atlas" type="xs:string"/>
538 <xs:attribute name="useAtlasSize" type="xs:boolean"/>
539 <xs:attribute name="desaturated" type="xs:boolean" default="false"/>
540 </xs:extension>
541 </xs:complexContent>
542 </xs:complexType>
543 <xs:element name="Texture" type="TextureType" substitutionGroup="LayoutFrame"/>
544
545 <xs:complexType name="MaskTextureType">
546 <xs:complexContent>
547 <xs:extension base="TextureType">
548 <xs:sequence minOccurs="0" maxOccurs="1">
549 <xs:element name="MaskedTextures">
550 <xs:complexType>
551 <xs:sequence>
552 <xs:element name="MaskedTexture" maxOccurs="unbounded">
553 <xs:complexType>
554 <xs:attribute name="childKey" type="xs:string"/>
555 <xs:attribute name="target" type="xs:string"/>
556 </xs:complexType>
557 </xs:element>
558 </xs:sequence>
559 </xs:complexType>
560 </xs:element>
561 </xs:sequence>
562 </xs:extension>
563 </xs:complexContent>
564 </xs:complexType>
565 <xs:element name="MaskTexture" type="MaskTextureType" substitutionGroup="LayoutFrame"/>
566
567 <xs:complexType name="FontStringType">
568 <xs:complexContent>
569 <xs:extension base="LayoutFrameType">
570 <xs:sequence minOccurs="0">
571 <xs:choice maxOccurs="unbounded">
572 <xs:element name="FontHeight" type="Value"/>
573 <xs:element name="Color" type="ColorType"/>
574 <xs:element name="Shadow" type="ShadowType"/>
575 </xs:choice>
576 </xs:sequence>
577 <xs:attribute name="font" type="xs:string"/>
578 <xs:attribute name="bytes" default="255">
579 <xs:simpleType>
580 <xs:restriction base="xs:int">
581 <xs:minInclusive value="0"/>
582 </xs:restriction>
583 </xs:simpleType>
584 </xs:attribute>
585 <xs:attribute name="text" type="xs:string"/>
586 <xs:attribute name="spacing" type="xs:float" default="0"/>
587 <xs:attribute name="outline" type="OUTLINETYPE" default="NONE"/>
588 <xs:attribute name="monochrome" type="xs:boolean" default="false"/>
589 <xs:attribute name="nonspacewrap" type="xs:boolean" default="false"/>
590 <xs:attribute name="wordwrap" type="xs:boolean" default="true"/>
591 <xs:attribute name="justifyV" type="JUSTIFYVTYPE" default="MIDDLE"/>
592 <xs:attribute name="justifyH" type="JUSTIFYHTYPE" default="CENTER"/>
593 <xs:attribute name="maxLines" type="xs:unsignedInt" default="0"/>
594 <xs:attribute name="indented" type="xs:boolean" default="false"/>
595 <xs:attribute name="alpha" type="xs:float" default="1.0"/>
596 <xs:attribute name="ignoreParentAlpha" type="xs:boolean" default="false"/>
597 <xs:attribute name="ignoreParentScale" type="xs:boolean" default="false"/>
598 </xs:extension>
599 </xs:complexContent>
600 </xs:complexType>
601 <xs:element name="FontString" type="FontStringType" substitutionGroup="LayoutFrame"/>
602
603 <xs:complexType name="LineType">
604 <xs:complexContent>
605 <xs:extension base="TextureType">
606 <xs:sequence minOccurs="0">
607 <xs:element name="StartAnchor" maxOccurs="1">
608 <xs:complexType>
609 <xs:sequence minOccurs="0">
610 <xs:element name="Offset" type="Dimension"/>
611 </xs:sequence>
612 <xs:attribute name="relativeTo" type="xs:string"/>
613 <xs:attribute name="relativePoint" type="FRAMEPOINT"/>
614 <xs:attribute name="relativeKey" type="xs:string"/>
615 <xs:attribute name="x" type="xs:float"/>
616 <xs:attribute name="y" type="xs:float"/>
617 </xs:complexType>
618 </xs:element>
619 <xs:element name="EndAnchor" maxOccurs="1">
620 <xs:complexType>
621 <xs:sequence minOccurs="0">
622 <xs:element name="Offset" type="Dimension"/>
623 </xs:sequence>
624 <xs:attribute name="relativeTo" type="xs:string"/>
625 <xs:attribute name="relativePoint" type="FRAMEPOINT"/>
626 <xs:attribute name="relativeKey" type="xs:string"/>
627 <xs:attribute name="x" type="xs:float"/>
628 <xs:attribute name="y" type="xs:float"/>
629 </xs:complexType>
630 </xs:element>
631 </xs:sequence>
632 <xs:attribute name="thickness" type="xs:float" default="4"/>
633 </xs:extension>
634 </xs:complexContent>
635 </xs:complexType>
636 <xs:element name="Line" type="LineType" substitutionGroup="LayoutFrame"/>
637
638 <xs:complexType name="FrameType">
639 <xs:complexContent>
640 <xs:extension base="LayoutFrameType">
641 <xs:sequence minOccurs="0">
642 <xs:choice maxOccurs="unbounded">
643 <xs:element name="TitleRegion" type="ui:LayoutFrameType"/>
644 <xs:element name="ResizeBounds">
645 <xs:complexType>
646 <xs:sequence>
647 <xs:choice maxOccurs="unbounded">
648 <xs:element name="minResize" type="Dimension"/>
649 <xs:element name="maxResize" type="Dimension"/>
650 </xs:choice>
651 </xs:sequence>
652 </xs:complexType>
653 </xs:element>
654 <xs:element name="Backdrop" type="BackdropType"/>
655 <xs:element name="HitRectInsets" type="Inset"/>
656 <xs:element name="Layers">
657 <xs:complexType>
658 <xs:sequence>
659 <xs:element name="Layer" maxOccurs="unbounded">
660 <xs:complexType>
661 <xs:sequence>
662 <xs:choice maxOccurs="unbounded">
663 <xs:element ref="Texture"/>
664 <xs:element ref="MaskTexture"/>
665 <xs:element ref="FontString"/>
666 <xs:element ref="Line"/>
667 </xs:choice>
668 </xs:sequence>
669 <xs:attribute name="level" type="DRAWLAYER" default="ARTWORK"/>
670 <xs:attribute name="textureSubLevel" default="0">
671 <xs:simpleType>
672 <xs:restriction base="xs:int">
673 <xs:minInclusive value="-8"/>
674 <xs:maxInclusive value="7"/>
675 </xs:restriction>
676 </xs:simpleType>
677 </xs:attribute>
678 </xs:complexType>
679 </xs:element>
680 </xs:sequence>
681 </xs:complexType>
682 </xs:element>
683 <xs:element name="Attributes" type="AttributesType"/>
684 <xs:element name="Frames">
685 <xs:complexType>
686 <xs:sequence>
687 <xs:element ref="Frame" maxOccurs="unbounded"/>
688 </xs:sequence>
689 </xs:complexType>
690 </xs:element>
691 <xs:element name="Scripts" type="ScriptsType"/>
692 </xs:choice>
693 </xs:sequence>
694 <xs:attribute name="alpha" type="xs:float" default="1.0"/>
695 <xs:attribute name="scale" type="xs:float" default="1.0"/>
696 <xs:attribute name="parent" type="xs:string"/>
697 <xs:attribute name="toplevel" type="xs:boolean" default="false"/>
698 <xs:attribute name="flattenRenderLayers" type="xs:boolean" default="false"/>
699 <xs:attribute name="useParentLevel" type="xs:boolean" default="false"/>
700 <xs:attribute name="movable" type="xs:boolean" default="false"/>
701 <xs:attribute name="resizable" type="xs:boolean" default="false"/>
702 <xs:attribute name="frameStrata" type="ui:FRAMESTRATA" default="PARENT"/>
703 <xs:attribute name="frameLevel" type="xs:int"/>
704 <xs:attribute name="id" type="xs:int" default="0"/>
705 <xs:attribute name="enableMouse" type="xs:boolean" default="false"/>
706 <xs:attribute name="enableMouseClicks" type="xs:boolean" default="false"/>
707 <xs:attribute name="enableMouseMotion" type="xs:boolean" default="false"/>
708 <xs:attribute name="enableKeyboard" type="xs:boolean" default="false"/>
709 <xs:attribute name="clampedToScreen" type="xs:boolean" default="false"/>
710 <xs:attribute name="protected" type="xs:boolean" default="false"/>
711 <xs:attribute name="depth" type="xs:float" default="0.0"/>
712 <xs:attribute name="dontSavePosition" type="xs:boolean" default="false"/>
713 <xs:attribute name="propagateKeyboardInput" type="xs:boolean" default="false"/>
714 <xs:attribute name="ignoreParentAlpha" type="xs:boolean" default="false"/>
715 <xs:attribute name="ignoreParentScale" type="xs:boolean" default="false"/>
716 <xs:attribute name="intrinsic" type="xs:boolean" default="false"/>
717 <xs:attribute name="clipChildren" type="xs:boolean" default="false"/>
718 <xs:attribute name="propagateHyperlinksToParent" type="xs:boolean" default="false"/>
719 <xs:attribute name="hyperlinksEnabled" type="xs:boolean" default="false"/>
720 </xs:extension>
721 </xs:complexContent>
722 </xs:complexType>
723 <xs:element name="Frame" type="FrameType" substitutionGroup="LayoutFrame"/>
724
725 <xs:complexType name="UnitPositionFrameType">
726 <xs:complexContent>
727 <xs:extension base="FrameType" />
728 </xs:complexContent>
729 </xs:complexType>
730 <xs:element name="UnitPositionFrame" type="UnitPositionFrameType" substitutionGroup="ui:Frame"/>
731
732 <xs:complexType name="ButtonType">
733 <xs:complexContent>
734 <xs:extension base="FrameType">
735 <xs:sequence minOccurs="0">
736 <xs:choice maxOccurs="unbounded">
737 <xs:element name="NormalTexture" type="ui:TextureType"/>
738 <xs:element name="PushedTexture" type="ui:TextureType"/>
739 <xs:element name="DisabledTexture" type="ui:TextureType"/>
740 <xs:element name="HighlightTexture" type="ui:TextureType"/>
741 <xs:element name="ButtonText" type="FontStringType"/>
742 <xs:element name="NormalFont" type="ButtonStyleType"/>
743 <xs:element name="HighlightFont" type="ButtonStyleType"/>
744 <xs:element name="DisabledFont" type="ButtonStyleType"/>
745 <xs:element name="NormalColor" type="ColorType"/>
746 <xs:element name="HighlightColor" type="ColorType"/>
747 <xs:element name="DisabledColor" type="ColorType"/>
748 <xs:element name="PushedTextOffset" type="Dimension"/>
749 </xs:choice>
750 </xs:sequence>
751 <xs:attribute name="text" type="xs:string"/>
752 <xs:attribute name="registerForClicks" type="xs:string"/>
753 <xs:attribute name="motionScriptsWhileDisabled" type="xs:boolean" default="false"/>
754 </xs:extension>
755 </xs:complexContent>
756 </xs:complexType>
757 <xs:element name="Button" type="ButtonType" substitutionGroup="ui:Frame"/>
758
759 <xs:complexType name="CheckButtonType">
760 <xs:complexContent>
761 <xs:extension base="ButtonType">
762 <xs:sequence minOccurs="0">
763 <xs:choice maxOccurs="unbounded">
764 <xs:element name="CheckedTexture" type="TextureType"/>
765 <xs:element name="DisabledCheckedTexture" type="TextureType"/>
766 </xs:choice>
767 </xs:sequence>
768 <xs:attribute name="checked" type="xs:boolean" default="false"/>
769 </xs:extension>
770 </xs:complexContent>
771 </xs:complexType>
772 <xs:element name="CheckButton" type="CheckButtonType" substitutionGroup="ui:Button"/>
773
774 <xs:complexType name="StatusBarType">
775 <xs:complexContent>
776 <xs:extension base="FrameType">
777 <xs:sequence minOccurs="0">
778 <xs:choice maxOccurs="unbounded">
779 <xs:element name="BarTexture" type="TextureType"/>
780 <xs:element name="BarColor" type="ui:ColorType"/>
781 </xs:choice>
782 </xs:sequence>
783 <xs:attribute name="drawLayer" type="ui:DRAWLAYER" default="ARTWORK"/>
784 <xs:attribute name="minValue" type="xs:float"/>
785 <xs:attribute name="maxValue" type="xs:float"/>
786 <xs:attribute name="defaultValue" type="xs:float"/>
787 <xs:attribute name="orientation" type="ui:ORIENTATION" default="HORIZONTAL"/>
788 <xs:attribute name="rotatesTexture" type="xs:boolean" default="false"/>
789 <xs:attribute name="reverseFill" type="xs:boolean" default="false"/>
790 </xs:extension>
791 </xs:complexContent>
792 </xs:complexType>
793 <xs:element name="StatusBar" type="StatusBarType" substitutionGroup="ui:Frame"/>
794
795 <xs:complexType name="SliderType">
796 <xs:complexContent>
797 <xs:extension base="FrameType">
798 <xs:sequence minOccurs="0">
799 <xs:choice maxOccurs="unbounded">
800 <xs:element name="ThumbTexture" type="TextureType"/>
801 </xs:choice>
802 </xs:sequence>
803 <xs:attribute name="drawLayer" type="ui:DRAWLAYER" default="OVERLAY"/>
804 <xs:attribute name="minValue" type="xs:float"/>
805 <xs:attribute name="maxValue" type="xs:float"/>
806 <xs:attribute name="defaultValue" type="xs:float"/>
807 <xs:attribute name="valueStep" type="xs:float"/>
808 <xs:attribute name="orientation" type="ui:ORIENTATION" default="VERTICAL"/>
809 <xs:attribute name="obeyStepOnDrag" type="xs:boolean"/>
810 </xs:extension>
811 </xs:complexContent>
812 </xs:complexType>
813 <xs:element name="Slider" type="SliderType" substitutionGroup="ui:Frame"/>
814
815 <xs:complexType name="EditBoxType">
816 <xs:complexContent>
817 <xs:extension base="FrameType">
818 <xs:sequence minOccurs="0">
819 <xs:choice maxOccurs="unbounded">
820 <xs:element ref="FontString"/>
821 <xs:element name="HighlightColor" type="ColorType"/>
822 <xs:element name="TextInsets" type="Inset"/>
823 </xs:choice>
824 </xs:sequence>
825 <xs:attribute name="font" type="xs:string"/>
826 <xs:attribute name="letters" type="xs:int" default="0"/>
827 <xs:attribute name="blinkSpeed" type="xs:float" default="0.5"/>
828 <xs:attribute name="numeric" type="xs:boolean" default="false"/>
829 <xs:attribute name="password" type="xs:boolean" default="false"/>
830 <xs:attribute name="multiLine" type="xs:boolean" default="false"/>
831 <xs:attribute name="historyLines" type="xs:int" default="0"/>
832 <xs:attribute name="autoFocus" type="xs:boolean" default="true"/>
833 <xs:attribute name="ignoreArrows" type="xs:boolean" default="false"/>
834 <xs:attribute name="countInvisibleLetters" type="xs:boolean" default="false"/>
835 <xs:attribute name="invisibleBytes" type="xs:int"/>
836 </xs:extension>
837 </xs:complexContent>
838 </xs:complexType>
839 <xs:element name="EditBox" type="EditBoxType" substitutionGroup="ui:Frame"/>
840
841 <xs:complexType name="ColorSelectType">
842 <xs:complexContent>
843 <xs:extension base="FrameType">
844 <xs:sequence>
845 <xs:choice maxOccurs="unbounded">
846 <xs:element name="ColorWheelTexture" type="TextureType"/>
847 <xs:element name="ColorWheelThumbTexture" type="TextureType"/>
848 <xs:element name="ColorValueTexture" type="TextureType"/>
849 <xs:element name="ColorValueThumbTexture" type="TextureType"/>
850 </xs:choice>
851 </xs:sequence>
852 </xs:extension>
853 </xs:complexContent>
854 </xs:complexType>
855 <xs:element name="ColorSelect" type="ui:ColorSelectType" substitutionGroup="ui:Frame"/>
856
857 <xs:complexType name="ModelType">
858 <xs:complexContent>
859 <xs:extension base="FrameType">
860 <xs:sequence minOccurs="0">
861 <xs:element name="FogColor" type="ColorType"/>
862 </xs:sequence>
863 <xs:attribute name="file" type="xs:string"/>
864 <xs:attribute name="modelScale" type="xs:float" default="1.0"/>
865 <xs:attribute name="fogNear" default="0.0">
866 <xs:simpleType>
867 <xs:restriction base="xs:float"/>
868 </xs:simpleType>
869 </xs:attribute>
870 <xs:attribute name="fogFar" default="1.0">
871 <xs:simpleType>
872 <xs:restriction base="xs:float"/>
873 </xs:simpleType>
874 </xs:attribute>
875 <xs:attribute name="glow" default="1.0">
876 <xs:simpleType>
877 <xs:restriction base="xs:float"/>
878 </xs:simpleType>
879 </xs:attribute>
880 <xs:attribute name="drawLayer" type="ui:DRAWLAYER" default="ARTWORK"/>
881 </xs:extension>
882 </xs:complexContent>
883 </xs:complexType>
884 <xs:element name="Model" type="ModelType" substitutionGroup="ui:Frame"/>
885 <xs:element name="ModelFFX" type="ModelType" substitutionGroup="ui:Frame"/>
886
887 <xs:complexType name="SimpleHTMLType">
888 <xs:complexContent>
889 <xs:extension base="ui:FrameType">
890 <xs:sequence>
891 <xs:element ref="FontString"/>
892 <xs:sequence minOccurs="0">
893 <xs:choice maxOccurs="unbounded">
894 <xs:element name="FontStringHeader1" type="ui:FontStringType"/>
895 <xs:element name="FontStringHeader2" type="ui:FontStringType"/>
896 <xs:element name="FontStringHeader3" type="ui:FontStringType"/>
897 </xs:choice>
898 </xs:sequence>
899 </xs:sequence>
900 <xs:attribute name="font" type="xs:string"/>
901 <xs:attribute name="file" type="xs:string"/>
902 <xs:attribute name="hyperlinkFormat" type="xs:string" default="|H%s|h%s|h"/>
903 <xs:attribute name="resizeToFitContents" type="xs:boolean" default="false"/>
904 </xs:extension>
905 </xs:complexContent>
906 </xs:complexType>
907 <xs:element name="SimpleHTML" type="ui:SimpleHTMLType" substitutionGroup="ui:Frame"/>
908
909 <xs:complexType name="MessageFrameType">
910 <xs:complexContent>
911 <xs:extension base="FrameType">
912 <xs:sequence minOccurs="0">
913 <xs:choice maxOccurs="unbounded">
914 <xs:element ref="FontString"/>
915 <xs:element name="TextInsets" type="Inset"/>
916 </xs:choice>
917 </xs:sequence>
918 <xs:attribute name="font" type="xs:string"/>
919 <xs:attribute name="fade" type="xs:boolean" default="true"/>
920 <xs:attribute name="fadeDuration" type="xs:float" default="3.0"/>
921 <xs:attribute name="fadePower" type="xs:float" default="1.0"/>
922 <xs:attribute name="displayDuration" type="xs:float" default="10.0"/>
923 <xs:attribute name="insertMode" type="INSERTMODE" default="BOTTOM"/>
924 </xs:extension>
925 </xs:complexContent>
926 </xs:complexType>
927 <xs:element name="MessageFrame" type="MessageFrameType" substitutionGroup="ui:Frame"/>
928
929 <!-- This is now an intrinsic type-->
930 <xs:complexType name="ScrollingMessageFrameType">
931 <xs:complexContent>
932 <xs:extension base="FrameType" />
933 </xs:complexContent>
934 </xs:complexType>
935 <xs:element name="ScrollingMessageFrame" type="ScrollingMessageFrameType" substitutionGroup="ui:Frame"/>
936
937 <xs:complexType name="ScrollFrameType">
938 <xs:complexContent>
939 <xs:extension base="FrameType">
940 <xs:sequence minOccurs="0">
941 <xs:choice>
942 <xs:element name="ScrollChild">
943 <xs:complexType>
944 <xs:sequence>
945 <xs:element ref="Frame"/>
946 </xs:sequence>
947 </xs:complexType>
948 </xs:element>
949 </xs:choice>
950 </xs:sequence>
951 </xs:extension>
952 </xs:complexContent>
953 </xs:complexType>
954 <xs:element name="ScrollFrame" type="ScrollFrameType" substitutionGroup="ui:Frame"/>
955
956 <xs:complexType name="MovieFrameType">
957 <xs:complexContent>
958 <xs:extension base="FrameType"/>
959 </xs:complexContent>
960 </xs:complexType>
961 <xs:element name="MovieFrame" type="MovieFrameType" substitutionGroup="ui:Frame"/>
962
963 <xs:complexType name="ActorScriptsType">
964 <xs:sequence>
965 <xs:choice maxOccurs="unbounded">
966 <xs:element name="OnLoad" type="ScriptType"/>
967 <xs:element name="OnUpdate" type="ScriptType"/>
968 <xs:element name="OnModelLoading" type="ScriptType"/>
969 <xs:element name="OnModelLoaded" type="ScriptType"/>
970 <xs:element name="OnAnimFinished" type="ScriptType"/>
971 </xs:choice>
972 </xs:sequence>
973 </xs:complexType>
974 <xs:complexType name="ModeSceneActorType">
975 <xs:sequence>
976 <xs:element name="Scripts" type="ActorScriptsType" minOccurs="0" maxOccurs="unbounded"/>
977 <xs:element name="Animations">
978 <xs:complexType>
979 <xs:sequence>
980 <xs:element ref="AnimationGroup" maxOccurs="unbounded"/>
981 </xs:sequence>
982 </xs:complexType>
983 </xs:element>
984 </xs:sequence>
985
986 <xs:attribute name="name" type="xs:string"/>
987 <xs:attribute name="inherits" type="xs:string"/>
988 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
989 <xs:attribute name="parentKey" type="xs:string"/>
990 <xs:attribute name="parentArray" type="xs:string"/>
991 <xs:attribute name="mixin" type="xs:string"/>
992
993 <xs:attribute name="file" type="xs:string"/>
994 <xs:attribute name="fileID" type="xs:int"/>
995
996 <xs:attribute name="alpha" type="xs:float" default="1.0" />
997 <xs:attribute name="scale" type="xs:float" default="1.0" />
998 <xs:attribute name="desaturation" type="xs:float" default="0.0" />
999 </xs:complexType>
1000 <xs:element name="Actor" type="ModeSceneActorType"/>
1001
1002 <xs:element name="Ui">
1003 <xs:complexType>
1004 <xs:sequence>
1005 <xs:choice maxOccurs="unbounded">
1006 <xs:element name="Include" minOccurs="0" maxOccurs="unbounded">
1007 <xs:complexType>
1008 <xs:simpleContent>
1009 <xs:extension base="xs:string">
1010 <xs:attribute name="file" type="xs:string" use="required"/>
1011 </xs:extension>
1012 </xs:simpleContent>
1013 </xs:complexType>
1014 </xs:element>
1015 <xs:element name="Script" minOccurs="0" maxOccurs="unbounded">
1016 <xs:complexType>
1017 <xs:simpleContent>
1018 <xs:extension base="xs:string">
1019 <xs:attribute name="file" type="xs:string" use="optional"/>
1020 </xs:extension>
1021 </xs:simpleContent>
1022 </xs:complexType>
1023 </xs:element>
1024 <xs:element ref="Font" minOccurs="0" maxOccurs="unbounded"/>
1025 <xs:element ref="FontFamily" minOccurs="0" maxOccurs="unbounded"/>
1026 <xs:element ref="LayoutFrame" minOccurs="0" maxOccurs="unbounded"/>
1027 <xs:element ref="Animation" minOccurs="0" maxOccurs="unbounded"/>
1028 <xs:element ref="AnimationGroup" minOccurs="0" maxOccurs="unbounded"/>
1029 <xs:element ref="Actor" minOccurs="0" maxOccurs="unbounded"/>
1030 </xs:choice>
1031 </xs:sequence>
1032 </xs:complexType>
1033 </xs:element>
1034
1035 <xs:complexType name="WorldFrameType">
1036 <xs:complexContent>
1037 <xs:extension base="FrameType"/>
1038 </xs:complexContent>
1039 </xs:complexType>
1040 <xs:element name="WorldFrame" type="WorldFrameType" substitutionGroup="ui:Frame"/>
1041
1042 <xs:complexType name="GameTooltipType">
1043 <xs:complexContent>
1044 <xs:extension base="FrameType"/>
1045 </xs:complexContent>
1046 </xs:complexType>
1047 <xs:element name="GameTooltip" type="GameTooltipType" substitutionGroup="ui:Frame"/>
1048
1049 <xs:complexType name="CooldownType">
1050 <xs:complexContent>
1051 <xs:extension base="FrameType">
1052 <xs:sequence minOccurs="0">
1053 <xs:choice maxOccurs="unbounded">
1054 <xs:element name="SwipeTexture" type="TextureType"/>
1055 <xs:element name="EdgeTexture" type="TextureType"/>
1056 <xs:element name="BlingTexture" type="TextureType"/>
1057 </xs:choice>
1058 </xs:sequence>
1059 <xs:attribute name="reverse" type="xs:boolean" default="false"/>
1060 <xs:attribute name="hideCountdownNumbers" type="xs:boolean" default="false"/>
1061 <xs:attribute name="drawEdge" type="xs:boolean" default="false"/>
1062 <xs:attribute name="drawBling" type="xs:boolean" default="false"/>
1063 <xs:attribute name="drawSwipe" type="xs:boolean" default="false"/>
1064 <xs:attribute name="rotation" type="xs:float" default="0.0"/>
1065 </xs:extension>
1066 </xs:complexContent>
1067 </xs:complexType>
1068 <xs:element name="Cooldown" type="CooldownType" substitutionGroup="ui:Frame"/>
1069
1070 <xs:complexType name="QuestPOIFrameType">
1071 <xs:complexContent>
1072 <xs:extension base="FrameType">
1073 <xs:attribute name="filltexture" type="xs:string"/>
1074 <xs:attribute name="bordertexture" type="xs:string"/>
1075 </xs:extension>
1076 </xs:complexContent>
1077 </xs:complexType>
1078 <xs:element name="QuestPOIFrame" type="QuestPOIFrameType" substitutionGroup="ui:Frame"/>
1079
1080 <xs:complexType name="ArchaeologyDigSiteFrameType">
1081 <xs:complexContent>
1082 <xs:extension base="FrameType">
1083 <xs:attribute name="filltexture" type="xs:string"/>
1084 <xs:attribute name="bordertexture" type="xs:string"/>
1085 </xs:extension>
1086 </xs:complexContent>
1087 </xs:complexType>
1088 <xs:element name="ArchaeologyDigSiteFrame" type="ArchaeologyDigSiteFrameType" substitutionGroup="ui:Frame"/>
1089
1090 <xs:complexType name="ScenarioPOIFrameType">
1091 <xs:complexContent>
1092 <xs:extension base="FrameType">
1093 <xs:attribute name="filltexture" type="xs:string"/>
1094 <xs:attribute name="bordertexture" type="xs:string"/>
1095 </xs:extension>
1096 </xs:complexContent>
1097 </xs:complexType>
1098 <xs:element name="ScenarioPOIFrame" type="ScenarioPOIFrameType" substitutionGroup="ui:Frame"/>
1099
1100 <xs:complexType name="MinimapType">
1101 <xs:complexContent>
1102 <xs:extension base="FrameType">
1103 <xs:attribute name="questBlobInsideTexture" type="xs:string"/>
1104 <xs:attribute name="questBlobOutsideTexture" type="xs:string"/>
1105 <xs:attribute name="questBlobOutsideSelectedTexture" type="xs:string"/>
1106 <xs:attribute name="questBlobRingTexture" type="xs:string"/>
1107 <xs:attribute name="taskBlobInsideTexture" type="xs:string"/>
1108 <xs:attribute name="taskBlobOutsideTexture" type="xs:string"/>
1109 <xs:attribute name="taskBlobOutsideSelectedTexture" type="xs:string"/>
1110 <xs:attribute name="taskBlobRingTexture" type="xs:string"/>
1111 <xs:attribute name="archBlobInsideTexture" type="xs:string"/>
1112 <xs:attribute name="archBlobOutsideTexture" type="xs:string"/>
1113 <xs:attribute name="archBlobRingTexture" type="xs:string"/>
1114 </xs:extension>
1115 </xs:complexContent>
1116 </xs:complexType>
1117 <xs:element name="Minimap" type="MinimapType" substitutionGroup="ui:Frame"/>
1118
1119 <xs:complexType name="PlayerModelType">
1120 <xs:complexContent>
1121 <xs:extension base="ModelType"/>
1122 </xs:complexContent>
1123 </xs:complexType>
1124 <xs:element name="PlayerModel" type="PlayerModelType" substitutionGroup="ui:Frame"/>
1125
1126 <xs:complexType name="DressUpModelType">
1127 <xs:complexContent>
1128 <xs:extension base="PlayerModelType"/>
1129 </xs:complexContent>
1130 </xs:complexType>
1131 <xs:element name="DressUpModel" type="DressUpModelType" substitutionGroup="ui:Frame"/>
1132
1133 <xs:complexType name="TabardModelType">
1134 <xs:complexContent>
1135 <xs:extension base="PlayerModelType"/>
1136 </xs:complexContent>
1137 </xs:complexType>
1138 <xs:element name="TabardModel" type="TabardModelType" substitutionGroup="ui:Frame"/>
1139
1140 <xs:complexType name="CinematicModelType">
1141 <xs:complexContent>
1142 <xs:extension base="ModelType">
1143 <xs:attribute name="facing" type="xs:boolean" default="false"/>
1144 </xs:extension>
1145 </xs:complexContent>
1146 </xs:complexType>
1147 <xs:element name="CinematicModel" type="CinematicModelType" substitutionGroup="ui:Frame"/>
1148
1149 <xs:complexType name="UiCameraType">
1150 <xs:complexContent>
1151 <xs:extension base="ModelType"/>
1152 </xs:complexContent>
1153 </xs:complexType>
1154 <xs:element name="UiCamera" type="UiCameraType" substitutionGroup="ui:Frame"/>
1155
1156 <xs:complexType name="UnitButtonType">
1157 <xs:complexContent>
1158 <xs:extension base="ButtonType"/>
1159 </xs:complexContent>
1160 </xs:complexType>
1161
1162 <xs:complexType name="TaxiRouteFrameType">
1163 <xs:complexContent>
1164 <xs:extension base="FrameType"/>
1165 </xs:complexContent>
1166 </xs:complexType>
1167 <xs:element name="TaxiRouteFrame" type="TaxiRouteFrameType" substitutionGroup="ui:Frame"/>
1168
1169 <xs:complexType name="BrowserType">
1170 <xs:complexContent>
1171 <xs:extension base="FrameType">
1172 <xs:attribute name="IMEFont" type="xs:string"/>
1173 </xs:extension>
1174 </xs:complexContent>
1175 </xs:complexType>
1176 <xs:element name="Browser" type="BrowserType" substitutionGroup="ui:Frame"/>
1177
1178 <xs:complexType name="CheckoutType">
1179 <xs:complexContent>
1180 <xs:extension base="FrameType">
1181 <xs:attribute name="IMEFont" type="xs:string"/>
1182 </xs:extension>
1183 </xs:complexContent>
1184 </xs:complexType>
1185 <xs:element name="Checkout" type="CheckoutType" substitutionGroup="ui:Frame"/>
1186
1187 <xs:complexType name="FogOfWarFrameType">
1188 <xs:complexContent>
1189 <xs:extension base="FrameType">
1190 <xs:attribute name="IMEFont" type="xs:string"/>
1191 </xs:extension>
1192 </xs:complexContent>
1193 </xs:complexType>
1194 <xs:element name="FogOfWarFrame" type="FogOfWarFrameType" substitutionGroup="ui:Frame"/>
1195
1196 <xs:complexType name="ModelSceneType">
1197 <xs:complexContent>
1198 <xs:extension base="FrameType">
1199 <xs:sequence minOccurs="0">
1200 <xs:choice maxOccurs="unbounded">
1201 <xs:element name="FogColor" type="ColorType"/>
1202
1203 <xs:element name="Actors">
1204 <xs:complexType>
1205 <xs:sequence>
1206 <xs:element ref="Actor" maxOccurs="unbounded"/>
1207 </xs:sequence>
1208 </xs:complexType>
1209 </xs:element>
1210 </xs:choice>
1211 </xs:sequence>
1212
1213 <xs:attribute name="fogNear" type="xs:float" default="0.0" />
1214 <xs:attribute name="fogFar" type="xs:float" default="1.0" />
1215 <xs:attribute name="drawLayer" type="ui:DRAWLAYER" default="ARTWORK"/>
1216 </xs:extension>
1217 </xs:complexContent>
1218 </xs:complexType>
1219 <xs:element name="ModelScene" type="ModelSceneType" substitutionGroup="ui:Frame"/>
1220
1221 <xs:simpleType name="ANIMLOOPTYPE">
1222 <xs:restriction base="xs:NMTOKEN">
1223 <xs:enumeration value="NONE"/>
1224 <xs:enumeration value="REPEAT"/>
1225 <xs:enumeration value="BOUNCE"/>
1226 </xs:restriction>
1227 </xs:simpleType>
1228
1229 <xs:simpleType name="ANIMSMOOTHTYPE">
1230 <xs:restriction base="xs:NMTOKEN">
1231 <xs:enumeration value="NONE"/>
1232 <xs:enumeration value="IN"/>
1233 <xs:enumeration value="OUT"/>
1234 <xs:enumeration value="IN_OUT"/>
1235 <xs:enumeration value="OUT_IN"/>
1236 </xs:restriction>
1237 </xs:simpleType>
1238
1239 <xs:simpleType name="ANIMCURVETYPE">
1240 <xs:restriction base="xs:NMTOKEN">
1241 <xs:enumeration value="NONE"/>
1242 <xs:enumeration value="SMOOTH"/>
1243 </xs:restriction>
1244 </xs:simpleType>
1245
1246 <xs:simpleType name="AnimOrderType">
1247 <xs:restriction base="xs:int">
1248 <xs:minInclusive value="1"/>
1249 <xs:maxInclusive value="100"/>
1250 </xs:restriction>
1251 </xs:simpleType>
1252
1253 <xs:complexType name="AnimScriptsType">
1254 <xs:sequence>
1255 <xs:choice maxOccurs="unbounded">
1256 <xs:element name="OnLoad" type="ScriptType"/>
1257 <xs:element name="OnPlay" type="ScriptType"/>
1258 <xs:element name="OnPause" type="ScriptType"/>
1259 <xs:element name="OnStop" type="ScriptType"/>
1260 <xs:element name="OnUpdate" type="ScriptType"/>
1261 <xs:element name="OnFinished" type="ScriptType"/>
1262 </xs:choice>
1263 </xs:sequence>
1264 </xs:complexType>
1265
1266 <xs:complexType name="AnimGroupScriptsType">
1267 <xs:sequence>
1268 <xs:choice maxOccurs="unbounded">
1269 <xs:element name="OnLoad" type="ScriptType"/>
1270 <xs:element name="OnPlay" type="ScriptType"/>
1271 <xs:element name="OnPause" type="ScriptType"/>
1272 <xs:element name="OnStop" type="ScriptType"/>
1273 <xs:element name="OnUpdate" type="ScriptType"/>
1274 <xs:element name="OnFinished" type="ScriptType"/>
1275 <xs:element name="OnLoop" type="ScriptType"/>
1276 </xs:choice>
1277 </xs:sequence>
1278 </xs:complexType>
1279
1280 <xs:complexType name="AnimOriginType">
1281 <xs:sequence minOccurs="0">
1282 <xs:element name="Offset" type="Dimension"/>
1283 </xs:sequence>
1284 <xs:attribute name="point" type="FRAMEPOINT" default="CENTER"/>
1285 </xs:complexType>
1286
1287 <xs:complexType name="AnimationType">
1288 <xs:sequence>
1289 <xs:element name="Scripts" type="AnimScriptsType" minOccurs="0" maxOccurs="unbounded"/>
1290 </xs:sequence>
1291 <xs:attribute name="name" type="xs:string"/>
1292 <xs:attribute name="inherits" type="xs:string"/>
1293 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
1294 <xs:attribute name="target" type="xs:string"/>
1295 <xs:attribute name="targetKey" type="xs:string"/>
1296 <xs:attribute name="parentKey" type="xs:string"/>
1297 <xs:attribute name="childKey" type="xs:string"/>
1298 <xs:attribute name="startDelay" type="xs:float" default="0.0"/>
1299 <xs:attribute name="endDelay" type="xs:float" default="0.0"/>
1300 <xs:attribute name="duration" type="xs:float"/>
1301 <xs:attribute name="order" type="AnimOrderType" default="1"/>
1302 <xs:attribute name="smoothing" type="ANIMSMOOTHTYPE" default="NONE"/>
1303 </xs:complexType>
1304 <xs:element name="Animation" type="AnimationType"/>
1305
1306 <xs:complexType name="TranslationType">
1307 <xs:complexContent>
1308 <xs:extension base="AnimationType">
1309 <xs:attribute name="offsetX" type="xs:float" default="0.0"/>
1310 <xs:attribute name="offsetY" type="xs:float" default="0.0"/>
1311 </xs:extension>
1312 </xs:complexContent>
1313 </xs:complexType>
1314 <xs:element name="Translation" type="TranslationType" substitutionGroup="Animation"/>
1315
1316 <xs:complexType name="LineTranslationType">
1317 <xs:complexContent>
1318 <xs:extension base="TranslationType" />
1319 </xs:complexContent>
1320 </xs:complexType>
1321 <xs:element name="LineTranslation" type="LineTranslationType" substitutionGroup="Animation"/>
1322
1323 <xs:complexType name="RotationType">
1324 <xs:complexContent>
1325 <xs:extension base="AnimationType">
1326 <xs:sequence>
1327 <xs:element name="Origin" type="AnimOriginType" minOccurs="0"/>
1328 </xs:sequence>
1329 <xs:attribute name="degrees" type="xs:float" default="0.0"/>
1330 <xs:attribute name="radians" type="xs:float" default="0.0"/>
1331 </xs:extension>
1332 </xs:complexContent>
1333 </xs:complexType>
1334 <xs:element name="Rotation" type="RotationType" substitutionGroup="Animation"/>
1335
1336 <xs:complexType name="ScaleType">
1337 <xs:complexContent>
1338 <xs:extension base="AnimationType">
1339 <xs:sequence>
1340 <xs:element name="Origin" type="AnimOriginType" minOccurs="0"/>
1341 </xs:sequence>
1342 <xs:attribute name="scaleX" type="xs:float" default="1.0"/>
1343 <xs:attribute name="scaleY" type="xs:float" default="1.0"/>
1344 <xs:attribute name="fromScaleX" type="xs:float" default="1.0"/>
1345 <xs:attribute name="fromScaleY" type="xs:float" default="1.0"/>
1346 <xs:attribute name="toScaleX" type="xs:float" default="1.0"/>
1347 <xs:attribute name="toScaleY" type="xs:float" default="1.0"/>
1348 </xs:extension>
1349 </xs:complexContent>
1350 </xs:complexType>
1351 <xs:element name="Scale" type="ScaleType" substitutionGroup="Animation"/>
1352
1353 <xs:complexType name="LineScaleType">
1354 <xs:complexContent>
1355 <xs:extension base="ScaleType"/>
1356 </xs:complexContent>
1357 </xs:complexType>
1358 <xs:element name="LineScale" type="LineScaleType" substitutionGroup="Animation"/>
1359
1360 <xs:complexType name="AlphaType">
1361 <xs:complexContent>
1362 <xs:extension base="AnimationType">
1363 <xs:attribute name="fromAlpha" type="xs:float" default="0.0"/>
1364 <xs:attribute name="toAlpha" type="xs:float" default="1.0"/>
1365 </xs:extension>
1366 </xs:complexContent>
1367 </xs:complexType>
1368 <xs:element name="Alpha" type="AlphaType" substitutionGroup="Animation"/>
1369
1370 <xs:complexType name="ControlPointsType">
1371 <xs:sequence minOccurs="0">
1372 <xs:choice maxOccurs="unbounded">
1373 <xs:element name="ControlPoint" maxOccurs="unbounded">
1374 <xs:complexType>
1375 <xs:attribute name="name" type="xs:string"/>
1376 <xs:attribute name="offsetX" type="xs:float" default="0.0"/>
1377 <xs:attribute name="offsetY" type="xs:float" default="0.0"/>
1378 </xs:complexType>
1379 </xs:element>
1380 </xs:choice>
1381 </xs:sequence>
1382 </xs:complexType>
1383 <xs:element name="ControlPoints" type="ControlPointsType"/>
1384
1385 <xs:complexType name="PathType">
1386 <xs:complexContent>
1387 <xs:extension base="AnimationType">
1388 <xs:sequence minOccurs="0">
1389 <xs:choice maxOccurs="unbounded">
1390 <xs:element name="ControlPoints" type="ControlPointsType"/>
1391 </xs:choice>
1392 </xs:sequence>
1393 <xs:attribute name="curve" type="ANIMCURVETYPE" default="NONE"/>
1394 </xs:extension>
1395 </xs:complexContent>
1396 </xs:complexType>
1397 <xs:element name="Path" type="PathType" substitutionGroup="Animation"/>
1398
1399 <xs:complexType name="AnimationGroupType">
1400 <xs:sequence minOccurs="0">
1401 <xs:choice maxOccurs="unbounded">
1402 <xs:element ref="Animation"/>
1403 <xs:element name="Scripts" type="AnimGroupScriptsType"/>
1404 </xs:choice>
1405 </xs:sequence>
1406 <xs:attribute name="name" type="xs:string"/>
1407 <xs:attribute name="inherits" type="xs:string"/>
1408 <xs:attribute name="virtual" type="xs:boolean" default="false"/>
1409 <xs:attribute name="parentKey" type="xs:string"/>
1410 <xs:attribute name="looping" type="ANIMLOOPTYPE" default="NONE"/>
1411 <xs:attribute name="setToFinalAlpha" type="xs:boolean" default="false"/>
1412 </xs:complexType>
1413 <xs:element name="AnimationGroup" type="AnimationGroupType"/>
1414 </xs:schema>
File src/ClearcastingFrame.lua deleted (index 235a400..0000000)
1 --[[--
2 Clearcasting addon.
3
4 @script clearcasting
5 ]]
6
7 local function debug(msg)
8 if true == ClearcastingDebugFlag then
9 print('[Clearcasting]: ' .. tostring(msg) .. '.')
10 end
11 end
12
13 --[[--
14 Attempt to find a file that contains picture appropriate for given effect.
15 @function findPictureFile
16 @tparam string auraName localised name of an effect that requires a picture
17 @treturn string path to the picture file, either in client archive or
18 add-on directory
19 ]]
20 local function findPictureFile(auraName)
21 local pictureFile
22
23 --[[ Apply picture of associated spell, if present. ]]--
24 pictureFile = GetSpellTexture(auraName)
25 if pictureFile ~= nil then
26 return pictureFile
27 end
28
29 --[[ If not, apply picture of associated talent, if present. ]]--
30 local i = 0
31 while (i < 4) do
32 i = i + 1
33 local j = 0
34 while (j < 64) do
35 j = j + 1
36 local talentName, talentPictureFile = GetTalentInfo(i, j)
37 if auraName == talentName then
38 pictureFile = talentPictureFile
39 return pictureFile
40 end
41 end
42 end
43
44 --[[ If talents are not yet loaded, which happens at start of the game,
45 -- use predefined picture. ]]--
46 local pictureMap = {
47 ["Infusion of Light"] = "Interface\\Icons\\Ability_Paladin_InfusionofLight",
48 ["Judgements of the Pure"] = "Interface\\Icons\\Ability_Paladin_JudgementofthePure",
49 ["Light's Grace"] = "Interface\\Icons\\Spell_Holy_LightsGrace",
50 ["Serendipity"] = "Interface\\Icons\\Spell_Holy_Serendipity",
51 ["Borrowed Time"] = "Interface\\Icons\\Spell_Holy_BorrowedTime",
52 ["Surge of Light"] = "Interface\\Icons\\Spell_Holy_SurgeofLight",
53 ["Enrage"] = "Interface\\Icons\\Spell_Shadow_UnholyFrenzy",
54 }
55 pictureFile = pictureMap[auraName]
56
57 --[[ If nothing was found use a question mark picture as a fallback. ]]--
58 if nil == pictureFile or string.len(pictureFile) < 1 then
59 pictureFile = "Interface\\Icons\\INV_Misc_QuestionMark"
60 end
61
62 return pictureFile
63 end
64
65 local function getIndicatorDefaultSize()
66 return 32
67 end
68
69 local function createIndicator(frameName, parentFrame, unitDesignation, auraName, auraId)
70 assert (frameName ~= nil)
71 assert (parentFrame ~= nil)
72 assert (unitDesignation ~= nil)
73 assert (auraName ~= nil)
74 if auraId ~= nil then
75 assert (auraId >= 1)
76 end
77
78 local f = CreateFrame('FRAME', frameName, parentFrame)
79 local size = getIndicatorDefaultSize()
80 f:SetSize(size, size)
81 f:SetPoint('BOTTOMLEFT', 0, 0)
82
83 local b = f:CreateTexture(frameName .. 'Background', 'BACKGROUND')
84 b:SetAllPoints()
85 local icon = findPictureFile(auraName)
86 b:SetTexture(icon)
87
88 local t = f:CreateFontString(frameName .. 'Text', 'OVERLAY')
89 local fontObject = ClearcastingFont
90 if nil == fontObject then
91 fontObject = GameFontNormal
92 end
93 t:SetFontObject(fontObject)
94 t:SetAllPoints()
95 t:SetText('?')
96
97 f.auraName = auraName
98 if nil ~= auraId then
99 f.auraId = math.floor(auraId)
100 end
101 f.background = b
102 f.text = t
103 f.unitDesignation = unitDesignation
104
105 debug('create indicator ' .. auraName .. ' ' .. tostring(auraId) ..
106 ' ' .. icon )
107
108 f:Hide()
109 return f
110 end
111
112 local function acceptUnitAura(rootFrame, unitDesignation)
113 if 'player' ~= unitDesignation then
114 return
115 end
116
117 local t = rootFrame.indicatorTable
118 assert (t ~= nil)
119
120 local k = #t
121 while (k > 0) do
122 local v = t[k]
123 if v ~= nil then
124 v:Hide()
125 end
126 k = k - 1
127 end
128
129 local j = 0
130 while (j < 1024) do
131 j = j + 1
132 local _, _, icon, _, _, _, _,
133 _, _, _,
134 spellId = UnitAura(unitDesignation, j)
135 if nil == spellId then
136 break
137 end
138 --[[assert (name ~= nil)
139 assert (rank ~= nil)
140 assert (icon ~= nil)
141 assert (count ~= nil)
142 assert (debuffType ~= nil)
143 assert (duration ~= nil)
144 assert (expirationTime ~= nil)
145 assert (unitCaster ~= nil)
146 assert (isStealable ~= nil)
147 assert (shouldConsolidate ~= nil)
148 assert (spellId ~= nil)]]--
149
150 local i = #t
151 while (i > 0) do
152 local f = t[i]
153 if f ~= nil then
154 if f.auraId == spellId then
155 f.background:SetTexture(icon)
156 f:Show()
157 end
158 end
159 i = i - 1
160 end
161
162 end
163 end
164
165 local function getAuraId(spellName, spellCategory)
166 local spellLink = GetSpellLink(spellName, spellCategory)
167 if spellLink then
168 return tonumber(spellLink:match("spell:(%d+)"))
169 else
170 return nil
171 end
172 end
173
174 local function reload(rootFrame)
175 debug('enter reload')
176 assert (rootFrame ~= nil)
177
178 local t = rootFrame.indicatorTable
179 assert (t ~= nil)
180 assert ('table' == type(t))
181 assert (#t >= 1)
182 assert (#t <= 1024)
183
184 rootFrame.elapsedSecs = 0.0
185
186 local i = #t
187 while (i > 0) do
188 local f = t[i]
189 assert (f ~= nil)
190 assert (f:GetName() ~= nil)
191 assert (f.background ~= nil)
192
193 local auraName = f.auraName
194 assert (auraName ~= nil)
195 assert ('string' == type(auraName))
196 assert (string.len(auraName) >= 2)
197
198 if not f.auraId then
199 f.auraId = getAuraId(auraName)
200 if not f.auraId then
201 debug('spell "' .. tostring(auraName) .. '" is unavailable (188).')
202 end
203 end
204
205 local pictureFile = findPictureFile(auraName)
206 if pictureFile then
207 assert (pictureFile ~= nil)
208 assert ('string' == type(pictureFile))
209 assert (string.len(pictureFile) >= 2)
210 f.background:SetTexture(pictureFile)
211 else
212 f.background:SetTexture(nil)
213 end
214
215 i = i - 1
216 end
217 debug('exit reload')
218 end
219
220 function ClearcastingReload()
221 if nil == ClearcastingFrame then
222 error('[Clearcasting]: could not access root frame')
223 end
224 reload(ClearcastingFrame)
225 end
226
227 local function eventProcessor(rootFrame, eventCategory, ...)
228 if 'UNIT_AURA' == eventCategory then
229 local unitDesignation = select(1, ...)
230 acceptUnitAura(rootFrame, unitDesignation)
231 elseif 'SPELLS_CHANGED' == eventCategory then
232 reload(rootFrame)
233 elseif 'ADDON_LOADED' == eventCategory then
234 reload(rootFrame)
235 elseif 'PLAYER_ENTERS_WORLD' == eventCategory then
236 reload(rootFrame)
237 end
238 end
239
240 local function getUnitAuraRemainingSecs(unitDesignation, auraId)
241 local auraName = GetSpellInfo(auraId)
242 assert (auraName ~= nil)
243 local name, _, _, stackQuantity, _,
244 duration, expirationTime = UnitAura(unitDesignation, auraName)
245 if nil == name then
246 return -1
247 end
248 if nil == stackQuantity or type(stackQuantity) ~= 'number' then
249 stackQuantity = 0
250 end
251 stackQuantitiy = math.min(math.max(0, stackQuantity), 99)
252 return (expirationTime - GetTime()), duration, stackQuantity
253 end
254
255 local function updateEveryIndicator(rootFrame)
256 local t = rootFrame.indicatorTable
257 local i = #t
258 while (i > 0) do
259 local f = t[i]
260 assert (f ~= nil)
261 local auraId = f.auraId
262 local auraName = f.auraName
263 if auraId ~= nil then
264 assert (auraId >= 1)
265 local unitDesignation = f.unitDesignation
266 local remainingSecs, duration, stackQuantity = getUnitAuraRemainingSecs(unitDesignation, auraId)
267 if remainingSecs > 0 then
268 f:Show()
269 local t = ''
270 if stackQuantity > 1 then
271 t = string.format("%.0f\r\n%d*", remainingSecs, stackQuantity)
272 else
273 t = string.format("%.0f", remainingSecs)
274 end
275 f.text:SetText(t)
276 local r = remainingSecs / duration
277 local bleed = math.min(1.5 * r, 1)
278 f.background:SetVertexColor(1, bleed, bleed)
279 else
280 f:Hide()
281 f.text:SetText(nil)
282 end
283 end
284 i = i - 1
285 end
286 end
287
288 local function updateProcessor(rootFrame, elapsedSecs)
289 assert (rootFrame ~= nil)
290 assert (elapsedSecs ~= nil)
291 assert (type(elapsedSecs) == 'number')
292 elapsedSecs = math.min(math.max(0, elapsedSecs), 999)
293
294 local duration = rootFrame.elapsedSecs
295 if duration == nil then
296 duration = 0.0
297 elseif type(duration) ~= 'number' then
298 duration = 0.0
299 end
300 duration = math.min(math.max(0, duration + elapsedSecs), 999)
301 rootFrame.elapsedSecs = duration
302 if duration >= 0.08 then
303 updateEveryIndicator(rootFrame)
304 rootFrame.elapsedSecs = 0.0
305 end
306 end
307
308 --[[--
309 Use unique aura identifier when possible.
310 Otherwise use aura name. Function may fail when given spell name.
311 An aura is either a spell in character spell book or talent effect.
312 Given unique identifier of a currently unavailable ability
313 the function produces an error.
314 ]]
315 local function isSpellAvailable(eitherSpellIdOrName)
316 local n = GetSpellInfo(eitherSpellIdOrName)
317 return n ~= nil
318 end
319
320 local function initIndicator(rootFrame, auraName, column, row, auraId)
321 assert (rootFrame ~= nil)
322
323 assert (auraName ~= nil)
324 assert (string.len(auraName) >= 2)
325
326 if not column then
327 column = 0
328 end
329 column = math.max(column, 0)
330
331 if not row then
332 row = 0
333 end
334 row = math.max(row, 0)
335
336 if nil == auraId then
337 auraId = getAuraId(auraName)
338 end
339 if auraId ~= nil then
340 assert (auraId >= 1, '[Clearcasting]: invalid aura identifier')
341 end
342
343 if not isSpellAvailable(auraName) then
344 debug('cannot initialise spell "' .. tostring(auraName) .. '" ' ..
345 'aura identifier ' .. tostring(auraId) .. ' (line 343)')
346 end
347
348 if nil == rootFrame.indicatorTable then
349 rootFrame.indicatorTable = {}
350 end
351
352 local t = rootFrame.indicatorTable
353 if not t then
354 t = {}
355 rootFrame.indicatorTable = t
356 end
357 assert (t ~= nil)
358 assert ('table' == type(t))
359
360 local frameName = string.format('ClearcastingButton%02d', #t + 1)
361 local f = createIndicator(frameName, rootFrame, 'player', auraName, auraId)
362 assert (f ~= nil)
363
364 local size = getIndicatorDefaultSize()
365 f:SetPoint('BOTTOMLEFT', size * column, size * row)
366 table.insert(t, f)
367
368 assert (f ~= nil)
369 assert (f:GetName() ~= nil)
370 return f
371 end
372
373 local function initPaladinIndicator(rootFrame)
374 initIndicator(rootFrame, "Aura Mastery", 0, 4, 31821)
375 initIndicator(rootFrame, "Avenging Wrath", 0, 2)
376 initIndicator(rootFrame, "Divine Illumination", 0, 0)
377 initIndicator(rootFrame, "Divine Plea", 1, 0)
378 initIndicator(rootFrame, "Divine Protection", 0, 1)
379 initIndicator(rootFrame, "Divine Sacrifice", 2, 2)
380 initIndicator(rootFrame, "Divine Shield", 0, 0)
381 initIndicator(rootFrame, "Gift of the Naaru", 0, 4)
382 initIndicator(rootFrame, "Hand of Freedom", 2, 0)
383 initIndicator(rootFrame, "Hand of Protection", 0, 3)
384 initIndicator(rootFrame, "Hand of Sacrifice", 2, 1)
385 initIndicator(rootFrame, "Hand of Salvation", 2, 3)
386 initIndicator(rootFrame, "Holy Shield", 1, 3)
387 initIndicator(rootFrame, "Infusion of Light", 1, 3, 54149)
388 initIndicator(rootFrame, "Judgements of the Pure", 1, 1, 54153)
389 initIndicator(rootFrame, "Light's Grace", 1, 2, 31834)
390 end
391
392 local function initWarriorIndicator(rootFrame)
393 initIndicator(rootFrame, "Berserker Rage", 1, 0)
394 initIndicator(rootFrame, "Bladestorm", 0, 0)
395 initIndicator(rootFrame, "Death Wish", 1, 0)
396 initIndicator(rootFrame, "Enrage", 1, 2, 57514)
397 initIndicator(rootFrame, "Glyph of Blocking", 1, 1, 58374)
398 initIndicator(rootFrame, "Juggernaut", 1, 1)
399 initIndicator(rootFrame, "Last Stand", 0, 2)
400 initIndicator(rootFrame, "Recklessness", 0, 0)
401 initIndicator(rootFrame, "Retaliation", 0, 1)
402 initIndicator(rootFrame, "Shield Block", 0, 1)
403 initIndicator(rootFrame, "Shield Wall", 0, 0)
404 initIndicator(rootFrame, "Spell Reflection", 2, 2)
405 initIndicator(rootFrame, "Sudden Death", 1, 2, 29723)
406 initIndicator(rootFrame, "Sword and Board", 1, 3, 50227)
407 initIndicator(rootFrame, "Taste for Blood", 1, 3, 60503)
408 end
409
410 local function initEveryIndicator(rootFrame)
411 local _, playerClassDesignation = UnitClass('player')
412 if 'DEATHKNIGHT' == playerClassDesignation then
413 initIndicator(rootFrame, 'Anti-Magic Shell', 0, 2)
414 initIndicator(rootFrame, 'Icebound Fortitude', 0, 3)
415 initIndicator(rootFrame, 'Anti-Magic Zone', 0, 0)
416 elseif 'PALADIN' == playerClassDesignation then
417 initPaladinIndicator(rootFrame)
418 elseif 'PRIEST' == playerClassDesignation then
419 initIndicator(rootFrame, 'Surge of Light', 0, 2, 33151)
420 initIndicator(rootFrame, 'Serendipity', 0, 3, 63731)
421 initIndicator(rootFrame, 'Borrowed Time', 0, 3, 59891)
422 elseif 'DRUID' == playerClassDesignation then
423 initIndicator(rootFrame, 'Clearcasting', 0, 0)
424 elseif 'WARRIOR' == playerClassDesignation then
425 initWarriorIndicator(rootFrame)
426 elseif 'WARLOCK' == playerClassDesignation then
427 initIndicator(rootFrame, 'Backdraft', 0, 1, 47260)
428 initIndicator(rootFrame, 'Backlash', 0, 2, 34939)
429 initIndicator(rootFrame, 'Decimation', 0, 1, 63158)
430 initIndicator(rootFrame, 'Eradication', 0, 1, 64371)
431 initIndicator(rootFrame, 'Molten Core', 0, 1, 71165)
432 initIndicator(rootFrame, 'Shadow Trance', 0, 2, 17941)
433 initIndicator(rootFrame, 'Life Tap', 0, 0, 63321)
434 else
435 error('[Clearcasting]: Unsupported class ' .. playerClassDesignation .. '.')
436 end
437 return rootFrame.indicatorTable
438 end
439
440 local function init(rootFrame)
441 debug('enter init')
442 local t = initEveryIndicator(rootFrame)
443 assert (t ~= nil)
444 assert (#t >= 1)
445
446 rootFrame:UnregisterAllEvents()
447
448 rootFrame:SetScript('OnEvent', eventProcessor)
449
450 rootFrame.elapsedSecs = 0.0
451 rootFrame:SetScript('OnUpdate', updateProcessor)
452
453 rootFrame:RegisterEvent('UNIT_AURA')
454 rootFrame:RegisterEvent('SPELLS_CHANGED')
455 debug('exit init')
456 end
457
458 local function main()
459 assert ('enGB' == GetLocale() or 'enUS' == GetLocale())
460 local rootFrame = CreateFrame('FRAME', 'ClearcastingFrame', UIParent)
461 rootFrame:SetSize(384, 288)
462 rootFrame:SetPoint('CENTER', UIParent, 'CENTER', 0, 0)
463
464 rootFrame:SetScript('OnEvent', init)
465 rootFrame:RegisterEvent('VARIABLES_LOADED')
466 end
467 main()
Hints:
Before first commit, do not forget to setup your git environment:
git config --global user.name "your_name_here"
git config --global user.email "your@email_here"

Clone this repository using HTTP(S):
git clone https://rocketgit.com/user/vrtc/clearcasting

Clone this repository using ssh (do not forget to upload a key first):
git clone ssh://rocketgit@ssh.rocketgit.com/user/vrtc/clearcasting

Clone this repository using git:
git clone git://git.rocketgit.com/user/vrtc/clearcasting

You are allowed to anonymously push to this repository.
This means that your pushed commits will automatically be transformed into a merge request:
... clone the repository ...
... make some changes and some commits ...
git push origin main