Repository navigation
Expand file tree
/
Copy pathRange.lua
More file actions
156 lines (142 loc) · 5.05 KB
/
Copy pathRange.lua
File metadata and controls
156 lines (142 loc) · 5.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
local _, CK = ...
-- Out of range, the whole spell in red (the game only turns its small dot
-- red): the gamepad bar's buttons and our extra buttons. On the game's
-- buttons, their icon itself is coloured, so it keeps the button's own
-- shape (a red veil over the button tinted its ring too: a red cross on the
-- round ones, reported). Nothing hooked: the range is checked five times a
-- second and the red put back every frame the game has repainted it (secure
-- hooks on their RefreshRange and UpdateUsable broke the game's own bar
-- refresh with the taint log on: "attempt to call a nil value",
-- ActionButton.lua:584). Only the icon's colour changes, nothing is written
-- on the game's buttons.
local R = {}
CK.Range = R
R.RED = { 0.9, 0.15, 0.15 }
local CHECK = 0.2
local function on()
return CK.db and CK.db.settings.features.rangeTint == true
end
R.On = on
local function inRange(slot)
local check = (C_ActionBar and C_ActionBar.IsActionInRange) or IsActionInRange
if not (check and slot) then return nil end
return check(slot)
end
R.InRange = inRange
-- The game's colour for a slot (usable, not enough mana, unusable), given
-- back once a button is in range again
local function usableColor(icon, slot)
local isUsable = C_ActionBar and C_ActionBar.IsUsableAction or IsUsableAction
local usable, noMana = true, false
if isUsable and slot then usable, noMana = isUsable(slot) end
if usable then
icon:SetVertexColor(1, 1, 1)
elseif noMana then
icon:SetVertexColor(0.5, 0.5, 1)
else
icon:SetVertexColor(0.4, 0.4, 0.4)
end
end
-- The game's bar buttons: each bar's, and the stance bar's in their place
local function gameButtons()
local P, list = CK.Paddles, {}
for _, bar in ipairs(P.BARS) do
for _, b in ipairs(P.BUTTONS) do
local action = "bar:" .. bar.key .. ":" .. b.key
list[#list + 1] = P:NativeButton(action)
list[#list + 1] = P:StanceButton(action)
end
end
return list
end
local out, tinted = {}, {}
R.out, R.tinted = out, tinted
-- Our pictures over the game's buttons we replaced (Mapping.lua): a spell
-- there is red too when out of range of the target (reported: Wrath on X,
-- never red; the game's slot under it holds something else)
local outMarks, tintedMarks = {}, {}
R.outMarks = outMarks
local function spellOutOfRange(action)
local id = type(action) == "string" and tonumber(action:match("^spell:(%d+)$") or "")
if not (id and C_Spell and C_Spell.IsSpellInRange and UnitExists("target")) then return false end
local ok, inRange = pcall(function() return C_Spell.IsSpellInRange(id, "target") == false end)
return ok and inRange or false
end
R.SpellOutOfRange = spellOutOfRange
-- Which of the game's buttons shown are out of range
function R:Check()
wipe(out)
wipe(outMarks)
if not on() then return end
for _, button in ipairs(gameButtons()) do
if type(button.icon) == "table" and button:IsVisible() and inRange(button.action) == false then
out[button] = true
end
end
local marks = CK.Mapping and CK.Mapping.marks
for _, mark in pairs(marks or {}) do
if mark:IsVisible() and spellOutOfRange(mark.action) then outMarks[mark] = true end
end
end
local function isRed(icon)
local red = R.RED
local r, g, b = icon:GetVertexColor()
return r and math.abs(r - red[1]) < 0.01 and math.abs(g - red[2]) < 0.01 and math.abs(b - red[3]) < 0.01
end
-- Every frame: the out of range icons red (again, when the game repainted
-- them), the game's colour back on those in range again
function R:Paint()
local red = R.RED
for button in pairs(out) do
if not isRed(button.icon) then button.icon:SetVertexColor(red[1], red[2], red[3]) end
tinted[button] = true
end
for button in pairs(tinted) do
if not out[button] then
tinted[button] = nil
usableColor(button.icon, button.action)
end
end
-- Our pictures: nothing else paints them, set on a change only
for mark in pairs(outMarks) do
if not tintedMarks[mark] then
mark.icon:SetVertexColor(red[1], red[2], red[3])
tintedMarks[mark] = true
end
end
for mark in pairs(tintedMarks) do
if not outMarks[mark] then
tintedMarks[mark] = nil
mark.icon:SetVertexColor(1, 1, 1)
end
end
end
-- The option turned on or off
function R:Apply()
if not self.holder then return end
if on() then
self.holder:Show()
self:Check()
else
self.holder:Hide()
wipe(out)
wipe(outMarks)
end
self:Paint()
if CK.Paddles.Refresh and CK.Paddles.frame then CK.Paddles:Refresh(false) end
end
function R:Init()
local holder = CK.NewFrame("Frame", nil, UIParent)
holder:Hide()
local elapsed = CHECK
holder:SetScript("OnUpdate", function(_, dt)
elapsed = elapsed + (dt or 0)
if elapsed >= CHECK then
elapsed = 0
R:Check()
end
R:Paint()
end)
self.holder = holder
self:Apply()
end