Compare commits
21
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
289a555cee | ||
|
|
eaebe470b9 | ||
|
|
8be0732930 | ||
|
|
86e5ed78b0 | ||
|
|
77ae4ddad3 | ||
|
|
5ac84782d2 | ||
|
|
24a72cb02f | ||
|
|
851fb5740b | ||
|
|
b9d16f5ba2 | ||
|
|
90d71a54cf | ||
|
|
abeac379f3 | ||
|
|
763bf0bdae | ||
|
|
f181c0022c | ||
|
|
0cced419a6 | ||
|
|
5bbbde3ca7 | ||
|
|
6f954b9d15 | ||
|
|
c56b847710 | ||
|
|
dc62b031a9 | ||
|
|
ec7e2c74ff | ||
|
|
b1dca1639d | ||
|
|
47542c7147 |
No files matched your search
@@ -0,0 +1 @@
|
||||
indent_type = "Spaces"
|
||||
@@ -11,6 +11,10 @@ if [[ ! -d "${WOW_ADDON_DIR}" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initial build / install
|
||||
make -s build
|
||||
rsync -q -a ./build/OmicronFrames "${WOW_ADDON_DIR}/" --delete
|
||||
|
||||
# Every time the source or texture directory tree is changed, wait 1 second and
|
||||
# build the addon, then install it to the directory passed on the command line
|
||||
while true; do
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -17,6 +17,7 @@ types/statusbar.lua
|
||||
types/auralist.lua
|
||||
types/indicators/indicator.lua
|
||||
types/indicators/squareindicator.lua
|
||||
types/indicators/iconindicator.lua
|
||||
types/indicators/borderindicator.lua
|
||||
types/unitgroup.lua
|
||||
types/unitframe.lua
|
||||
|
||||
+401
-110
@@ -21,32 +21,46 @@ local colors = {
|
||||
white = { 1.0, 1.0, 1.0 },
|
||||
orange = { 1.0, 0.5, 0 },
|
||||
violet = { 1.0, 0, 1.0 },
|
||||
yellow = { 1.0, 1.0, 0 },
|
||||
magic = { 0.4, 0.4, 1.0 },
|
||||
disease = { 0.4, 0.2, 0.0 },
|
||||
poison = { 0.0, 0.7, 0.7 },
|
||||
curse = { 0.7, 0.0, 0.7 },
|
||||
red = { 1, 0, 0 },
|
||||
blue = { .4, 0.4, 1 },
|
||||
light_blue = { .7, .7, 1 },
|
||||
blue = { 0.4, 0.4, 1 },
|
||||
light_blue = { 0.7, 0.7, 1 },
|
||||
}
|
||||
|
||||
---@param list number[]
|
||||
---@return table<number, true>
|
||||
local function set(list)
|
||||
local s = {}
|
||||
for _, v in ipairs(list) do
|
||||
s[v] = true
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
local AURAS_PRIEST_RENEW = set({ 139, 6074, 6075, 6076, 6077, 6078, 10927, 10928, 10929, 25315, 25221, 25222 })
|
||||
local AURAS_PRIEST_PWS = set({ 17, 592, 600, 3747, 6065, 6066, 10898, 10899, 10900, 10901, 25217, 25218 })
|
||||
|
||||
local function RangeConfig()
|
||||
local _, class = UnitClass("player")
|
||||
if class == "SHAMAN" then
|
||||
return {
|
||||
friendly = "Healing Surge",
|
||||
friendly = "Healing Wave",
|
||||
enemy = "Lightning Bolt",
|
||||
fade = 0.2
|
||||
fade = 0.2,
|
||||
}
|
||||
elseif class == "PRIEST" then
|
||||
return {
|
||||
friendly = "Flash Heal",
|
||||
friendly = "Heal",
|
||||
enemy = "Smite",
|
||||
fade = 0.2
|
||||
fade = 0.2,
|
||||
}
|
||||
else
|
||||
return {
|
||||
fade = 0.2
|
||||
fade = 0.2,
|
||||
}
|
||||
end
|
||||
end
|
||||
@@ -56,128 +70,220 @@ local function MouseConfig()
|
||||
if class == "SHAMAN" then
|
||||
return {
|
||||
-- No modifier
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{
|
||||
button = "mouse2",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data =
|
||||
"/use [@UNIT,dead,help]Ancestral Vision; [@UNIT,help]Chain Heal"
|
||||
data = "/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT,help]Chain Heal",
|
||||
},
|
||||
{
|
||||
button = "mouse3",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data =
|
||||
"/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT,help]Purify Spirit"
|
||||
data = "/use [@UNIT,help]Cure Poison",
|
||||
},
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Lesser Healing Wave",
|
||||
},
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Healing Wave",
|
||||
},
|
||||
{ button = "wheel-up", mods = {}, kind = "macro", data = "/use [@UNIT,help]Healing Surge" },
|
||||
{ button = "wheel-down", mods = {}, kind = "macro", data = "/use [@UNIT,help]Riptide" },
|
||||
|
||||
-- alt
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Healing Wave" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Earth Shield" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Earth Shield" },
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = { alt = true },
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help,nodead]Nature's Swiftness\n/use [@UNIT,help]Healing Wave",
|
||||
},
|
||||
{
|
||||
button = "mouse3",
|
||||
mods = { alt = true },
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Cure Disease",
|
||||
},
|
||||
|
||||
-- Shift
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data =
|
||||
"/cast [@UNIT,help]Water Walking;\n/stopspelltarget"
|
||||
data = "/cast [@UNIT,help]Water Walking;\n/stopspelltarget",
|
||||
},
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Healing Wave(rank 1)",
|
||||
},
|
||||
}
|
||||
elseif class == "PRIEST" then
|
||||
return {
|
||||
-- No modifier
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{
|
||||
button = "mouse2",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,dead,help]Mass Resurrection; [@UNIT,help]Power Word: Radiance"
|
||||
data = "/use [@UNIT,dead,help]Mass Resurrection; [@UNIT,help]Power Word: Radiance",
|
||||
},
|
||||
{
|
||||
button = "mouse3",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,dead,help]Resurrection; [@UNIT,help]Purify"
|
||||
data = "/use [@UNIT,dead,help]Resurrection; [@UNIT,help]Purify",
|
||||
},
|
||||
{ button = "mouse4", mods = {}, kind = "spell", data = "Shadow Covenant" },
|
||||
{ button = "wheel-up", mods = {}, kind = "macro", data = "/use [@UNIT,help]Flash Heal" },
|
||||
{ button = "wheel-down", mods = {}, kind = "macro", data = "/use [@UNIT,help]Renew" },
|
||||
{ button = "mouse4", mods = {}, kind = "spell", data = "Shadow Covenant" },
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Lesser Heal",
|
||||
},
|
||||
{ button = "wheel-down", mods = {}, kind = "macro", data = "/use [@UNIT,help]Heal" },
|
||||
|
||||
-- alt
|
||||
{ button = "mouse1", mods = { alt = true }, kind = "spell", data = "Power Word: Life" },
|
||||
{ button = "mouse2", mods = { alt = true }, kind = "spell", data = "Pain Suppression" },
|
||||
{ button = "mouse3", mods = { alt = true }, kind = "spell", data = "Power Infusion" },
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Rapture" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Power Word: Shield" },
|
||||
{ button = "mouse1", mods = { alt = true }, kind = "spell", data = "Power Word: Life" },
|
||||
{ button = "mouse2", mods = { alt = true }, kind = "spell", data = "Pain Suppression" },
|
||||
{ button = "mouse3", mods = { alt = true }, kind = "spell", data = "Power Infusion" },
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Renew" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Power Word: Shield" },
|
||||
|
||||
-- Shift
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data = "/cast [@UNIT,help]Levitate;\n/stopspelltarget"
|
||||
data = "/cast [@UNIT,help]Levitate;\n/stopspelltarget",
|
||||
},
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data = "/cast [@UNIT,help]Leap of Faith;\n/stopspelltarget"
|
||||
data = "/cast [@UNIT,help]Leap of Faith;\n/stopspelltarget",
|
||||
},
|
||||
}
|
||||
elseif class == "MONK" then
|
||||
return {
|
||||
-- No modifier
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{
|
||||
button = "mouse2",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = ("/use [@UNIT,known:Reawaken,dead,help]Reawaken; "
|
||||
data = (
|
||||
"/use [@UNIT,known:Reawaken,dead,help]Reawaken; "
|
||||
.. "[@UNIT,dead,help]Resuscitate; "
|
||||
.. "[@UNIT,help]Tiger's Lust"),
|
||||
.. "[@UNIT,help]Tiger's Lust"
|
||||
),
|
||||
},
|
||||
{
|
||||
button = "mouse3",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,dead,help]Resuscitate; [@UNIT,help]Detox"
|
||||
data = "/use [@UNIT,dead,help]Resuscitate; [@UNIT,help]Detox",
|
||||
},
|
||||
{ button = "mouse4", mods = {}, kind = "spell", data = "Shadow Covenant" },
|
||||
{ button = "wheel-up", mods = {}, kind = "macro", data = "/use [@UNIT,help]Vivify" },
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Soothing Mist",
|
||||
},
|
||||
{ button = "mouse4", mods = {}, kind = "spell", data = "Shadow Covenant" },
|
||||
{ button = "wheel-up", mods = {}, kind = "macro", data = "/use [@UNIT,help]Vivify" },
|
||||
{ button = "wheel-down", mods = {}, kind = "macro", data = "/use [@UNIT,help]Soothing Mist" },
|
||||
|
||||
-- alt
|
||||
{ button = "mouse1", mods = { alt = true }, kind = "spell", data = "Power Word: Life" },
|
||||
{ button = "mouse2", mods = { alt = true }, kind = "spell", data = "Pain Suppression" },
|
||||
{ button = "mouse3", mods = { alt = true }, kind = "spell", data = "Power Infusion" },
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Rapture" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Power Word: Shield" },
|
||||
{ button = "mouse1", mods = { alt = true }, kind = "spell", data = "Power Word: Life" },
|
||||
{ button = "mouse2", mods = { alt = true }, kind = "spell", data = "Pain Suppression" },
|
||||
{ button = "mouse3", mods = { alt = true }, kind = "spell", data = "Power Infusion" },
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Rapture" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Power Word: Shield" },
|
||||
|
||||
-- Shift
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data = "/cast [@UNIT,help]Levitate;\n/stopspelltarget"
|
||||
data = "/cast [@UNIT,help]Levitate;\n/stopspelltarget",
|
||||
},
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = { shift = true },
|
||||
kind = "macro",
|
||||
data = "/cast [@UNIT,help]Leap of Faith;\n/stopspelltarget"
|
||||
data = "/cast [@UNIT,help]Leap of Faith;\n/stopspelltarget",
|
||||
},
|
||||
}
|
||||
elseif class == "PALADIN" then
|
||||
return {
|
||||
-- No modifier
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{
|
||||
button = "mouse2",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = (
|
||||
"/use [@UNIT,combat,dead,help]Intercession; "
|
||||
.. "[@UNIT,known:Absolution,dead,help]Absolution; "
|
||||
.. "[@UNIT,dead,help]Redemption; "
|
||||
.. "[@UNIT,help]Blessing of Freedom"
|
||||
),
|
||||
},
|
||||
{
|
||||
button = "mouse3",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,dead,help]Redemption; [@UNIT,help]Cleanse Toxins",
|
||||
},
|
||||
{
|
||||
button = "mouse4",
|
||||
mods = {},
|
||||
kind = "spell",
|
||||
data = "Word of Glory",
|
||||
},
|
||||
{
|
||||
button = "mouse5",
|
||||
mods = {},
|
||||
kind = "spell",
|
||||
data = "Blessing of Summer",
|
||||
},
|
||||
{
|
||||
button = "wheel-up",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help]Flash of Light",
|
||||
},
|
||||
{
|
||||
button = "wheel-down",
|
||||
mods = {},
|
||||
kind = "macro",
|
||||
data = "/use [@UNIT,help,known:Holy Shock]Holy Shock; [@UNIT,help]Word of Glory",
|
||||
},
|
||||
|
||||
-- Shift
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
|
||||
-- alt
|
||||
{ button = "mouse1", mods = { alt = true }, kind = "spell", data = "Blessing of Sacrifice" },
|
||||
{ button = "mouse2", mods = { alt = true }, kind = "spell", data = "Blessing of Protection" },
|
||||
{ button = "mouse3", mods = { alt = true }, kind = "spell", data = "Blessing of Spellwarding" },
|
||||
{ button = "wheel-up", mods = { alt = true }, kind = "spell", data = "Holy Light" },
|
||||
{ button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Lay on Hands" },
|
||||
}
|
||||
else
|
||||
return {
|
||||
-- Super basic defaults
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{ button = "mouse1", mods = {}, kind = "target" },
|
||||
{ button = "mouse2", mods = { shift = true }, kind = "togglemenu" },
|
||||
}
|
||||
end
|
||||
@@ -189,7 +295,7 @@ local function TriggerClassConfig()
|
||||
return {
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 383648,
|
||||
spellIds = set({ 32594 }),
|
||||
own = true, -- Second Earth Shield on yourself
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -199,35 +305,35 @@ local function TriggerClassConfig()
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
showStacks = true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 974,
|
||||
own = true, -- Second Earth Shield on yourself
|
||||
spellIds = set({ 29203 }),
|
||||
own = true, -- Healing Way
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 3,
|
||||
x = 20,
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
color = colors.yellow,
|
||||
showStacks = true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 61295,
|
||||
own = true, -- Riptide
|
||||
spellIds = set({ 16237 }),
|
||||
own = true, -- Ancestral Fortitude
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMLEFT",
|
||||
x = 3,
|
||||
y = 3,
|
||||
color = colors.cyan,
|
||||
fadeTime = 10.0,
|
||||
}
|
||||
point = "TOPLEFT",
|
||||
x = 40,
|
||||
y = -3,
|
||||
color = colors.orange,
|
||||
showStacks = false,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "StatusTrigger",
|
||||
@@ -238,14 +344,14 @@ local function TriggerClassConfig()
|
||||
thickness = 3.0,
|
||||
color = colors.red,
|
||||
level = 0,
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
elseif class == "PRIEST" then
|
||||
return {
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 17,
|
||||
spellIds = AURAS_PRIEST_PWS,
|
||||
own = true, -- Power Word: Shield
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -255,11 +361,11 @@ local function TriggerClassConfig()
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
fadeTime = 10.0,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 33206,
|
||||
spellIds = set({ 33206 }),
|
||||
own = true, -- Pain Suppression
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -270,11 +376,11 @@ local function TriggerClassConfig()
|
||||
color = colors.orange,
|
||||
fadeTime = 10.0,
|
||||
flashTime = 1.3,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 41635,
|
||||
spellIds = set({ 41635 }),
|
||||
own = true, -- Prayer of Mending
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -284,11 +390,11 @@ local function TriggerClassConfig()
|
||||
y = -3,
|
||||
color = { 0.7, 0.9, 1 },
|
||||
showStacks = true,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 139,
|
||||
spellIds = AURAS_PRIEST_RENEW,
|
||||
own = true, -- Renew
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -298,11 +404,11 @@ local function TriggerClassConfig()
|
||||
y = 3,
|
||||
color = colors.cyan,
|
||||
fadeTime = 10.0,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 194384,
|
||||
spellIds = set({ 194384 }),
|
||||
own = true, -- Atonement
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -313,11 +419,11 @@ local function TriggerClassConfig()
|
||||
color = colors.white,
|
||||
fadeTime = 10.0,
|
||||
flashTime = 1.3,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellId = 10060,
|
||||
spellIds = set({ 10060 }),
|
||||
own = true, -- Power Infusion
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
@@ -327,7 +433,7 @@ local function TriggerClassConfig()
|
||||
y = 3,
|
||||
color = colors.violet,
|
||||
fadeTime = 10.0,
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "StatusTrigger",
|
||||
@@ -338,26 +444,161 @@ local function TriggerClassConfig()
|
||||
thickness = 3.0,
|
||||
color = colors.red,
|
||||
level = 0,
|
||||
}
|
||||
},
|
||||
--[[{
|
||||
kind="MultiTrigger", invert=false,
|
||||
children = {
|
||||
{kind="StatusTrigger", status="Immune", defaultData={color=colors.violet}}, -- Renew
|
||||
{kind="AuraTrigger", spellId=139, own=true, defaultData={color=colors.cyan}}, -- Renew
|
||||
{kind="AuraTrigger", spellId=21562, own=true, defaultData={color=colors.white}}, -- pw:f
|
||||
},
|
||||
},
|
||||
}
|
||||
elseif class == "PALADIN" then
|
||||
return {
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 287280 }), -- Glimmer of Light
|
||||
own = true,
|
||||
indicator = {
|
||||
kind="SquareIndicator",
|
||||
size=17,
|
||||
point="TOPRIGHT",
|
||||
x=-3, y=-3,
|
||||
color=colors.white,
|
||||
}
|
||||
}--]]
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 3,
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
fadeTime = 10.0,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 25771 }), -- Forbearance
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 22,
|
||||
y = -3,
|
||||
color = colors.red,
|
||||
fadeTime = 10.0,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 53563 }), -- Beacon of Light
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 41,
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 156910 }), -- Beacon of Faith
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 41,
|
||||
y = -3,
|
||||
color = colors.light_blue,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 200025 }), -- Beacon of Virtue
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "TOPLEFT",
|
||||
x = 41,
|
||||
y = -3,
|
||||
color = colors.white,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 1044 }), -- Blessing of Freedom
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMLEFT",
|
||||
x = 3,
|
||||
y = 3,
|
||||
color = colors.orange,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 1111 }), -- Blessing of Spellwarding
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMLEFT",
|
||||
x = 41,
|
||||
y = 3,
|
||||
color = colors.cyan,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 1022 }), -- Blessing of Protection
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMLEFT",
|
||||
x = 41,
|
||||
y = 3,
|
||||
color = colors.cyan,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 6940 }), -- Blessing of Saccrifice
|
||||
own = true,
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMLEFT",
|
||||
x = 61,
|
||||
y = 3,
|
||||
color = colors.red,
|
||||
flashTime = 1.3,
|
||||
},
|
||||
},
|
||||
{
|
||||
kind = "StatusTrigger",
|
||||
status = "Burn",
|
||||
invert = false,
|
||||
indicator = {
|
||||
kind = "BorderIndicator",
|
||||
thickness = 3.0,
|
||||
color = colors.red,
|
||||
level = 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
else
|
||||
return {}
|
||||
return {
|
||||
{
|
||||
kind = "StatusTrigger",
|
||||
status = "Burn",
|
||||
invert = false,
|
||||
indicator = {
|
||||
kind = "BorderIndicator",
|
||||
thickness = 3.0,
|
||||
color = colors.red,
|
||||
level = 0,
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
@@ -368,7 +609,7 @@ local function MakeDebuffTrigger(slot, spellid, color, stacks)
|
||||
end
|
||||
return {
|
||||
kind = "AuraTrigger",
|
||||
spellId = spellid,
|
||||
spellIds = set({ spellid }),
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 15,
|
||||
@@ -377,45 +618,89 @@ local function MakeDebuffTrigger(slot, spellid, color, stacks)
|
||||
y = -3,
|
||||
color = color,
|
||||
showStacks = stacks,
|
||||
}
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local function TriggerConfig()
|
||||
local triggers = TriggerClassConfig()
|
||||
print("Class triggers:", #triggers)
|
||||
|
||||
-- slot, spellid, color, stacks
|
||||
local debuffs = {
|
||||
-- Kezzara, Aberrus
|
||||
{ 1, 406525, colors.orange }, -- Dread Rift
|
||||
{ 2, 402253, colors.red }, -- Ray of Anguish
|
||||
{ 1, 406525, colors.orange }, -- Dread Rift
|
||||
{ 2, 402253, colors.red }, -- Ray of Anguish
|
||||
{ 3, 404743, colors.violet, true }, -- Terror Claws
|
||||
|
||||
-- Forgotten Experiment, Aberrus
|
||||
{ 1, 406365, colors.red, true }, -- Rending Charge (p1)
|
||||
{ 1, 407327, colors.cyan, true }, -- Unstable Essence (p2/p3)
|
||||
{ 1, 406365, colors.red, true }, -- Rending Charge (p1)
|
||||
{ 1, 407327, colors.cyan, true }, -- Unstable Essence (p2/p3)
|
||||
{ 3, 407313, colors.violet, true }, -- Infused Strikes
|
||||
|
||||
-- Uldaman: Legacy of Tyr
|
||||
{ 1, 377510, colors.cyan, true }, -- Stolen Time
|
||||
{ 1, 377510, colors.cyan, true }, -- Stolen Time
|
||||
|
||||
-- Brackenhide Hollow
|
||||
{ 1, 367521, colors.cyan, true }, -- Bone Bolt
|
||||
{ 1, 367521, colors.cyan, true }, -- Bone Bolt
|
||||
|
||||
-- The Underrot
|
||||
--{1, 273226, colors.green, true}, -- Decaying Spores
|
||||
|
||||
-- Sarkareth, Aberrus
|
||||
{ 3, 401330, colors.violet }, -- Burning Claws (P1 tank)
|
||||
{ 3, 411241, colors.violet }, -- Void Claws (P2 tank)
|
||||
{ 3, 408429, colors.violet }, -- Void Slash (P3 tank)
|
||||
{ 2, 404218, colors.blue }, -- Void Fracture (carry bomb)
|
||||
{ 1, 401951, colors.cyan, true }, -- Oblivion
|
||||
{ 3, 401330, colors.violet }, -- Burning Claws (P1 tank)
|
||||
{ 3, 411241, colors.violet }, -- Void Claws (P2 tank)
|
||||
{ 3, 408429, colors.violet }, -- Void Slash (P3 tank)
|
||||
{ 2, 404218, colors.blue }, -- Void Fracture (carry bomb)
|
||||
{ 1, 401951, colors.cyan, true }, -- Oblivion
|
||||
|
||||
-- Darkheart Thicket
|
||||
{ 3, 225484, colors.violet }, -- Grievous Rip
|
||||
{ 3, 196376, colors.violet }, -- Grievous Tear
|
||||
|
||||
-- Throne of the Tides
|
||||
{ 1, 426660, colors.red, true }, -- Razor Jaws
|
||||
|
||||
-- Nymue, Amirdrassil
|
||||
{ 1, 429785, colors.red }, -- Loom (line stun)
|
||||
{ 1, 417807, colors.red, true }, -- Fyrakk
|
||||
|
||||
-- Algeth'ar Academy
|
||||
{ 1, 389033, colors.poison, true },
|
||||
{ 1, 388912, colors.red, true },
|
||||
{ 2, 391977, colors.cyan, true },
|
||||
{ 2, 389011, colors.cyan, true },
|
||||
|
||||
-- Nokhud Offensive
|
||||
{ 1, 381692, colors.red, true },
|
||||
|
||||
-- Tazavesh
|
||||
{ 1, 1240102, colors.orange, true },
|
||||
|
||||
-- Priory of the Sacred Flame
|
||||
{ 1, 424414, colors.violet, true },
|
||||
}
|
||||
|
||||
for _, debuff in ipairs(debuffs) do
|
||||
table.insert(triggers, MakeDebuffTrigger(debuff[1], debuff[2], debuff[3], debuff[4]))
|
||||
end
|
||||
print("All triggers:", #triggers)
|
||||
|
||||
-- Some more debuffs in the bottom row
|
||||
table.insert(triggers, {
|
||||
kind = "AuraTrigger",
|
||||
spellIds = set({ 240443 }), -- Bursting
|
||||
indicator = {
|
||||
kind = "SquareIndicator",
|
||||
size = 17,
|
||||
point = "BOTTOMRIGHT",
|
||||
x = -3,
|
||||
y = 3,
|
||||
color = colors.red,
|
||||
fadeTime = 3.0,
|
||||
showStacks = true,
|
||||
},
|
||||
})
|
||||
|
||||
return triggers
|
||||
end
|
||||
@@ -433,7 +718,7 @@ function HideBlizzardFrames()
|
||||
TargetFrame,
|
||||
FocusFrame,
|
||||
PartyFrame,
|
||||
CompactRaidFrameContainer
|
||||
CompactRaidFrameContainer,
|
||||
}
|
||||
|
||||
for _, frame in ipairs(blizzardFrames) do
|
||||
@@ -452,6 +737,8 @@ function CreateRaidFrames(left, top, config)
|
||||
local num = i * 5 + j + 1
|
||||
local frame = UnitFrame:new("raid" .. num, config)
|
||||
group:AddUnitFrame(frame)
|
||||
local raidpet = UnitFrame:new("raidpet" .. num, config)
|
||||
group:AddUnitFrame(raidpet)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -462,9 +749,13 @@ function CreatePartyFrames(left, top, config)
|
||||
local group = UnitGroup:new(left, top, width, height)
|
||||
local player = UnitFrame:new("player", config)
|
||||
group:AddUnitFrame(player)
|
||||
local pet = UnitFrame:new("pet", config)
|
||||
group:AddUnitFrame(pet)
|
||||
for i = 1, 4 do
|
||||
local frame = UnitFrame:new("party" .. i, config)
|
||||
group:AddUnitFrame(frame)
|
||||
local partypet = UnitFrame:new("partypet" .. i, config)
|
||||
group:AddUnitFrame(partypet)
|
||||
end
|
||||
group:Sort()
|
||||
end
|
||||
@@ -494,10 +785,10 @@ function CreateFrames()
|
||||
triggers = TriggerConfig(),
|
||||
}
|
||||
|
||||
CreatePartyFrames(-0.05, -290.05, config)
|
||||
CreatePartyFrames(-0.05, -240.05, config)
|
||||
config.hideInRaid = false
|
||||
CreateRaidFrames(-0.05, -290.05, config)
|
||||
CreateTargetFrames(110 * 3 + 50 - 0.05, -245.05, config)
|
||||
CreateRaidFrames(-0.05, -240.05, config)
|
||||
CreateTargetFrames(110 * 3 + 50 - 0.05, -240.05, config)
|
||||
HideBlizzardFrames()
|
||||
end
|
||||
|
||||
|
||||
+5
-3
@@ -88,7 +88,7 @@ Commander.RegisterCommand("omi-pstart", {
|
||||
PrintLn("To enable the script profiler run `/console scriptProfile 1`, then reload the UI.")
|
||||
return
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
Commander.RegisterCommand("omi-pstop", {
|
||||
@@ -117,7 +117,9 @@ Commander.RegisterCommand("omi-pstop", {
|
||||
time = time * 1000,
|
||||
})
|
||||
end
|
||||
table.sort(data, function(a, b) return a.time < b.time end)
|
||||
table.sort(data, function(a, b)
|
||||
return a.time < b.time
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
@@ -136,5 +138,5 @@ Commander.RegisterCommand("omi-pprint", {
|
||||
local ms_per_sec = time / total
|
||||
Printf("% 6.1f%% % 7.2fms %7.2fms/s %s\n", pct, time, ms_per_sec, item.name)
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
+55
-17
@@ -16,6 +16,8 @@
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
local AuraTrigger = types.AuraTrigger
|
||||
local StatusTrigger = types.StatusTrigger
|
||||
|
||||
--- AuraList keeps track of all the auras attached to a unitframe
|
||||
---@class AuraList: Object
|
||||
@@ -24,10 +26,10 @@ types.AuraList = AuraList
|
||||
|
||||
local statusLists = {
|
||||
Immune = {
|
||||
[642] = true, -- Divine Shield, Paladin
|
||||
[642] = true, -- Divine Shield, Paladin
|
||||
[186265] = true, -- Aspect of the Turtle, Hunter
|
||||
[45438] = true, -- Ice Block
|
||||
[31224] = true, -- Cloak of Shadows
|
||||
[45438] = true, -- Ice Block
|
||||
[31224] = true, -- Cloak of Shadows
|
||||
[196555] = true, -- Netherwalk
|
||||
},
|
||||
Bomb = {
|
||||
@@ -41,6 +43,7 @@ local statusLists = {
|
||||
[411241] = true, -- Sarkareth, Void Claws (p2 tank)
|
||||
[408429] = true, -- Sarkareth, Void Slash (p3 tank)
|
||||
[404218] = true, -- Sarkareth, Void fracture (bombs)
|
||||
[427722] = true, -- Nymue, Weaver's Burden (hehe jk it's private because reasons)
|
||||
},
|
||||
Burn = {
|
||||
-- Jade Serpent Temple
|
||||
@@ -68,6 +71,8 @@ local statusLists = {
|
||||
|
||||
-- Atal'Dazar
|
||||
[255582] = true, -- Priestess Alun'za, Molten Gold
|
||||
[250096] = true, -- Yazma, Wracking pain
|
||||
[255434] = true, -- Rezan, Serrated Teeth
|
||||
|
||||
-- The MOTHERLODE!!
|
||||
[259853] = true, -- Rixxa Fluxflame, Chemical Burn
|
||||
@@ -104,6 +109,27 @@ local statusLists = {
|
||||
-- Aberrus
|
||||
[404010] = true, -- Zkarn, ???
|
||||
[405462] = true, -- Zkarn, ???
|
||||
|
||||
-- Dawn of the infinite: Galakrond's fall
|
||||
[407406] = true,
|
||||
|
||||
-- Darkheart Thicket
|
||||
|
||||
-- Amirdrassil
|
||||
[427721] = true, -- Nymue, Weaver's burden (dot part)
|
||||
|
||||
-- Waycrest Manor
|
||||
[263943] = true, -- Etch
|
||||
[264378] = true, -- Fragment Soul
|
||||
|
||||
-- Ruby Lifepools
|
||||
[381862] = true, -- Kyrakka, Infernocore
|
||||
|
||||
-- Nokhud Offensive
|
||||
[381692] = true, -- Swift Stab
|
||||
|
||||
-- Priory of the Sacred Flame
|
||||
[447439] = true, -- Savage Mauling
|
||||
},
|
||||
}
|
||||
|
||||
@@ -111,7 +137,7 @@ local statusLists = {
|
||||
-- callback function with UnitAuraInfo table as argument
|
||||
local function ForEachAuraSlots(unit, fn, continuationToken, ...)
|
||||
local GetAuraDataBySlot = C_UnitAuras.GetAuraDataBySlot
|
||||
local n = select('#', ...)
|
||||
local n = select("#", ...)
|
||||
for i = 1, n do
|
||||
local slot = select(i, ...)
|
||||
fn(GetAuraDataBySlot(unit, slot))
|
||||
@@ -121,11 +147,11 @@ end
|
||||
|
||||
-- Helper function that goes over all aura slots for a given filter
|
||||
local function ForEachAuraFiltered(unit, filter, fn)
|
||||
local UnitAuraSlots = UnitAuraSlots
|
||||
local UnitAuraSlots = C_UnitAuras.GetAuraSlots
|
||||
local continuationToken = nil
|
||||
repeat
|
||||
continuationToken = ForEachAuraSlots(unit, fn, UnitAuraSlots(unit, filter, nil, continuationToken))
|
||||
until (continuationToken == nil)
|
||||
until continuationToken == nil
|
||||
end
|
||||
|
||||
-- Similar to what AuraUtils.ForEachAura does except the callback fn takes a
|
||||
@@ -135,7 +161,6 @@ local function ForEachAura(unit, fn)
|
||||
ForEachAuraFiltered(unit, "HARMFUL", fn)
|
||||
end
|
||||
|
||||
|
||||
---@return AuraList
|
||||
function AuraList.new(cls, ...)
|
||||
--- I really dislike duplicating this everywhere but it makes
|
||||
@@ -152,27 +177,40 @@ function AuraList:Init(unitframe)
|
||||
self.statusCount = {}
|
||||
self.auras = {} -- map AuraInstanceID to UnitAuraInfo table
|
||||
|
||||
|
||||
self.triggers = {}
|
||||
self.triggersBySpell = {}
|
||||
self.triggersByStatus = {}
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger | StatusTrigger
|
||||
function AuraList:AddTrigger(trigger)
|
||||
---@param trigger StatusTrigger
|
||||
function AuraList:AddStatusTrigger(trigger)
|
||||
table.insert(self.triggers, trigger)
|
||||
local spellId = trigger.spellId
|
||||
local status = trigger.status
|
||||
if spellId then
|
||||
if self.triggersByStatus[status] == nil then
|
||||
self.triggersByStatus[status] = {}
|
||||
end
|
||||
table.insert(self.triggersByStatus[status], trigger)
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger
|
||||
function AuraList:AddAuraTrigger(trigger)
|
||||
table.insert(self.triggers, trigger)
|
||||
for spellId in pairs(trigger.spellIds) do
|
||||
if self.triggersBySpell[spellId] == nil then
|
||||
self.triggersBySpell[spellId] = {}
|
||||
end
|
||||
table.insert(self.triggersBySpell[spellId], trigger)
|
||||
end
|
||||
end
|
||||
|
||||
---@param trigger AuraTrigger | StatusTrigger
|
||||
function AuraList:AddTrigger(trigger)
|
||||
if trigger:IsInstanceOf(AuraTrigger) then
|
||||
self:AddAuraTrigger(trigger)
|
||||
elseif trigger:IsInstanceOf(StatusTrigger) then
|
||||
self:AddStatusTrigger(trigger)
|
||||
else
|
||||
if self.triggersByStatus[status] == nil then
|
||||
self.triggersByStatus[status] = {}
|
||||
end
|
||||
table.insert(self.triggersByStatus[status], trigger)
|
||||
error("AddTrigger: trigger is neither an AuraTrigger nor a StatusTrigger")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -247,7 +285,7 @@ end
|
||||
---@param aura UnitAuraInfo
|
||||
function AuraList:UpdateAura(aura)
|
||||
for _, trigger in ipairs(self.triggersBySpell[aura.spellId] or {}) do
|
||||
trigger:UpdateAura(self.auras[aura.auraInstanceId], aura)
|
||||
trigger:UpdateAura(self.auras[aura.auraInstanceID], aura)
|
||||
end
|
||||
self.auras[aura.auraInstanceID] = aura
|
||||
end
|
||||
|
||||
@@ -0,0 +1,215 @@
|
||||
-- Copyright 2025 <omicron.me@protonmail.com>
|
||||
--
|
||||
-- This file is part of Omicron Frames
|
||||
--
|
||||
-- Omicron Frames is free software: you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 3 of the License, or (at your option)
|
||||
-- any later version.
|
||||
--
|
||||
-- Omicron Frames is distributed in the hope that it will be useful, but
|
||||
-- WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
-- or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
-- more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
|
||||
local iconPool = CreateFramePool("Frame", nil, "BackdropTemplate")
|
||||
|
||||
---IconIndicator is an indicator that displays an icon with border
|
||||
---@class IconIndicator: Indicator
|
||||
local IconIndicator = types.CreateClass("IconIndicator", Indicator)
|
||||
types.IconIndicator = IconIndicator
|
||||
|
||||
---@return IconIndicator
|
||||
function IconIndicator.new(cls, ...)
|
||||
--- I really dislike duplicating this everywhere but it makes
|
||||
--lua-language-server able to deduce the type of Object:new calls and that
|
||||
--is honestly worth it
|
||||
return types.Object.new(cls, ...)
|
||||
end
|
||||
|
||||
--- Initialize a new IconIndicator
|
||||
-- unitframe Unitframe it is attached to
|
||||
-- size Size of the indicator square
|
||||
-- point Attachment point to the unitframe's overlay frame
|
||||
-- x, y x and y offset for the attachment point
|
||||
-- color Color of the square
|
||||
---@param unitframe UnitFrame
|
||||
---@param size number
|
||||
---@param point string
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param showStacks boolean
|
||||
---@param doFade nil|number
|
||||
---@param doFlash nil|number
|
||||
---@param showTooltip nil|boolean
|
||||
function IconIndicator:Init(unitframe, size, point, x, y, showStacks, fadeTime, flashTime, showTooltip)
|
||||
self.unitframe = unitframe
|
||||
self.frameParent = unitframe.overlays
|
||||
self.size = size
|
||||
self.point = point
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.icon = 134400
|
||||
self.showStacks = showStacks
|
||||
self.fadeTime = fadeTime
|
||||
self.flashTime = flashTime
|
||||
self.showTooltip = showTooltip or false
|
||||
|
||||
self.instanceId = 0
|
||||
self.spellId = 0
|
||||
end
|
||||
|
||||
--- Show the square indicator
|
||||
---@param data table
|
||||
function IconIndicator:Show(data)
|
||||
local frame, stacks = self:GetFrame()
|
||||
local numStacks = data.applications or 0
|
||||
|
||||
self.auraInstanceID = data.auraInstanceID
|
||||
self.spellId = data.spellId
|
||||
|
||||
self.frame = frame
|
||||
self.stacks = stacks
|
||||
if self.showStacks and numStacks > 0 then
|
||||
stacks:SetText(numStacks)
|
||||
stacks:Show()
|
||||
end
|
||||
if self.flashTime or self.fadeTime then
|
||||
self.frame:SetScript("OnUpdate", function(frame, dt)
|
||||
self:OnUpdate(dt)
|
||||
end)
|
||||
self.expirationTime = data.expirationTime
|
||||
self.updateThrottle = 0
|
||||
end
|
||||
if self.showTooltip then
|
||||
frame:SetScript("OnEnter", function()
|
||||
GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
|
||||
GameTooltip:SetSpellByID(self.spellId)
|
||||
GameTooltip:Show()
|
||||
end)
|
||||
frame:SetScript("OnLeave", function()
|
||||
GameTooltip:Hide()
|
||||
end)
|
||||
end
|
||||
if data.icon then
|
||||
self:SetIcon(data.icon)
|
||||
else
|
||||
self:SetIcon(self.icon)
|
||||
end
|
||||
frame:Show()
|
||||
self:UpdateAlpha()
|
||||
end
|
||||
|
||||
--- Set the icon of the Icon Indicator
|
||||
function IconIndicator:SetIcon(icon)
|
||||
self.icon = icon
|
||||
local frame = self.frame
|
||||
if frame then
|
||||
frame.iconTexture:SetTexture(icon)
|
||||
end
|
||||
end
|
||||
|
||||
function IconIndicator:GetFrame()
|
||||
local frame, new = iconPool:Acquire()
|
||||
local stacks
|
||||
if new then
|
||||
local iconTexture = frame:CreateTexture(nil, "BACKGROUND")
|
||||
iconTexture:SetAllPoints()
|
||||
frame.iconTexture = iconTexture
|
||||
|
||||
frame.backdropInfo = {
|
||||
bgFile = nil,
|
||||
edgeFile = "Interface\\Addons\\OmicronFrames\\media\\textures\\pixel_edge",
|
||||
edgeSize = 2,
|
||||
insets = { left = 0, right = 0, top = 0, bottom = 0 },
|
||||
}
|
||||
frame:ApplyBackdrop()
|
||||
|
||||
stacks = frame:CreateFontString(nil, "OVERLAY")
|
||||
frame.stacks = stacks
|
||||
stacks:SetFont("Interface\\AddOns\\OmicronFrames\\media\\fonts\\roboto\\Roboto-Medium.ttf", 12, "OUTLINE")
|
||||
stacks:SetPoint("CENTER")
|
||||
stacks:SetTextColor(1, 1, 1)
|
||||
end
|
||||
|
||||
frame:SetSize(self.size, self.size)
|
||||
frame:SetParent(self.frameParent)
|
||||
frame:SetPoint(self.point, self.x, self.y)
|
||||
frame:SetBackdropBorderColor(0, 0, 0, 1)
|
||||
frame:SetAlpha(1)
|
||||
stacks = frame.stacks
|
||||
return frame, stacks
|
||||
end
|
||||
|
||||
---@param data table
|
||||
function IconIndicator:Update(data)
|
||||
if data.icon then
|
||||
self:SetIcon(data.icon)
|
||||
end
|
||||
local numStacks = data.applications or 0
|
||||
if numStacks > 0 then
|
||||
self.stacks:SetText(numStacks)
|
||||
self.stacks:Show()
|
||||
end
|
||||
self.expirationTime = data.expirationTime
|
||||
|
||||
self.auraInstanceID = data.auraInstanceID
|
||||
self.spellId = data.spellId
|
||||
|
||||
self:UpdateAlpha()
|
||||
end
|
||||
|
||||
function IconIndicator:UpdateAlpha()
|
||||
if self.expirationTime == 0 then
|
||||
self.frame:SetAlpha(1)
|
||||
return
|
||||
end
|
||||
|
||||
local timeLeft = self.expirationTime - GetTime()
|
||||
local fadeTime = self.fadeTime or 0
|
||||
local flashTime = self.flashTime or 0
|
||||
|
||||
if timeLeft < flashTime then
|
||||
local alpha = ((timeLeft * 4) % 1)
|
||||
self.frame:SetAlpha(alpha)
|
||||
elseif timeLeft < fadeTime then
|
||||
local alpha = timeLeft / fadeTime
|
||||
self.frame:SetAlpha(alpha)
|
||||
else
|
||||
self.frame:SetAlpha(1)
|
||||
end
|
||||
end
|
||||
|
||||
function IconIndicator:OnUpdate(dt)
|
||||
dt = self.updateThrottle + dt
|
||||
if dt < 0.04 then
|
||||
self.updateThrottle = dt
|
||||
return
|
||||
else
|
||||
self.updateThrottle = 0
|
||||
end
|
||||
|
||||
self:UpdateAlpha()
|
||||
end
|
||||
|
||||
--- Hide the square indicator.
|
||||
function IconIndicator:Hide()
|
||||
local frame = self.frame
|
||||
if frame == nil then
|
||||
return
|
||||
end
|
||||
self.stacks:Hide()
|
||||
self.frame = nil
|
||||
self.stacks = nil
|
||||
self.instanceId = nil
|
||||
self.spellId = nil
|
||||
frame:SetScript("OnUpdate", nil)
|
||||
frame:SetScript("OnLeave", nil)
|
||||
frame:SetScript("OnEnter", nil)
|
||||
iconPool:Release(frame)
|
||||
end
|
||||
@@ -26,13 +26,10 @@ local Indicator = types.CreateClass("Indicator")
|
||||
types.Indicator = Indicator
|
||||
|
||||
--- Show the indicator and supply it with data
|
||||
function Indicator:Show(data)
|
||||
end
|
||||
function Indicator:Show(data) end
|
||||
|
||||
--- Update the indicator with new data
|
||||
function Indicator:Update(data)
|
||||
end
|
||||
function Indicator:Update(data) end
|
||||
|
||||
--- Hide the indicator
|
||||
function Indicator:Hide()
|
||||
end
|
||||
function Indicator:Hide() end
|
||||
@@ -21,7 +21,9 @@ types.StatusBar = types.CreateClass("StatusBar")
|
||||
local StatusBar = types.StatusBar
|
||||
|
||||
function StatusBar:Init(parent, width, height, level, top, texture, bgtexture)
|
||||
if top == nil then top = true end
|
||||
if top == nil then
|
||||
top = true
|
||||
end
|
||||
level = level or 0
|
||||
-- parent: the parent frame
|
||||
self.parent = parent
|
||||
|
||||
@@ -21,26 +21,20 @@ local Trigger = types.Trigger
|
||||
|
||||
---AuraTrigger is a Trigger that can be attached to AuraList as datasource
|
||||
---@class AuraTrigger: Trigger
|
||||
---@field spellId number
|
||||
---@field spellIds table<number, true>
|
||||
---@field count number
|
||||
---@field requiredCount number
|
||||
local AuraTrigger = types.CreateClass("AuraTrigger", Trigger)
|
||||
types.AuraTrigger = AuraTrigger
|
||||
|
||||
|
||||
---Creates a new AuraTrigger from a config description and attaches it to the
|
||||
---correct data source
|
||||
---@param unit UnitFrame
|
||||
---@param config table
|
||||
---@return AuraTrigger
|
||||
function AuraTrigger.CreateFromConfig(unit, config)
|
||||
local trigger = AuraTrigger:new(
|
||||
config.spellId,
|
||||
config.own,
|
||||
config.requiredCount,
|
||||
config.invert,
|
||||
config.defaultData
|
||||
)
|
||||
local trigger =
|
||||
AuraTrigger:new(config.spellIds, config.own, config.requiredCount, config.invert, config.defaultData)
|
||||
unit.auras:AddTrigger(trigger)
|
||||
return trigger
|
||||
end
|
||||
@@ -54,29 +48,33 @@ function AuraTrigger.new(cls, ...)
|
||||
end
|
||||
|
||||
--- Initialize a new AuraTrigger object
|
||||
---@param spellId number
|
||||
---@param spellIds table<number, true>
|
||||
---@param own boolean
|
||||
---@param requiredCount number | nil
|
||||
---@param invert boolean | nil
|
||||
---@param defaultData table | nil
|
||||
function AuraTrigger:Init(spellId, own, requiredCount, invert, defaultData)
|
||||
function AuraTrigger:Init(spellIds, own, requiredCount, invert, defaultData)
|
||||
Trigger.Init(self, invert, defaultData)
|
||||
self.spellId = spellId
|
||||
self.spellIds = spellIds
|
||||
self.instanceData = {}
|
||||
self.requiredCount = requiredCount or 1
|
||||
self.own = own
|
||||
self.count = 0
|
||||
self.bestAuraID = nil
|
||||
end
|
||||
|
||||
--- Reset the AuraTrigger to the default state
|
||||
function AuraTrigger:Reset()
|
||||
self.count = 0
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
self.bestAuraID = nil
|
||||
table.wipe(self.instanceData)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, {})
|
||||
end
|
||||
|
||||
---Check if a given aura matches this AuraTrigger
|
||||
---@param aura UnitAuraInfo
|
||||
function AuraTrigger:IsMatching(aura)
|
||||
if aura.spellId ~= aura.spellId then
|
||||
if not self.spellIds[aura.spellId] then
|
||||
return false
|
||||
end
|
||||
if self.own and aura.sourceUnit ~= "player" then
|
||||
@@ -85,25 +83,68 @@ function AuraTrigger:IsMatching(aura)
|
||||
return true
|
||||
end
|
||||
|
||||
-- Get the ID of the current best matching aura in AuraTrigger.instanceData
|
||||
function AuraTrigger:BestAuraID()
|
||||
local found = nil
|
||||
for k, v in pairs(self.instanceData) do
|
||||
if not found then
|
||||
found = k
|
||||
elseif v.expirationTime > self.instanceData[found].expirationTime then
|
||||
found = k
|
||||
end
|
||||
end
|
||||
return found
|
||||
end
|
||||
|
||||
---Grab the best aura data and update the current recorded best aura
|
||||
---It returns data if the current best aura is different from the previous
|
||||
---@param updatedInstanceId number|nil the aura id that was recently updated
|
||||
function AuraTrigger:BestAuraData(updatedInstanceId)
|
||||
local bid = self:BestAuraID()
|
||||
if bid == nil then
|
||||
self.bestAuraID = nil
|
||||
return nil
|
||||
end
|
||||
|
||||
local data = nil
|
||||
if bid ~= self.bestAuraID or (updatedInstanceId and bid == updatedInstanceId) then
|
||||
local aura = self.instanceData[bid]
|
||||
data = {
|
||||
stacks = aura.applications,
|
||||
duration = aura.duration,
|
||||
expirationTime = aura.expirationTime,
|
||||
icon = aura.icon,
|
||||
}
|
||||
self.bestAuraID = bid
|
||||
end
|
||||
return data
|
||||
end
|
||||
|
||||
---Inform the trigger about an added aura
|
||||
---@param aura UnitAuraInfo
|
||||
function AuraTrigger:AddAura(aura)
|
||||
if not self:IsMatching(aura) then
|
||||
return
|
||||
end
|
||||
local aid = aura.auraInstanceID
|
||||
self.instanceData[aid] = aura
|
||||
self.count = self.count + 1
|
||||
self:SetData({ stacks = aura.applications, duration = aura.duration, expirationTime = aura.expirationTime })
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
local newData = self:BestAuraData(nil)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
|
||||
---Inform the trigger about an updated aura
|
||||
---@param before UnitAuraInfo
|
||||
---@param after UnitAuraInfo
|
||||
function AuraTrigger:UpdateAura(before, after)
|
||||
self:SetData({ stacks = after.applications, duration = after.duration, expirationTime = after.expirationTime })
|
||||
if self.active then
|
||||
self.indicator:Update(self.data)
|
||||
if not self:IsMatching(after) then
|
||||
return
|
||||
end
|
||||
local aid = after.auraInstanceID
|
||||
self.instanceData[aid] = after
|
||||
|
||||
local newData = self:BestAuraData(aid)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
|
||||
---Inform the trigger about an aura that got removed
|
||||
@@ -112,7 +153,11 @@ function AuraTrigger:RemoveAura(aura)
|
||||
if not self:IsMatching(aura) then
|
||||
return
|
||||
end
|
||||
|
||||
local aid = aura.auraInstanceID
|
||||
self.instanceData[aid] = nil
|
||||
self.count = self.count - 1
|
||||
self:SetData({})
|
||||
self:SetState(self.count >= self.requiredCount, false)
|
||||
|
||||
local newData = self:BestAuraData(nil)
|
||||
self:SetStateAndData(self.count >= self.requiredCount, newData)
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Copyright 2023 <omicron.me@protonmail.com>
|
||||
--
|
||||
-- This file is part of Omicron Frames
|
||||
--
|
||||
--
|
||||
-- Omicron Frames is free software: you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 3 of the License, or (at your option)
|
||||
@@ -13,7 +13,7 @@
|
||||
-- more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
|
||||
@@ -26,7 +26,7 @@ local Trigger = types.Trigger
|
||||
---indicator.
|
||||
---@class MultiTrigger: Trigger
|
||||
---@field active boolean
|
||||
---@field invert boolean
|
||||
---@field invert boolean
|
||||
local MultiTrigger = types.CreateClass("MultiTrigger", Trigger)
|
||||
types.MultiTrigger = MultiTrigger
|
||||
|
||||
@@ -73,7 +73,7 @@ function MultiTrigger:AddTrigger(trigger)
|
||||
end,
|
||||
Hide = function(_, data)
|
||||
self:OnChildDeactivate(idx, trigger, data)
|
||||
end
|
||||
end,
|
||||
})
|
||||
end
|
||||
|
||||
@@ -92,8 +92,7 @@ function MultiTrigger:OnChildActivate(idx, trigger, data)
|
||||
table.sort(activeChildren)
|
||||
-- The highest priority active trigger has changed
|
||||
if activeChild ~= activeChildren[1] then
|
||||
self:SetData(data)
|
||||
self:SetState(true, true)
|
||||
self:SetStateAndData(true, data)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -117,11 +116,9 @@ function MultiTrigger:OnChildDeactivate(idx, trigger, data)
|
||||
local newActiveChild = activeChildren[1]
|
||||
if activeChild ~= newActiveChild then
|
||||
if activeChildren[1] ~= nil then
|
||||
self:SetData(childrenData[newActiveChild])
|
||||
self:SetState(true, true)
|
||||
self:SetStateAndData(true, childrenData[newActiveChild])
|
||||
else
|
||||
self:SetData({})
|
||||
self:SetState(false, false)
|
||||
self:SetStateAndData(false, {})
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -139,6 +136,5 @@ end
|
||||
-- Reset the trigger to the default state. If this changes the activation of the
|
||||
-- trigger then the target will be notified.
|
||||
function MultiTrigger:Reset()
|
||||
self:SetState(false)
|
||||
self:SetStateAndData(false, {})
|
||||
end
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Copyright 2023 <omicron.me@protonmail.com>
|
||||
--
|
||||
-- This file is part of Omicron Frames
|
||||
--
|
||||
--
|
||||
-- Omicron Frames is free software: you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 3 of the License, or (at your option)
|
||||
@@ -13,7 +13,7 @@
|
||||
-- more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
---@class Trigger
|
||||
@@ -29,8 +29,7 @@ types.StatusTrigger = StatusTrigger
|
||||
---@param unit UnitFrame
|
||||
---@param config table
|
||||
function StatusTrigger.CreateFromConfig(unit, config)
|
||||
local trigger = StatusTrigger:new(config.status, config.requiredCount,
|
||||
config.invert, config.defaultData)
|
||||
local trigger = StatusTrigger:new(config.status, config.requiredCount, config.invert, config.defaultData)
|
||||
unit.auras:AddTrigger(trigger)
|
||||
return trigger
|
||||
end
|
||||
@@ -45,7 +44,7 @@ end
|
||||
|
||||
--- Initialize a new AuraTrigger object
|
||||
---@param status string The kind of status to trigger on
|
||||
---@param requiredCount number | nil
|
||||
---@param requiredCount number | nil
|
||||
---@param invert boolean | nil
|
||||
function StatusTrigger:Init(status, requiredCount, invert, defaultData)
|
||||
Trigger.Init(self, invert, defaultData)
|
||||
@@ -59,5 +58,5 @@ end
|
||||
-- status:
|
||||
-- Must be a valid UnitAuraInfo
|
||||
function StatusTrigger:UpdateStatus(count)
|
||||
self:SetState(count >= self.requiredCount, false)
|
||||
self:SetStateAndData(count >= self.requiredCount, nil)
|
||||
end
|
||||
@@ -1,7 +1,7 @@
|
||||
-- Copyright 2023 <omicron.me@protonmail.com>
|
||||
--
|
||||
-- This file is part of Omicron Frames
|
||||
--
|
||||
--
|
||||
-- Omicron Frames is free software: you can redistribute it and/or modify it
|
||||
-- under the terms of the GNU General Public License as published by the Free
|
||||
-- Software Foundation, either version 3 of the License, or (at your option)
|
||||
@@ -13,22 +13,21 @@
|
||||
-- more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License along with
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
-- Omicron Frames. If not, see <https://www.gnu.org/licenses/>.
|
||||
local omi = select(2, ...)
|
||||
local types = omi.GetModule("types")
|
||||
|
||||
--- Triggers objects provide a link between indicators and some data source. They
|
||||
-- can pass data from the data source into the indicator. This is a supertype for
|
||||
-- all triggers and should not be constructed on its own.
|
||||
-- can pass data from the data source into the indicator. This is a supertype for
|
||||
-- all triggers and should not be constructed on its own.
|
||||
---@class Trigger: Object
|
||||
---@field active boolean
|
||||
---@field invert boolean
|
||||
---@field invert boolean
|
||||
---@field indicator Indicator
|
||||
---@field data table The most recent data updated by the data source
|
||||
local Trigger = types.CreateClass("Trigger")
|
||||
types.Trigger = Trigger
|
||||
|
||||
|
||||
---@param unit UnitFrame
|
||||
---@param config table
|
||||
---@return Trigger
|
||||
@@ -48,7 +47,9 @@ function Trigger:Init(invert, defaultData)
|
||||
end
|
||||
|
||||
---Save new data from the datasource into the trigger. This method will make
|
||||
---sure the default data is always present
|
||||
---sure the default data is always present. This method will not ensure the
|
||||
---target gets notified of new state or new data. Subclasses of Trigger should
|
||||
---use Trigger:SetStateAndData instead.
|
||||
---@param data table
|
||||
function Trigger:SetData(data)
|
||||
if self.defaultData then
|
||||
@@ -70,9 +71,21 @@ function Trigger:SetTarget(target)
|
||||
end
|
||||
end
|
||||
|
||||
---Set the state of the trigger. Will activate the indicator if needed.
|
||||
---Set the data and state of the trigger. Will update the trigger as needed.
|
||||
---
|
||||
--- If the state changes this function will call Show or Hide on the indicator.
|
||||
--- If the state remains the same and the data is not nil, it will call Update
|
||||
--- on the indicator.
|
||||
---
|
||||
---@param state boolean
|
||||
function Trigger:SetState(state, doUpdate)
|
||||
---@param data table|nil
|
||||
function Trigger:SetStateAndData(state, data)
|
||||
local doUpdate = false
|
||||
if data then
|
||||
doUpdate = true
|
||||
self:SetData(data)
|
||||
end
|
||||
|
||||
state = state ~= self.invert -- state xor inverted
|
||||
if self.active ~= state then
|
||||
if state then
|
||||
@@ -89,6 +102,5 @@ end
|
||||
-- Reset the trigger to the default state. If this changes the activation of the
|
||||
-- trigger then the target will be notified.
|
||||
function Trigger:Reset()
|
||||
self:SetState(false, false)
|
||||
self:SetStateAndData(false, nil)
|
||||
end
|
||||
|
||||
+1
-2
@@ -24,7 +24,7 @@ local function CreateClassRaw(name, parent)
|
||||
c.__typeInfo = {
|
||||
name = name,
|
||||
class = c,
|
||||
parent = parent
|
||||
parent = parent,
|
||||
}
|
||||
c.__index = c
|
||||
if parent ~= nil then
|
||||
@@ -49,6 +49,5 @@ function types.IsDerivedFrom(a, b)
|
||||
end
|
||||
current = current.__typeInfo.parent
|
||||
until current == nil
|
||||
;
|
||||
return false
|
||||
end
|
||||
+118
-21
@@ -17,6 +17,11 @@
|
||||
local omif = select(2, ...)
|
||||
local types = omif.GetModule("types")
|
||||
|
||||
local NameFont = CreateFont("OicronFrames_NameFont")
|
||||
NameFont:SetFont("Interface\\AddOns\\OmicronFrames\\media\\fonts\\roboto\\Roboto-Bold.ttf", 13, "")
|
||||
NameFont:SetShadowColor(0, 0, 0)
|
||||
NameFont:SetShadowOffset(1, -1)
|
||||
|
||||
---@class StatusBar
|
||||
local StatusBar = types.StatusBar
|
||||
|
||||
@@ -26,6 +31,9 @@ local AuraList = types.AuraList
|
||||
---@class SquareIndicator
|
||||
local SquareIndicator = types.SquareIndicator
|
||||
|
||||
---@class IconIndicator
|
||||
local IconIndicator = types.IconIndicator
|
||||
|
||||
---@class SquareIndicator
|
||||
local BorderIndicator = types.BorderIndicator
|
||||
|
||||
@@ -33,7 +41,6 @@ local BorderIndicator = types.BorderIndicator
|
||||
local UnitFrame = types.CreateClass("UnitFrame")
|
||||
types.UnitFrame = UnitFrame
|
||||
|
||||
|
||||
local colors = {
|
||||
hostile = { 0.5, 0.0, 0.0 },
|
||||
neutral = { 0.7, 0.7, 0.0 },
|
||||
@@ -51,8 +58,8 @@ local colors = {
|
||||
bomb = { 1.0, 0.7, 0.7 },
|
||||
cyan = { 0.0, 0.8, 0.8 },
|
||||
white = { 1.0, 1.0, 1.0 },
|
||||
shield = { 0.85, .95, 1.0 },
|
||||
absorb = { 0.5, .4, .75 },
|
||||
shield = { 0.85, 0.95, 1.0 },
|
||||
absorb = { 0.5, 0.4, 0.75 },
|
||||
}
|
||||
|
||||
-- This trucates _codepoints_ not graphemes. If combination codepoints are
|
||||
@@ -99,17 +106,16 @@ function UnitFrame:Init(unit, config)
|
||||
|
||||
self.absorb = StatusBar:new(self, width, height, 1, true, texture_top)
|
||||
self.absorb:SetColor(unpack(colors.absorb))
|
||||
self.absorb:SetFillStyle("REVERSE")
|
||||
self.absorb:SetFillStyle(Enum.StatusBarFillStyle.Reverse)
|
||||
|
||||
self.shield = StatusBar:new(self, width, height, 1, true, texture_bot)
|
||||
self.shield:SetColor(unpack(colors.shield))
|
||||
self.shield:SetRange(0, 1)
|
||||
self.shield:SetValue(0.6)
|
||||
self.shield:SetFillStyle("REVERSE")
|
||||
self.shield:SetFillStyle(Enum.StatusBarFillStyle.Reverse)
|
||||
|
||||
self.auras = AuraList:new(self)
|
||||
|
||||
|
||||
local overlays = CreateFrame("Frame", nil, secure)
|
||||
overlays:SetFrameStrata("MEDIUM")
|
||||
overlays:SetFrameLevel(100)
|
||||
@@ -120,6 +126,8 @@ function UnitFrame:Init(unit, config)
|
||||
|
||||
self:CreateTriggers(config.triggers)
|
||||
|
||||
self:InitDebuffs()
|
||||
|
||||
self:RegisterEvents()
|
||||
self:Enable()
|
||||
end
|
||||
@@ -148,12 +156,19 @@ function UnitFrame:CreateIndicator(indicator)
|
||||
indicator.fadeTime,
|
||||
indicator.flashTime
|
||||
)
|
||||
elseif kind == "BorderIndicator" then
|
||||
return BorderIndicator:new(
|
||||
elseif kind == "IconIndicator" then
|
||||
return IconIndicator:new(
|
||||
self,
|
||||
indicator.thickness,
|
||||
indicator.color
|
||||
indicator.size,
|
||||
indicator.point,
|
||||
indicator.x,
|
||||
indicator.y,
|
||||
indicator.showStacks,
|
||||
indicator.fadeTime,
|
||||
indicator.flashTime
|
||||
)
|
||||
elseif kind == "BorderIndicator" then
|
||||
return BorderIndicator:new(self, indicator.thickness, indicator.color)
|
||||
else
|
||||
error(string.format("Invalid Indicator kind `%s` requested", indicator.kind))
|
||||
end
|
||||
@@ -174,10 +189,8 @@ function UnitFrame:CreateName()
|
||||
local name = self.overlays:CreateFontString(nil, "BACKGROUND")
|
||||
self.name = name
|
||||
|
||||
name:SetFont("Interface\\AddOns\\OmicronFrames\\media\\fonts\\roboto\\Roboto-Bold.ttf", 13, "")
|
||||
name:SetFontObject(NameFont)
|
||||
name:SetTextColor(0.8, 0.6, 0.1)
|
||||
name:SetShadowColor(0, 0, 0)
|
||||
name:SetShadowOffset(1, -1)
|
||||
name:SetPoint("CENTER")
|
||||
name:SetText("")
|
||||
name:Show()
|
||||
@@ -201,9 +214,9 @@ function UnitFrame:IsInRange()
|
||||
|
||||
-- Prefer to use configured spells
|
||||
if friendlySpell and UnitCanAssist("player", unit) then
|
||||
return IsSpellInRange(friendlySpell, unit) == 1
|
||||
return C_Spell.IsSpellInRange(friendlySpell, unit) == true
|
||||
elseif enemySpell and UnitCanAttack("player", unit) then
|
||||
return IsSpellInRange(enemySpell, unit) == 1
|
||||
return C_Spell.IsSpellInRange(enemySpell, unit) == true
|
||||
end
|
||||
|
||||
-- Fall back to raid/party only range check
|
||||
@@ -282,9 +295,15 @@ function UnitFrame:PrepareWheelBinds(bindings)
|
||||
if bind.button == "wheel-up" or bind.button == "wheel-down" then
|
||||
local prefix = ModifiersToPrefix(bind.mods)
|
||||
local button = bind.button == "wheel-up" and "MOUSEWHEELUP" or "MOUSEWHEELDOWN"
|
||||
table.insert(bindScript,
|
||||
string.format([[self:SetBindingClick(false, "%s%s", "OmicronSecureFrame%s", "%s%s")]],
|
||||
prefix, button, unit, prefix, bind.button
|
||||
table.insert(
|
||||
bindScript,
|
||||
string.format(
|
||||
[[self:SetBindingClick(false, "%s%s", "OmicronSecureFrame%s", "%s%s")]],
|
||||
prefix,
|
||||
button,
|
||||
unit,
|
||||
prefix,
|
||||
bind.button
|
||||
)
|
||||
)
|
||||
end
|
||||
@@ -375,10 +394,9 @@ function UnitFrame:Disable()
|
||||
if self.hideInRaid then
|
||||
UnregisterAttributeDriver(self.secureFrame, "state-visibility")
|
||||
elseif self.unit ~= "player" then
|
||||
UnregisterUnitWatch(self.secure_frame, self.condition)
|
||||
else
|
||||
self.secureFrame:Hide()
|
||||
UnregisterUnitWatch(self.secureFrame, false)
|
||||
end
|
||||
self.secureFrame:Hide()
|
||||
end
|
||||
|
||||
-- returns true if this unit is a target unit
|
||||
@@ -425,6 +443,7 @@ function UnitFrame:RegisterEvents()
|
||||
end
|
||||
end
|
||||
|
||||
secure:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||
secure:RegisterUnitEvent("UNIT_AURA", unit)
|
||||
secure:RegisterUnitEvent("UNIT_HEALTH", unit)
|
||||
secure:RegisterUnitEvent("UNIT_MAXHEALTH", unit)
|
||||
@@ -467,6 +486,81 @@ function UnitFrame:UNIT_ABSORB_AMOUNT_CHANGED()
|
||||
self:UpdateShield()
|
||||
end
|
||||
|
||||
function UnitFrame:GROUP_ROSTER_UPDATE()
|
||||
if self:HasUnitChanged() then
|
||||
self:UpdateAll(true)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
-- FIXME: This is a total hack job, just quickly want to get debuffs rendering on my unit frames to learn new dungeons
|
||||
function UnitFrame:InitDebuffs()
|
||||
local icons = {}
|
||||
self.debuffIndicators = icons
|
||||
for i = 1, 5 do
|
||||
local icon = IconIndicator:new(self, 17, "BOTTOMRIGHT", -2 - (i - 1) * 19, 2, true, 10.0, nil, true)
|
||||
icons[i] = icon
|
||||
end
|
||||
end
|
||||
|
||||
local ignoredDebuffs = {
|
||||
[57723] = true, -- Sated, shaman lust debuff (alliance)
|
||||
[57724] = true, -- Sated, shaman lust debuff (horde)
|
||||
[80354] = true, -- Temporal displacement
|
||||
[390435] = true, -- Exhausstion
|
||||
[264689] = true, -- Fatigued
|
||||
[87024] = true, -- Cauterized
|
||||
[45181] = true, -- Cheated Death
|
||||
[41425] = true, -- hypothermia
|
||||
[124275] = true, -- Light stagger
|
||||
[124274] = true, -- moderate stagger
|
||||
[124273] = true, -- heavy stagger
|
||||
[25771] = true, -- Forbearance
|
||||
[456447] = true, -- Battle-Scarred Veteran
|
||||
[382912] = true, -- Well-Honed Instincts
|
||||
[1223611] = true, -- Ethereal Exhaustion
|
||||
[456779] = true, -- Will of the Dawn
|
||||
[448005] = true, -- Light of the Martyr
|
||||
[157131] = true, -- Recently Saved by the Light
|
||||
[387847] = true,
|
||||
[206151] = true, -- Challenger's Burden
|
||||
[113942] = true, -- Demonic Gateway
|
||||
[1216943] = true, -- void pulsar
|
||||
[462661] = true, -- Voidbinding
|
||||
[1239229] = true, -- k'areshi surge
|
||||
[449042] = true, -- Radiant Light
|
||||
-- blood draw
|
||||
}
|
||||
|
||||
function UnitFrame:UpdateDebuffs()
|
||||
local auras = {}
|
||||
local i = 1
|
||||
while #auras < 5 do
|
||||
local aura = C_UnitAuras.GetAuraDataByIndex(self.unit, i, "HARMFUL")
|
||||
if aura == nil then
|
||||
break
|
||||
end
|
||||
if not ignoredDebuffs[aura.spellId] then
|
||||
table.insert(auras, aura)
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
for i = 1, 5 do
|
||||
local aura = auras[i]
|
||||
local icon = self.debuffIndicators[i]
|
||||
|
||||
if aura then
|
||||
if icon.frame then
|
||||
icon:Update(aura)
|
||||
else
|
||||
icon:Show(aura)
|
||||
end
|
||||
elseif icon.frame then
|
||||
icon:Hide()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function UnitFrame:UNIT_AURA(unit, info)
|
||||
if self:HasUnitChanged() then
|
||||
self:UpdateAll(true)
|
||||
@@ -475,6 +569,8 @@ function UnitFrame:UNIT_AURA(unit, info)
|
||||
if self.auras:Update(info) then
|
||||
self:UpdateHealthColor()
|
||||
end
|
||||
|
||||
self:UpdateDebuffs()
|
||||
end
|
||||
|
||||
function UnitFrame:UNIT_HEALTH()
|
||||
@@ -578,6 +674,7 @@ function UnitFrame:UpdateAll(unitChanged)
|
||||
self:UpdateRange()
|
||||
self:UpdateName()
|
||||
self:UpdateRole() -- Also calls UpdatePower if power is visible
|
||||
self:UpdateDebuffs()
|
||||
end
|
||||
|
||||
function UnitFrame:UpdateHealth()
|
||||
|
||||
+12
-11
@@ -32,9 +32,10 @@ local function RoleValue(role)
|
||||
end
|
||||
|
||||
local function UnitFrameDefaultCompare(lhs, rhs)
|
||||
-- visible < invisible
|
||||
if lhs.secureFrame:IsShown() ~= rhs.secureFrame:IsShown() then
|
||||
return lhs.secureFrame:IsShown()
|
||||
-- exists < not exists
|
||||
local lexists, rexists = UnitExists(lhs.unit), UnitExists(rhs.unit)
|
||||
if lexists ~= rexists then
|
||||
return lexists
|
||||
end
|
||||
|
||||
local lunit, runit = lhs.unit, rhs.unit
|
||||
@@ -69,7 +70,6 @@ function UnitGroup:Init(left, top, width, height)
|
||||
self.top = top
|
||||
self.left = left
|
||||
self.units = {}
|
||||
self.sortAfterCombat = false
|
||||
self:RegisterEvents()
|
||||
end
|
||||
|
||||
@@ -84,6 +84,7 @@ function UnitGroup:RegisterEvents()
|
||||
frame:RegisterEvent("GROUP_ROSTER_UPDATE")
|
||||
frame:RegisterEvent("PLAYER_REGEN_ENABLED")
|
||||
frame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
frame:RegisterEvent("UNIT_PET")
|
||||
end
|
||||
|
||||
function UnitGroup:GROUP_ROSTER_UPDATE()
|
||||
@@ -94,23 +95,23 @@ function UnitGroup:PLAYER_ENTERING_WORLD()
|
||||
self:OnRosterUpdate()
|
||||
end
|
||||
|
||||
function UnitGroup:UNIT_PET()
|
||||
self:OnRosterUpdate()
|
||||
end
|
||||
|
||||
function UnitGroup:PLAYER_REGEN_ENABLED()
|
||||
self:OnLeaveCombat()
|
||||
end
|
||||
|
||||
function UnitGroup:OnLeaveCombat()
|
||||
if self.sortAfterCombat then
|
||||
self:Sort()
|
||||
self.sortAfterCombat = false
|
||||
end
|
||||
self:Sort()
|
||||
end
|
||||
|
||||
function UnitGroup:OnRosterUpdate()
|
||||
if InCombatLockdown() then
|
||||
self.sortAfterCombat = true
|
||||
else
|
||||
self:Sort()
|
||||
return
|
||||
end
|
||||
self:Sort()
|
||||
end
|
||||
|
||||
function UnitGroup:AddUnitFrame(unit)
|
||||
|
||||
Reference in new issue
Block a user