vrtc / chorus (public) (License: CC0) (since 2023-08-12) (hash sha1)
World of Warcraft add-on stub. The overall goal is to create a specialized raid frame.
List of commits:
Subject Hash Author Date (UTC)
feat!: Correct range indcator for all characters 8ef1a987ac4431ce90131c354d1a1775b653f3e3 Vladyslav Bondarenko 2023-08-22 15:05:35
fix: Improve health bar robustness 2be053184653a6cd282437f8190e9196af495d81 Vladyslav Bondarenko 2023-08-22 13:24:12
fix: Upgrade aura sorting a2132995674f81e0775def67b0f5786945b0bba3 Vladyslav Bondarenko 2023-08-22 13:21:37
feat: Add threat percentage for hostiles 590bc95167dfc0f22a135fe173182104b6f5b923 Vladyslav Bondarenko 2023-08-22 13:17:57
feat: Add threat for hostiles 22562481a0c9dfb297ebbe47da4aa19046cf6eeb Vladyslav Bondarenko 2023-08-21 22:28:50
fix(build): Add more luacheck definitions aac4bb444d894b5d565af3abe417cbafd4f966f5 Vladyslav Bondarenko 2023-08-21 18:09:50
fix: Ensure TargetFrame is hidden 98bd355e604bf1c51791d5f5874ef33ab640123c Vladyslav Bondarenko 2023-08-21 14:04:40
fix: Show only meaningful numbers for health 37217b1dc78c0a2b4711dc45ada0c4873e904a1f Vladyslav Bondarenko 2023-08-21 13:32:19
fix: Remove testing range frame 4fcfd5c7bf4626137a1251cbcbe54157055ac875 Vladyslav Bondarenko 2023-08-21 13:10:16
fix: Place solo frames range frame correctly f926b1fb857a48b14a706926f14b5da730d210f1 Vladyslav Bondarenko 2023-08-21 13:08:42
feat!: Re-add player solo frames bf5346aa96a3daeadafeb3a723f7821012f1d5e5 Vladyslav Bondarenko 2023-08-21 12:22:48
fix: Render raid target icon on correct layer 890bb5340a3876b611f67ac1277cc009e5e4df5b Vladyslav Bondarenko 2023-08-20 18:12:31
feat: Display health deficit 0620038bf95d2c8e77eb088f2345764f428563d4 Vladyslav Bondarenko 2023-08-20 17:55:49
fix(build): Update rockspec dcffb9897deb97fa4039cd4513a51e397ebc4ab7 Vladyslav Bondarenko 2023-08-20 17:16:25
feat!: Update raid frame layout ad51f7e37e8babd30ee45c5b87d931a09c1fc0f3 Vladyslav Bondarenko 2023-08-20 14:45:38
fix: Do not show range to oneself c055a76806c5646e4027698c6a105f06199be4ae Vladyslav Bondarenko 2023-08-20 04:29:32
feat!: Add raid targeting icons 53121d5d75fb55d745734337ab70283496e46e7c Vladyslav Bondarenko 2023-08-19 23:22:01
feat!: Add general threat situation widget a002db1c9c810f21fe1e1c042a435875bbe5f317 Vladyslav Bondarenko 2023-08-19 22:20:58
fix!: Highlight offline players 7c28b6efa34f6e5450d2999acfd5a54880aa6df0 Vladyslav Bondarenko 2023-08-19 21:06:38
fix!: Change aura sorting ba249c7309ccbcb14fea727b347c3dd532af73ee Vladyslav Bondarenko 2023-08-19 20:40:31
Commit 8ef1a987ac4431ce90131c354d1a1775b653f3e3 - feat!: Correct range indcator for all characters
Modify approximate range widget of unit buttons to work and display
correct values for all character classes. Previously only paladins and
priests showed meaningful numbers.

Additionally, show range to resurrectable player character corpses.

Range is approximated based on spell available in the player character's
spell book at present time. Previously the possible combinations were
explicitly defined in the source. Since this change the spell map is
populated at runtime when appropriate.

