diff --git a/Conditionals.lua b/Conditionals.lua index 17edb81..ce676db 100644 --- a/Conditionals.lua +++ b/Conditionals.lua @@ -850,33 +850,72 @@ function CleveRoids.ValidateUnitDebuff(unit, args) return false end - -- Step 1: Search DEBUFFS first - i = (unit == "player") and 0 or 1 - while true do - if unit == "player" then - texture, stacks, spellID, remaining = CleveRoids.GetPlayerAura(i, false) - else - texture, stacks, _, spellID = UnitDebuff(unit, i) - end - if not texture then break end + -- For non-player units, use libdebuff with smart caster filtering + -- Personal debuffs (Rake, Rip, etc.) filter by "player" caster + -- Shared debuffs (Sunder, Thunder Clap, etc.) match any caster + if unit ~= "player" and CleveRoids.libdebuff then + -- Determine if we should filter by player caster + local filterCaster = nil - if (CleveRoids.hasSuperwow and args.name == SpellInfo(spellID)) - or (not CleveRoids.hasSuperwow and texture == CleveRoids.auraTextures[args.name]) then - found = true - break + -- Try to get spell ID to check if it's personal/shared + local spellID = nil + if CleveRoids.Spells and CleveRoids.Spells[args.name] then + spellID = CleveRoids.Spells[args.name].id end - i = i + 1 - end - -- Step 2: If not found, search BUFFS (overflow debuffs shown as buffs on some servers) - if not found then - i = (unit == "player") and 0 or 1 - while true do - if unit == "player" then - texture, stacks, spellID, remaining = CleveRoids.GetPlayerAura(i, true) - else - texture, stacks, spellID = UnitBuff(unit, i) + -- Check if this is a personal debuff (should filter by caster) + if spellID and CleveRoids.libdebuff.IsPersonalDebuff then + if CleveRoids.libdebuff:IsPersonalDebuff(spellID) then + filterCaster = "player" end + else + -- Unknown debuffs default to personal (safer for multi-player) + filterCaster = "player" + end + + -- Search debuff slots + i = 1 + while true do + local name, rank, tex, stk, dtype, duration, timeleft, caster = + CleveRoids.libdebuff:UnitDebuff(unit, i, filterCaster) + + if not name then break end + + if name == args.name then + found = true + texture = tex + stacks = stk + remaining = timeleft + break + end + i = i + 1 + end + + -- If not found in debuffs, check buff slots (overflow debuffs) + if not found then + i = 1 + while true do + local name, rank, tex, stk, dtype, duration, timeleft, caster = + CleveRoids.libdebuff:UnitBuff(unit, i, filterCaster) + + if not name then break end + + if name == args.name then + found = true + texture = tex + stacks = stk + remaining = timeleft + break + end + i = i + 1 + end + end + -- For player unit, use standard search (player only sees own debuffs on self) + elseif unit == "player" then + -- Search DEBUFFS first + i = 0 + while true do + texture, stacks, spellID, remaining = CleveRoids.GetPlayerAura(i, false) if not texture then break end if (CleveRoids.hasSuperwow and args.name == SpellInfo(spellID)) @@ -886,6 +925,22 @@ function CleveRoids.ValidateUnitDebuff(unit, args) end i = i + 1 end + + -- If not found, search BUFFS (overflow debuffs shown as buffs on some servers) + if not found then + i = 0 + while true do + texture, stacks, spellID, remaining = CleveRoids.GetPlayerAura(i, true) + if not texture then break end + + if (CleveRoids.hasSuperwow and args.name == SpellInfo(spellID)) + or (not CleveRoids.hasSuperwow and texture == CleveRoids.auraTextures[args.name]) then + found = true + break + end + i = i + 1 + end + end end -- Step 3: Perform conditional validation diff --git a/Core.lua b/Core.lua index a97c3a5..c952fa0 100644 --- a/Core.lua +++ b/Core.lua @@ -707,6 +707,24 @@ function CleveRoids.TestForActiveAction(actions) else actions.active.usable = nil end + + -- Check if this is a toggled buff ability (Prowl, Shadowmeld) and darken if buff is active + -- This must come AFTER all other usability checks to have final say + local spellName = string.gsub(actions.active.action, "%s*%(.-%)%s*$", "") + spellName = string.gsub(spellName, "_", " ") + + local toggledBuffAbilities = { + [CleveRoids.Localized.Spells["Prowl"]] = true, + [CleveRoids.Localized.Spells["Shadowmeld"]] = true, + } + + if toggledBuffAbilities[spellName] then + if CleveRoids.ValidatePlayerBuff(spellName) then + -- Buff is active, darken the icon like "wrong stance" (grayed out, not red) + actions.active.usable = nil + actions.active.oom = false -- Make sure we don't show red tint + end + end else actions.active.inRange = 1 actions.active.usable = 1 @@ -2816,6 +2834,30 @@ function GetActionTexture(slot) end end + -- Check if this is a toggled buff ability (Prowl, Shadowmeld) and swap icon based on buff state + -- Note: Stealth is handled above by shapeshift form logic + if a and a.spell and a.action then + local spellName = string.gsub(a.action, "%s*%(.-%)%s*$", "") + spellName = string.gsub(spellName, "_", " ") + + -- Check if this is one of our toggled buff abilities (not shapeshift forms) + local toggledAbilities = { + [CleveRoids.Localized.Spells["Prowl"]] = true, + [CleveRoids.Localized.Spells["Shadowmeld"]] = true, + } + + if toggledAbilities[spellName] then + -- Check if the buff is active + if CleveRoids.ValidatePlayerBuff(spellName) then + -- Buff is active, use the active texture from auraTextures + local activeTexture = CleveRoids.auraTextures[spellName] + if activeTexture then + texture = activeTexture + end + end + end + end + if texture then return texture end diff --git a/Init.lua b/Init.lua index 60a5bfc..ad40f2e 100644 --- a/Init.lua +++ b/Init.lua @@ -142,8 +142,9 @@ CleveRoids.spamConditions = { CleveRoids.auraTextures = { [CleveRoids.Localized.Spells["Stealth"]] = "Interface\\Icons\\Ability_Stealth", - [CleveRoids.Localized.Spells["Prowl"]] = "Interface\\Icons\\Ability_Ambush", + [CleveRoids.Localized.Spells["Prowl"]] = "Interface\\Icons\\Spell_Nature_Invisibilty", [CleveRoids.Localized.Spells["Shadowform"]] = "Interface\\Icons\\Spell_Shadow_Shadowform", + [CleveRoids.Localized.Spells["Shadowmeld"]] = "Interface\\Icons\\Spell_Nature_WispSplode", ["Seal of Wisdom"] = "Interface\\Icons\\Spell_Holy_RighteousnessAura", ["Seal of the Crusader"] = "Interface\\Icons\\Spell_Holy_HolySmite", ["Seal of Light"] = "Interface\\Icons\\Spell_Holy_HealingAura", diff --git a/Localization.lua b/Localization.lua index 39fbd8e..2550a98 100644 --- a/Localization.lua +++ b/Localization.lua @@ -49,6 +49,7 @@ if CleveRoids.Locale == "enUS" or CleveRoids.Locale == "enGB" then ["Shadowform"] = "Shadowform", ["Stealth"] = "Stealth", ["Prowl"] = "Prowl", + ["Shadowmeld"] = "Shadowmeld", ["Revenge"] = "Revenge", ["Overpower"] = "Overpower", ["Riposte"] = "Riposte", @@ -106,6 +107,7 @@ elseif CleveRoids.Locale == "deDE" then ["Shadowform"] = "Schattengestalt", ["Stealth"] = "Verstohlenheit", ["Prowl"] = "Schleichen", + ["Shadowmeld"] = "Schattenmimik", ["Revenge"] = "Rache", ["Overpower"] = "Überwältigen", ["Riposte"] = "Riposte", @@ -161,6 +163,7 @@ elseif CleveRoids.Locale == "frFR" then ["Shadowform"] = "Forme d'Ombre", ["Stealth"] = "Camouflage", ["Prowl"] = "Rôder", + ["Shadowmeld"] = "Camouflage dans l'ombre", ["Revenge"] = "Vengeance", ["Overpower"] = "Fulgurance", ["Riposte"] = "Riposte", @@ -215,6 +218,7 @@ elseif CleveRoids.Locale == "koKR" then ["Shadowform"] = "어둠의 형상", ["Stealth"] = "은신", ["Prowl"] = "숨기", + ["Shadowmeld"] = "그림자 숨기", ["Revenge"] = "복수", ["Overpower"] = "제압", ["Riposte"] = "반격", @@ -269,6 +273,7 @@ elseif CleveRoids.Locale == "zhCN" then ["Shadowform"] = "暗影形态", ["Stealth"] = "潜行", ["Prowl"] = "潜行", + ["Shadowmeld"] = "影遁", ["Revenge"] = "复仇", ["Overpower"] = "压制", ["Riposte"] = "还击", @@ -323,6 +328,7 @@ elseif CleveRoids.Locale == "zhTW" then ["Shadowform"] = "暗影形態", ["Stealth"] = "隱形", ["Prowl"] = "徘徊", + ["Shadowmeld"] = "影遁", ["Revenge"] = "復仇", ["Overpower"] = "壓倒", ["Riposte"] = "還擊", @@ -377,6 +383,7 @@ elseif CleveRoids.Locale == "ruRU" then ["Shadowform"] = "Облик Тени", ["Stealth"] = "Незаметность", ["Prowl"] = "Крадущийся зверь", + ["Shadowmeld"] = "Слияние с тенью", ["Revenge"] = "Реванш", ["Overpower"] = "Превосходство", ["Riposte"] = "Ответный удар", @@ -431,6 +438,7 @@ elseif CleveRoids.Locale == "esES" then ["Shadowform"] = "Forma de las Sombras", ["Stealth"] = "Sigilo", ["Prowl"] = "Acechar", + ["Shadowmeld"] = "Fusión con las sombras", ["Revenge"] = "Revancha", ["Overpower"] = "Abrumar", ["Riposte"] = "Estocada",