Compare commits
	
		
			11 Commits
		
	
	
		
			ff9d8b2289
			...
			763bf0bdae
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 763bf0bdae | |||
| f181c0022c | |||
| 0cced419a6 | |||
| 5bbbde3ca7 | |||
| 6f954b9d15 | |||
| c56b847710 | |||
| dc62b031a9 | |||
| ec7e2c74ff | |||
| b1dca1639d | |||
| 47542c7147 | |||
| 1fce6017bd | 
							
								
								
									
										1
									
								
								.stylua.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.stylua.toml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| indent_type = "Spaces" | ||||
							
								
								
									
										4
									
								
								devloop
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								devloop
									
									
									
									
									
								
							| @@ -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 | ||||
|   | ||||
							
								
								
									
										
											BIN
										
									
								
								media/textures/bar_subtle_diagonal_bottom.tga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/textures/bar_subtle_diagonal_bottom.tga
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								media/textures/bar_subtle_diagonal_top.tga
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								media/textures/bar_subtle_diagonal_top.tga
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
										
											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 | ||||
|   | ||||
							
								
								
									
										426
									
								
								src/frames.lua
									
									
									
									
									
								
							
							
						
						
									
										426
									
								
								src/frames.lua
									
									
									
									
									
								
							| @@ -26,27 +26,27 @@ local colors = { | ||||
|     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 }, | ||||
| } | ||||
|  | ||||
| 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", | ||||
|             enemy = "Smite", | ||||
|             fade = 0.2 | ||||
|             fade = 0.2, | ||||
|         } | ||||
|     else | ||||
|         return { | ||||
|             fade = 0.2 | ||||
|             fade = 0.2, | ||||
|         } | ||||
|     end | ||||
| end | ||||
| @@ -56,128 +56,198 @@ 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 Vision; [@UNIT,help]Chain Heal", | ||||
|             }, | ||||
|             { | ||||
|                 button = "mouse3", | ||||
|                 mods = {}, | ||||
|                 kind = "macro", | ||||
|                 data = | ||||
|                 "/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT,help]Purify Spirit" | ||||
|                 data = "/use [@UNIT,dead,help]Ancestral Spirit; [@UNIT,help]Purify Spirit", | ||||
|             }, | ||||
|             { button = "wheel-up",   mods = {},               kind = "macro",     data = "/use [@UNIT,help]Healing Surge" }, | ||||
|             { button = "wheel-down", mods = {},               kind = "macro",     data = "/use [@UNIT,help]Riptide" }, | ||||
|             { | ||||
|                 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-up", mods = { alt = true }, kind = "spell", data = "Healing Wave" }, | ||||
|             { button = "wheel-down", mods = { alt = true }, kind = "spell", data = "Earth 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]Water Walking;\n/stopspelltarget" | ||||
|                 data = "/cast [@UNIT,help]Water Walking;\n/stopspelltarget", | ||||
|             }, | ||||
|         } | ||||
|     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]Flash Heal", | ||||
|             }, | ||||
|             { button = "wheel-down", mods = {}, kind = "macro", data = "/use [@UNIT,help]Renew" }, | ||||
|  | ||||
|             -- 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 == "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 | ||||
| @@ -199,7 +269,7 @@ local function TriggerClassConfig() | ||||
|                     y = -3, | ||||
|                     color = colors.white, | ||||
|                     showStacks = true, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -213,21 +283,20 @@ local function TriggerClassConfig() | ||||
|                     y = -3, | ||||
|                     color = colors.white, | ||||
|                     showStacks = true, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
|                 spellId = 61295, | ||||
|                 own = true, -- Riptide | ||||
|                 indicator = { | ||||
|                     kind = "SquareIndicator", | ||||
|                     kind = "IconIndicator", | ||||
|                     size = 17, | ||||
|                     point = "BOTTOMLEFT", | ||||
|                     x = 3, | ||||
|                     y = 3, | ||||
|                     color = colors.cyan, | ||||
|                     fadeTime = 10.0, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "StatusTrigger", | ||||
| @@ -238,7 +307,7 @@ local function TriggerClassConfig() | ||||
|                     thickness = 3.0, | ||||
|                     color = colors.red, | ||||
|                     level = 0, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|         } | ||||
|     elseif class == "PRIEST" then | ||||
| @@ -255,7 +324,7 @@ local function TriggerClassConfig() | ||||
|                     y = -3, | ||||
|                     color = colors.white, | ||||
|                     fadeTime = 10.0, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -270,7 +339,7 @@ local function TriggerClassConfig() | ||||
|                     color = colors.orange, | ||||
|                     fadeTime = 10.0, | ||||
|                     flashTime = 1.3, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -284,7 +353,7 @@ local function TriggerClassConfig() | ||||
|                     y = -3, | ||||
|                     color = { 0.7, 0.9, 1 }, | ||||
|                     showStacks = true, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -298,7 +367,7 @@ local function TriggerClassConfig() | ||||
|                     y = 3, | ||||
|                     color = colors.cyan, | ||||
|                     fadeTime = 10.0, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -313,7 +382,7 @@ local function TriggerClassConfig() | ||||
|                     color = colors.white, | ||||
|                     fadeTime = 10.0, | ||||
|                     flashTime = 1.3, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
| @@ -327,7 +396,7 @@ local function TriggerClassConfig() | ||||
|                     y = 3, | ||||
|                     color = colors.violet, | ||||
|                     fadeTime = 10.0, | ||||
|                 } | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "StatusTrigger", | ||||
| @@ -338,26 +407,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", | ||||
|                 spellId = 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", | ||||
|                 spellId = 25771, -- Forbearance | ||||
|                 indicator = { | ||||
|                     kind = "SquareIndicator", | ||||
|                     size = 17, | ||||
|                     point = "TOPLEFT", | ||||
|                     x = 22, | ||||
|                     y = -3, | ||||
|                     color = colors.red, | ||||
|                     fadeTime = 10.0, | ||||
|                     flashTime = 1.3, | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
|                 spellId = 53563, -- Beacon of Light | ||||
|                 own = true, | ||||
|                 indicator = { | ||||
|                     kind = "SquareIndicator", | ||||
|                     size = 17, | ||||
|                     point = "TOPLEFT", | ||||
|                     x = 41, | ||||
|                     y = -3, | ||||
|                     color = colors.white, | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
|                 spellId = 156910, -- Beacon of Faith | ||||
|                 own = true, | ||||
|                 indicator = { | ||||
|                     kind = "SquareIndicator", | ||||
|                     size = 17, | ||||
|                     point = "TOPLEFT", | ||||
|                     x = 41, | ||||
|                     y = -3, | ||||
|                     color = colors.light_blue, | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
|                 spellId = 200025, -- Beacon of Virtue | ||||
|                 own = true, | ||||
|                 indicator = { | ||||
|                     kind = "SquareIndicator", | ||||
|                     size = 17, | ||||
|                     point = "TOPLEFT", | ||||
|                     x = 41, | ||||
|                     y = -3, | ||||
|                     color = colors.white, | ||||
|                 }, | ||||
|             }, | ||||
|             { | ||||
|                 kind = "AuraTrigger", | ||||
|                 spellId = 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", | ||||
|                 spellId = 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", | ||||
|                 spellId = 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", | ||||
|                 spellId = 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 | ||||
|  | ||||
| @@ -377,45 +581,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", | ||||
|         spellId = 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 +681,7 @@ function HideBlizzardFrames() | ||||
|         TargetFrame, | ||||
|         FocusFrame, | ||||
|         PartyFrame, | ||||
|         CompactRaidFrameContainer | ||||
|         CompactRaidFrameContainer, | ||||
|     } | ||||
|  | ||||
|     for _, frame in ipairs(blizzardFrames) do | ||||
|   | ||||
| @@ -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, | ||||
| }) | ||||
|   | ||||
| @@ -24,10 +24,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 +41,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 +69,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 +107,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 +135,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 +145,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 +159,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,7 +175,6 @@ function AuraList:Init(unitframe) | ||||
|     self.statusCount = {} | ||||
|     self.auras = {} -- map AuraInstanceID to UnitAuraInfo table | ||||
|  | ||||
|  | ||||
|     self.triggers = {} | ||||
|     self.triggersBySpell = {} | ||||
|     self.triggersByStatus = {} | ||||
|   | ||||
							
								
								
									
										173
									
								
								src/types/indicators/iconindicator.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										173
									
								
								src/types/indicators/iconindicator.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,173 @@ | ||||
