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)
fix!: Cast bar consistent between targets a7c5e11ec5094033e946a95002010e5b02d6da74 Vladyslav Bondarenko 2023-08-26 21:56:35
feat(build): Update project descriptors for 0.3 740e01cc3a8888e0500ce213d7901f66625919ab Vladyslav Bondarenko 2023-08-25 21:15:10
feat: Add solo target of target f11b332540168ff42f4f9b53abd87b8b2a09db65 Vladyslav Bondarenko 2023-08-25 20:44:27
feat: Add player pet button to solo frame 00e67525cafb6db5256cd43ecf8a7f510354b88f Vladyslav Bondarenko 2023-08-25 19:58:10
fix: Hide power (mana) bar when appropriate e307bbfdabbe63faed3a7de9e0152639418496b8 Vladyslav Bondarenko 2023-08-25 19:56:53
feat!: Add party frame f50f93dc80f86f8fb280836366252520fd417b29 Vladyslav Bondarenko 2023-08-25 18:18:24
fix!: Toggle frame visibility with unit watch 3ab89d1ee3ae8d2a1afa94610140767b28f12c6a Vladyslav Bondarenko 2023-08-25 18:09:32
feat!: Add target of target or raid target units af78c022d560f964fd38e973491a4e815bf13275 Vladyslav Bondarenko 2023-08-25 18:03:08
fix!: Hidden unit buttons obstruct mouse clicks d746f12ffb2a6e87968c80224cc8a2f5485a4c76 Vladyslav Bondarenko 2023-08-25 13:51:56
feat: Add unit level to huge unit buttons 57c502e2ea48241401428e7de523e2672911b2c6 Vladyslav Bondarenko 2023-08-25 13:13:05
feat!: Add cast bar for huge unit buttons f921c3e2c1417036981f9e7ac9d070d66e4d7d19 Vladyslav Bondarenko 2023-08-25 11:38:37
fix: Add threat and range widgets to large buttons 8956671551dbd110d2f62b482579851f5283a065 Vladyslav Bondarenko 2023-08-25 09:36:02
fix: Filter out irrelevant events for status bars d11036a029bb51458c5bc592baf592463a05f11a Vladyslav Bondarenko 2023-08-25 09:02:07
feat: When group member out of range fade out e1b06d6c96ddceb3aa35ad5cc249671a5c1bf852 Vladyslav Bondarenko 2023-08-25 08:58:53
fix: Add unit tooltip 9b853289a7730a8783f02691c944492e0ef53f86 Vladyslav Bondarenko 2023-08-25 08:15:33
fix: Yet another health bar sanitization 979af69272eec06c45cb300132bc020a91a180c2 Vladyslav Bondarenko 2023-08-24 03:52:05
feat(build): Add stub RocketGit hook b1a0bb523fb570ee7cc73776bfbba1a6886e685f Vladyslav Bondarenko 2023-08-23 23:59:35
feat(build): Add 0.2-1 rockspec 92a2b006a47f1a242bbb08467c431362d64d6ef8 Vladyslav Bondarenko 2023-08-23 23:31:41
fix!: Use native mechanism of inheriting values 6a2ebf1aa52e4a300b4ad959670878b292140c4f Vladyslav Bondarenko 2023-08-23 23:05:39
fix: Typo in unit button template anchor 98027a2779639493c97c4259b61cb53d25709255 Vladyslav Bondarenko 2023-08-23 22:06:16
Commit a7c5e11ec5094033e946a95002010e5b02d6da74 - fix!: Cast bar consistent between targets
Since this commit the cast bar for target frame should work as expected.
Previously, when user changed current target, the cast bar for the
target frame would not update accordingly and present false information.
Author: Vladyslav Bondarenko
Author date (UTC): 2023-08-26 21:56
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2023-08-26 21:56
Parent(s): 1c8dcb8a7f1d3253ef32dae5a650e11e4ae8c184
Signer:
Signing key: EFF9624877D25D02
Signing status: E
Tree: 22ac63228ace1b0fc71068666cc40bef724f6f87
File Lines added Lines deleted
src/ChorusCastFrameTemplate.lua 161 53
File src/ChorusCastFrameTemplate.lua changed (mode: 100644) (index 21fcc6e..c234ef8)
... ... local SecureButton_GetUnit = SecureButton_GetUnit
8 8
9 9 local Chorus = Chorus local Chorus = Chorus
10 10
11 local function getDurationRemainingSec(nowMili, startInstanceMili, endInstanceMili)
12 assert(nowMili ~= nil)
13 assert('number' == type(nowMili))
14
15 assert(startInstanceMili ~= nil)
16 assert('number' == type(startInstanceMili))
17
18 assert(endInstanceMili ~= nil)
19 assert('number' == type(endInstanceMili))
20
21 local durationRemainingSec = (endInstanceMili - nowMili) / 1000
22
23 assert(durationRemainingSec ~= nil)
24 assert('number' == type(durationRemainingSec))
25 assert(durationRemainingSec >= 0 or durationRemainingSec <= 0)
26
27 return durationRemainingSec
28 end
29
30 local function getCastInfo(unitDesignation)
31 assert(unitDesignation ~= nil)
32
33 local spellName = UnitCastingInfo(unitDesignation)
34 if spellName then
35 return UnitCastingInfo(unitDesignation)
36 else
37 return UnitChannelInfo(unitDesignation)
38 end
39 end
40
11 41 local function castFrameEventIsRelevant(self, eventCategory, ...) local function castFrameEventIsRelevant(self, eventCategory, ...)
12 42 assert(self ~= nil) assert(self ~= nil)
13 43 assert(eventCategory ~= nil) assert(eventCategory ~= nil)
 
