Detect bleeds authoritatively via Spell.dbc mechanics

Add a GetSpellSchool bleed check (Priority 0.5) backed by DBC SpellMechanic
data instead of damage-event learning / name patterns:
- GetSpellMechanicByID == 15 catches spell-level bleeds (Garrote, Rupture,
  Rend, Rip, Pounce, Deep Wounds).
- New ClassicAPI GetSpellEffectMechanics catches effect-level bleeds that the
  spell-level field misses -- Rake is spell-level 0 with EffectMechanic[2]=15.

Wrap C_Spell.GetSpellEffectMechanics in ClassicAPI.lua (nil-guarded so older
builds fall back to spell-level only). Verified against the client Spell.dbc.

Also drop Hemorrhage from the bleed name-pattern fallback: the DBC gives it no
bleed mechanic (physical damage), so bleed-immune mobs don't resist it -- it was
a false positive. Existing learning / split-damage / patterns remain as fallback.
This commit is contained in:
Brues
2026-07-26 15:40:26 -05:00
parent 2ce4d11698
commit 586c51b53a
2 changed files with 45 additions and 2 deletions
+13
View File
@@ -168,6 +168,19 @@ function API.GetSpellMechanicByID(spellID)
return C_Spell.GetSpellMechanicByID(spellID)
end
-- Per-effect SpellMechanic ids (Spell.dbc EffectMechanic[3]) as {m1, m2, m3},
-- or nil for an invalid spell / 0 for an effect with no mechanic. Complements
-- GetSpellMechanicByID, which only reads the spell-level Mechanic field: vanilla
-- stores some mechanics on an effect instead (e.g. Rake's bleed is effect-level,
-- so GetSpellMechanicByID returns 0 but this returns {0,15,0}). Nil-guarded so an
-- older ClassicAPI build without the function degrades gracefully.
function API.GetSpellEffectMechanics(spellID)
if type(C_Spell.GetSpellEffectMechanics) == "function" then
return C_Spell.GetSpellEffectMechanics(spellID)
end
return nil
end
--------------------------------------------------------------------------------
-- State
--------------------------------------------------------------------------------
+32 -2
View File
@@ -7515,6 +7515,26 @@ local spellSchoolCache = {}
-- 7. Tooltip scanning (player's spellbook only)
-- 8. Name pattern matching (fallback, least accurate)
-- Returns nil if school cannot be determined (not cached)
-- Authoritative bleed test from Spell.dbc mechanics. A bleed carries
-- SpellMechanic 15 either at the spell level (Garrote/Rupture/Rend/Rip/Pounce/
-- Deep Wounds) OR on an effect (Rake: spell-level 0, EffectMechanic[2]=15), so
-- both must be checked -- GetSpellMechanicByID alone misses the effect-level case.
local SPELL_MECHANIC_BLEED = 15
local function IsBleedByMechanic(spellID)
if not spellID then return false end
local API = CleveRoids.ClassicAPI
if API.GetSpellMechanicByID(spellID) == SPELL_MECHANIC_BLEED then
return true
end
local em = API.GetSpellEffectMechanics(spellID)
if em then
for i = 1, 3 do
if em[i] == SPELL_MECHANIC_BLEED then return true end
end
end
return false
end
local function GetSpellSchool(spellName, spellID)
if not spellName and not spellID then return nil end
@@ -7522,7 +7542,7 @@ local function GetSpellSchool(spellName, spellID)
local baseName = nil
if spellName then
baseName = string.gsub(spellName, "%s*%(.-%)%s*$", "")
elseif spellID and GetSpellRecField then
elseif spellID then
local fullName = C_Spell.GetSpellName(spellID)
if fullName then
baseName = string.gsub(fullName, "%s*%(.-%)%s*$", "")
@@ -7538,6 +7558,14 @@ local function GetSpellSchool(spellName, spellID)
return school
end
-- PRIORITY 0.5: DBC bleed mechanic (authoritative, proactive). Catches bleeds
-- before any damage event is seen, incl. effect-level ones like Rake, and
-- correctly excludes non-bleeds the name patterns would false-positive (e.g.
-- Hemorrhage). Only bleed is decided here; other schools fall through.
if spellID and IsBleedByMechanic(spellID) then
return "bleed"
end
-- PRIORITY 1: Use learned school from Nampower damage events (most accurate)
if spellID and CleveRoids.spellSchoolMapping[spellID] then
return CleveRoids.spellSchoolMapping[spellID]
@@ -7656,7 +7684,9 @@ local function GetSpellSchool(spellName, spellID)
-- Bleed effects (DoTs that ignore armor)
if string.find(lower, "rip") or string.find(lower, "rake") or string.find(lower, "rupture") or
string.find(lower, "garrote") or string.find(lower, "rend") or string.find(lower, "deep wound") or
string.find(lower, "hemorrhage") or string.find(lower, "pounce") then
string.find(lower, "pounce") then
-- NOTE: Hemorrhage intentionally excluded -- Spell.dbc gives it no bleed
-- mechanic (its damage is physical), so bleed-immune mobs don't resist it.
school = "bleed"
-- Arcane