| -- 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 | ||||
| function IconIndicator:Init(unitframe, size, point, x, y, showStacks, fadeTime, flashTime) | ||||
|     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 | ||||
| end | ||||
|  | ||||
| --- Show the square indicator | ||||
| ---@param data table | ||||
| function IconIndicator:Show(data) | ||||
|     local frame, stacks = self:GetFrame() | ||||
|     local numStacks = data.stacks or 0 | ||||
|     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 data.icon then | ||||
|         self:SetIcon(data.icon) | ||||
|     else | ||||
|         self:SetIcon(self.icon) | ||||
|     end | ||||
|     frame:Show() | ||||
| 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.stacks or 0 | ||||
|     if numStacks > 0 then | ||||
|         self.stacks:SetText(numStacks) | ||||
|         self.stacks:Show() | ||||
|     end | ||||
|     self.expirationTime = data.expirationTime | ||||
|     self.frame:SetAlpha(1) | ||||
| end | ||||
|  | ||||
| function IconIndicator:OnUpdate(dt) | ||||
|     dt = self.updateThrottle + dt | ||||
|     if dt < 0.04 then | ||||
|         self.updateThrottle = dt | ||||
|         return | ||||
|     else | ||||
|         self.updateThrottle = 0 | ||||
|     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) | ||||
|     end | ||||
| end | ||||
|  | ||||
| --- Hide the square indicator. | ||||
| function IconIndicator:Hide() | ||||
|     local frame = self.frame | ||||
|     self.stacks:Hide() | ||||
|     self.frame = nil | ||||
|     self.stacks = nil | ||||
|     frame:SetScript("OnUpdate", 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 | ||||
|   | ||||
| @@ -20,8 +20,10 @@ local types = omi.GetModule("types") | ||||
| types.StatusBar = types.CreateClass("StatusBar") | ||||
| local StatusBar = types.StatusBar | ||||
|  | ||||
| function StatusBar:Init(parent, width, height, level, top) | ||||
|     if top == nil then top = true end | ||||
| function StatusBar:Init(parent, width, height, level, top, texture, bgtexture) | ||||
|     if top == nil then | ||||
|         top = true | ||||
|     end | ||||
|     level = level or 0 | ||||
|     -- parent: the parent frame | ||||
|     self.parent = parent | ||||
| @@ -38,15 +40,17 @@ function StatusBar:Init(parent, width, height, level, top) | ||||
|     end | ||||
|  | ||||
|     bar:SetSize(width, height) | ||||
|     bar:SetStatusBarTexture("Interface\\Addons\\OmicronFrames\\media\\textures\\bar_subtle_diagonal") | ||||
|     bar:SetStatusBarTexture(texture) | ||||
|     bar:GetStatusBarTexture():SetHorizTile(false) | ||||
|     bar:GetStatusBarTexture():SetVertTile(false) | ||||
|     self.bar = bar | ||||
|  | ||||
|     local bg = bar:CreateTexture(nil, "BACKGROUND") | ||||
|     bg:SetTexture("Interface\\Addons\\OmicronFrames\\media\\textures\\bar_subtle_diagonal") | ||||
|     bg:SetAllPoints(true) | ||||
|     self.bg = bg | ||||
|     if bgtexture ~= nil then | ||||
|         local bg = bar:CreateTexture(nil, "BACKGROUND") | ||||
|         bg:SetTexture(bgtexture) | ||||
|         bg:SetAllPoints(true) | ||||
|         self.bg = bg | ||||
|     end | ||||
|  | ||||
|     self:SetRange(0, 1) | ||||
|     self:SetValue(1) | ||||
| @@ -61,6 +65,10 @@ function StatusBar:SetValue(value) | ||||
|     self.bar:SetValue(value) | ||||
| end | ||||
|  | ||||
| function StatusBar:SetFillStyle(style) | ||||
|     self.bar:SetFillStyle(style) | ||||
| end | ||||
|  | ||||
| function StatusBar:Show() | ||||
|     self.bar:Show() | ||||
| end | ||||
| @@ -78,5 +86,7 @@ end | ||||
|  | ||||
| function StatusBar:SetColor(r, g, b) | ||||
|     self.bar:SetStatusBarColor(r, g, b) | ||||
|     self.bg:SetVertexColor(0.2 * r, 0.2 * g, 0.2 * b) | ||||
|     if self.bg ~= nil then | ||||
|         self.bg:SetVertexColor(0.2 * r, 0.2 * g, 0.2 * b) | ||||
|     end | ||||
| end | ||||
|   | ||||
| @@ -27,20 +27,13 @@ local Trigger = types.Trigger | ||||
| 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.spellId, config.own, config.requiredCount, config.invert, config.defaultData) | ||||
|     unit.auras:AddTrigger(trigger) | ||||
|     return trigger | ||||
| end | ||||
| @@ -92,7 +85,12 @@ function AuraTrigger:AddAura(aura) | ||||
|         return | ||||
|     end | ||||
|     self.count = self.count + 1 | ||||
|     self:SetData({ stacks = aura.applications, duration = aura.duration, expirationTime = aura.expirationTime }) | ||||
|     self:SetData({ | ||||
|         stacks = aura.applications, | ||||
|         duration = aura.duration, | ||||
|         expirationTime = aura.expirationTime, | ||||
|         icon = aura.icon, | ||||
|     }) | ||||
|     self:SetState(self.count >= self.requiredCount, false) | ||||
| end | ||||
|  | ||||
| @@ -100,7 +98,12 @@ end | ||||
| ---@param before UnitAuraInfo | ||||
| ---@param after UnitAuraInfo | ||||
| function AuraTrigger:UpdateAura(before, after) | ||||
|     self:SetData({ stacks = after.applications, duration = after.duration, expirationTime = after.expirationTime }) | ||||
|     self:SetData({ | ||||
|         stacks = after.applications, | ||||
|         duration = after.duration, | ||||
|         expirationTime = after.expirationTime, | ||||
|         icon = after.icon, | ||||
|     }) | ||||
|     if self.active then | ||||
|         self.indicator:Update(self.data) | ||||
|     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 | ||||
|  | ||||
| @@ -141,4 +141,3 @@ end | ||||
| function MultiTrigger:Reset() | ||||
|     self:SetState(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) | ||||
|   | ||||
| @@ -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 | ||||
| @@ -91,4 +90,3 @@ end | ||||
| function Trigger:Reset() | ||||
|     self:SetState(false, false) | ||||
| end | ||||
|  | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
| @@ -26,6 +26,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 +36,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 }, | ||||
| @@ -50,7 +52,9 @@ local colors = { | ||||
|     immune = { 0.0, 0.2, 0.4 }, | ||||
|     bomb = { 1.0, 0.7, 0.7 }, | ||||
|     cyan = { 0.0, 0.8, 0.8 }, | ||||
|     white = { 1.0, 1.0, 1.0 } | ||||
|     white = { 1.0, 1.0, 1.0 }, | ||||
|     shield = { 0.85, 0.95, 1.0 }, | ||||
|     absorb = { 0.5, 0.4, 0.75 }, | ||||
| } | ||||
|  | ||||
| -- This trucates _codepoints_ not graphemes. If combination codepoints are | ||||
| @@ -86,9 +90,25 @@ function UnitFrame:Init(unit, config) | ||||
|  | ||||
|     self:SetMouseBinds(config.mouse) | ||||
|  | ||||
|     self.hp = StatusBar:new(self, width, height, 0, true) | ||||
|     self.power = StatusBar:new(self, width, 6, 2, false) | ||||
|     local texture = "Interface\\Addons\\OmicronFrames\\media\\textures\\bar_subtle_diagonal" | ||||
|     local texture_top = "Interface\\Addons\\OmicronFrames\\media\\textures\\bar_subtle_diagonal_top" | ||||
|     local texture_bot = "Interface\\Addons\\OmicronFrames\\media\\textures\\bar_subtle_diagonal_bottom" | ||||
|  | ||||
|     self.hp = StatusBar:new(self, width, height, 0, true, texture, texture) | ||||
|  | ||||
|     self.power = StatusBar:new(self, width, 6, 2, false, texture, texture) | ||||
|     self.power:Hide() | ||||
|  | ||||
|     self.absorb = StatusBar:new(self, width, height, 1, true, texture_top) | ||||
|     self.absorb:SetColor(unpack(colors.absorb)) | ||||
|     self.absorb:SetFillStyle("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.auras = AuraList:new(self) | ||||
|  | ||||
|     local overlays = CreateFrame("Frame", nil, secure) | ||||
| @@ -129,12 +149,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 | ||||
| @@ -182,9 +209,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 | ||||
| @@ -263,9 +290,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 | ||||
| @@ -406,10 +439,13 @@ 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) | ||||
|     secure:RegisterUnitEvent("UNIT_NAME_UPDATE", unit) | ||||
|     secure:RegisterUnitEvent("UNIT_ABSORB_AMOUNT_CHANGED", unit) | ||||
|     secure:RegisterUnitEvent("UNIT_HEAL_ABSORB_AMOUNT_CHANGED", unit) | ||||
| end | ||||
|  | ||||
| -- returns whether or not the unit guid has changed since the last call to this | ||||
| @@ -430,6 +466,29 @@ function UnitFrame:HasUnitChanged() | ||||
|     end | ||||
| end | ||||
|  | ||||
| function UnitFrame:UNIT_HEAL_ABSORB_AMOUNT_CHANGED() | ||||
|     if self:HasUnitChanged() then | ||||
|         self:UpdateAll(true) | ||||
|         return | ||||
|     end | ||||
|     self:UpdateAbsorb() | ||||
| end | ||||
|  | ||||
| function UnitFrame:UNIT_ABSORB_AMOUNT_CHANGED() | ||||
|     if self:HasUnitChanged() then | ||||
|         self:UpdateAll(true) | ||||
|         return | ||||
|     end | ||||
|     self:UpdateShield() | ||||
| end | ||||
|  | ||||
| function UnitFrame:GROUP_ROSTER_UPDATE() | ||||
|     if self:HasUnitChanged() then | ||||
|         self:UpdateAll(true) | ||||
|         return | ||||
|     end | ||||
| end | ||||
|  | ||||
| function UnitFrame:UNIT_AURA(unit, info) | ||||
|     if self:HasUnitChanged() then | ||||
|         self:UpdateAll(true) | ||||
| @@ -536,6 +595,8 @@ function UnitFrame:UpdateAll(unitChanged) | ||||
|     end | ||||
|     self:UpdateHealth() | ||||
|     self:UpdateHealthColor() | ||||
|     self:UpdateAbsorb() | ||||
|     self:UpdateShield() | ||||
|     self:UpdateRange() | ||||
|     self:UpdateName() | ||||
|     self:UpdateRole() -- Also calls UpdatePower if power is visible | ||||
| @@ -550,6 +611,32 @@ function UnitFrame:UpdateHealth() | ||||
|     self.hp:SetValue(val) | ||||
| end | ||||
|  | ||||
| function UnitFrame:UpdateShield() | ||||
|     local unit = self.unit | ||||
|     local val = UnitGetTotalAbsorbs(unit) | ||||
|     local max = UnitHealthMax(unit) | ||||
|     if val <= 0 then | ||||
|         self.shield:Hide() | ||||
|     else | ||||
|         self.shield:SetRange(0, max) | ||||
|         self.shield:SetValue(val) | ||||
|         self.shield:Show() | ||||
|     end | ||||
| end | ||||
|  | ||||
| function UnitFrame:UpdateAbsorb() | ||||
|     local unit = self.unit | ||||
|     local val = UnitGetTotalHealAbsorbs(unit) | ||||
|     local max = UnitHealthMax(unit) | ||||
|     if val <= 0 then | ||||
|         self.absorb:Hide() | ||||
|     else | ||||
|         self.absorb:SetRange(0, max) | ||||
|         self.absorb:SetValue(val) | ||||
|         self.absorb:Show() | ||||
|     end | ||||
| end | ||||
|  | ||||
| function UnitFrame:UpdateHealthColor() | ||||
|     local unit = self.unit | ||||
|     local val = UnitHealth(unit) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user