From 150ddea6e7642ff73fbe3aaecaf440bee399d4a8 Mon Sep 17 00:00:00 2001 From: wutname1 Date: Wed, 1 May 2024 00:53:01 -0500 Subject: [PATCH] oUF Updates --- .vscode/settings.json | 15 +- SpartanUI.toc | 1 + libs/LibDispel/LibDispel.lua | 1084 ++++++++++++++++++++- libs/oUF/LICENSE.txt | 8 +- libs/oUF/colors.lua | 33 +- libs/oUF/elements/additionalpower.lua | 5 +- libs/oUF/elements/auras.lua | 19 +- libs/oUF/elements/castbar.lua | 188 ++-- libs/oUF/elements/classpower.lua | 14 +- libs/oUF/elements/eclipsebar.lua | 147 +++ libs/oUF/elements/healthprediction.lua | 33 +- libs/oUF/elements/portrait.lua | 36 +- libs/oUF/elements/power.lua | 2 +- libs/oUF/elements/powerprediction.lua | 23 +- libs/oUF/elements/raidroleindicator.lua | 2 +- libs/oUF/elements/readycheckindicator.lua | 56 +- libs/oUF/elements/runes.lua | 16 +- libs/oUF/elements/stagger.lua | 13 - libs/oUF/events.lua | 5 +- libs/oUF/init.lua | 7 +- libs/oUF/oUF.lua | 87 +- libs/oUF/oUF_Wrath.xml | 3 +- libs/oUF/units.lua | 1 + 23 files changed, 1540 insertions(+), 258 deletions(-) create mode 100644 libs/oUF/elements/eclipsebar.lua diff --git a/.vscode/settings.json b/.vscode/settings.json index b9eb02fb..9abd1982 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -307,7 +307,6 @@ "UIParent", "QuestFrame", "GossipFrame", - "GetAddOnMetadata", "WOW_PROJECT_ID", "WOW_PROJECT_MAINLINE", "WOW_PROJECT_BURNING_CRUSADE_CLASSIC", @@ -532,7 +531,19 @@ "SecureHandlerSetFrameRef", "IsLoggedIn", "FramerateFrame", - "GossipFrameMaterialBotLeft" + "AchievementMicroButton", + "SplashFrameMixin", + "ObjectiveTracker_Update", + "TextureKitConstants", + "AlertFrame", + "SPLASH_BASE_HEADER", + "SPLASH_NEW_HEADER_SEASON", + "PlayerFrame", + "PetFrame", + "TargetFrame", + "FocusFrame", + "BossTargetFrameContainer", + "CompactArenaFrame" ], "Lua.workspace.ignoreDir": [".vscode", "libs/*"], "Lua.diagnostics.enable": true, diff --git a/SpartanUI.toc b/SpartanUI.toc index a8208241..761c4356 100644 --- a/SpartanUI.toc +++ b/SpartanUI.toc @@ -31,6 +31,7 @@ libs\AceGUI-3.0-SharedMediaWidgets\widget.xml # Unit Frame libraries libs\LibHealComm-4.0\LibHealComm-4.0.lua +libs\LibDispel\LibDispel.lua libs\oUF\oUF_Wrath.xml libs\oUF_Plugins\Loader.xml diff --git a/libs/LibDispel/LibDispel.lua b/libs/LibDispel/LibDispel.lua index f460001c..c40c7ab3 100644 --- a/libs/LibDispel/LibDispel.lua +++ b/libs/LibDispel/LibDispel.lua @@ -1,5 +1,5 @@ -local MAJOR, MINOR = "LibDispel-1.0", 1 -assert(LibStub, MAJOR.." requires LibStub") +local MAJOR, MINOR = 'LibDispel-1.0', 6 +assert(LibStub, MAJOR .. ' requires LibStub') local lib = LibStub:NewLibrary(MAJOR, MINOR) if not lib then return end @@ -7,12 +7,1017 @@ local Retail = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE local Wrath = WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC local next = next -local GetCVar, SetCVar = GetCVar, SetCVar +local CreateFrame = CreateFrame +local IsPlayerSpell = IsPlayerSpell local IsSpellKnownOrOverridesKnown = IsSpellKnownOrOverridesKnown -local DispelList = {} +local GetCVar = C_CVar.GetCVar +local SetCVar = C_CVar.SetCVar + +local DebuffColors = CopyTable(DebuffTypeColor) +lib.DebuffTypeColor = DebuffColors + +-- These dont exist in Blizzards color table +DebuffColors.Bleed = { r = 1, g = 0.2, b = 0.6 } +DebuffColors.EnemyNPC = { r = 0.9, g = 0.1, b = 0.1 } +DebuffColors.BadDispel = { r = 0.05, g = 0.85, b = 0.94 } +DebuffColors.Stealable = { r = 0.93, g = 0.91, b = 0.55 } + +local DispelList = {} -- List of types the player can dispel lib.DispelList = DispelList +local BleedList = {} -- Contains spells classified as Bleeds +lib.BleedList = BleedList + +local BlockList = {} -- Spells blocked from AuraHighlight +lib.BlockList = BlockList + +local BadList = {} -- Spells that backfire when dispelled +lib.BadList = BadList + +if Retail then + -- Bad to dispel spells + BadList[34914] = 'Vampiric Touch' -- horrifies + BadList[233490] = 'Unstable Affliction' -- silences + + -- Block spells from AuraHighlight + BlockList[140546] = 'Fully Mutated' + BlockList[136184] = 'Thick Bones' + BlockList[136186] = 'Clear Mind' + BlockList[136182] = 'Improved Synapses' + BlockList[136180] = 'Keen Eyesight' + BlockList[105171] = 'Deep Corruption' + BlockList[108220] = 'Deep Corruption' + BlockList[116095] = 'Disable' -- slow + + -- Bleed spells updated March 30th 2024 by Simpy for Patch 10.2.6 + --- Combined lists (without duplicates, filter requiring either main or effect bleed): + ----> Apply Aura + -----> Mechanic Bleeding: https://www.wowhead.com/spells/mechanic:15?filter=109;6;0 + -----> Physical DoT > Damage Type + ------> None: https://www.wowhead.com/spells/school:0?filter=29:40;3:1;0:0 + ------> Magic: https://www.wowhead.com/spells/school:0?filter=29:40;3:2;0:0 + ------> Melee: https://www.wowhead.com/spells/school:0?filter=29:40;3:3;0:0 + ------> Ranged: https://www.wowhead.com/spells/school:0?filter=29:40;3:4;0:0 + + BleedList[703] = 'Garrote' + BleedList[1079] = 'Rip' + BleedList[1943] = 'Rupture' + BleedList[3147] = 'Rend Flesh' + BleedList[5597] = 'Serious Wound' + BleedList[5598] = 'Serious Wound' + BleedList[8818] = 'Garrote' + BleedList[10266] = 'Lung Puncture' + BleedList[11977] = 'Rend' + BleedList[12054] = 'Rend' + BleedList[13318] = 'Rend' + BleedList[13443] = 'Rend' + BleedList[13445] = 'Rend' + BleedList[13738] = 'Rend' + BleedList[14087] = 'Rend' + BleedList[14118] = 'Rend' + BleedList[14331] = 'Vicious Rend' + BleedList[14874] = 'Rupture' + BleedList[14903] = 'Rupture' + BleedList[15583] = 'Rupture' + BleedList[15976] = 'Puncture' + BleedList[16095] = 'Vicious Rend' + BleedList[16393] = 'Rend' + BleedList[16403] = 'Rend' + BleedList[16406] = 'Rend' + BleedList[16509] = 'Rend' + BleedList[17153] = 'Rend' + BleedList[17504] = 'Rend' + BleedList[18075] = 'Rend' + BleedList[18078] = 'Rend' + BleedList[18106] = 'Rend' + BleedList[18200] = 'Rend' + BleedList[18202] = 'Rend' + BleedList[19771] = 'Serrated Bite' + BleedList[21949] = 'Rend' + BleedList[24192] = 'Speed Slash' + BleedList[24331] = 'Rake' + BleedList[24332] = 'Rake' + BleedList[27555] = 'Shred' + BleedList[27556] = 'Rake' + BleedList[27638] = 'Rake' + BleedList[28913] = 'Flesh Rot' + BleedList[29574] = 'Rend' + BleedList[29578] = 'Rend' + BleedList[29583] = 'Impale' + BleedList[29906] = 'Ravage' + BleedList[29935] = 'Gaping Maw' + BleedList[30285] = 'Eagle Claw' + BleedList[30639] = 'Carnivorous Bite' + BleedList[31041] = 'Mangle' + BleedList[31410] = 'Coral Cut' + BleedList[31956] = 'Grievous Wound' + BleedList[32019] = 'Gore' + BleedList[32901] = 'Carnivorous Bite' + BleedList[33865] = 'Singe' + BleedList[33912] = 'Rip' + BleedList[35144] = 'Vicious Rend' + BleedList[35318] = 'Saw Blade' + BleedList[35321] = 'Gushing Wound' + BleedList[36023] = 'Deathblow' + BleedList[36054] = 'Deathblow' + BleedList[36332] = 'Rake' + BleedList[36383] = 'Carnivorous Bite' + BleedList[36590] = 'Rip' + BleedList[36617] = 'Gaping Maw' + BleedList[36789] = 'Diminish Soul' + BleedList[36965] = 'Rend' + BleedList[36991] = 'Rend' + BleedList[37066] = 'Garrote' + BleedList[37123] = 'Saw Blade' + BleedList[37487] = 'Blood Heal' + BleedList[37641] = 'Whirlwind' + BleedList[37662] = 'Rend' + BleedList[37937] = 'Flayed Flesh' + BleedList[37973] = 'Coral Cut' + BleedList[38056] = 'Flesh Rip' + BleedList[38363] = 'Gushing Wound' + BleedList[38772] = 'Grievous Wound' + BleedList[38801] = 'Grievous Wound' + BleedList[38810] = 'Gaping Maw' + BleedList[38848] = 'Diminish Soul' + BleedList[39198] = 'Carnivorous Bite' + BleedList[39215] = 'Gushing Wound' + BleedList[39382] = 'Carnivorous Bite' + BleedList[40199] = 'Flesh Rip' + BleedList[41092] = 'Carnivorous Bite' + BleedList[41932] = 'Carnivorous Bite' + BleedList[42395] = 'Lacerating Slash' + BleedList[42397] = 'Rend Flesh' + BleedList[42658] = "Sic'em!" + BleedList[43093] = 'Grievous Throw' + BleedList[43104] = 'Deep Wound' + BleedList[43153] = 'Lynx Rush' + BleedList[43246] = 'Rend' + BleedList[43931] = 'Rend' + BleedList[43937] = 'Grievous Wound' + BleedList[48130] = 'Gore' + BleedList[48261] = 'Impale' + BleedList[48286] = 'Grievous Slash' + BleedList[48374] = 'Puncture Wound' + BleedList[48880] = 'Rend' + BleedList[48920] = 'Grievous Bite' + BleedList[49678] = 'Flesh Rot' + BleedList[50729] = 'Carnivorous Bite' + BleedList[50871] = 'Savage Rend' + BleedList[51275] = 'Gut Rip' + BleedList[52401] = 'Gut Rip' + BleedList[52504] = 'Lacerate' + BleedList[52771] = 'Wounding Strike' + BleedList[52873] = 'Open Wound' + BleedList[53317] = 'Rend' + BleedList[53499] = 'Rake' + BleedList[53602] = 'Dart' + BleedList[54668] = 'Rake' + BleedList[54703] = 'Rend' + BleedList[54708] = 'Rend' + BleedList[55102] = 'Determined Gore' + BleedList[55249] = 'Whirling Slash' + BleedList[55250] = 'Whirling Slash' + BleedList[55276] = 'Puncture' + BleedList[55550] = 'Jagged Knife' + BleedList[55604] = 'Death Plague' + BleedList[55622] = 'Impale' + BleedList[55645] = 'Death Plague' + BleedList[57661] = 'Rip' + BleedList[58459] = 'Impale' + BleedList[58517] = 'Grievous Wound' + BleedList[58830] = 'Wounding Strike' + BleedList[58978] = 'Impale' + BleedList[59007] = 'Flesh Rot' + BleedList[59239] = 'Rend' + BleedList[59256] = 'Impale' + BleedList[59262] = 'Grievous Wound' + BleedList[59264] = 'Gore' + BleedList[59268] = 'Impale' + BleedList[59269] = 'Carnivorous Bite' + BleedList[59343] = 'Rend' + BleedList[59349] = 'Dart' + BleedList[59444] = 'Determined Gore' + BleedList[59682] = 'Grievous Wound' + BleedList[59691] = 'Rend' + BleedList[59824] = 'Whirling Slash' + BleedList[59825] = 'Whirling Slash' + BleedList[59826] = 'Puncture' + BleedList[59881] = 'Rake' + BleedList[59989] = 'Rip' + BleedList[61164] = 'Impale' + BleedList[61896] = 'Lacerate' + BleedList[62318] = 'Barbed Shot' + BleedList[62331] = 'Impale' + BleedList[62418] = 'Impale' + BleedList[63468] = 'Careful Aim' + BleedList[64374] = 'Savage Pounce' + BleedList[64666] = 'Savage Pounce' + BleedList[65033] = 'Constricting Rend' + BleedList[65406] = 'Rake' + BleedList[66620] = 'Old Wounds' + BleedList[67280] = 'Dagger Throw' + BleedList[69203] = 'Vicious Bite' + BleedList[70278] = 'Puncture Wound' + BleedList[71926] = 'Rip' + BleedList[74846] = 'Bleeding Wound' + BleedList[75160] = 'Bloody Rip' + BleedList[75161] = 'Spinning Rake' + BleedList[75388] = 'Rusty Cut' + BleedList[75930] = 'Mangle' + BleedList[76507] = 'Claw Puncture' + BleedList[76524] = 'Grievous Whirl' + BleedList[76594] = 'Rend' + BleedList[78842] = 'Carnivorous Bite' + BleedList[78859] = 'Elementium Spike Shield' + BleedList[79444] = 'Impale' + BleedList[79828] = 'Mangle' + BleedList[79829] = 'Rip' + BleedList[80028] = 'Rock Bore' + BleedList[80051] = 'Grievous Wound' + BleedList[81043] = 'Razor Slice' + BleedList[81087] = 'Puncture Wound' + BleedList[81568] = 'Spinning Slash' + BleedList[81569] = 'Spinning Slash' + BleedList[81690] = 'Scent of Blood' + BleedList[82753] = 'Ritual of Bloodletting' + BleedList[82766] = 'Eye Gouge' + BleedList[83783] = 'Impale' + BleedList[84642] = 'Puncture' + BleedList[85415] = 'Mangle' + BleedList[87395] = 'Serrated Slash' + BleedList[89212] = 'Eagle Claw' + BleedList[90098] = 'Axe to the Head' + BleedList[91348] = 'Tenderize' + BleedList[93587] = 'Ritual of Bloodletting' + BleedList[93675] = 'Mortal Wound' + BleedList[95334] = 'Elementium Spike Shield' + BleedList[96570] = 'Gaping Wound' + BleedList[96592] = 'Ravage' + BleedList[96700] = 'Ravage' + BleedList[97357] = 'Gaping Wound' + BleedList[98282] = 'Tiny Rend' + BleedList[99100] = 'Mangle' + BleedList[102066] = 'Flesh Rip' + BleedList[102925] = 'Garrote' + BleedList[112896] = 'Drain Blood' + BleedList[113344] = 'Bloodbath' + BleedList[113855] = 'Bleeding Wound' + BleedList[114056] = 'Bloody Mess' + BleedList[114860] = 'Rend' + BleedList[114881] = 'Hawk Rend' + BleedList[115767] = 'Deep Wounds' + BleedList[115774] = 'Vicious Wound' + BleedList[115871] = 'Rake' + BleedList[118146] = 'Lacerate' + BleedList[119840] = 'Serrated Blade' + BleedList[120166] = 'Serrated Blade' + BleedList[120560] = 'Rake' + BleedList[120699] = 'Lynx Rush' + BleedList[121247] = 'Impale' + BleedList[121411] = 'Crimson Tempest' + BleedList[122962] = 'Carnivorous Bite' + BleedList[123422] = 'Arterial Bleeding' + BleedList[123852] = 'Gored' + BleedList[124015] = 'Gored' + BleedList[124296] = 'Vicious Strikes' + BleedList[124341] = 'Bloodletting' + BleedList[124678] = 'Hacking Slash' + BleedList[124800] = 'Pinch Limb' + BleedList[125099] = 'Rake' + BleedList[125206] = 'Rend Flesh' + BleedList[125431] = 'Slice Bone' + BleedList[125624] = 'Vicious Rend' + BleedList[126901] = 'Mortal Rend' + BleedList[126912] = 'Grievous Whirl' + BleedList[127872] = 'Consume Flesh' + BleedList[127987] = 'Bleeding Bite' + BleedList[128051] = 'Serrated Slash' + BleedList[128903] = 'Garrote' + BleedList[129463] = 'Crane Kick' + BleedList[129497] = 'Pounced' + BleedList[129537] = 'Snap!' + BleedList[130191] = 'Rake' + BleedList[130306] = 'Ankle Bite' + BleedList[130785] = 'My Eye!' + BleedList[130897] = 'Vicious Bite' + BleedList[131662] = 'Vicious Stabbing' + BleedList[133074] = 'Puncture' + BleedList[133081] = 'Rip' + BleedList[134691] = 'Impale' + BleedList[135528] = 'Bleeding Wound' + BleedList[135892] = 'Razor Slice' + BleedList[136654] = 'Rending Charge' + BleedList[136753] = 'Slashing Talons' + BleedList[137497] = 'Garrote' + BleedList[138956] = 'Dark Bite' + BleedList[139514] = 'Bloodstorm' + BleedList[140274] = 'Vicious Wound' + BleedList[140275] = 'Rend' + BleedList[140276] = 'Rend' + BleedList[140396] = 'Rend' + BleedList[143198] = 'Garrote' + BleedList[144113] = 'Chomp' + BleedList[144263] = 'Rend' + BleedList[144264] = 'Rend' + BleedList[144304] = 'Rend' + BleedList[144853] = 'Carnivorous Bite' + BleedList[145263] = 'Chomp' + BleedList[145417] = 'Rupture' + BleedList[146556] = 'Pierce' + BleedList[146927] = 'Rend' + BleedList[147396] = 'Rake' + BleedList[148033] = 'Grapple' + BleedList[148375] = 'Brutal Hemorrhage' + BleedList[150807] = 'Traumatic Strike' + BleedList[151092] = 'Traumatic Strike' + BleedList[151475] = 'Drain Life' + BleedList[152357] = 'Rend' + BleedList[152623] = 'Rend' + BleedList[152724] = 'Lacerating Strike' + BleedList[153897] = 'Rending Cleave' + BleedList[154489] = 'Puncturing Horns' + BleedList[154953] = 'Internal Bleeding' + BleedList[154960] = 'Pinned Down' + BleedList[155065] = 'Ripping Claw' + BleedList[155701] = 'Serrated Slash' + BleedList[155722] = 'Rake' + BleedList[157344] = 'Vital Strike' + BleedList[158150] = 'Goring Swipe' + BleedList[158341] = 'Gushing Wounds' + BleedList[158453] = 'Rending Swipe' + BleedList[158667] = "Warleader's Spear" + BleedList[159238] = 'Shattered Bleed' + BleedList[161117] = 'Puncturing Tusk' + BleedList[161229] = 'Pounce' + BleedList[161765] = 'Iron Axe' + BleedList[162487] = 'Steel Trap' + BleedList[162516] = 'Whirling Steel' + BleedList[162921] = 'Peck' + BleedList[162951] = 'Lacerating Spines' + BleedList[163276] = 'Shredded Tendons' + BleedList[164218] = 'Double Slash' + BleedList[164323] = 'Precise Strike' + BleedList[164427] = 'Ravage' + BleedList[165308] = 'Gushing Wound' + BleedList[166185] = 'Rending Slash' + BleedList[166638] = 'Gushing Wound' + BleedList[166639] = 'Item - Druid T17 Feral 4P Bonus Proc Driver' + BleedList[166917] = 'Savage' + BleedList[167334] = 'Windfang Bite' + BleedList[167597] = 'Rending Nails' + BleedList[167978] = 'Jagged Edge' + BleedList[168097] = 'Shredder Bomb' + BleedList[168392] = 'Fangs of the Predator' + BleedList[169584] = 'Serrated Spines' + BleedList[170367] = 'Vicious Throw' + BleedList[170373] = 'Razor Teeth' + BleedList[170936] = 'Talador Venom' + BleedList[172019] = 'Stingtail Venom' + BleedList[172035] = 'Thrash' + BleedList[172139] = 'Lacerating Bite' + BleedList[172361] = 'Puncturing Strike' + BleedList[172366] = 'Jagged Slash' + BleedList[172657] = 'Serrated Edge' + BleedList[172889] = 'Charging Slash' + BleedList[173113] = 'Hatchet Toss' + BleedList[173278] = 'Spinal Shards' + BleedList[173299] = 'Rip' + BleedList[173307] = 'Serrated Spear' + BleedList[173378] = 'Rending Bite' + BleedList[173643] = 'Drill Fist' + BleedList[173876] = 'Rending Claws' + BleedList[174423] = 'Pinning Spines' + BleedList[174734] = 'Axe to the Face!' + BleedList[174820] = 'Rending Claws' + BleedList[175014] = 'Rupture' + BleedList[175151] = 'Thousand Fangs' + BleedList[175156] = 'Painful Pinch' + BleedList[175372] = 'Sharp Teeth' + BleedList[175461] = 'Sadistic Slice' + BleedList[175747] = 'Big Sharp Nasty Claws' + BleedList[176147] = 'Ignite' + BleedList[176256] = 'Talon Sweep' + BleedList[176575] = 'Consume Flesh' + BleedList[176695] = 'Bone Fragments' + BleedList[177337] = 'Carnivorous Bite' + BleedList[177422] = 'Thrash' + BleedList[181346] = 'Lacerating Swipe' + BleedList[181533] = 'Jagged Blade' + BleedList[182325] = 'Phantasmal Wounds' + BleedList[182330] = 'Coral Cut' + BleedList[182347] = 'Impaling Coral' + BleedList[182795] = 'Primal Mangle' + BleedList[182846] = 'Thrash' + BleedList[183025] = 'Rending Lash' + BleedList[183952] = 'Shadow Claws' + BleedList[184025] = 'Rending Claws' + BleedList[184090] = 'Bloody Arc' + BleedList[184175] = 'Primal Rake' + BleedList[185539] = 'Rapid Rupture' + BleedList[185698] = 'Bloody Hack' + BleedList[185855] = 'Lacerate' + BleedList[186191] = 'Bloodletting Slash' + BleedList[186365] = 'Sweeping Blade' + BleedList[186594] = 'Laceration' + BleedList[186639] = 'Big Sharp Nasty Teeth' + BleedList[186730] = 'Exposed Wounds' + BleedList[187647] = 'Bloodletting Pounce' + BleedList[188353] = 'Rip' + BleedList[189035] = 'Barbed Cutlass' + BleedList[191977] = 'Impaling Spear' + BleedList[192090] = 'Thrash' + BleedList[192131] = 'Throw Spear' + BleedList[192925] = 'Blood of the Assassinated' + BleedList[193092] = 'Bloodletting Sweep' + BleedList[193340] = "Fenri's Bite" + BleedList[193585] = 'Bound' + BleedList[193639] = 'Bone Chomp' + BleedList[194279] = 'Caltrops' + BleedList[194636] = 'Cursed Rend' + BleedList[194639] = 'Rending Claws' + BleedList[194674] = 'Barbed Spear' + BleedList[195094] = 'Coral Slash' + BleedList[195279] = 'Bind' + BleedList[195506] = 'Razorsharp Axe' + BleedList[196111] = 'Jagged Claws' + BleedList[196189] = 'Bloody Talons' + BleedList[196313] = 'Lacerating Talons' + BleedList[196376] = 'Grievous Tear' + BleedList[196497] = 'Ravenous Leap' + BleedList[197359] = 'Shred' + BleedList[197381] = 'Exposed Wounds' + BleedList[197546] = 'Brutal Glaive' + BleedList[199108] = 'Frantic Gore' + BleedList[199146] = 'Bucking Charge' + BleedList[199337] = 'Bear Trap' + BleedList[199847] = 'Grievous Wound' + BleedList[200182] = 'Festering Rip' + BleedList[200620] = 'Frantic Rip' + BleedList[204175] = 'Rend' + BleedList[204179] = 'Rend Flesh' + BleedList[204968] = 'Hemoraging Barbs' + BleedList[205437] = 'Laceration' + BleedList[207662] = 'Nightmare Wounds' + BleedList[207690] = 'Bloodlet' + BleedList[208470] = 'Necrotic Thrash' + BleedList[208945] = 'Mangle' + BleedList[208946] = 'Rip' + BleedList[209336] = 'Mangle' + BleedList[209378] = 'Whirling Blades' + BleedList[209667] = 'Blade Surge' + BleedList[209858] = 'Necrotic Wound' + BleedList[210013] = 'Bloodletting Slash' + BleedList[210177] = 'Spiked Shield' + BleedList[210723] = "Ashamane's Frenzy" + BleedList[211672] = 'Mutilated Flesh' + BleedList[211846] = 'Bloodletting Lunge' + BleedList[213431] = 'Gnawing Eagle' + BleedList[213537] = 'Bloody Pin' + BleedList[213824] = 'Rending Pounce' + BleedList[213933] = 'Harpoon Swipe' + BleedList[213990] = 'Shard Bore' + BleedList[214676] = 'Razorsharp Teeth' + BleedList[215442] = 'Shred' + BleedList[215506] = 'Jagged Quills' + BleedList[215537] = 'Trauma' + BleedList[215721] = 'Gut Slash' + BleedList[217023] = 'Antler Gore' + BleedList[217041] = 'Shred' + BleedList[217091] = 'Puncturing Stab' + BleedList[217142] = 'Mangle' + BleedList[217163] = 'Rend' + BleedList[217200] = 'Barbed Shot' + BleedList[217235] = 'Rending Whirl' + BleedList[217363] = "Ashamane's Frenzy" + BleedList[217369] = 'Rake' + BleedList[217868] = 'Impale' + BleedList[218506] = 'Jagged Slash' + BleedList[219167] = 'Chomp' + BleedList[219240] = 'Bloody Ricochet' + BleedList[219339] = 'Thrash' + BleedList[219680] = 'Impale' + BleedList[220222] = 'Rending Snap' + BleedList[220874] = 'Lacerate' + BleedList[221352] = 'Cut the Flank' + BleedList[221422] = 'Vicious Bite' + BleedList[221759] = 'Feathery Stab' + BleedList[221770] = 'Rend Flesh' + BleedList[222491] = 'Gutripper' + BleedList[223111] = 'Rake' + BleedList[223572] = 'Rend' + BleedList[223954] = 'Rake' + BleedList[223967] = 'Tear Flesh' + BleedList[224435] = "Ashamane's Rip" + BleedList[225484] = 'Grievous Rip' + BleedList[225963] = 'Bloodthirsty Leap' + BleedList[227742] = 'Garrote' + BleedList[228275] = 'Rend' + BleedList[228281] = 'Rend' + BleedList[228305] = 'Unyielding Rend' + BleedList[229127] = 'Powershot' + BleedList[229265] = 'Garrote' + BleedList[229923] = 'Talon Rend' + BleedList[230011] = 'Cruel Garrote' + BleedList[231003] = 'Barbed Talons' + BleedList[231998] = 'Jagged Abrasion' + BleedList[232135] = 'Bloody Jab' + BleedList[235832] = 'Bloodletting Strike' + BleedList[237346] = 'Rend' + BleedList[238594] = 'Ripper Blade' + BleedList[238618] = 'Fel Swipe' + BleedList[240449] = 'Grievous Wound' + BleedList[240539] = 'Wild Bite' + BleedList[240559] = 'Grievous Wound' + BleedList[241070] = 'Bloodletting Strike' + BleedList[241092] = 'Rend' + BleedList[241212] = 'Fel Slash' + BleedList[241465] = 'Coral Cut' + BleedList[241644] = 'Mangle' + BleedList[242376] = 'Puncturing Strike' + BleedList[242828] = 'Dire Thrash' + BleedList[242931] = 'Rake' + BleedList[244040] = "Eskhandar's Rake" + BleedList[246904] = 'Smoldering Rend' + BleedList[247932] = 'Shrapnel Blast' + BleedList[247949] = 'Shrapnel Blast' + BleedList[250393] = 'Rake' + BleedList[251332] = 'Rip' + BleedList[253384] = 'Slaughter' + BleedList[253516] = 'Hexabite' + BleedList[253610] = 'Ripper Blade' + BleedList[254280] = 'Jagged Maw' + BleedList[254575] = 'Rend' + BleedList[254901] = 'Blood Frenzy' + BleedList[255299] = 'Bloodletting' + BleedList[255434] = 'Serrated Teeth' + BleedList[255595] = 'Chomp' + BleedList[255814] = 'Rending Maul' + BleedList[256077] = 'Gore' + BleedList[256314] = 'Barbed Strike' + BleedList[256363] = 'Ripper Punch' + BleedList[256476] = 'Rending Whirl' + BleedList[256715] = 'Jagged Maw' + BleedList[256880] = 'Bone Splinter' + BleedList[256914] = 'Barbed Blade' + BleedList[256965] = 'Thorned Barrage' + BleedList[257036] = 'Feral Charge' + BleedList[257170] = 'Savage Tempest' + BleedList[257250] = 'Bramblepelt' + BleedList[257544] = 'Jagged Cut' + BleedList[257790] = 'Gutripper' + BleedList[257971] = 'Leaping Thrash' + BleedList[258058] = 'Squeeze' + BleedList[258075] = 'Itchy Bite' + BleedList[258143] = 'Rending Claws' + BleedList[258718] = 'Scratched!' + BleedList[258798] = 'Razorsharp Teeth' + BleedList[258825] = 'Vampiric Bite' + BleedList[259220] = 'Barbed Net' + BleedList[259277] = 'Kill Command' + BleedList[259328] = 'Gory Whirl' + BleedList[259382] = 'Shell Slash' + BleedList[259739] = 'Stone Claws' + BleedList[259873] = 'Rip' + BleedList[259983] = 'Pierce' + BleedList[260016] = 'Itchy Bite' + BleedList[260025] = 'Rending Whirl' + BleedList[260400] = 'Rend' + BleedList[260455] = 'Serrated Fangs' + BleedList[260563] = 'Gnaw' + BleedList[260582] = 'Gushing Wound' + BleedList[260741] = 'Jagged Nettles' + BleedList[261882] = 'Steel Jaw Trap' + BleedList[262115] = 'Deep Wounds' + BleedList[262143] = 'Ravenous Claws' + BleedList[262557] = 'Rake' + BleedList[262677] = 'Keelhaul' + BleedList[262875] = 'Papercut' + BleedList[263144] = 'Talon Slash' + BleedList[264145] = 'Shatter' + BleedList[264150] = 'Shatter' + BleedList[264210] = 'Jagged Mandible' + BleedList[264556] = 'Tearing Strike' + BleedList[265019] = 'Savage Cleave' + BleedList[265074] = 'Rend' + BleedList[265165] = 'Charging Gore' + BleedList[265232] = 'Rend' + BleedList[265377] = 'Hooked Snare' + BleedList[265533] = 'Blood Maw' + BleedList[265948] = 'Denticulated' + BleedList[266035] = 'Bone Splinter' + BleedList[266191] = 'Whirling Axe' + BleedList[266231] = 'Severing Axe' + BleedList[266505] = 'Rending Claw' + BleedList[267064] = 'Bleeding' + BleedList[267080] = "Blight of G'huun" + BleedList[267103] = "Blight of G'huun" + BleedList[267441] = 'Serrated Axe' + BleedList[267523] = 'Cutting Surge' + BleedList[269576] = 'Master Marksman' + BleedList[270084] = 'Axe Barrage' + BleedList[270139] = 'Gore' + BleedList[270343] = 'Internal Bleeding' + BleedList[270473] = 'Serrated Arrows' + BleedList[270487] = 'Severing Blade' + BleedList[270979] = 'Rend and Tear' + BleedList[271178] = 'Ravaging Leap' + BleedList[271798] = 'Click' + BleedList[272273] = 'Rending Cleave' + BleedList[273436] = 'Gore' + BleedList[273632] = 'Gaping Maw' + BleedList[273794] = "Rezan's Fury" + BleedList[273900] = 'Bramble Swipe' + BleedList[273909] = 'Steelclaw Trap' + BleedList[274089] = 'Rend' + BleedList[274389] = 'Rat Traps' + BleedList[274838] = 'Feral Frenzy' + BleedList[275895] = 'Rend of Kimbul' + BleedList[276868] = 'Impale' + BleedList[277077] = 'Big Sharp Nasty Teeth' + BleedList[277309] = 'Jagged Maw' + BleedList[277431] = 'Hunter Toxin' + BleedList[277517] = 'Serrated Slash' + BleedList[277569] = 'Bloodthirsty Rend' + BleedList[277592] = 'Blood Frenzy' + BleedList[277794] = 'Paw Swipe' + BleedList[278175] = 'Bramble Claw' + BleedList[278570] = 'Boils and Sores' + BleedList[278733] = 'Deep Wound' + BleedList[278866] = 'Carve and Spit' + BleedList[279133] = 'Rend' + BleedList[280286] = 'Dagger in the Back' + BleedList[280321] = 'Garrote' + BleedList[280940] = 'Mangle' + BleedList[281711] = 'Cut of Death' + BleedList[282444] = 'Lacerating Claws' + BleedList[282845] = 'Bear Trap' + BleedList[283419] = 'Rend' + BleedList[283667] = 'Rupture' + BleedList[283668] = 'Crimson Tempest' + BleedList[283700] = 'Rake' + BleedList[283708] = 'Rip' + BleedList[284158] = 'Circular Saw' + BleedList[285875] = 'Rending Bite' + BleedList[286269] = 'Mangle' + BleedList[288091] = 'Gushing Wound' + BleedList[288266] = 'Mangle' + BleedList[288535] = 'Rip' + BleedList[288539] = 'Mangle' + BleedList[289355] = 'Smoldering Rend' + BleedList[289373] = 'Lacerating Pounce' + BleedList[289848] = 'Rending Claw' + BleedList[292348] = 'Bloodletting' + BleedList[292611] = 'Rake' + BleedList[292626] = 'Rip' + BleedList[293670] = 'Chainblade' + BleedList[294617] = 'Rupture' + BleedList[294741] = 'Saber Slash' + BleedList[294901] = 'Serrated Blades' + BleedList[295008] = 'Bloody Cleaver' + BleedList[295929] = 'Rats!' + BleedList[295945] = 'Rat Traps' + BleedList[296777] = 'Bleeding Wound' + BleedList[299474] = 'Ripping Slash' + BleedList[299502] = 'Nanoslicer' + BleedList[299923] = 'Tear Flesh' + BleedList[300610] = 'Fanged Bite' + BleedList[301061] = 'Thrash' + BleedList[301712] = 'Pounce' + BleedList[302295] = 'Slicing Claw' + BleedList[302474] = 'Phantom Laceration' + BleedList[303162] = 'Carve Flesh' + BleedList[303215] = 'Shell Slash' + BleedList[303501] = 'Rending Strike' + BleedList[308342] = 'Bore' + BleedList[308859] = 'Carnivorous Bite' + BleedList[308891] = 'Jagged Chop' + BleedList[308938] = 'Lacerating Swipe' + BleedList[309760] = 'Raking Claws' + BleedList[311122] = 'Jagged Wound' + BleedList[311744] = 'Deep Wound' + BleedList[311748] = 'Lacerating Swipe' + BleedList[313674] = 'Jagged Wound' + BleedList[313734] = 'Ravaging Leap' + BleedList[313747] = 'Rend' + BleedList[313957] = 'Rend' + BleedList[314130] = 'Skewer' + BleedList[314160] = 'Penetrating Lance' + BleedList[314454] = 'Thrashing Lunge' + BleedList[314531] = 'Tear Flesh' + BleedList[314533] = 'Rend' + BleedList[314568] = 'Deep Wound' + BleedList[314847] = 'Decapitate' + BleedList[315311] = 'Ravage' + BleedList[315711] = 'Serrated Strike' + BleedList[315805] = 'Crippler' + BleedList[316511] = 'Scratch' + BleedList[317561] = 'Swooping Lunge' + BleedList[317908] = 'Razor Wing' + BleedList[317916] = 'Razor Clip' + BleedList[318187] = 'Gushing Wound' + BleedList[319127] = 'Gore' + BleedList[319275] = 'Razor Wing' + BleedList[320007] = 'Gash' + BleedList[320147] = 'Bleeding' + BleedList[320200] = 'Stitchneedle' + BleedList[321538] = 'Bloodshed' + BleedList[321807] = 'Boneflay' + BleedList[322429] = 'Severing Slice' + BleedList[322796] = 'Wicked Gash' + BleedList[322965] = 'Tearing Bite' + BleedList[323043] = 'Bloodletting' + BleedList[323406] = 'Jagged Gash' + BleedList[324073] = 'Serrated Bone Spike' + BleedList[324149] = 'Flayed Shot' + BleedList[324154] = 'Dark Stride' + BleedList[324447] = 'Slashing Rend' + BleedList[325021] = 'Mistveil Tear' + BleedList[325022] = 'Jagged Swipe' + BleedList[325037] = 'Death Chakram' + BleedList[326298] = 'Bleeding Wound' + BleedList[326586] = 'Crimson Flurry' + BleedList[327258] = 'Rend' + BleedList[327814] = 'Wicked Gash' + BleedList[328287] = 'Heart Strike' + BleedList[328897] = 'Exsanguinated' + BleedList[328910] = 'Tantrum' + BleedList[328940] = 'Gore' + BleedList[329293] = 'Vorpal Wound' + BleedList[329516] = 'Swift Slash' + BleedList[329563] = 'Goring Swipe' + BleedList[329906] = 'Carnage' + BleedList[329986] = 'Maul' + BleedList[329990] = 'Craggy Swipe' + BleedList[330400] = 'Bleeding Swipe' + BleedList[330457] = 'Ripping Strike' + BleedList[330532] = 'Jagged Quarrel' + BleedList[330632] = 'Maul' + BleedList[331045] = 'Talon Rake' + BleedList[331066] = 'Bursting Plumage' + BleedList[331072] = 'Talon Rake' + BleedList[331340] = 'Plague Swipe' + BleedList[331415] = 'Wicked Gash' + BleedList[332168] = 'Maul' + BleedList[332610] = 'Penetrating Insight' + BleedList[332678] = 'Gushing Wound' + BleedList[332792] = 'Gore' + BleedList[332835] = 'Ruthless Strikes' + BleedList[332836] = 'Chop' + BleedList[333235] = 'Horn Rush' + BleedList[333250] = 'Reaver' + BleedList[333478] = 'Gut Slice' + BleedList[333861] = 'Ricocheting Blade' + BleedList[333985] = 'Culling Strike' + BleedList[334669] = 'Tirnenn Wrath' + BleedList[334960] = 'Vicious Wound' + BleedList[334971] = 'Jagged Claws' + BleedList[335105] = 'Dinner Time' + BleedList[336628] = 'Eternal Polearm' + BleedList[336810] = 'Ragged Claws' + BleedList[337349] = 'Triple Thrash' + BleedList[337729] = "Kerim's Laceration" + BleedList[337892] = 'Gore' + BleedList[338935] = 'Razor Petals' + BleedList[339163] = 'Wicked Gash' + BleedList[339189] = 'Chain Bleed' + BleedList[339453] = 'Darksworn Blast' + BleedList[339789] = 'Darksworn Blast' + BleedList[339975] = 'Grievous Strike' + BleedList[340058] = 'Heart Piercer' + BleedList[340374] = 'Bloody Tantrum' + BleedList[340431] = 'Mutilated Flesh' + BleedList[341435] = 'Lunge' + BleedList[341475] = 'Crimson Flurry' + BleedList[341833] = 'Rending Cleave' + BleedList[341863] = 'Bleeding Out' + BleedList[342250] = 'Jagged Swipe' + BleedList[342464] = 'Javelin Flurry' + BleedList[342675] = 'Bone Spear' + BleedList[343159] = 'Stone Claws' + BleedList[343722] = 'Crushing Bite' + BleedList[344312] = 'Serrated Edge' + BleedList[344464] = 'Shield Spike' + BleedList[344993] = 'Jagged Swipe' + BleedList[345548] = 'Spare Meat Hook' + BleedList[346770] = 'Grinding Bite' + BleedList[346807] = 'Rending Roar' + BleedList[347716] = 'Letter Opener' + BleedList[347807] = 'Barbed Arrow' + BleedList[348074] = 'Assailing Lance' + BleedList[348385] = 'Bloody Cleave' + BleedList[348726] = 'Lethal Shot' + BleedList[351119] = 'Shuriken Blitz' + BleedList[351976] = 'Shredder' + BleedList[353068] = 'Razor Trap' + BleedList[353466] = 'Sadistic Glee' + BleedList[353919] = "Rury's Sleepy Tantrum" + BleedList[354334] = "Hook'd!" + BleedList[355087] = 'Piercing Quill' + BleedList[355256] = 'Rending Roar' + BleedList[355416] = 'Sharpened Hide' + BleedList[355832] = 'Quickblade' + BleedList[356445] = 'Sharpened Hide' + BleedList[356620] = 'Pouch of Razor Fragments' + BleedList[356808] = 'Spiked' + BleedList[356923] = 'Sever' + BleedList[356925] = 'Carnage' + BleedList[357091] = 'Cleave Flesh' + BleedList[357192] = 'Dark Flurry' + BleedList[357239] = 'Cleave Flesh' + BleedList[357322] = 'Night Glaive' + BleedList[357665] = 'Crystalline Flesh' + BleedList[357827] = 'Frantic Rip' + BleedList[357953] = 'Fanged Bite' + BleedList[358197] = 'Searing Scythe' + BleedList[358224] = 'Jagged Swipe' + BleedList[359587] = 'Bloody Peck' + BleedList[359981] = 'Rend' + BleedList[360194] = 'Deathmark' + BleedList[360775] = 'Puncture' + BleedList[360826] = 'Rupture' + BleedList[360830] = 'Garrote' + BleedList[361024] = "Thief's Blade" + BleedList[361049] = 'Bleeding Gash' + BleedList[361756] = 'Death Chakram' + BleedList[362149] = 'Ascended Phalanx' + BleedList[362194] = 'Suffering' + BleedList[362819] = 'Rend' + BleedList[363830] = 'Sickle of the Lion' + BleedList[363831] = 'Bleeding Soul' + BleedList[365336] = 'Rending Bite' + BleedList[365877] = 'Jagged Blade' + BleedList[366075] = 'Bloody Peck' + BleedList[366275] = 'Rending Bite' + BleedList[366884] = 'Ripped Secrets' + BleedList[367481] = 'Bloody Bite' + BleedList[367521] = 'Bone Bolt' + BleedList[367726] = "Lupine's Slash" + BleedList[368401] = 'Puncture' + BleedList[368637] = 'The Third Rune' + BleedList[368651] = 'Vicious Wound' + BleedList[368701] = 'Boon of Harvested Hope' + BleedList[369408] = 'Rending Slash' + BleedList[369828] = 'Chomp' + BleedList[370742] = 'Jagged Strike' + BleedList[371472] = 'Rake' + BleedList[372224] = 'Dragonbone Axe' + BleedList[372397] = 'Vicious Bite' + BleedList[372404] = 'Rend' + BleedList[372570] = 'Bold Ambush' + BleedList[372718] = 'Earthen Shards' + BleedList[372796] = 'Blazing Rush' + BleedList[372860] = 'Searing Wounds' + BleedList[373735] = 'Dragon Strike' + BleedList[373947] = 'Rending Swipe' + BleedList[375201] = 'Talon Rip' + BleedList[375416] = 'Bleeding' + BleedList[375475] = 'Rending Bite' + BleedList[375803] = 'Mammoth Trap' + BleedList[375893] = 'Death Chakram' + BleedList[375937] = 'Rending Strike' + BleedList[376997] = 'Savage Peck' + BleedList[376999] = 'Thrash' + BleedList[377002] = 'Thrash' + BleedList[377344] = 'Peck' + BleedList[377609] = 'Dragon Rend' + BleedList[377732] = 'Jagged Bite' + BleedList[378020] = 'Gash Frenzy' + BleedList[378118] = 'Knocked Down' + BleedList[381575] = 'Lacerate' + BleedList[381628] = 'Internal Bleeding' + BleedList[381672] = 'Mutilated Flesh' + BleedList[381692] = 'Swift Stab' + BleedList[384134] = 'Pierce' + BleedList[384148] = 'Ensnaring Trap' + BleedList[384575] = 'Crippling Bite' + BleedList[385042] = 'Gushing Wound' + BleedList[385060] = "Odyn's Fury" + BleedList[385511] = 'Messy' + BleedList[385638] = 'Razor Fragments' + BleedList[385834] = 'Bloodthirsty Charge' + BleedList[385905] = 'Tailstrike' + BleedList[386116] = 'Messy' + BleedList[386640] = 'Tear Flesh' + BleedList[387205] = 'Beak Rend' + BleedList[387473] = 'Big Sharp Teeth' + BleedList[387809] = 'Splatter!' + BleedList[388301] = 'Savage Tear' + BleedList[388377] = 'Rending Slash' + BleedList[388473] = 'Feeding Frenzy' + BleedList[388539] = 'Rend' + BleedList[388912] = 'Severing Slash' + BleedList[389505] = 'Rending Slice' + BleedList[389881] = 'Spearhead' + BleedList[390194] = 'Rending Slash' + BleedList[390583] = 'Logcutter' + BleedList[390834] = 'Primal Rend' + BleedList[391098] = 'Puncturing Impalement' + BleedList[391114] = 'Cutting Winds' + BleedList[391140] = 'Frenzied Assault' + BleedList[391308] = 'Rending Swoop' + BleedList[391356] = 'Tear' + BleedList[391725] = 'Swooping Dive' + BleedList[392006] = 'Vicious Chomp' + BleedList[392235] = 'Furious Charge' + BleedList[392236] = 'Furious Charge' + BleedList[392332] = 'Horn Gore' + BleedList[392341] = 'Mighty Swipe' + BleedList[392411] = 'Beetle Thrust' + BleedList[392416] = 'Beetle Charge' + BleedList[392841] = 'Hungry Chomp' + BleedList[393426] = 'Spear Swipe' + BleedList[393444] = 'Gushing Wound' + BleedList[393718] = 'Heartpiercer' + BleedList[393817] = 'Hardened Shards' + BleedList[393820] = 'Horn Swing' + BleedList[394021] = 'Mutilated Flesh' + BleedList[394036] = 'Serrated Bone Spike' + BleedList[394063] = 'Rend' + BleedList[394371] = 'Hit the Mark' + BleedList[394628] = 'Peck' + BleedList[394647] = 'Merciless Gore' + BleedList[395827] = 'Severing Gore' + BleedList[395832] = 'Jagged Cuts' + BleedList[396007] = 'Vicious Peck' + BleedList[396093] = 'Savage Leap' + BleedList[396348] = 'Dismember' + BleedList[396353] = 'Fatal Chomp' + BleedList[396476] = 'Rending Claw' + BleedList[396639] = 'Bloody Pounce' + BleedList[396641] = 'Rending Slash' + BleedList[396674] = 'Rupturing Slash' + BleedList[396675] = 'Hemorrhaging Rend' + BleedList[396716] = 'Splinterbark' + BleedList[396807] = 'Savage Gore' + BleedList[397037] = 'Slicing Winds' + BleedList[397092] = 'Impaling Horn' + BleedList[397112] = 'Primal Devastation' + BleedList[397364] = 'Thunderous Roar' + BleedList[398392] = 'Stomp' + BleedList[398497] = 'Rock Needle' + BleedList[400050] = 'Claw Rip' + BleedList[400344] = 'Spike Traps' + BleedList[400941] = 'Ragged Slash' + BleedList[401370] = 'Deep Claws' + BleedList[403589] = 'Gushing Wound' + BleedList[403662] = 'Garrote' + BleedList[403790] = 'Vicious Swipe' + BleedList[404907] = 'Rupturing Slash' + BleedList[404945] = 'Raking Slice' + BleedList[404978] = 'Devastating Rend' + BleedList[405233] = 'Thrash' + BleedList[406183] = 'Time Slash' + BleedList[406365] = 'Rending Charge' + BleedList[406499] = 'Ravening Leaps' + BleedList[407120] = 'Serrated Axe' + BleedList[407313] = 'Shrapnel' + BleedList[411101] = 'Artifact Shards' + BleedList[411437] = 'Brutal Lacerations' + BleedList[411700] = 'Slobbering Bite' + BleedList[411924] = 'Drilljaws' + BleedList[412172] = 'Ceaseless Nibbling' + BleedList[412285] = 'Stonebolt' + BleedList[412505] = 'Rending Cleave' + BleedList[413131] = 'Whirling Dagger' + BleedList[413136] = 'Whirling Dagger' + BleedList[414340] = 'Drenched Blades' + BleedList[414466] = 'Jagged Gills' + BleedList[414506] = 'Lacerate' + BleedList[414552] = 'Stonecrack' + BleedList[416258] = 'Stonebolt' + BleedList[418009] = 'Serrated Arrows' + BleedList[418160] = 'Sawblade-Storm' + BleedList[418624] = 'Rending Slash' + BleedList[422466] = 'Shadow Spines' + BleedList[422683] = 'Thrash' + BleedList[423431] = 'Crushing Blow' + BleedList[424065] = 'Umbral Destruction' + BleedList[424493] = 'Shadow Rupture' + BleedList[426284] = 'Finishing Wound' + BleedList[426587] = 'Bramble Burst' + BleedList[426660] = 'Razor Jaws' + BleedList[427182] = 'Bloody Pounce' + BleedList[429233] = "Rezan's Fury" +end + +function lib:GetDebuffTypeColor() + return DebuffColors +end + +function lib:GetBleedList() + return BleedList +end + +function lib:GetBadList() + return BadList +end + +function lib:GetBlockList() + return BlockList +end + function lib:GetMyDispelTypes() return DispelList end @@ -22,31 +1027,30 @@ function lib:IsDispellableByMe(debuffType) end do - local _, myClass = UnitClass("player") + local _, myClass = UnitClass('player') local WarlockPetSpells = { [89808] = 'Singe', - [19505] = 'Devour Magic Rank 1', - [19731] = 'Devour Magic Rank 2', - [19734] = 'Devour Magic Rank 3', - [19736] = 'Devour Magic Rank 4', - [27276] = 'Devour Magic Rank 5', - [27277] = 'Devour Magic Rank 6', - [48011] = 'Devour Magic Rank 7' } + if Retail then + WarlockPetSpells[132411] = 'Singe Magic' -- Grimoire of Sacrifice + else + WarlockPetSpells[19505] = 'Devour Magic Rank 1' + WarlockPetSpells[19731] = 'Devour Magic Rank 2' + WarlockPetSpells[19734] = 'Devour Magic Rank 3' + WarlockPetSpells[19736] = 'Devour Magic Rank 4' + WarlockPetSpells[27276] = 'Devour Magic Rank 5' + WarlockPetSpells[27277] = 'Devour Magic Rank 6' + WarlockPetSpells[48011] = 'Devour Magic Rank 7' + end + local function CheckSpell(spellID, pet) return IsSpellKnownOrOverridesKnown(spellID, pet) and true or nil end local function CheckPetSpells() - if Retail then - return CheckSpell(89808, true) - else - for spellID in next, WarlockPetSpells do - if CheckSpell(spellID, true) then - return true - end - end + for spellID in next, WarlockPetSpells do + if CheckSpell(spellID, true) then return true end end end @@ -56,7 +1060,7 @@ do end -- this will fix a problem where spells dont show as existing because they are 'hidden' - local undoRanks = Wrath and GetCVar('ShowAllSpellRanks') ~= '1' and SetCVar('ShowAllSpellRanks', 1) + local undoRanks = (not Retail and GetCVar('ShowAllSpellRanks') ~= '1') and SetCVar('ShowAllSpellRanks', '1') if event == 'UNIT_PET' then DispelList.Magic = CheckPetSpells() @@ -84,43 +1088,49 @@ do elseif myClass == 'PRIEST' then local dispel = CheckSpell(527) -- Dispel Magic DispelList.Magic = dispel or CheckSpell(32375) - DispelList.Disease = Retail and (dispel or CheckSpell(213634)) or not Retail and (CheckSpell(552) or CheckSpell(528)) -- Purify Disease / Abolish Disease / Cure Disease + DispelList.Disease = Retail and (IsPlayerSpell(390632) or CheckSpell(213634)) or not Retail and (CheckSpell(552) or CheckSpell(528)) -- Purify Disease / Abolish Disease / Cure Disease elseif myClass == 'SHAMAN' then local purify = Retail and CheckSpell(77130) -- Purify Spirit local cleanse = purify or CheckSpell(51886) -- Cleanse Spirit - local toxins = CheckSpell(526) + local toxins = Retail and CheckSpell(383013) or CheckSpell(526) -- Poison Cleansing Totem (Retail), Cure Toxins (TBC/Classic) DispelList.Magic = purify DispelList.Curse = cleanse - DispelList.Poison = not Retail and (cleanse or toxins) + DispelList.Poison = toxins or (not Retail and cleanse) DispelList.Disease = not Retail and (cleanse or toxins) elseif myClass == 'EVOKER' then local naturalize = CheckSpell(360823) -- Naturalize (Preservation) local expunge = CheckSpell(365585) -- Expunge (Devastation) + local cauterizing = CheckSpell(374251) -- Cauterizing Flame DispelList.Magic = naturalize - DispelList.Poison = naturalize or expunge + DispelList.Poison = naturalize or expunge or cauterizing + DispelList.Disease = cauterizing + DispelList.Curse = cauterizing + DispelList.Bleed = cauterizing end - if undoRanks then - SetCVar('ShowAllSpellRanks', 0) - end + if undoRanks then SetCVar('ShowAllSpellRanks', '0') end + end + + -- setup events + if not lib.frame then + lib.frame = CreateFrame('Frame') + else -- we are resetting it + lib.frame:UnregisterAllEvents() end - local frame = CreateFrame('Frame') + local frame = lib.frame frame:SetScript('OnEvent', UpdateDispels) frame:RegisterEvent('CHARACTER_POINTS_CHANGED') frame:RegisterEvent('PLAYER_LOGIN') - if myClass == 'WARLOCK' then - frame:RegisterUnitEvent('UNIT_PET', 'player') - end + if myClass == 'WARLOCK' then frame:RegisterUnitEvent('UNIT_PET', 'player') end - if Retail or Wrath then + if Wrath then frame:RegisterEvent('PLAYER_TALENT_UPDATE') - end - - if Retail then - frame:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') + elseif Retail then + frame:RegisterEvent('LEARNED_SPELL_IN_TAB') + frame:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', 'player') end end diff --git a/libs/oUF/LICENSE.txt b/libs/oUF/LICENSE.txt index 476398b1..32a8562b 100644 --- a/libs/oUF/LICENSE.txt +++ b/libs/oUF/LICENSE.txt @@ -1,7 +1,7 @@ -Copyright (c) 2006-2022 Trond A Ekseth -Copyright (c) 2016-2022 Val Voronov -Copyright (c) 2016-2022 Adrian L Lange -Copyright (c) 2016-2022 Rainrider +Copyright (c) 2006-2024 Trond A Ekseth +Copyright (c) 2016-2024 Val Voronov +Copyright (c) 2016-2024 Adrian L Lange +Copyright (c) 2016-2024 Rainrider Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/libs/oUF/colors.lua b/libs/oUF/colors.lua index eb33c86b..2ff4b210 100644 --- a/libs/oUF/colors.lua +++ b/libs/oUF/colors.lua @@ -4,6 +4,9 @@ local Private = oUF.Private local frame_metatable = Private.frame_metatable +local LibDispel = LibStub('LibDispel-1.0') +local DebuffColors = LibDispel:GetDebuffTypeColor() + local colorMixin = { SetRGBA = function(self, r, g, b, a) if(r > 1 or g > 1 or b > 1) then @@ -139,7 +142,7 @@ if(not customClassColors()) then end) end -for debuffType, color in next, _G.DebuffTypeColor do +for debuffType, color in next, DebuffColors do colors.debuff[debuffType] = oUF:CreateColor(color.r, color.g, color.b) end @@ -147,20 +150,34 @@ for eclass, color in next, _G.FACTION_BAR_COLORS do colors.reaction[eclass] = oUF:CreateColor(color.r, color.g, color.b) end +local staggerIndices = { + green = 1, + yellow = 2, + red = 3 +} + for power, color in next, PowerBarColor do if (type(power) == 'string') then - if(type(select(2, next(color))) == 'table') then - colors.power[power] = {} - - for index, color_ in next, color do - colors.power[power][index] = oUF:CreateColor(color_.r, color_.g, color_.b) - end - else + if(color.r) then colors.power[power] = oUF:CreateColor(color.r, color.g, color.b) if(color.atlas) then colors.power[power]:SetAtlas(color.atlas) end + else + -- special handling for stagger + colors.power[power] = {} + + for name, color_ in next, color do + local index = staggerIndices[name] + if(index) then + colors.power[power][index] = oUF:CreateColor(color_.r, color_.g, color_.b) + + if(color_.atlas) then + colors.power[power][index]:SetAtlas(color_.atlas) + end + end + end end end end diff --git a/libs/oUF/elements/additionalpower.lua b/libs/oUF/elements/additionalpower.lua index ae5f55a2..359182e2 100644 --- a/libs/oUF/elements/additionalpower.lua +++ b/libs/oUF/elements/additionalpower.lua @@ -72,7 +72,8 @@ local UnitPowerType = UnitPowerType -- sourced from FrameXML/AlternatePowerBar.lua local POWER_NAME = _G.ADDITIONAL_POWER_BAR_NAME or 'MANA' local POWER_INDEX = _G.ADDITIONAL_POWER_BAR_INDEX or 0 -local ALT_MANA_INFO = _G.ALT_MANA_BAR_PAIR_DISPLAY_INFO or {DRUID={[8]=true}, SHAMAN={[11]=true}, PRIEST={[13]=true}} +local ALT_POWER_INFO = _G.ALT_POWER_BAR_PAIR_DISPLAY_INFO or _G.ALT_MANA_BAR_PAIR_DISPLAY_INFO or {DRUID={[8]=true}, SHAMAN={[11]=true}, PRIEST={[13]=true}} +-- NOTE: ALT_POWER and ALT_MANA have different table structures! so update this later if needed. local function UpdateColor(self, event, unit, powerType) if(not (unit and UnitIsUnit(unit, 'player') and powerType == POWER_NAME)) then return end @@ -282,7 +283,7 @@ local function Enable(self, unit) self:RegisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) if(not element.displayPairs) then - element.displayPairs = CopyTable(ALT_MANA_INFO) + element.displayPairs = CopyTable(ALT_POWER_INFO) end if(element:IsObjectType('StatusBar') and not element:GetStatusBarTexture()) then diff --git a/libs/oUF/elements/auras.lua b/libs/oUF/elements/auras.lua index 38ebda62..86cb5be5 100644 --- a/libs/oUF/elements/auras.lua +++ b/libs/oUF/elements/auras.lua @@ -81,13 +81,11 @@ local CREATED = 2 local wipe = wipe local pcall = pcall local tinsert = tinsert -local UnitAura = UnitAura local UnitIsUnit = UnitIsUnit local CreateFrame = CreateFrame local GameTooltip = GameTooltip local GetSpellInfo = GetSpellInfo local floor, min = math.floor, math.min -local LCD = oUF.isClassic and LibStub('LibClassicDurations', true) -- end block -- ElvUI adds IsForbidden checks @@ -168,22 +166,7 @@ local function customFilter(element, unit, button, name) end local function updateAura(element, unit, index, offset, filter, isDebuff, visible) - local name, icon, count, debuffType, duration, expiration, source, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, modRate, effect1, effect2, effect3 - - if LCD and not UnitIsUnit('player', unit) then - local durationNew, expirationTimeNew - name, icon, count, debuffType, duration, expiration, source, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, modRate, effect1, effect2, effect3 = LCD:UnitAura(unit, index, filter) - - if spellID then - durationNew, expirationTimeNew = LCD:GetAuraDurationByUnit(unit, spellID, source, name) - end - - if durationNew and durationNew > 0 then - duration, expiration = durationNew, expirationTimeNew - end - else - name, icon, count, debuffType, duration, expiration, source, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, modRate, effect1, effect2, effect3 = UnitAura(unit, index, filter) - end + local name, icon, count, debuffType, duration, expiration, source, isStealable, nameplateShowPersonal, spellID, canApplyAura, isBossDebuff, castByPlayer, nameplateShowAll, modRate, effect1, effect2, effect3 = oUF:GetAuraData(unit, index, filter) if element.forceShow or element.forceCreate then spellID = 5782 diff --git a/libs/oUF/elements/castbar.lua b/libs/oUF/elements/castbar.lua index 73f78faf..3a7963eb 100644 --- a/libs/oUF/elements/castbar.lua +++ b/libs/oUF/elements/castbar.lua @@ -96,6 +96,7 @@ local INTERRUPTED = _G.INTERRUPTED or 'Interrupted' local CASTBAR_STAGE_DURATION_INVALID = -1 -- defined in FrameXML/CastingBarFrame.lua -- ElvUI block +local wipe = wipe local next = next local select = select local CreateFrame = CreateFrame @@ -130,6 +131,8 @@ local function resetAttributes(self) self.spellID = nil self.spellName = nil -- ElvUI + wipe(self.stagePoints) + for _, pip in next, self.Pips do pip:Hide() end @@ -144,6 +147,8 @@ local function UpdatePips(element, numStages) local stageMaxValue = element.max * 1000 local isHoriz = element:GetOrientation() == 'HORIZONTAL' local elementSize = isHoriz and element:GetWidth() or element:GetHeight() + element.numStages = numStages + element.curStage = -1 -- dummy for stage = 1, numStages do local duration @@ -155,6 +160,7 @@ local function UpdatePips(element, numStages) if(duration > CASTBAR_STAGE_DURATION_INVALID) then stageTotalDuration = stageTotalDuration + duration + element.stagePoints[stage] = stageTotalDuration local portion = stageTotalDuration / stageMaxValue local offset = elementSize * portion @@ -178,7 +184,9 @@ local function UpdatePips(element, numStages) pip:Show() if(isHoriz) then - pip:RotateTextures(0) + if(pip.RotateTextures) then + pip:RotateTextures(0) + end if(element:GetReverseFill()) then pip:SetPoint('TOP', element, 'TOPRIGHT', -offset, 0) @@ -188,7 +196,9 @@ local function UpdatePips(element, numStages) pip:SetPoint('BOTTOM', element, 'BOTTOMLEFT', offset, 0) end else - pip:RotateTextures(1.5708) + if(pip.RotateTextures) then + pip:RotateTextures(1.5708) + end if(element:GetReverseFill()) then pip:SetPoint('LEFT', element, 'TOPLEFT', 0, -offset) @@ -198,15 +208,33 @@ local function UpdatePips(element, numStages) pip:SetPoint('RIGHT', element, 'BOTTOMRIGHT', 0, offset) end end + + if element.PostUpdatePip then -- ElvUI + element:PostUpdatePip(pip, stage) + end end end end +--[[ Override: Castbar:ShouldShow(unit) +Handles check for which unit the castbar should show for. +Defaults to the object unit. +* self - the Castbar widget +* unit - the unit for which the update has been triggered (string) +--]] +local function ShouldShow(element, unit) + return element.__owner.unit == unit +end + + local function CastStart(self, real, unit, castGUID) - if self.unit ~= unit then return end if oUF.isRetail and real == 'UNIT_SPELLCAST_START' and not castGUID then return end local element = self.Castbar + if(not (element.ShouldShow or ShouldShow) (element, unit)) then + return + end + local name, text, texture, startTime, endTime, isTradeSkill, castID, notInterruptible, spellID = UnitCastingInfo(unit) local numStages, _ @@ -224,6 +252,14 @@ local function CastStart(self, real, unit, castGUID) return end + element.casting = event == 'UNIT_SPELLCAST_START' + element.channeling = event == 'UNIT_SPELLCAST_CHANNEL_START' + element.empowering = event == 'UNIT_SPELLCAST_EMPOWER_START' + + if element.empowering then + endTime = endTime + GetUnitEmpowerHoldAtMaxTime(unit) + end + endTime = endTime / 1000 startTime = startTime / 1000 @@ -231,20 +267,12 @@ local function CastStart(self, real, unit, castGUID) element.startTime = startTime element.delay = 0 - element.casting = event == 'UNIT_SPELLCAST_START' - element.channeling = event == 'UNIT_SPELLCAST_CHANNEL_START' - element.empowering = event == 'UNIT_SPELLCAST_EMPOWER_START' - element.notInterruptible = notInterruptible element.holdTime = 0 element.castID = castID element.spellID = spellID element.spellName = name -- ElvUI - if element.empowering then - endTime = endTime + GetUnitEmpowerHoldAtMaxTime(unit) - end - if element.channeling then element.duration = endTime - GetTime() else @@ -269,7 +297,7 @@ local function CastStart(self, real, unit, castGUID) if(element.Icon) then element.Icon:SetTexture(texture or FALLBACK_ICON) end if(element.Shield) then element.Shield:SetShown(notInterruptible) end if(element.Spark) then element.Spark:Show() end - if(element.Text) then element.Text:SetText(text) end + if(element.Text) then element.Text:SetText(text ~= '' and text or name) end if(element.Time) then element.Time:SetText() end local safeZone = element.SafeZone @@ -318,9 +346,11 @@ local function CastStart(self, real, unit, castGUID) end local function CastUpdate(self, event, unit, castID, spellID) - if(self.unit ~= unit) then return end - local element = self.Castbar + if(not (element.ShouldShow or ShouldShow) (element, unit)) then + return + end + if(not element:IsShown() or ((unit == 'player' or oUF.isRetail) and (element.castID ~= castID)) or (oUF.isRetail and (element.spellID ~= spellID))) then return end @@ -375,9 +405,11 @@ local function CastUpdate(self, event, unit, castID, spellID) end local function CastStop(self, event, unit, castID, spellID) - if(self.unit ~= unit) then return end - local element = self.Castbar + if(not (element.ShouldShow or ShouldShow) (element, unit)) then + return + end + if(not element:IsShown() or ((unit == 'player' or oUF.isRetail) and (element.castID ~= castID)) or (oUF.isRetail and (element.spellID ~= spellID))) then return end @@ -405,9 +437,11 @@ local function CastStop(self, event, unit, castID, spellID) end local function CastFail(self, event, unit, castID, spellID) - if(self.unit ~= unit) then return end - local element = self.Castbar + if(not (element.ShouldShow or ShouldShow) (element, unit)) then + return + end + if(not element:IsShown() or ((unit == 'player' or oUF.isRetail) and (element.castID ~= castID)) or (oUF.isRetail and (element.spellID ~= spellID))) then return end @@ -443,9 +477,11 @@ local function CastFail(self, event, unit, castID, spellID) end local function CastInterruptible(self, event, unit) - if(self.unit ~= unit) then return end - local element = self.Castbar + if(not (element.ShouldShow or ShouldShow) (element, unit)) then + return + end + if(not element:IsShown()) then return end element.notInterruptible = event == 'UNIT_SPELLCAST_NOT_INTERRUPTIBLE' @@ -463,6 +499,27 @@ local function CastInterruptible(self, event, unit) end end +local function OnUpdateStage(element) + if element.UpdatePipStep then + local maxStage = 0 + local stageValue = element.duration * 1000 + for i = 1, element.numStages do + local step = element.stagePoints[i] + if not step or stageValue < step then + break + else + maxStage = i + end + end + + if maxStage ~= element.curStage then + element:UpdatePipStep(maxStage) + + element.curStage = maxStage + end + end +end + local function onUpdate(self, elapsed) self.elapsed = (self.elapsed or 0) + elapsed @@ -513,6 +570,10 @@ local function onUpdate(self, elapsed) end end + if(self.empowering) then + OnUpdateStage(self) + end + self.elapsed = 0 end @@ -533,37 +594,20 @@ local function ForceUpdate(element) return Update(element.__owner, 'ForceUpdate', element.__owner.unit) end -local LCC, EventFunctions = oUF.isClassic and LibStub('LibClassicCasterino', true), {} - local function Enable(self, unit) local element = self.Castbar if(element and unit and not unit:match('%wtarget$')) then element.__owner = self element.ForceUpdate = ForceUpdate - if LCC then - local CastbarEventHandler = function(event, ...) - return EventFunctions[event](self, event, ...) - end - - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_START', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_DELAYED', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_STOP', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_FAILED', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_INTERRUPTED', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_START', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_UPDATE', CastbarEventHandler) - LCC.RegisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_STOP', CastbarEventHandler) - else - self:RegisterEvent('UNIT_SPELLCAST_START', CastStart) - self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart) - self:RegisterEvent('UNIT_SPELLCAST_STOP', CastStop) - self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop) - self:RegisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate) - self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate) - self:RegisterEvent('UNIT_SPELLCAST_FAILED', CastFail) - self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail) - end + self:RegisterEvent('UNIT_SPELLCAST_START', CastStart) + self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart) + self:RegisterEvent('UNIT_SPELLCAST_STOP', CastStop) + self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop) + self:RegisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate) + self:RegisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate) + self:RegisterEvent('UNIT_SPELLCAST_FAILED', CastFail) + self:RegisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail) if oUF.isRetail then self:RegisterEvent('UNIT_SPELLCAST_EMPOWER_START', CastStart) @@ -578,7 +622,13 @@ local function Enable(self, unit) -- end block element.holdTime = 0 - element.Pips = {} + + if not element.Pips then + element.Pips = {} + end + if not element.stagePoints then + element.stagePoints = {} + end element:SetScript('OnUpdate', element.OnUpdate or onUpdate) @@ -612,25 +662,14 @@ local function Disable(self) if(element) then element:Hide() - if LCC then - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_START') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_DELAYED') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_STOP') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_FAILED') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_INTERRUPTED') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_START') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_UPDATE') - LCC.UnregisterCallback(self, 'UNIT_SPELLCAST_CHANNEL_STOP') - else - self:UnregisterEvent('UNIT_SPELLCAST_START', CastStart) - self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart) - self:UnregisterEvent('UNIT_SPELLCAST_STOP', CastStop) - self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop) - self:UnregisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate) - self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate) - self:UnregisterEvent('UNIT_SPELLCAST_FAILED', CastFail) - self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail) - end + self:UnregisterEvent('UNIT_SPELLCAST_START', CastStart) + self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_START', CastStart) + self:UnregisterEvent('UNIT_SPELLCAST_STOP', CastStop) + self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_STOP', CastStop) + self:UnregisterEvent('UNIT_SPELLCAST_DELAYED', CastUpdate) + self:UnregisterEvent('UNIT_SPELLCAST_CHANNEL_UPDATE', CastUpdate) + self:UnregisterEvent('UNIT_SPELLCAST_FAILED', CastFail) + self:UnregisterEvent('UNIT_SPELLCAST_INTERRUPTED', CastFail) if oUF.isRetail then self:UnregisterEvent('UNIT_SPELLCAST_EMPOWER_START', CastStart) @@ -644,25 +683,6 @@ local function Disable(self) end end -if LCC then - UnitCastingInfo = function(unit) - return LCC:UnitCastingInfo(unit) - end - - UnitChannelInfo = function(unit) - return LCC:UnitChannelInfo(unit) - end - - EventFunctions.UNIT_SPELLCAST_START = CastStart - EventFunctions.UNIT_SPELLCAST_FAILED = CastFail - EventFunctions.UNIT_SPELLCAST_INTERRUPTED = CastFail - EventFunctions.UNIT_SPELLCAST_DELAYED = CastUpdate - EventFunctions.UNIT_SPELLCAST_STOP = CastStop - EventFunctions.UNIT_SPELLCAST_CHANNEL_START = CastStart - EventFunctions.UNIT_SPELLCAST_CHANNEL_UPDATE = CastUpdate - EventFunctions.UNIT_SPELLCAST_CHANNEL_STOP = CastStop -end - if oUF.isRetail then -- ElvUI hooksecurefunc(C_TradeSkillUI, 'CraftRecipe', function(_, num) tradeskillCurrent = 0 diff --git a/libs/oUF/elements/classpower.lua b/libs/oUF/elements/classpower.lua index 423e0653..d0cdeac2 100644 --- a/libs/oUF/elements/classpower.lua +++ b/libs/oUF/elements/classpower.lua @@ -184,8 +184,8 @@ local function Visibility(self, event, unit) local element = self.ClassPower local shouldEnable - if (oUF.isRetail or oUF.isWrath) and UnitHasVehicleUI('player') then - shouldEnable = oUF.isWrath and UnitPowerType('vehicle') == SPELL_POWER_COMBO_POINTS or oUF.isRetail and PlayerVehicleHasComboPoints() + if (oUF.isRetail or oUF.isCata) and UnitHasVehicleUI('player') then + shouldEnable = oUF.isCata and UnitPowerType('vehicle') == SPELL_POWER_COMBO_POINTS or oUF.isRetail and PlayerVehicleHasComboPoints() unit = 'vehicle' elseif(ClassPowerID) then if(not RequireSpec or oUF.isRetail and (RequireSpec == GetSpecialization())) then @@ -256,7 +256,7 @@ end do function ClassPowerEnable(self) self:RegisterEvent('UNIT_MAXPOWER', Path) - self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + self:RegisterEvent('UNIT_POWER_UPDATE', Path) if not oUF.isRetail then self:RegisterEvent('PLAYER_TARGET_CHANGED', VisibilityPath, true) @@ -268,7 +268,7 @@ do self.ClassPower.__isEnabled = true - if (oUF.isRetail or oUF.isWrath) and UnitHasVehicleUI('player') then + if (oUF.isRetail or oUF.isCata) and UnitHasVehicleUI('player') then Path(self, 'ClassPowerEnable', 'vehicle', 'COMBO_POINTS') else Path(self, 'ClassPowerEnable', 'player', ClassPowerType) @@ -276,7 +276,7 @@ do end function ClassPowerDisable(self) - self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + self:UnregisterEvent('UNIT_POWER_UPDATE', Path) self:UnregisterEvent('UNIT_MAXPOWER', Path) if oUF.isRetail then @@ -329,7 +329,7 @@ local function Enable(self, unit) element.__max = #element element.ForceUpdate = ForceUpdate - if(oUF.isRetail or oUF.isWrath) and (RequireSpec or RequireSpell) then + if(oUF.isRetail or oUF.isCata) and (RequireSpec or RequireSpell) then self:RegisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath, true) end @@ -359,7 +359,7 @@ local function Disable(self) if(self.ClassPower) then ClassPowerDisable(self) - if oUF.isRetail or oUF.isWrath then + if oUF.isRetail or oUF.isCata then self:UnregisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath) end diff --git a/libs/oUF/elements/eclipsebar.lua b/libs/oUF/elements/eclipsebar.lua new file mode 100644 index 00000000..b7e70e6e --- /dev/null +++ b/libs/oUF/elements/eclipsebar.lua @@ -0,0 +1,147 @@ +if(select(2, UnitClass('player')) ~= 'DRUID') then return end + +local _, ns = ... +local oUF = ns.oUF + +local UnitPower = UnitPower +local UnitPowerMax = UnitPowerMax +local UnitHasVehicleUI = UnitHasVehicleUI +local GetShapeshiftFormID = GetShapeshiftFormID +local GetPrimaryTalentTree = GetPrimaryTalentTree +local GetEclipseDirection = GetEclipseDirection + +local POWERTYPE_BALANCE = Enum.PowerType.Balance +local MOONKIN_FORM = MOONKIN_FORM + +local function Update(self, event, unit, powerType) + if(self.unit ~= unit or (event == 'UNIT_POWER' and powerType ~= 'ECLIPSE')) then return end + + local element = self.EclipseBar + if(element.PreUpdate) then element:PreUpdate(unit) end + + local CUR = UnitPower('player', POWERTYPE_BALANCE) + local MAX = UnitPowerMax('player', POWERTYPE_BALANCE) + + if(element.LunarBar) then + element.LunarBar:SetMinMaxValues(-MAX, MAX) + element.LunarBar:SetValue(CUR) + end + + if(element.SolarBar) then + element.SolarBar:SetMinMaxValues(-MAX, MAX) + element.SolarBar:SetValue(CUR * -1) + end + + if(element.PostUpdate) then + return element:PostUpdate(unit, CUR, MAX, event) + end +end + +local function Path(self, ...) + return (self.EclipseBar.Override or Update) (self, ...) +end + +local function EclipseDirection(self, event, status) + local element = self.EclipseBar + + element.direction = status + + if(element.PostDirectionChange) then + return element:PostDirectionChange(status) + end +end + +local function EclipseDirectionPath(self, ...) + return (self.EclipseBar.OverrideEclipseDirection or EclipseDirection) (self, ...) +end + +local function ElementEnable(self) + self:RegisterEvent('UNIT_POWER_FREQUENT', Path) + + self.EclipseBar:Show() + EclipseDirectionPath(self, 'ElementEnable', GetEclipseDirection()) + + if self.EclipseBar.PostUpdateVisibility then + self.EclipseBar:PostUpdateVisibility(true, not self.EclipseBar.isEnabled) + end + + self.EclipseBar.isEnabled = true + + Path(self, 'ElementEnable', 'player', POWERTYPE_BALANCE) +end + +local function ElementDisable(self) + self:UnregisterEvent('UNIT_POWER_FREQUENT', Path) + + self.EclipseBar:Hide() + + if self.EclipseBar.PostUpdateVisibility then + self.EclipseBar:PostUpdateVisibility(false, self.EclipseBar.isEnabled) + end + + self.EclipseBar.isEnabled = nil + + Path(self, 'ElementDisable', 'player', POWERTYPE_BALANCE) +end + +local function Visibility(self) + local shouldEnable + + if not UnitHasVehicleUI('player') then + local form = GetShapeshiftFormID() + local ptt = GetPrimaryTalentTree() + + if ptt and ptt == 1 and (form == MOONKIN_FORM or not form) then + shouldEnable = true + end + end + + if(shouldEnable) then + ElementEnable(self) + else + ElementDisable(self) + end +end + +local function VisibilityPath(self, ...) + return (self.EclipseBar.OverrideVisibility or Visibility) (self, ...) +end + +local function ForceUpdate(element) + EclipseDirectionPath(element.__owner, 'ForceUpdate', GetEclipseDirection()) + return VisibilityPath(element.__owner, 'ForceUpdate', element.__owner.unit, 'ECLIPSE') +end + +local function Enable(self, unit) + local element = self.EclipseBar + if(element and unit == 'player') then + element.__owner = self + element.ForceUpdate = ForceUpdate + + self:RegisterEvent('ECLIPSE_DIRECTION_CHANGE', EclipseDirectionPath, true) + self:RegisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath, true) + self:RegisterEvent('UPDATE_SHAPESHIFT_FORM', VisibilityPath, true) + + if(element.LunarBar and element.LunarBar:IsObjectType('StatusBar') and not element.LunarBar:GetStatusBarTexture()) then + element.LunarBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + if(element.SolarBar and element.SolarBar:IsObjectType('StatusBar') and not element.SolarBar:GetStatusBarTexture()) then + element.SolarBar:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) + end + + return true + end +end + +local function Disable(self) + local element = self.EclipseBar + if(element) then + ElementDisable(self) + + self:UnregisterEvent('ECLIPSE_DIRECTION_CHANGE', EclipseDirectionPath) + self:UnregisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath) + self:UnregisterEvent('UPDATE_SHAPESHIFT_FORM', VisibilityPath) + end +end + +oUF:AddElement('EclipseBar', VisibilityPath, Enable, Disable) diff --git a/libs/oUF/elements/healthprediction.lua b/libs/oUF/elements/healthprediction.lua index f2174af9..847655cc 100644 --- a/libs/oUF/elements/healthprediction.lua +++ b/libs/oUF/elements/healthprediction.lua @@ -108,6 +108,21 @@ local function Update(self, event, unit) local otherIncomingHeal = 0 local hasOverHealAbsorb = false + -- Kludge to override value for heals not reported by WoW client (ref: https://github.com/Stanzilla/WoWUIBugs/issues/163) + -- There may be other bugs that this workaround does not catch, but this does fix Priest PoH + if(HealComm and not oUF.isRetail) then + local healAmount = HealComm:GetHealAmount(GUID, HealComm.CASTED_HEALS) or 0 + if(healAmount > 0) then + if(myIncomingHeal == 0 and unit == 'player') then + myIncomingHeal = healAmount + end + + if(allIncomingHeal == 0) then + allIncomingHeal = healAmount + end + end + end + if(healAbsorb > allIncomingHeal) then healAbsorb = healAbsorb - allIncomingHeal allIncomingHeal = 0 @@ -259,14 +274,17 @@ local function Enable(self) oUF:RegisterEvent(self, 'UNIT_MAXHEALTH', Path) oUF:RegisterEvent(self, 'UNIT_HEAL_PREDICTION', Path) - if oUF.isRetail then + if oUF.isClassic then + oUF:RegisterEvent(self, 'UNIT_HEALTH_FREQUENT', Path) + else oUF:RegisterEvent(self, 'UNIT_HEALTH', Path) + end + + if oUF.isRetail then oUF:RegisterEvent(self, 'UNIT_ABSORB_AMOUNT_CHANGED', Path) oUF:RegisterEvent(self, 'UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path) else element:SetUseHealComm(true) - - oUF:RegisterEvent(self, 'UNIT_HEALTH_FREQUENT', Path) end if (not element.maxOverflow) then @@ -345,14 +363,17 @@ local function Disable(self) oUF:UnregisterEvent(self, 'UNIT_MAXHEALTH', Path) oUF:UnregisterEvent(self, 'UNIT_HEAL_PREDICTION', Path) - if oUF.isRetail then + if oUF.isClassic then + oUF:UnregisterEvent(self, 'UNIT_HEALTH_FREQUENT', Path) + else oUF:UnregisterEvent(self, 'UNIT_HEALTH', Path) + end + + if oUF.isRetail then oUF:UnregisterEvent(self, 'UNIT_ABSORB_AMOUNT_CHANGED', Path) oUF:UnregisterEvent(self, 'UNIT_HEAL_ABSORB_AMOUNT_CHANGED', Path) else element:SetUseHealComm(false) - - oUF:UnregisterEvent(self, 'UNIT_HEALTH_FREQUENT', Path) end end end diff --git a/libs/oUF/elements/portrait.lua b/libs/oUF/elements/portrait.lua index 81df9bf6..13e4c417 100644 --- a/libs/oUF/elements/portrait.lua +++ b/libs/oUF/elements/portrait.lua @@ -40,18 +40,28 @@ local _, ns = ... local oUF = ns.oUF -- ElvUI block -local UnitIsUnit = UnitIsUnit local UnitGUID = UnitGUID local UnitIsConnected = UnitIsConnected local UnitIsVisible = UnitIsVisible local UnitClassBase = UnitClassBase -local SetPortraitTexture = SetPortraitTexture -- end block -local function Update(self, event, unit) - if(not unit or not UnitIsUnit(self.unit, unit)) then return end - +local function Update(self, event) local element = self.Portrait + if not element then return end + + local unit = self.unit + if not unit then return end + + local guid = UnitGUID(unit) + local newGUID = element.guid ~= guid + + local nameplate = event == 'NAME_PLATE_UNIT_ADDED' + if newGUID then + element.guid = guid + elseif nameplate then + return + end --[[ Callback: Portrait:PreUpdate(unit) Called before the element has been updated. @@ -61,34 +71,28 @@ local function Update(self, event, unit) --]] if(element.PreUpdate) then element:PreUpdate(unit) end - local guid = UnitGUID(unit) local isAvailable = UnitIsConnected(unit) and UnitIsVisible(unit) - local hasStateChanged = event ~= 'OnUpdate' or element.guid ~= guid or element.state ~= isAvailable + local hasStateChanged = newGUID or (not nameplate or element.state ~= isAvailable) if hasStateChanged then element.playerModel = element:IsObjectType('PlayerModel') element.state = isAvailable - element.guid = guid if element.playerModel then if not isAvailable then element:SetCamDistanceScale(0.25) element:SetPortraitZoom(0) element:SetPosition(0, 0, 0.25) - element:ClearModel() element:SetModel([[Interface\Buttons\TalkToMeQuestionMark.m2]]) else element:SetCamDistanceScale(1) element:SetPortraitZoom(1) element:SetPosition(0, 0, 0) - element:ClearModel() element:SetUnit(unit) end - elseif not element.customTexture then -- ElvUI changed - local class = element.showClass and UnitClassBase(unit) - if class then - element:SetAtlas('classicon-' .. class) - else - SetPortraitTexture(element, unit) + elseif element.useClassBase then + local classBase = UnitClassBase(unit) + if classBase then + element:SetAtlas('classicon-' .. classBase) end end end diff --git a/libs/oUF/elements/power.lua b/libs/oUF/elements/power.lua index 0464dba4..b19755c7 100644 --- a/libs/oUF/elements/power.lua +++ b/libs/oUF/elements/power.lua @@ -171,7 +171,7 @@ local function UpdateColor(self, event, unit) end if(atlas) then - element:SetStatusBarAtlas(atlas) + element:SetStatusBarTexture(atlas) element:SetStatusBarColor(1, 1, 1) elseif(b) then element:SetStatusBarColor(r, g, b) diff --git a/libs/oUF/elements/powerprediction.lua b/libs/oUF/elements/powerprediction.lua index 4fcebd50..def4f56c 100644 --- a/libs/oUF/elements/powerprediction.lua +++ b/libs/oUF/elements/powerprediction.lua @@ -43,12 +43,20 @@ A default texture will be applied if the widget is a StatusBar and doesn't have local _, ns = ... local oUF = ns.oUF --- sourced from FrameXML/AlternatePowerBar.lua -local ADDITIONAL_POWER_BAR_INDEX = _G.ADDITIONAL_POWER_BAR_INDEX or 0 -local ALT_MANA_BAR_PAIR_DISPLAY_INFO = _G.ALT_MANA_BAR_PAIR_DISPLAY_INFO - local _, playerClass = UnitClass('player') +-- ElvUI block +local next = next +local GetSpellPowerCost = GetSpellPowerCost +local UnitCastingInfo = UnitCastingInfo +local UnitPowerType = UnitPowerType +local UnitPowerMax = UnitPowerMax +local UnitIsUnit = UnitIsUnit + +local POWERTYPE_MANA = Enum.PowerType.Mana +local ALT_POWER_BAR_PAIR_DISPLAY_INFO = ALT_POWER_BAR_PAIR_DISPLAY_INFO +-- end block + local function Update(self, event, unit) if(self.unit ~= unit) then return end @@ -68,7 +76,8 @@ local function Update(self, event, unit) local mainType = UnitPowerType(unit) local mainMax = UnitPowerMax(unit, mainType) local isPlayer = UnitIsUnit('player', unit) - local altManaInfo = isPlayer and oUF.isRetail and ALT_MANA_BAR_PAIR_DISPLAY_INFO[playerClass] + local DISPLAY_INFO = isPlayer and ALT_POWER_BAR_PAIR_DISPLAY_INFO + local altManaInfo = DISPLAY_INFO and DISPLAY_INFO[playerClass] local hasAltManaBar = altManaInfo and altManaInfo[mainType] local _, _, _, startTime, endTime, _, _, _, spellID = UnitCastingInfo(unit) @@ -87,7 +96,7 @@ local function Update(self, event, unit) element.mainCost = mainCost break - elseif hasAltManaBar and checkSpec and ctype == ADDITIONAL_POWER_BAR_INDEX then + elseif hasAltManaBar and checkSpec and ctype == POWERTYPE_MANA then altCost = cost element.altCost = altCost @@ -111,7 +120,7 @@ local function Update(self, event, unit) end if(element.altBar and hasAltManaBar) then - element.altBar:SetMinMaxValues(0, UnitPowerMax(unit, ADDITIONAL_POWER_BAR_INDEX)) + element.altBar:SetMinMaxValues(0, UnitPowerMax(unit, POWERTYPE_MANA)) element.altBar:SetValue(altCost) element.altBar:Show() end diff --git a/libs/oUF/elements/raidroleindicator.lua b/libs/oUF/elements/raidroleindicator.lua index 26941bcb..afcbdd63 100644 --- a/libs/oUF/elements/raidroleindicator.lua +++ b/libs/oUF/elements/raidroleindicator.lua @@ -42,7 +42,7 @@ local function Update(self, event) end local role, isShown - local inVehicle = (oUF.isRetail or oUF.isWrath) and UnitHasVehicleUI(unit) + local inVehicle = (oUF.isRetail or oUF.isCata) and UnitHasVehicleUI(unit) if(UnitInRaid(unit) and not inVehicle) then if(GetPartyAssignment('MAINTANK', unit)) then isShown = true diff --git a/libs/oUF/elements/readycheckindicator.lua b/libs/oUF/elements/readycheckindicator.lua index 1c710c3c..074fb344 100644 --- a/libs/oUF/elements/readycheckindicator.lua +++ b/libs/oUF/elements/readycheckindicator.lua @@ -42,6 +42,15 @@ local Private = oUF.Private local unitExists = Private.unitExists +local _G = _G +local GetReadyCheckStatus = GetReadyCheckStatus +local C_Texture_GetAtlasInfo = C_Texture and C_Texture.GetAtlasInfo + +-- fallback blizzard icons (incase a plugin fails to change icon properly) +local READY_TEX = [[Interface\RaidFrame\ReadyCheck-Ready]] +local NOT_READY_TEX = [[Interface\RaidFrame\ReadyCheck-NotReady]] +local WAITING_TEX = [[Interface\RaidFrame\ReadyCheck-Waiting]] + local function OnFinished(self) local element = self:GetParent() element:Hide() @@ -56,6 +65,14 @@ local function OnFinished(self) end end +local function SetIcon(element, texture) + if C_Texture_GetAtlasInfo and C_Texture_GetAtlasInfo(texture) then + element:SetAtlas(texture) + else + element:SetTexture(texture) + end +end + local function Update(self, event) local element = self.ReadyCheckIndicator local unit = self.unit @@ -72,11 +89,11 @@ local function Update(self, event) local status = GetReadyCheckStatus(unit) if(unitExists(unit) and status) then if(status == 'ready') then - element:SetTexture(element.readyTexture) + SetIcon(element, element.readyTexture or READY_TEX) elseif(status == 'notready') then - element:SetTexture(element.notReadyTexture) + SetIcon(element, element.notReadyTexture or NOT_READY_TEX) else - element:SetTexture(element.waitingTexture) + SetIcon(element, element.waitingTexture or WAITING_TEX) end element.status = status @@ -88,7 +105,7 @@ local function Update(self, event) if(event == 'READY_CHECK_FINISHED') then if(element.status == 'waiting') then - element:SetTexture(element.notReadyTexture) + SetIcon(element, element.notReadyTexture or NOT_READY_TEX) end element.Animation:Play() @@ -127,19 +144,28 @@ local function Enable(self, unit) element.__owner = self element.ForceUpdate = ForceUpdate - element.readyTexture = element.readyTexture or _G.READY_CHECK_READY_TEXTURE - element.notReadyTexture = element.notReadyTexture or _G.READY_CHECK_NOT_READY_TEXTURE - element.waitingTexture = element.waitingTexture or _G.READY_CHECK_WAITING_TEXTURE + if not element.readyTexture then element.readyTexture = _G.READY_CHECK_READY_TEXTURE end + if not element.notReadyTexture then element.notReadyTexture = _G.READY_CHECK_NOT_READY_TEXTURE end + if not element.waitingTexture then element.waitingTexture = _G.READY_CHECK_WAITING_TEXTURE end - local AnimationGroup = element:CreateAnimationGroup() - AnimationGroup:HookScript('OnFinished', OnFinished) - element.Animation = AnimationGroup + local anim = element.Animation + if not anim then + anim = element:CreateAnimationGroup() + element.Animation = anim + end + + anim:SetScript('OnFinished', OnFinished) -- use Set to purge other scripts on reenable + + local animAlpha = anim.Alpha + if not animAlpha then + animAlpha = anim:CreateAnimation('Alpha') + anim.Alpha = animAlpha + end - local Animation = AnimationGroup:CreateAnimation('Alpha') - Animation:SetFromAlpha(1) - Animation:SetToAlpha(0) - Animation:SetDuration(element.fadeTime or 1.5) - Animation:SetStartDelay(element.finishedTime or 10) + animAlpha:SetFromAlpha(1) + animAlpha:SetToAlpha(0) + animAlpha:SetDuration(element.fadeTime or 1.5) + animAlpha:SetStartDelay(element.finishedTime or 10) self:RegisterEvent('READY_CHECK', Path, true) self:RegisterEvent('READY_CHECK_CONFIRM', Path, true) diff --git a/libs/oUF/elements/runes.lua b/libs/oUF/elements/runes.lua index 82237ab0..fe9fbc53 100644 --- a/libs/oUF/elements/runes.lua +++ b/libs/oUF/elements/runes.lua @@ -56,7 +56,7 @@ local GetRuneType = GetRuneType local UnitIsUnit = UnitIsUnit local GetTime = GetTime -local runemap = oUF.isWrath and {1, 2, 5, 6, 3, 4} or {1, 2, 3, 4, 5, 6} +local runemap = oUF.isCata and {1, 2, 5, 6, 3, 4} or {1, 2, 3, 4, 5, 6} local hasSortOrder = false local function onUpdate(self, elapsed) @@ -117,7 +117,7 @@ local function UpdateColor(self, event, runeID, alt) local element = self.Runes local rune, specType - if oUF.isWrath then -- runeID, alt + if oUF.isCata then -- runeID, alt if runeID and event == 'RUNE_TYPE_UPDATE' then rune = UpdateRuneType(element[runemap[runeID]], runeID, alt) end @@ -134,7 +134,7 @@ local function UpdateColor(self, event, runeID, alt) else for i = 1, #element do local bar = element[i] - if oUF.isWrath then + if oUF.isCata then if not bar.runeType then bar.runeType = GetRuneType(runemap[i]) end @@ -159,7 +159,11 @@ local function UpdateColor(self, event, runeID, alt) end end -local function ColorPath(self, event, ...) +local function ColorPath(self, event, arg1, ...) + if event == 'PLAYER_SPECIALIZATION_CHANGED' and arg1 ~= 'player' then + return -- ignore others + end + --[[ Override: Runes.UpdateColor(self, event, ...) Used to completely override the internal function for updating the widgets' colors. @@ -167,13 +171,13 @@ local function ColorPath(self, event, ...) * event - the event triggering the update (string) * ... - the arguments accompanying the event --]] - (self.Runes.UpdateColor or UpdateColor) (self, event, ...) + (self.Runes.UpdateColor or UpdateColor) (self, event, arg1, ...) end local function Update(self, event) local element = self.Runes - if not oUF.isWrath then + if not oUF.isCata then if element.sortOrder == 'asc' then sort(runemap, ascSort) hasSortOrder = true diff --git a/libs/oUF/elements/stagger.lua b/libs/oUF/elements/stagger.lua index da1d8926..e44b4a04 100644 --- a/libs/oUF/elements/stagger.lua +++ b/libs/oUF/elements/stagger.lua @@ -40,7 +40,6 @@ local UnitHasVehiclePlayerFrameUI = UnitHasVehiclePlayerFrameUI local UnitHealthMax = UnitHealthMax local UnitIsUnit = UnitIsUnit local UnitStagger = UnitStagger --- GLOBALS: MonkStaggerBar -- end block -- sourced from FrameXML/Constants.lua @@ -217,12 +216,6 @@ local function Enable(self, unit) element:SetStatusBarTexture([[Interface\TargetingFrame\UI-StatusBar]]) end - MonkStaggerBar:UnregisterEvent('PLAYER_ENTERING_WORLD') - MonkStaggerBar:UnregisterEvent('PLAYER_SPECIALIZATION_CHANGED') - MonkStaggerBar:UnregisterEvent('UNIT_DISPLAYPOWER') - MonkStaggerBar:UnregisterEvent('UNIT_EXITED_VEHICLE') - MonkStaggerBar:UnregisterEvent('UPDATE_VEHICLE_ACTIONBAR') - -- do not change this without taking Visibility into account element:Hide() @@ -238,12 +231,6 @@ local function Disable(self) self:UnregisterEvent('UNIT_AURA', Path) self:UnregisterEvent('UNIT_DISPLAYPOWER', VisibilityPath) self:UnregisterEvent('PLAYER_TALENT_UPDATE', VisibilityPath) - - MonkStaggerBar:RegisterEvent('PLAYER_ENTERING_WORLD') - MonkStaggerBar:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') - MonkStaggerBar:RegisterEvent('UNIT_DISPLAYPOWER') - MonkStaggerBar:RegisterEvent('UNIT_EXITED_VEHICLE') - MonkStaggerBar:RegisterEvent('UPDATE_VEHICLE_ACTIONBAR') end end diff --git a/libs/oUF/events.lua b/libs/oUF/events.lua index a5aece9b..45d63ddb 100644 --- a/libs/oUF/events.lua +++ b/libs/oUF/events.lua @@ -49,10 +49,7 @@ function Private.UpdateUnits(frame, unit, realUnit) -- we don't want to re-register unitless/shared events in case -- someone added them by hand to the unitEvents table if(not registered or unit1 and (unit1 ~= unit or unit2 ~= realUnit)) then - -- BUG: passing explicit nil units to RegisterUnitEvent - -- makes it silently fall back to RegisterEvent, using '' - -- instead of explicit nils doesn't cause this behaviour - registerUnitEvent(frame, event, unit, realUnit or '') + registerUnitEvent(frame, event, unit, realUnit) end if(resetRealUnit) then diff --git a/libs/oUF/init.lua b/libs/oUF/init.lua index 1a8e9788..189d90ef 100644 --- a/libs/oUF/init.lua +++ b/libs/oUF/init.lua @@ -2,9 +2,8 @@ local _, ns = ... ns.oUF = {} ns.oUF.Private = {} -local _, _, _, toc = GetBuildInfo() - ns.oUF.isRetail = WOW_PROJECT_ID == WOW_PROJECT_MAINLINE ns.oUF.isClassic = WOW_PROJECT_ID == WOW_PROJECT_CLASSIC -ns.oUF.isTBC = toc >= 20500 and toc < 30000 -- TODO: Wrath -ns.oUF.isWrath = toc >= 30400 and toc < 40000 -- TODO: Wrath +ns.oUF.isTBC = WOW_PROJECT_ID == WOW_PROJECT_BURNING_CRUSADE_CLASSIC +ns.oUF.isWrath = WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC +ns.oUF.isCata = WOW_PROJECT_ID == WOW_PROJECT_CATACLYSM_CLASSIC diff --git a/libs/oUF/oUF.lua b/libs/oUF/oUF.lua index e4aab984..e16c2d1a 100644 --- a/libs/oUF/oUF.lua +++ b/libs/oUF/oUF.lua @@ -1,9 +1,7 @@ local parent, ns = ... +local GetAddOnMetadata = (C_AddOns and C_AddOns.GetAddOnMetadata) or GetAddOnMetadata local global = GetAddOnMetadata(parent, 'X-oUF') -local _VERSION = '@project-version@' -if(_VERSION:find('project%-version')) then - _VERSION = 'devel' -end +local _VERSION = 'devel' local oUF = ns.oUF local Private = oUF.Private @@ -26,10 +24,7 @@ local unpack, tinsert, tremove = unpack, tinsert, tremove local next, time, wipe, type = next, time, wipe, type local select, pairs, ipairs = select, pairs, ipairs local strupper, strsplit = strupper, strsplit - -local SecureButton_GetUnit = SecureButton_GetUnit -local SecureButton_GetModifiedUnit = SecureButton_GetModifiedUnit -local GetNamePlateForUnit = C_NamePlate.GetNamePlateForUnit +local hooksecurefunc = hooksecurefunc local SecureHandlerSetFrameRef = SecureHandlerSetFrameRef local RegisterAttributeDriver = RegisterAttributeDriver @@ -38,7 +33,18 @@ local RegisterUnitWatch = RegisterUnitWatch local CreateFrame = CreateFrame local IsLoggedIn = IsLoggedIn local UnitGUID = UnitGUID -local SetCVar = SetCVar +local Mixin = Mixin + +local SecureButton_GetUnit = SecureButton_GetUnit +local SecureButton_GetModifiedUnit = SecureButton_GetModifiedUnit +local PingableType_UnitFrameMixin = PingableType_UnitFrameMixin + +local GetAuraDataByIndex = C_UnitAuras and C_UnitAuras.GetAuraDataByIndex +local UnpackAuraData = AuraUtil and AuraUtil.UnpackAuraData +local UnitAura = UnitAura + +local GetNamePlateForUnit = C_NamePlate.GetNamePlateForUnit +local SetCVar = C_CVar.SetCVar -- end local UFParent = CreateFrame('Frame', (global or parent) .. 'Parent', UIParent, 'SecureHandlerStateTemplate') @@ -170,6 +176,21 @@ for k, v in next, { return active and active[name] end, + --[[ frame:SetEnabled(enabled, asState) + * self - unit frame + * enabled - on or off + * asState - if true, the frame's "state-unitexists" attribute will be set to a boolean value denoting whether the + unit exists; if false, the frame will be shown if its unit exists, and hidden if it does not (boolean) + --]] + SetEnabled = function(self, enabled, asState) + if enabled then + RegisterUnitWatch(self, asState) + else + UnregisterUnitWatch(self) + self:Hide() + end + end, + --[[ frame:Enable(asState) Used to toggle the visibility of a unit frame based on the existence of its unit. This is a reference to `RegisterUnitWatch`. @@ -296,6 +317,11 @@ local function initObject(unit, style, styleFunc, header, ...) -- Expose the frame through oUF.objects. tinsert(objects, object) + -- add the mixin for pings + if PingableType_UnitFrameMixin then + Mixin(object, PingableType_UnitFrameMixin) + end + -- We have to force update the frames when PEW fires. -- It's also important to evaluate units before running an update -- because sometimes events that are required for unit updates end up @@ -323,11 +349,18 @@ local function initObject(unit, style, styleFunc, header, ...) object:SetAttribute('*type2', 'togglemenu') object:SetAttribute('toggleForVehicle', true) + --[[ frame.IsPingable + This boolean can be set to false to disable the frame from being pingable. Enabled by default. + --]] + --[[ Override: frame:GetContextualPingType() + Used to define which contextual ping is used for the frame. + By default this wraps `C_Ping.GetContextualPingTypeForUnit(UnitGUID(frame.unit))`. + --]] + object:SetAttribute('ping-receiver', true) + if(isEventlessUnit(objectUnit)) then oUF:HandleEventlessUnit(object) else - -- No need to enable this for eventless units. - object:SetAttribute('toggleForVehicle', true) oUF:HandleUnit(object) end else @@ -615,6 +648,8 @@ do frame:SetAttribute('*type1', 'target') frame:SetAttribute('*type2', 'togglemenu') frame:SetAttribute('oUF-guessUnit', unit) + + frame:SetAttribute('ping-receiver', true) end local body = header:GetAttribute('oUF-initialConfigFunction') @@ -785,17 +820,15 @@ function oUF:SpawnNamePlates(namePrefix, nameplateCallback, nameplateCVars) -- and because forbidden nameplates exist, we have to allow default nameplate -- driver to create, update, and remove Blizz nameplates. -- Disable only not forbidden nameplates. - _G.NamePlateDriverFrame:HookScript('OnEvent', function(_, event, unit) - if(event == 'NAME_PLATE_UNIT_ADDED' and unit) then - self:DisableBlizzard(unit) - end - end) + hooksecurefunc(_G.NamePlateDriverFrame, 'AcquireUnitFrame', oUF.DisableNamePlate) local eventHandler = CreateFrame('Frame', 'oUF_NamePlateDriver') eventHandler:RegisterEvent('NAME_PLATE_UNIT_ADDED') eventHandler:RegisterEvent('NAME_PLATE_UNIT_REMOVED') eventHandler:RegisterEvent('PLAYER_TARGET_CHANGED') + eventHandler:RegisterEvent('UNIT_MAXHEALTH') eventHandler:RegisterEvent('UNIT_FACTION') + eventHandler:RegisterEvent('UNIT_HEALTH') if(IsLoggedIn()) then if(nameplateCVars) then @@ -816,16 +849,18 @@ function oUF:SpawnNamePlates(namePrefix, nameplateCallback, nameplateCVars) end elseif(event == 'PLAYER_TARGET_CHANGED') then local nameplate = GetNamePlateForUnit('target') + local unitFrame = nameplate and nameplate.unitFrame + if(nameplateCallback) then - nameplateCallback(nameplate and nameplate.unitFrame, event, 'target') + nameplateCallback(unitFrame, event, 'target') end -- UAE is called after the callback to reduce the number of -- ForceUpdate calls layout devs have to do themselves - if(nameplate) then + if unitFrame and unitFrame.UpdateAllElements then nameplate.unitFrame:UpdateAllElements(event) end - elseif(event == 'UNIT_FACTION' and unit) then + elseif((event == 'UNIT_FACTION' or event == 'UNIT_HEALTH' or event == 'UNIT_MAXHEALTH') and unit) then local nameplate = GetNamePlateForUnit(unit) if(not nameplate) then return end @@ -858,7 +893,9 @@ function oUF:SpawnNamePlates(namePrefix, nameplateCallback, nameplateCVars) -- UAE is called after the callback to reduce the number of -- ForceUpdate calls layout devs have to do themselves - nameplate.unitFrame:UpdateAllElements(event) + if nameplate.unitFrame.UpdateAllElements then + nameplate.unitFrame:UpdateAllElements(event) + end elseif(event == 'NAME_PLATE_UNIT_REMOVED' and unit) then local nameplate = GetNamePlateForUnit(unit) if(not nameplate) then return end @@ -895,6 +932,14 @@ function oUF:AddElement(name, update, enable, disable) } end +function oUF:GetAuraData(unitToken, index, filter) + if oUF.isRetail then + return UnpackAuraData(GetAuraDataByIndex(unitToken, index, filter)) + else + return UnitAura(unitToken, index, filter) + end +end + oUF.version = _VERSION --[[ oUF.objects Array containing all unit frames created by `oUF:Spawn`. @@ -931,7 +976,7 @@ do -- ShouldSkipAuraUpdate by Blizzard (implemented and heavily modified by Simp eventFrame:RegisterEvent('PLAYER_LEAVING_WORLD') if oUF.isRetail then - eventFrame:RegisterEvent('PLAYER_SPECIALIZATION_CHANGED') + eventFrame:RegisterUnitEvent('PLAYER_SPECIALIZATION_CHANGED', 'player') end eventFrame:SetScript('OnEvent', function(_, event) diff --git a/libs/oUF/oUF_Wrath.xml b/libs/oUF/oUF_Wrath.xml index 14500e0d..7459ddcf 100644 --- a/libs/oUF/oUF_Wrath.xml +++ b/libs/oUF/oUF_Wrath.xml @@ -14,6 +14,7 @@