This is a necessary change. It allows to encompass all classes and
abstract away the implementation specifics of each character type.
Author: Vladyslav Bondarenko
Author date (UTC): 2023-08-22 15:05
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2023-08-22 15:05
Parent(s): 2be053184653a6cd282437f8190e9196af495d81
Signer:
Signing key: EFF9624877D25D02
Signing status: E
Tree: 70c1eb669af326cfd2c172704df4134adba2956a
File Lines added Lines deleted
etc/luacheckrc.lua 2 0
src/ChorusRangeFrameTemplate.lua 87 20
src/ChorusRangeFrameTemplate.xml 5 0
File etc/luacheckrc.lua changed (mode: 100644) (index 1a5738c..5861842)
... ... stds.wowapi = {
12 12 'GetPlayerInfoByGUID', 'GetPlayerInfoByGUID',
13 13 'GetRaidTargetIndex', 'GetRaidTargetIndex',
14 14 'GetSpellInfo', 'GetSpellInfo',
15 'GetSpellName',
15 16 'GetSpellTexture', 'GetSpellTexture',
16 17 'GetThreatStatusColor', 'GetThreatStatusColor',
17 18 'GetTime', 'GetTime',
 
... ... stds.framexml = {
77 78 'FocusFrameSpellBar', 'FocusFrameSpellBar',
78 79 'GameFontWhite', 'GameFontWhite',
79 80 'MAX_PARTY_MEMBERS', 'MAX_PARTY_MEMBERS',
81 'MAX_SPELLS',
80 82 'NumberFontNormalSmall', 'NumberFontNormalSmall',
81 83 'PartyMemberBackground', 'PartyMemberBackground',
82 84 'PartyMemberFrame1', 'PartyMemberFrame1',
File src/ChorusRangeFrameTemplate.lua changed (mode: 100644) (index c2333fb..5c5bd94)
1 local GetSpellName = GetSpellName
1 2 local IsSpellInRange = IsSpellInRange local IsSpellInRange = IsSpellInRange
2 3
4 local MAX_SPELLS = MAX_SPELLS
5
3 6 local Chorus = Chorus local Chorus = Chorus
4 7
5 --[[ Populate range spell map at runtime initialization. ]]--
6 local spellMap = {
7 --[[ Paladin ]]--
8 ['Beacon of Light'] = 60,
9 ['Blessing of Might'] = 30,
10 ['Cleanse'] = 40,
11 ['Hammer of Justice'] = 10,
12 ['Purify'] = 40,
13 ['Holy Shock'] = 20,
14 ['Exorcism'] = 30,
15 --[[ Priest ]]--
16 ['Lesser Heal'] = 40,
17 ['Smite'] = 30,
18 ['Power Word: Fortitude'] = 30,
19 ['Resurrection'] = 30,
20 ['Mind Control'] = 20,
21 --[[ Any ]]--
22 ['Shoot'] = 30,
23 }
8 --[[ See ChorusRangeFrameTemplate.lua:function spellRangeMapUpdate. ]]--
9 --[[ See ChorusRangeFrameTemplate.lua:function rangeFrameUpdate. ]]--
10 local spellRangeMap = {}
11
12 local function spellRangeMapUpdate()
13 local maxSpells = MAX_SPELLS or 1024
14 maxSpells = math.min(math.max(1, math.abs(math.floor(maxSpells)), 8192))
15
16 local buffer = {}
17
18 local i = 0
19 while (i < maxSpells) do
20 i = i + 1
21
22 --[[ Get player spell book button number "i", and request it's
23 corresponding spell name. This is NOT a unique spell
24 identifier. Every spell rank is a separate button. ]]--
25 local spellName = GetSpellName(i, 'player')
26 if not spellName then
27 break
28 end
29
30 --[[ When GetSpellInfo is called with localized spell name
31 string, it only returns data on the spells stored in the
32 current player character's spell book. ]]--
33 local _, _, _, _, _, _, _, _, maxRangeYards = GetSpellInfo(spellName)
34 if spellName and maxRangeYards then
35 assert(spellName ~= nil)
36 assert('string' == type(spellName))
37 spellName = strtrim(spellName)
38 assert(string.len(spellName) >= 1)
39 assert(string.len(spellName) <= 8192)
40
41 assert(maxRangeYards ~= nil)
42 assert('number' == type(maxRangeYards))
43 maxRangeYards = math.abs(math.floor(maxRangeYards))
44
45 if maxRangeYards >= 1 then
46 local oldRangeYards = spellRangeMap[spellName]
47
48 --[[
49 Previous rank of the spell already mapped.
50 Only the most potentially efficient spell rank
51 will be mapped. ]]--
52
53 if oldRangeYards then
54 maxRangeYards = math.max(maxRangeYards, oldRangeYards)
55 end
56
57 --[[
58 Priest spell "Mind Vision" has range of 50_000
59 yards. This isn't a useful specificity, so
60 filter it out. Only allow spell ranges that can
61 be reasonably displayed and understood by the
62 user during game combat play. Do not round down
63 the value itself. Only store correct
64 values.]]--
65 if maxRangeYards < 99 then
66 buffer[spellName] = maxRangeYards
67 end
68 end
69 end
70 end
71
72 --[[ At this point assume no errors occurred. Re-write the actual spell
73 range map. ]]--
74 spellRangeMap = buffer
75 end
24 76
25 77 --[[ Duplicate getUnit logic to make sure it cannot be overriden at runtime. ]]-- --[[ Duplicate getUnit logic to make sure it cannot be overriden at runtime. ]]--
26 78
 
... ... local function rangeFrameUpdate(self)
56 108 local rangeFlag = nil local rangeFlag = nil
57 109 local distanceYards = nil local distanceYards = nil
58 110 local maxRangeYards = 0 local maxRangeYards = 0
59 for spellName, rangeYards in pairs(spellMap) do
111 for spellName, rangeYards in pairs(spellRangeMap) do
60 112 local flag = IsSpellInRange(spellName, unitDesignation) local flag = IsSpellInRange(spellName, unitDesignation)
61 113 --[[ 1 == flag: in range; ]]-- --[[ 1 == flag: in range; ]]--
62 114 --[[ 0 == flag: out of range; ]]-- --[[ 0 == flag: out of range; ]]--
 
... ... local function rangeFrameMain(self)
112 164 self:SetScript('OnUpdate', rangeFrameUpdateProcessor) self:SetScript('OnUpdate', rangeFrameUpdateProcessor)
113 165 end end
114 166
167 local function rangeSpellMapFrameMain(self)
168 assert(self ~= nil)
169
170 self:RegisterEvent('ACTIVE_TALENT_GROUP_CHANGED')
171 self:RegisterEvent('LEARNED_SPELL_IN_TAB')
172 self:RegisterEvent('PLAYER_LOGIN')
173 self:RegisterEvent('PLAYER_TALENT_UPDATE')
174 self:RegisterEvent('SPELLS_CHANGED')
175 self:SetScript('OnEvent', spellRangeMapUpdate)
176 end
177
115 178 --[[ Hide reference to the internal function, for some reason. ]]-- --[[ Hide reference to the internal function, for some reason. ]]--
116 179 Chorus.rangeFrameMain = function(...) Chorus.rangeFrameMain = function(...)
117 180 return rangeFrameMain(...) return rangeFrameMain(...)
118 181 end end
182
183 Chorus.rangeSpellMapFrameMain = function(...)
184 return rangeSpellMapFrameMain(...)
185 end
File src/ChorusRangeFrameTemplate.xml changed (mode: 100644) (index 3d60617..585750c)
1 1 <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
2 2 <Ui xmlns="http://www.blizzard.com/wow/ui/"> <Ui xmlns="http://www.blizzard.com/wow/ui/">
3 3 <Script file="ChorusRangeFrameTemplate.lua"/> <Script file="ChorusRangeFrameTemplate.lua"/>
4 <Frame name="ChorusRangeSpellMapFrame">
5 <Scripts>
6 <OnLoad>Chorus.rangeSpellMapFrameMain(self);</OnLoad>
7 </Scripts>
8 </Frame>
4 9 <Frame name="ChorusRangeFrameTemplate" virtual="true"> <Frame name="ChorusRangeFrameTemplate" virtual="true">
5 10 <Size> <Size>
6 11 <AbsDimension x="48" y="24" /> <AbsDimension x="48" y="24" />
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/chorus

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

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

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