... ... local function castFrameEventIsRelevant(self, eventCategory, ...)
21 51 end end
22 52 end end
23 53
24 local function castFrameEventProcessor(self, eventCategory, ...)
54 local function applyArtworkSpellIcon(self, pictureFile)
25 55 assert(self ~= nil) assert(self ~= nil)
26 56
27 if not castFrameEventIsRelevant(self, eventCategory, ...) then
28 return
57 if not pictureFile then
58 pictureFile = 'Interface\\Icons\\INV_Misc_QuestionMark'
29 59 end end
30 60
31 --print(self:GetName(), eventCategory, ...)
32
33 local u = SecureButton_GetUnit(self)
34 if not u or not UnitExists(u) then
35 self:Hide()
36 return
37 end
61 assert(pictureFile ~= nil)
62 assert('string' == type(pictureFile))
63 pictureFile = strtrim(pictureFile)
64 assert(string.len(pictureFile) >= 1)
65 assert(string.len(pictureFile) <= 8192)
38 66
67 --[[ Artwork1: spell icon ]]--
39 68 local artwork1 = self.artwork1 or _G[self:GetName() .. 'Artwork1'] local artwork1 = self.artwork1 or _G[self:GetName() .. 'Artwork1']
40 69 assert(artwork1 ~= nil) assert(artwork1 ~= nil)
41 70
42 local artwork2 = self.artwork2 or _G[self:GetName() .. 'Artwork2']
43 assert(artwork2 ~= nil)
71 artwork1:SetTexture(pictureFile)
72 end
73
74 local function applySpellName(self, spellName)
75 assert(self ~= nil)
76
77 if not spellName then
78 spellName = 'Unknown'
79 end
80
81 assert(spellName ~= nil)
82 assert('string' == type(spellName))
83 spellName = strtrim(spellName)
84 assert(string.len(spellName) >= 1)
85 assert(string.len(spellName) <= 8192)
44 86
45 87 local label1 = self.label1 or _G[self:GetName() .. 'Text1'] local label1 = self.label1 or _G[self:GetName() .. 'Text1']
46 88 assert(label1 ~= nil) assert(label1 ~= nil)
47 89
90 label1:SetText(spellName)
91 end
92
93 local function applyArtworkCastBar(self, unitDesignation, shieldedFlag)
94 assert(self ~= nil)
95
96 assert(unitDesignation ~= nil)
97 assert('string' == type(unitDesignation))
98 unitDesignation = string.lower(strtrim(unitDesignation))
99 assert(string.len(unitDesignation) >= 1)
100 assert(string.len(unitDesignation) <= 256)
101
102 local label1 = self.label1 or _G[self:GetName() .. 'Text1']
103 assert(label1 ~= nil)
104
105 --[[ Artwork2: bar texture ]]--
106 local artwork2 = self.artwork2 or _G[self:GetName() .. 'Artwork2']
107 assert(artwork2 ~= nil)
108
109 if shieldedFlag then
110 artwork2:SetVertexColor(248 / 255, 248 / 255, 1)
111 label1:SetTextColor(1, 215 / 255, 0)
112 elseif UnitIsFriend('player', unitDesignation) then
113 artwork2:SetVertexColor(143 / 255, 188 / 255, 143 / 255)
114 label1:SetTextColor(248 / 255, 248 / 255, 1)
115 else
116 artwork2:SetVertexColor(1, 69 / 255, 0)
117 label1:SetTextColor(248 / 255, 248 / 255, 1)
118 end
119 end
120
121 local function applyDurationRemainingSec(self, durationRemainingSec)
122 assert(self ~= nil)
123
124 assert(durationRemainingSec ~= nil)
125 assert('number' == type(durationRemainingSec))
126
48 127 local label2 = self.label2 or _G[self:GetName() .. 'Text2'] local label2 = self.label2 or _G[self:GetName() .. 'Text2']
49 128 assert(label2 ~= nil) assert(label2 ~= nil)
50 129
51 local spellName, pictureFile, startInstance, endInstance, shieldedFlag
52 local spellName0, _, _, pictureFile0, startInstance0, endInstance0, _, _, shieldedFlag0 = UnitCastingInfo(u)
53 local spellName1, _, _, pictureFile1, startInstance1, endInstance1, _, _, shieldedFlag1 = UnitChannelInfo(u)
54 if spellName0 then
55 spellName = spellName0
56 pictureFile = pictureFile0
57 startInstance = startInstance0
58 endInstance = endInstance0
59 shieldedFlag = shieldedFlag0
60 elseif spellName1 then
61 spellName = spellName1
62 pictureFile = pictureFile1
63 startInstance = startInstance1
64 endInstance = endInstance1
65 shieldedFlag = shieldedFlag1
130 local t = string.format('%.1f', durationRemainingSec)
131 label2:SetText(t)
132 end
133
134 local function applyBounds(self, startInstance, endInstance)
135 assert(self ~= nil)
136
137 assert(startInstance ~= nil)
138 assert('number' == type(startInstance))
139 startInstance = math.abs(startInstance)
140 assert(startInstance >= 0)
141
142 assert(endInstance ~= nil)
143 assert('number' == type(endInstance))
144 endInstance = math.abs(endInstance)
145 assert(endInstance >= 0)
146
147 local x = math.min(startInstance, endInstance)
148 local y = math.max(startInstance, endInstance)
149 assert(x <= y)
150
151 self:SetMinMaxValues(x, y)
152 end
153
154 local function applyCurrentInstanceMili(self, nowMili)
155 assert(self ~= nil)
156
157 assert(nowMili ~= nil)
158 assert('number' == type(nowMili))
159 nowMili = math.abs(nowMili)
160 assert(nowMili >= 0)
161
162 self:SetValue(nowMili)
163 end
164
165 local function castFrameEventProcessor(self, eventCategory, ...)
166 assert(self ~= nil)
167
168 if not castFrameEventIsRelevant(self, eventCategory, ...) then
169 return
66 170 end end
67 171
68 if tContains({'UNIT_SPELLCAST_START', 'UNIT_SPELLCAST_CHANNEL_START', 'UNIT_SPELLCAST_DELAYED'}, eventCategory) then
69 if spellName then
70 label1:SetText(spellName)
71 end
72 if pictureFile then
73 artwork1:SetTexture(pictureFile)
74 end
75 if shieldedFlag then
76 artwork2:SetVertexColor(248 / 255, 248 / 255, 1)
77 label1:SetTextColor(1, 215 / 255, 0)
78 elseif UnitIsFriend('player', u) then
79 artwork2:SetVertexColor(143 / 255, 188 / 255, 143 / 255)
80 label1:SetTextColor(248 / 255, 248 / 255, 1)
81 else
82 artwork2:SetVertexColor(1, 69 / 255, 0)
83 label1:SetTextColor(248 / 255, 248 / 255, 1)
84 end
85 self:SetMinMaxValues(startInstance, endInstance)
172 local u = SecureButton_GetUnit(self)
173 if not u or not UnitExists(u) then
174 return
175 end
176
177 local label2 = self.label2 or _G[self:GetName() .. 'Text2']
178 assert(label2 ~= nil)
179
180 local spellName, _, _, pictureFile, startInstance, endInstance, _, _, shieldedFlag = getCastInfo(u)
181
182 local castOngoingFlag = spellName ~= nil
183 if castOngoingFlag then
184 applyBounds(self, startInstance, endInstance)
185
186 local now = GetTime() * 1000
187 applyCurrentInstanceMili(self, now)
188
189 local dur = getDurationRemainingSec(now, startInstance, endInstance)
190 applyDurationRemainingSec(self, dur)
191
192 applyArtworkSpellIcon(self, pictureFile)
193 applyArtworkCastBar(self, u, shieldedFlag)
194 applySpellName(self, spellName)
86 195 self:Show() self:Show()
87 elseif tContains({'UNIT_SPELLCAST_STOP', 'UNIT_SPELLCAST_CHANNEL_STOP'}, eventCategory) then
196 else
88 197 self:Hide() self:Hide()
89 198 end end
90 199 end end
 
