mirror of
https://github.com/brues-code/SuperCleveRoidMacros.git
synced 2026-09-16 03:38:00 +00:00
fully update immunities system and force clear for version usage
This commit is contained in:
+4
-57
@@ -2147,16 +2147,8 @@ function CleveRoids.ValidatePlayerBuff(args)
|
||||
local numForms = GetNumShapeshiftForms()
|
||||
for i = 1, numForms do
|
||||
local icon, name, isActive, isCastable = GetShapeshiftFormInfo(i)
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cff00ff00[ValidatePlayerBuff]|r Form %d: name=%s, isActive=%s, searching=%s",
|
||||
i, tostring(name), tostring(isActive), searchName))
|
||||
end
|
||||
-- PERFORMANCE: Use cached lowercase to avoid per-iteration string allocation
|
||||
if name and isActive and GetLowercaseString(name) == searchName then
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ff00[ValidatePlayerBuff]|r MATCH FOUND - returning true")
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
@@ -3386,25 +3378,9 @@ CleveRoids.Keywords = {
|
||||
end,
|
||||
|
||||
nodebuff = function(conditionals)
|
||||
if CleveRoids.debug then
|
||||
local vals = conditionals.nodebuff
|
||||
local valStr = type(vals) == "table" and table.concat(vals, ", ") or tostring(vals)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff[nodebuff]|r Checking: " .. valStr .. " on " .. (conditionals.target or "target"))
|
||||
end
|
||||
local result = NegatedMulti(conditionals.nodebuff, function(v)
|
||||
local hasDebuff = CleveRoids.ValidateUnitDebuff(conditionals.target, v)
|
||||
if CleveRoids.debug then
|
||||
local vName = type(v) == "table" and (v.name or "table") or tostring(v)
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cff00ffff[nodebuff]|r ValidateUnitDebuff(%s) = %s, returning %s",
|
||||
vName, tostring(hasDebuff), tostring(not hasDebuff)))
|
||||
end
|
||||
return not hasDebuff
|
||||
return NegatedMulti(conditionals.nodebuff, function(v)
|
||||
return not CleveRoids.ValidateUnitDebuff(conditionals.target, v)
|
||||
end, conditionals, "nodebuff")
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cff00ffff[nodebuff]|r Final result: " .. tostring(result))
|
||||
end
|
||||
return result
|
||||
end,
|
||||
|
||||
mybuff = function(conditionals)
|
||||
@@ -3414,24 +3390,9 @@ CleveRoids.Keywords = {
|
||||
end,
|
||||
|
||||
nomybuff = function(conditionals)
|
||||
if CleveRoids.debug then
|
||||
local vals = conditionals.nomybuff
|
||||
local valStr = type(vals) == "table" and table.concat(vals, ", ") or tostring(vals)
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff00ff[nomybuff]|r Checking: " .. valStr)
|
||||
end
|
||||
local result = NegatedMulti(conditionals.nomybuff, function(v)
|
||||
local hasBuff = CleveRoids.ValidatePlayerBuff(v)
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cffff00ff[nomybuff]|r ValidatePlayerBuff(%s) = %s, returning %s",
|
||||
tostring(v), tostring(hasBuff), tostring(not hasBuff)))
|
||||
end
|
||||
return not hasBuff
|
||||
return NegatedMulti(conditionals.nomybuff, function(v)
|
||||
return not CleveRoids.ValidatePlayerBuff(v)
|
||||
end, conditionals, "nomybuff")
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff00ff[nomybuff]|r Final result: " .. tostring(result))
|
||||
end
|
||||
return result
|
||||
end,
|
||||
|
||||
mydebuff = function(conditionals)
|
||||
@@ -4291,25 +4252,11 @@ CleveRoids.Keywords = {
|
||||
checkValue = conditionals.action
|
||||
end
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cffff9900[noimmune]|r Checking: %s (action=%s) on %s",
|
||||
tostring(checkValue), tostring(conditionals.action), conditionals.target or "target"))
|
||||
end
|
||||
|
||||
if not checkValue then
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage("|cffff9900[noimmune]|r No checkValue, returning true")
|
||||
end
|
||||
return true -- If we can't determine spell/school, assume not immune
|
||||
end
|
||||
|
||||
local isImmune = CleveRoids.CheckImmunity(conditionals.target or "target", checkValue)
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(string.format(
|
||||
"|cffff9900[noimmune]|r CheckImmunity(%s) = %s, returning %s",
|
||||
checkValue, tostring(isImmune), tostring(not isImmune)))
|
||||
end
|
||||
return not isImmune
|
||||
end,
|
||||
|
||||
|
||||
@@ -259,12 +259,35 @@ local function PrintFeatures()
|
||||
end
|
||||
end
|
||||
|
||||
-- Immunity data version - increment this when changing immunity data format
|
||||
-- This will cause all immunity data to be reset on addon update
|
||||
CleveRoids.IMMUNITY_DATA_VERSION = 2
|
||||
|
||||
-- Call on next frame to ensure everything is loaded
|
||||
local initFrame = CreateFrame("Frame")
|
||||
initFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
|
||||
initFrame:SetScript("OnEvent", function()
|
||||
this:UnregisterAllEvents()
|
||||
|
||||
-- Check immunity data version and reset if outdated
|
||||
CleveRoidMacros = CleveRoidMacros or {}
|
||||
CleveRoids_ImmunityData = CleveRoids_ImmunityData or {}
|
||||
local savedVersion = CleveRoidMacros.immunityDataVersion or 0
|
||||
|
||||
if savedVersion < CleveRoids.IMMUNITY_DATA_VERSION then
|
||||
-- Check if there was existing data to clear
|
||||
local hadData = next(CleveRoids_ImmunityData) ~= nil
|
||||
|
||||
-- Version changed - reset all immunity data
|
||||
CleveRoids_ImmunityData = {}
|
||||
CleveRoidMacros.immunityDataVersion = CleveRoids.IMMUNITY_DATA_VERSION
|
||||
|
||||
if hadData then
|
||||
-- Show message if we actually cleared existing data
|
||||
CleveRoids.Print("|cffff9900Immunity data reset|r - addon updated to data version " .. CleveRoids.IMMUNITY_DATA_VERSION)
|
||||
end
|
||||
end
|
||||
|
||||
-- Initialize NampowerAPI if available
|
||||
if CleveRoids.NampowerAPI then
|
||||
local API = CleveRoids.NampowerAPI
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
## Author: DWG, _brain, Torio, yani9o, Avitasia
|
||||
## Title: [Super]CleveRoidMacros
|
||||
## Notes: /cleveroid for settings
|
||||
## Version: 1.7
|
||||
## Version: 1.8
|
||||
## OptionalDeps: ClassicFocus, FocusFrame, pfUI, SuperMacro, Bongos_ActionBar
|
||||
## SavedVariables: CleveRoidMacros, CleveRoids_LearnedDurations, CleveRoids_AuraTextures, CleveRoids_ImmunityData, CleveRoids_ComboDurations, CleveRoids_SpellSchools
|
||||
Localization.lua
|
||||
|
||||
+131
-25
@@ -1787,6 +1787,34 @@ lib.pendingPersonalDebuffs = lib.pendingPersonalDebuffs or {}
|
||||
-- Format: { [index] = { timestamp = GetTime(), targetGUID = guid, targetName = name, spellID = id, ccType = "stun" } }
|
||||
lib.pendingCCDebuffs = lib.pendingCCDebuffs or {}
|
||||
|
||||
-- Spells with HIDDEN CC debuffs - these apply CC effects but don't show visible debuffs
|
||||
-- Skip debuff-based immunity verification for these (only trust combat log "immune" messages)
|
||||
-- Pounce stun is hidden - the target is stunned but no debuff icon appears
|
||||
lib.hiddenCCSpells = {
|
||||
[9005] = true, -- Pounce (Rank 1)
|
||||
[9823] = true, -- Pounce (Rank 2)
|
||||
[9827] = true, -- Pounce (Rank 3)
|
||||
}
|
||||
|
||||
-- Reverse lookup: spell NAME -> immunity type for combat log tracking
|
||||
-- Used by ParseAfflictedCombatLog to confirm spells landed via "afflicted by" messages
|
||||
-- Format: { ["SpellName"] = { type = "cc" or "school", value = "stun" or "bleed" } }
|
||||
lib.trackedAfflictions = {
|
||||
-- Hidden CC effects (no visible debuff, must use combat log)
|
||||
["Pounce"] = { type = "cc", value = "stun" },
|
||||
|
||||
-- Bleed effects (visible debuff, but combat log is more reliable)
|
||||
["Pounce Bleed"] = { type = "school", value = "bleed" },
|
||||
["Rake"] = { type = "school", value = "bleed" },
|
||||
["Rip"] = { type = "school", value = "bleed" },
|
||||
["Lacerate"] = { type = "school", value = "bleed" },
|
||||
["Garrote"] = { type = "school", value = "bleed" },
|
||||
["Rupture"] = { type = "school", value = "bleed" },
|
||||
["Deep Wound"] = { type = "school", value = "bleed" },
|
||||
["Deep Wounds"] = { type = "school", value = "bleed" },
|
||||
["Rend"] = { type = "school", value = "bleed" },
|
||||
}
|
||||
|
||||
-- Function to apply Carnage refresh (exposed for ComboPointTracker to call on proc detection)
|
||||
function lib.ApplyCarnageRefresh(targetGUID, targetName, biteSpellID)
|
||||
if CleveRoids.debug then
|
||||
@@ -2515,32 +2543,55 @@ ev:SetScript("OnEvent", function()
|
||||
-- CC IMMUNITY TRACKING: Check if this spell is a CC spell and track for immunity verification
|
||||
-- Uses the original spellID (not trackingSpellID) to detect CC type
|
||||
local ccType = CleveRoids.GetSpellCCType and CleveRoids.GetSpellCCType(spellID)
|
||||
if ccType then
|
||||
local spellName = SpellInfo(spellID)
|
||||
-- Get target name from cache or current target
|
||||
local ccTargetName = lib.guidToName[targetGUID]
|
||||
if not ccTargetName then
|
||||
local _, currentTargetGUID = UnitExists("target")
|
||||
currentTargetGUID = CleveRoids.NormalizeGUID(currentTargetGUID)
|
||||
if currentTargetGUID == targetGUID then
|
||||
ccTargetName = UnitName("target")
|
||||
lib.guidToName[targetGUID] = ccTargetName
|
||||
end
|
||||
end
|
||||
table.insert(lib.pendingCCDebuffs, {
|
||||
timestamp = GetTime(),
|
||||
targetGUID = targetGUID,
|
||||
targetName = ccTargetName,
|
||||
spellID = spellID,
|
||||
spellName = spellName,
|
||||
ccType = ccType,
|
||||
})
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[CC Track]|r Tracking %s (%s) on %s for immunity verification",
|
||||
spellName or "Unknown", ccType, ccTargetName or "Unknown")
|
||||
)
|
||||
-- Debug: Show what GetSpellCCType returns for this spell
|
||||
if CleveRoids.debug then
|
||||
local spellNameDebug = SpellInfo(spellID) or "Unknown"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffaaaaaa[CC Check]|r %s (ID:%d) → ccType: %s",
|
||||
spellNameDebug, spellID, ccType or "nil")
|
||||
)
|
||||
end
|
||||
|
||||
if ccType then
|
||||
-- Skip debuff-based verification for spells with hidden CC effects (e.g., Pounce stun)
|
||||
-- These spells apply CC but don't show visible debuffs, so verification always fails
|
||||
-- Only trust combat log "immune" messages for these spells
|
||||
if lib.hiddenCCSpells and lib.hiddenCCSpells[spellID] then
|
||||
if CleveRoids.debug then
|
||||
local spellName = SpellInfo(spellID) or "Unknown"
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cffff6600[CC Skip]|r %s (%s) has hidden debuff - skipping verification",
|
||||
spellName, ccType)
|
||||
)
|
||||
end
|
||||
else
|
||||
local spellName = SpellInfo(spellID)
|
||||
-- Get target name from cache or current target
|
||||
local ccTargetName = lib.guidToName[targetGUID]
|
||||
if not ccTargetName then
|
||||
local _, currentTargetGUID = UnitExists("target")
|
||||
currentTargetGUID = CleveRoids.NormalizeGUID(currentTargetGUID)
|
||||
if currentTargetGUID == targetGUID then
|
||||
ccTargetName = UnitName("target")
|
||||
lib.guidToName[targetGUID] = ccTargetName
|
||||
end
|
||||
end
|
||||
table.insert(lib.pendingCCDebuffs, {
|
||||
timestamp = GetTime(),
|
||||
targetGUID = targetGUID,
|
||||
targetName = ccTargetName,
|
||||
spellID = spellID,
|
||||
spellName = spellName,
|
||||
ccType = ccType,
|
||||
})
|
||||
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[CC Track]|r Tracking %s (%s) on %s for immunity verification",
|
||||
spellName or "Unknown", ccType, ccTargetName or "Unknown")
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -4929,6 +4980,54 @@ local function ParseImmunityCombatLog()
|
||||
end
|
||||
end
|
||||
|
||||
-- Combat log parser for "afflicted by" messages
|
||||
-- Tracks when CC effects (like Pounce stun) and bleeds successfully land
|
||||
-- This confirms the effect worked and removes any false immunity records
|
||||
local function ParseAfflictedCombatLog()
|
||||
local message = arg1
|
||||
if not message then return end
|
||||
|
||||
-- Quick check: must contain "afflicted by"
|
||||
if not string.find(message, "afflicted by") then return end
|
||||
|
||||
-- Pattern: "X is afflicted by Y" or "X is afflicted by Y (N)."
|
||||
-- Handle both with and without trailing period
|
||||
local _, _, targetName, spellName = string.find(message, "^(.-)%s+is afflicted by%s+(.+)")
|
||||
if not targetName or not spellName then return end
|
||||
|
||||
-- Remove trailing period if present
|
||||
spellName = string.gsub(spellName, "%.$", "")
|
||||
-- Remove stack count like "(1)" from spell name
|
||||
spellName = string.gsub(spellName, "%s*%(%d+%)$", "")
|
||||
|
||||
-- Check if this is a tracked spell (CC or bleed)
|
||||
local affliction = lib.trackedAfflictions and lib.trackedAfflictions[spellName]
|
||||
if not affliction then
|
||||
return -- Not a tracked spell, ignore
|
||||
end
|
||||
|
||||
if affliction.type == "cc" then
|
||||
-- CC effect landed - remove any false CC immunity
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[CC Landed]|r %s afflicted by %s (%s)",
|
||||
targetName, spellName, affliction.value)
|
||||
)
|
||||
end
|
||||
RemoveCCImmunity(targetName, affliction.value)
|
||||
|
||||
elseif affliction.type == "school" then
|
||||
-- School/bleed effect landed - remove any false school immunity
|
||||
if CleveRoids.debug then
|
||||
DEFAULT_CHAT_FRAME:AddMessage(
|
||||
string.format("|cff00ff00[Bleed Landed]|r %s afflicted by %s (%s)",
|
||||
targetName, spellName, affliction.value)
|
||||
)
|
||||
end
|
||||
RemoveSpellImmunity(targetName, affliction.value)
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if a unit is immune to a spell, damage school, or CC type
|
||||
-- Supports: CheckImmunity(unitId, "Flame Shock") or CheckImmunity(unitId, "fire") or CheckImmunity(unitId, "stun")
|
||||
function CleveRoids.CheckImmunity(unitId, spellOrSchool)
|
||||
@@ -5315,14 +5414,21 @@ end
|
||||
-- PERFORMANCE: Only use RAW_COMBATLOG and SPELL_FAILURE to avoid spam from damage events
|
||||
-- CHAT_MSG_SPELL_*_DAMAGE fires on EVERY hit/resist (100+ times/second in combat)
|
||||
-- EXCEPTION: CHAT_MSG_SPELL_SELF_DAMAGE is needed for immunity detection (includes "is immune" messages)
|
||||
-- EXCEPTION: CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE is needed for "afflicted by" detection (hidden CC spells)
|
||||
local immunityFrame = CreateFrame("Frame", "CleveRoidsImmunityFrame")
|
||||
immunityFrame:RegisterEvent("RAW_COMBATLOG")
|
||||
immunityFrame:RegisterEvent("CHAT_MSG_SPELL_FAILURE")
|
||||
immunityFrame:RegisterEvent("CHAT_MSG_SPELL_SELF_DAMAGE")
|
||||
immunityFrame:RegisterEvent("CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE")
|
||||
immunityFrame:SetScript("OnEvent", function()
|
||||
if event == "RAW_COMBATLOG" or event == "CHAT_MSG_SPELL_FAILURE" or event == "CHAT_MSG_SPELL_SELF_DAMAGE" then
|
||||
ParseImmunityCombatLog()
|
||||
end
|
||||
-- Check for "afflicted by" messages for hidden CC spells (e.g., Pounce stun)
|
||||
-- These come through RAW_COMBATLOG and PERIODIC_CREATURE_DAMAGE
|
||||
if event == "RAW_COMBATLOG" or event == "CHAT_MSG_SPELL_PERIODIC_CREATURE_DAMAGE" then
|
||||
ParseAfflictedCombatLog()
|
||||
end
|
||||
end)
|
||||
|
||||
-- ============================================================================
|
||||
|
||||
Reference in New Issue
Block a user