vrtc / scepter (public) (License: Unspecified) (since 2022-07-30) (hash sha1)
WoW addon that helps to cast any spell on any raid member by a combination of key presses.
List of commits:
Subject Hash Author Date (UTC)
feat: Render graphics when aiming a Scepter spell 164fc31081a95a4895256a4dc801c39049ca024c Vladyslav Bondarenko 2022-07-30 23:02:51
feat!: Add configuration frame 094aeb85927b28f44a25f9b3763d5679aaf8a25f Vladyslav Bondarenko 2022-05-19 17:40:54
fix: Allow toggling the spell eb6bee9a8516d9f8987388b0ddb70a79193e2281 Vladyslav Bondarenko 2022-05-16 08:26:55
feat: Initial commit 904be4af686e0ce4423daaf91a6f8e0cb0dacc07 Vladyslav Bondarenko 2022-05-16 08:12:12
Commit 164fc31081a95a4895256a4dc801c39049ca024c - feat: Render graphics when aiming a Scepter spell
Author: Vladyslav Bondarenko
Author date (UTC): 2022-07-30 23:02
Committer name: Vladyslav Bondarenko
Committer date (UTC): 2022-07-30 23:02
Parent(s): 094aeb85927b28f44a25f9b3763d5679aaf8a25f
Signer:
Signing key:
Signing status: N
Tree: 7a2d860c64c610254b25fe78f9fd850b62981e15
File Lines added Lines deleted
conf/luacheckrc.lua 5 1
scepter.toc 1 0
src/ScepterFrame.lua 6 28
src/ScepterOverlayFrame.lua 115 0
File conf/luacheckrc.lua changed (mode: 100644) (index 7bacebf..b04ba10)
1 1 read_globals = { read_globals = {
2 2 'BOOKTYPE_SPELL', 'BOOKTYPE_SPELL',
3 'ClearOverrideBindings',
3 4 'CreateFrame', 'CreateFrame',
5 'GameFontNormal',
4 6 'GetNumSpellTabs', 'GetNumSpellTabs',
5 7 'GetSpellInfo', 'GetSpellInfo',
6 8 'GetSpellName', 'GetSpellName',
7 9 'GetSpellTabInfo', 'GetSpellTabInfo',
10 'GetTime',
8 11 'InterfaceOptions_AddCategory', 'InterfaceOptions_AddCategory',
9 12 'IsPassiveSpell', 'IsPassiveSpell',
10 13 'MAX_PARTY_MEMBERS', 'MAX_PARTY_MEMBERS',
 
... ... read_globals = {
13 16 'SetOverrideBindingClick', 'SetOverrideBindingClick',
14 17 'UIParent', 'UIParent',
15 18 'UnitClass', 'UnitClass',
19 'date',
16 20 'strtrim', 'strtrim',
17 21 'tContains', 'tContains',
18 'ClearOverrideBindings',
19 22 } }
20 23
21 24 globals = { globals = {
 
... ... globals = {
24 27 'ScepterConfKeyFrame', 'ScepterConfKeyFrame',
25 28 'ScepterConfSpellKeyMap', 'ScepterConfSpellKeyMap',
26 29 'ScepterFrame', 'ScepterFrame',
30 'ScepterOverlayFrame',
27 31 } }
File scepter.toc changed (mode: 100644) (index 49ecb2c..20a6217)
4 4 ##Version: 0 ##Version: 0
5 5 ##SavedVariablesPerCharacter: ScepterConfSpellKeyMap ##SavedVariablesPerCharacter: ScepterConfSpellKeyMap
6 6 src\Scepter.lua src\Scepter.lua
7 src\ScepterOverlayFrame.lua
7 8 src\ScepterFrame.lua src\ScepterFrame.lua
8 9 src\ScepterConfFrame.lua src\ScepterConfFrame.lua
File src/ScepterFrame.lua changed (mode: 100644) (index 18b7524..9483b1a)
1 1 --[[ TODO Show the current active spell graphically ]]-- --[[ TODO Show the current active spell graphically ]]--
2 --[[ TODO Add target, player and focus buttons ]]--
2 3 --[[ TODO Add spell GUI configuration menu ]]-- --[[ TODO Add spell GUI configuration menu ]]--
3 4 --[[ TODO Add unit key bindings GUI configuration menu ]]-- --[[ TODO Add unit key bindings GUI configuration menu ]]--
4 5 --[[ TODO When in party and not in a raid, rebind party keys to raid group one. ]]-- --[[ TODO When in party and not in a raid, rebind party keys to raid group one. ]]--
 
6 7 --[[ TODO Add LDoc comments ]]-- --[[ TODO Add LDoc comments ]]--
7 8
8 9 local Scepter = Scepter local Scepter = Scepter
10 local date = date
9 11
10 12 local function trace(...) local function trace(...)
11 print('[Scepter]:', ...)
13 print(date('%X'), '[|cFF2F4F4FScepter|r]:', ...)
12 14 end end
13 15
14 16 local function getUnitList() local function getUnitList()
 
... ... local function getUserPartyKeyList()
68 70 return partyKeyList return partyKeyList
69 71 end end
70 72
71 local function getUserSpellList()
72 local _, classDesignation = UnitClass('player')
73 local t
74 if 'PALADIN' == classDesignation then
75 t = {
76 'Cleanse',
77 'Flash of Light',
78 'Hand of Freedom',
79 }
80 elseif 'SHAMAN' == classDesignation then
81 t = {
82 'Cure Toxins',
83 'Lesser Healing Wave',
84 }
85 else
86 t = {}
87 end
88
89 assert (t ~= nil)
90 assert ('table' == type(t))
91 assert (#t >= 0)
92 return t
93 end
94
95 73 local function createAttributeButton(n, rootFrame, attributeFrame, spellName) local function createAttributeButton(n, rootFrame, attributeFrame, spellName)
96 74 assert (n ~= nil) assert (n ~= nil)
97 75 assert (rootFrame ~= nil) assert (rootFrame ~= nil)
 
... ... local function createToggleButton(n, rootFrame)
136 114
137 115 --[[ When the button is shown it's features are enabled, --[[ When the button is shown it's features are enabled,
138 116 specifically related override key bindings are applied. ]]-- specifically related override key bindings are applied. ]]--
117 --[[ FIXME If party or raid group change mid combat the button won't work correctly ]]--
118 --[[ FIXME There is no way to target party members in raid group, may or may not be an issue ]]--
139 119 f:WrapScript(f, 'OnShow', [=[ f:WrapScript(f, 'OnShow', [=[
140 120 self:SetBindingClick(true, 'ESCAPE', self) self:SetBindingClick(true, 'ESCAPE', self)
141 121 local groupCategory = PlayerInGroup() local groupCategory = PlayerInGroup()
 
... ... local function createToggleButton(n, rootFrame)
155 135 self:SetBindingClick(true, key, unitButton) self:SetBindingClick(true, key, unitButton)
156 136 end end
157 137 end end
158 print(self:GetName(), 1 == self:IsShown(), groupCategory)
159 138 ]=]) ]=])
160 139
161 140 --[[ When the button is hidden it's features are disabled, --[[ When the button is hidden it's features are disabled,
162 141 specifically, related override key bindings are cleared. ]]-- specifically, related override key bindings are cleared. ]]--
163 142 f:WrapScript(f, 'OnHide', [=[ f:WrapScript(f, 'OnHide', [=[
164 143 self:ClearBindings() self:ClearBindings()
165 print(self:GetName(), 1 == self:IsShown())
166 144 ]=]) ]=])
167 145
168 146 --[[ When the button's "spell" property is changed, --[[ When the button's "spell" property is changed,
 
... ... local function createToggleButton(n, rootFrame)
179 157 local unitButton = childrenList[i] local unitButton = childrenList[i]
180 158 unitButton:SetAttribute('spell', spellName) unitButton:SetAttribute('spell', spellName)
181 159 end end
182 print(self:GetName(), name, value)
183 160
184 161 self:Show() self:Show()
185 162 ]=]) ]=])
 