... ... local function castFrameUpdateProcessor(self)
98 207 end end
99 208
100 209 local now = GetTime() * 1000 local now = GetTime() * 1000
101 self:SetValue(now)
102 local _, b = self:GetMinMaxValues()
210 applyCurrentInstanceMili(self, now)
103 211
104 local label2 = self.label2 or _G[self:GetName() .. 'Text2']
105 assert(label2 ~= nil)
212 local a, b = self:GetMinMaxValues()
213 local durationRemainingSec = getDurationRemainingSec(now, a, b)
106 214
107 local durationRemainingSec = (b - now) / 1000
108 local t = string.format('%.1f', durationRemainingSec)
109 label2:SetText(t)
215 applyDurationRemainingSec(self, durationRemainingSec)
110 216 end end
111 217
112 218 local function castFrameMain(self) local function castFrameMain(self)
 
... ... local function castFrameMain(self)
131 237 self:SetScript('OnUpdate', castFrameUpdateProcessor) self:SetScript('OnUpdate', castFrameUpdateProcessor)
132 238
133 239 self:RegisterEvent("PLAYER_ENTERING_WORLD"); self:RegisterEvent("PLAYER_ENTERING_WORLD");
240 self:RegisterEvent("PLAYER_FOCUS_CHANGED");
241 self:RegisterEvent("PLAYER_TARGET_CHANGED");
134 242 self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START"); self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_START");
135 243 self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP"); self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_STOP");
136 244 self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE"); self:RegisterEvent("UNIT_SPELLCAST_CHANNEL_UPDATE");
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