... ... local function init(rootFrame)
329 306 return applySpellKeyMap(rootFrame, attributeButtonList, spellKeyMap) return applySpellKeyMap(rootFrame, attributeButtonList, spellKeyMap)
330 307 end end
331 308
309 Scepter.initOverlay(rootFrame, f)
332 310 Scepter.initConf() Scepter.initConf()
333 311
334 312 trace('init') trace('init')
File src/ScepterOverlayFrame.lua added (mode: 100644) (index 0000000..3145a37)
1 local CreateFrame = CreateFrame
2 local GameFontNormal = GameFontNormal
3 local GetTime = GetTime
4 local UIParent = UIParent
5
6 local function overlayFrameCreate(rootFrame, overlayDesignation, toggleButton)
7 assert (rootFrame ~= nil)
8 assert (toggleButton ~= nil)
9
10 local overlayFrame = CreateFrame('BUTTON', overlayDesignation, rootFrame, 'SecureHandlerShowHideTemplate')
11 overlayFrame:SetSize(144, 36)
12 overlayFrame:SetPoint('CENTER', UIParent, 'CENTER', 0, -36)
13 overlayFrame:SetFrameRef('ScepterToggleButton', toggleButton)
14 overlayFrame:Hide()
15
16 local artwork = overlayFrame:CreateTexture(overlayDesignation .. 'Artwork', 'ARTWORK')
17 artwork:SetSize(36, 36)
18 artwork:SetPoint('BOTTOMLEFT', 0, 0)
19 artwork:SetTexture("Interface\\Icons\\Inv_Mace_15")
20
21 local background = overlayFrame:CreateTexture(overlayDesignation .. 'Background', 'Background')
22 background:SetAllPoints()
23 background:SetTexture(0, 0, 0, 0.36)
24
25 local label = overlayFrame:CreateFontString(overlayDesignation .. 'Text')
26 label:SetFontObject(GameFontNormal)
27 label:SetPoint('BOTTOMLEFT', artwork:GetWidth(), 0)
28 label:SetPoint('TOPRIGHT', 0, 0)
29
30 overlayFrame:RegisterEvent('UNIT_SPELLCAST_FAILED')
31 overlayFrame:RegisterEvent('UNIT_SPELLCAST_SENT')
32 overlayFrame:RegisterEvent('UNIT_SPELLCAST_SUCCEEDED')
33 overlayFrame:SetScript('OnEvent', function(self, eventCategory, casterUnitDesignation, spellName, ...)
34 if 'player' ~= casterUnitDesignation then
35 return
36 end
37
38 local targetSpell = toggleButton:GetAttribute('spell')
39 if not targetSpell then
40 return
41 end
42
43 assert ('string' == type(targetSpell) or 'number' == type(targetSpell))
44 local targetSpellName = GetSpellInfo(targetSpell) or ''
45 if targetSpellName ~= spellName then
46 return
47 end
48
49 if 'UNIT_SPELLCAST_FAILED' == eventCategory then
50 label:SetTextColor(1, 0, 0)
51 self.lastUpdateInstance = GetTime()
52 elseif 'UNIT_SPELLCAST_SENT' == eventCategory then
53 local targetUnitName = select(2, ...) or 'Unknown target'
54 label:SetText(targetUnitName)
55 self.lastUpdateInstance = GetTime()
56 elseif 'UNIT_SPELLCAST_SUCCEEDED' == eventCategory then
57 label:SetTextColor(0, 1, 0)
58 self.lastUpdateInstance = GetTime()
59 end
60 end)
61
62 overlayFrame:HookScript('OnUpdate', function(self)
63 local now = GetTime()
64 local fadeDurationSec = 3
65 local lastUpdateInstance = self.lastUpdateInstance or 0
66 local a = 1 - ((now - lastUpdateInstance) / fadeDurationSec)
67 label:SetAlpha(math.min(math.max(0, a), 1))
68 end)
69
70 overlayFrame:SetScript('OnShow', function(self)
71 assert (self ~= nil)
72 local spellName = toggleButton:GetAttribute('spell')
73 local _, _, pictureFile = GetSpellInfo(spellName)
74 if pictureFile then
75 artwork:SetTexture(pictureFile)
76 else
77 artwork:SetTexture("Interface\\Icons\\Inv_Mace_15")
78 end
79 end)
80
81 overlayFrame:WrapScript(toggleButton, 'OnShow', [=[
82 owner:Hide()
83 owner:Show()
84 ]=])
85
86 overlayFrame:WrapScript(toggleButton, 'OnAttributeChanged', [=[
87 owner:Hide()
88 if self:IsShown() then
89 owner:Show()
90 else
91 owner:Hide()
92 end
93 ]=])
94
95 overlayFrame:WrapScript(toggleButton, 'OnHide', [=[
96 owner:Hide()
97 ]=])
98
99 return overlayFrame
100 end
101
102 local function initOverlay(rootFrame, toggleButton)
103 assert (rootFrame ~= nil)
104 assert (toggleButton ~= nil)
105
106 local overlayFrame = _G['ScepterOverlayFrame']
107 if not overlayFrame then
108 overlayFrame = overlayFrameCreate(rootFrame, 'ScepterOverlayFrame', toggleButton)
109 end
110 return overlayFrame
111 end
112
113 do
114 Scepter.initOverlay = initOverlay
115 end
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/scepter

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

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

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