2 Commits
Author SHA1 Message Date
Brues 496979f486 Add BigWigs packager config to bundle both addons in one zip
Add .pkgmeta (package-as MikScrollingBattleText, move-folders pulling both addon folders to top-level siblings) and a tag-triggered GitHub Actions workflow using BigWigsMods/packager that attaches the single zip to an auto-created GitHub release. Switch both TOCs' Version to the @project-version@ substitution token so the packager stamps the git tag version.
2026-06-23 13:26:13 -05:00
Brues a5e46a62b8 Change nampower school table to sequential index keys
nampowerSchoolToType now uses sequential keys (0=Physical, then implicit 1-6 for Holy/Fire/Nature/Frost/Shadow/Arcane) instead of the previous power-of-two bitmask keys (0,1,2,4,8,16,32).
2026-06-23 13:25:13 -05:00
8 changed files with 11263 additions and 543 deletions
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+172 -72
View File
@@ -1,4 +1,4 @@
------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------
-- Title: Mik's Scrolling Battle Text -- Title: Mik's Scrolling Battle Text
-- Author: Mik -- Author: Mik
-- Maintainer: Athene -- Maintainer: Athene
@@ -133,22 +133,36 @@ NO_ICON_CACHE = {}
-- Cache for spellId-based icon lookups (bypasses Babble-Spell and tooltip scanning). -- Cache for spellId-based icon lookups (bypasses Babble-Spell and tooltip scanning).
local spellIdIconCache = {} local spellIdIconCache = {}
-- Babble-Spell pour les icones des spells de classe
local BS = AceLibrary("Babble-Spell-2.2")
-- Damage type → color prefix lookup (lazily initialized after globals are available).
local damageTypeColors
local function GetDamageTypeColor(dt)
if not damageTypeColors then
damageTypeColors = {
[SPELL_SCHOOL1_CAP] = "\124cffF6F99E\124h",
[SPELL_SCHOOL2_CAP] = "\124cffFF4444\124h",
[SPELL_SCHOOL3_CAP] = "\124cff44FF44\124h",
[SPELL_SCHOOL4_CAP] = "\124cff4488FF\124h",
[SPELL_SCHOOL5_CAP] = "\124cff6600CC\124h",
[SPELL_SCHOOL6_CAP] = "\124cffCC66FF\124h",
["Inconnu"] = "\124cffCC66FF\124h",
}
end
return damageTypeColors[dt]
end
-- Damage type → {r, g, b} float lookup for SetTextColor (lazily initialized). -- Damage type → {r, g, b} float lookup for SetTextColor (lazily initialized).
local damageTypeFontColors local damageTypeFontColors
local function GetDamageTypeFontColor(dt) local function GetDamageTypeFontColor(dt)
if not damageTypeFontColors then if not damageTypeFontColors then
local function CreateSpellColor(r, g, b)
local color = CreateColor(r, g, b)
color.colorStr = color:GenerateHexColorMarkup() .. "\124h"
return color
end
damageTypeFontColors = { damageTypeFontColors = {
[SPELL_SCHOOL1_CAP] = CreateSpellColor(0.965, 0.976, 0.620), -- Holy [SPELL_SCHOOL2_CAP] = { r=1.0, g=0.27, b=0.27 }, -- Fire (red)
[SPELL_SCHOOL2_CAP] = CreateSpellColor(0.933, 0.490, 0.501), -- Fire [SPELL_SCHOOL3_CAP] = { r=0.27, g=1.0, b=0.27 }, -- Nature (green)
[SPELL_SCHOOL3_CAP] = CreateSpellColor(0.631, 0.858, 0.396), -- Nature [SPELL_SCHOOL4_CAP] = { r=0.27, g=0.53, b=1.0 }, -- Frost (blue)
[SPELL_SCHOOL4_CAP] = CreateSpellColor(0.462, 0.792, 0.929), -- Frost [SPELL_SCHOOL5_CAP] = { r=0.4, g=0.0, b=0.8 }, -- Shadow (deep purple)
[SPELL_SCHOOL5_CAP] = CreateSpellColor(0.356, 0.290, 0.596), -- Shadow [SPELL_SCHOOL6_CAP] = { r=0.8, g=0.4, b=1.0 }, -- Arcane (purple/pink)
[SPELL_SCHOOL6_CAP] = CreateSpellColor(0.956, 0.658, 0.894), -- Arcane
} }
end end
return damageTypeFontColors[dt] return damageTypeFontColors[dt]
@@ -524,6 +538,13 @@ function MikSBT.Init()
-- Register the triggers with the combat event helper. -- Register the triggers with the combat event helper.
MikSBT.RegisterTriggers(); MikSBT.RegisterTriggers();
-- Enable Nampower CVars for enhanced combat events when available.
if MikCEH.hasNampower then
pcall(SetCVar, "NP_EnableAutoAttackEvents", "1")
pcall(SetCVar, "NP_EnableSpellHealEvents", "1")
pcall(SetCVar, "NP_EnableSpellEnergizeEvents", "1")
end
-- Disable or enable the mod depending on the saved setting. -- Disable or enable the mod depending on the saved setting.
MikSBT.SetOptionUserDisabled(MikSBT_Save.UserDisabled) MikSBT.SetOptionUserDisabled(MikSBT_Save.UserDisabled)
end end
@@ -1124,14 +1145,14 @@ function MikSBT.FormatEventText(animationEvent)
end end
outputString = string_gsub(outputString, "-%%a", "\124cffff0000\124h-\124h\124r%%a"); outputString = string_gsub(outputString, "-%%a", "\124cffff0000\124h-\124h\124r%%a");
if animationEvent.DamageType then if animationEvent.DamageType then
local color = GetDamageTypeFontColor(animationEvent.DamageType) local color = GetDamageTypeColor(animationEvent.DamageType)
if color then if color then
outputString = string_gsub(outputString, "%%a", color.colorStr .. "%%a\124h\124r") outputString = string_gsub(outputString, "%%a", color .. "%%a\124h\124r")
end end
end end
-- Substitute amount. -- Substitute amount.
if (animationEvent.Amount ~= nil) then if (animationEvent.Amount ~= nil) then
-- Check if there is overheal info -- Check if there is overheal info
@@ -1322,7 +1343,7 @@ function MikSBT.UpdateProfiles()
if (profile.CreationVersion < 4.1) then if (profile.CreationVersion < 4.1) then
if profile.Triggers.MSBT_TRIGGER_WINDFURY then -- Fix Windfury Trigger if profile.Triggers.MSBT_TRIGGER_WINDFURY then -- Fix Windfury Trigger
profile.Triggers.MSBT_TRIGGER_WINDFURY.TriggerSettings.SearchPatterns[1] = string.format(AURAADDEDSELFHELPFUL, string_gsub(C_Spell.GetSpellName(8512) or "", "-", "%%-")) -- Windfury Totem (ID verified vs Spell.dbc) profile.Triggers.MSBT_TRIGGER_WINDFURY.TriggerSettings.SearchPatterns[1] = string.format(AURAADDEDSELFHELPFUL, string_gsub(BS["Windfury Totem"], "-", "%%-"))
end end
if profile.Triggers.MSBT_TRIGGER_HAND_OF_JUSTICE then -- Delete Hand of Justice Trigger if profile.Triggers.MSBT_TRIGGER_HAND_OF_JUSTICE then -- Delete Hand of Justice Trigger
@@ -1396,7 +1417,7 @@ function MikSBT.UpdateProfiles()
end end
if (profile.CreationVersion < 4.6) then if (profile.CreationVersion < 4.6) then
-- Add missing incoming evade/reflect event settings (needed for combat log miss events). -- Add missing incoming evade/reflect event settings (needed for Nampower events).
local incomingMissEvents = { local incomingMissEvents = {
"MSBT_EVENTTYPE_INCOMING_EVADE", "MSBT_EVENTTYPE_INCOMING_EVADE",
"MSBT_EVENTTYPE_INCOMING_SPELL_EVADE", "MSBT_EVENTTYPE_INCOMING_SPELL_EVADE",
@@ -1765,7 +1786,9 @@ function MikSBT.AddAnimation(animationEvent)
if animationEvent.DamageType and animationEvent.EventType then if animationEvent.DamageType and animationEvent.EventType then
local dtColor = GetDamageTypeFontColor(animationEvent.DamageType) local dtColor = GetDamageTypeFontColor(animationEvent.DamageType)
if dtColor then if dtColor then
animDisplayInfo.ColorR, animDisplayInfo.ColorG, animDisplayInfo.ColorB = dtColor:GetRGB() animDisplayInfo.ColorR = dtColor.r
animDisplayInfo.ColorG = dtColor.g
animDisplayInfo.ColorB = dtColor.b
end end
end end
@@ -1831,36 +1854,57 @@ function MikSBT.AddAnimation(animationEvent)
local sid = animationEvent.SpellId local sid = animationEvent.SpellId
if spellIdIconCache[sid] then if spellIdIconCache[sid] then
texture = spellIdIconCache[sid] texture = spellIdIconCache[sid]
elseif GetSpellInfo then elseif MikCEH.hasSuperWoW and SpellInfo then
local ok, _, _, tex = pcall(GetSpellInfo, sid) local ok, _, _, tex = pcall(SpellInfo, sid)
if ok and tex then texture = tex; spellIdIconCache[sid] = tex end if ok and tex then texture = tex; spellIdIconCache[sid] = tex end
elseif MikCEH.hasNampower and GetSpellRecField and GetSpellIconTexture then
local ok, iconId = pcall(GetSpellRecField, sid, "spellIconID")
if ok and iconId then
local ok2, tex = pcall(GetSpellIconTexture, iconId)
if ok2 and tex then texture = tex; spellIdIconCache[sid] = tex end
end
end end
end end
if animationEvent.EffectName then if animationEvent.EffectName then
local name = string_gsub(animationEvent.EffectName, " %(%d+%)", "") local name = string_gsub(animationEvent.EffectName, " %(%d+%)", "")
local lowerName = strlower(name)
-- DEFAULT_CHAT_FRAME:AddMessage(animationEvent.EffectName) -- DEFAULT_CHAT_FRAME:AddMessage(animationEvent.EffectName)
-- DEFAULT_CHAT_FRAME:AddMessage(name) -- DEFAULT_CHAT_FRAME:AddMessage(name)
if ICON_CACHE[lowerName] then -- texture = BS:GetSpellIcon(name)
texture = ICON_CACHE[lowerName] if ICON_CACHE[strlower(name)] then
elseif not texture and MikSBT.GetAuraIcon(name) then texture = ICON_CACHE[strlower(name)]
texture = MikSBT.GetAuraIcon(name) elseif not texture and MikSBT.FindBuff(name) then
ICON_CACHE[lowerName] = texture local bufftype,index,_ = MikSBT.FindBuff(name)
elseif not texture and GetSpellInfo then local icon
local ok, sid = pcall(function(n) return select(10, GetSpellInfo(n)) end, name) if bufftype == "buff" then
if ok and sid and sid ~= 0 then icon = UnitBuff("player", index)
local ok2, _, _, tex = pcall(GetSpellInfo, sid) ICON_CACHE[strlower(name)] = icon
if ok2 and tex then texture = tex; ICON_CACHE[lowerName] = tex end texture = icon
end elseif bufftype == "debuff" then
elseif not texture then icon = UnitDebuff("player", index)
local itemIcon = MikSBT.FindItemIcon(lowerName) ICON_CACHE[strlower(name)] = icon
if itemIcon then texture = icon
texture = itemIcon
ICON_CACHE[lowerName] = itemIcon
else else
NO_ICON_CACHE[lowerName] = 1 texture = nil
NO_ICON_CACHE[strlower(name)] = 1
end end
elseif not texture and MikCEH.hasNampower and GetSpellIdForName then
local ok, sid = pcall(GetSpellIdForName, name)
if ok and sid and sid ~= 0 then
local ok2, iconId = pcall(GetSpellRecField, sid, "spellIconID")
if ok2 and iconId then
local ok3, tex = pcall(GetSpellIconTexture, iconId)
if ok3 and tex then texture = tex; ICON_CACHE[strlower(name)] = tex end
end
end
elseif not texture and BS and BS.GetSpellIcon and BS:GetSpellIcon(name) then
texture = BS:GetSpellIcon(name)
elseif not texture and MikSBT.FindItemIcon(name) then
texture = MikSBT.FindItemIcon(name)
ICON_CACHE[strlower(name)] = MikSBT.FindItemIcon(name)
elseif not texture then
texture = nil
NO_ICON_CACHE[strlower(name)] = 1
end end
end end
@@ -1919,50 +1963,106 @@ function ItemLinkToName(link)
end end
function MikSBT.FindItemIcon(item) function MikSBT.FindItemIcon(item)
if ( not item ) then return end if ( not item ) then return; end
item = string.lower(item); item = string.lower(item);
for slot = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED + 4 do local link;
local itemLocation = ItemLocation:CreateFromEquipmentSlot(slot) for i = 1,23 do
local itemName = C_Item.GetItemName(itemLocation) link = GetInventoryItemLink("player",i);
if itemName and item == string.lower(itemName) then if ( link ) then
return C_Item.GetItemIcon(itemLocation) if ( item == string.lower(ItemLinkToName(link)) )then
end return i, nil, GetInventoryItemTexture('player', i), GetInventoryItemCount('player', i);
end
for i = 0, NUM_BAG_FRAMES do
for j = 1, GetContainerNumSlots(i) do
local itemName = C_Item.GetItemName(ItemLocation:CreateFromBagAndSlot(i,j))
if itemName and item == string.lower(itemName) then
return (GetContainerItemInfo(i,j))
end end
end end
end end
local count, bag, slot, texture;
for i = 0,NUM_BAG_FRAMES do
for j = 1,MAX_CONTAINER_ITEMS do
link = GetContainerItemLink(i,j);
if ( link ) then
if ( item == string.lower(ItemLinkToName(link))) then
bag, slot = i, j;
texture, count = GetContainerItemInfo(i,j);
end
end
end
end
return texture;
end end
-- ********************************************************************************** -- **********************************************************************************
-- Returns the icon for an active buff/debuff or temporary weapon enchant whose -- This function return the buff texture based on
-- name matches, or nil. Uses ClassicAPI (C_UnitAuras / C_Item) instead of the old -- it's name.
-- tooltip-scanning approach.
-- ********************************************************************************** -- **********************************************************************************
function MikSBT.GetAuraIcon(name, unit) function MikSBT.FindBuff( obuff, unit, item)
unit = unit or "player"; local buff=strlower(obuff);
-- Buffs and debuffs (helpful then harmful) -- AuraData carries the icon directly. local tooltip=MSBT_Tooltip;
local aura = C_UnitAuras.GetAuraDataBySpellName(unit, name); local textleft1=getglobal(tooltip:GetName().."TextLeft1");
if ( aura and aura.icon ) then return aura.icon end if ( not unit ) then
unit ='player';
-- Temporary weapon enchant (oils, poisons, imbues) matching this name.
local hasMain, _, _, mainID, hasOff, _, _, offID = C_Item.GetWeaponEnchantInfo();
if ( hasMain and mainID ) then
local info = C_Item.GetEnchantInfo(mainID);
if ( info and info.name == name and info.spellID ) then
return C_Spell.GetSpellTexture(info.spellID);
end
end end
if ( hasOff and offID ) then local my, me, mc, oy, oe, oc = GetWeaponEnchantInfo();
local info = C_Item.GetEnchantInfo(offID); if ( my ) then
if ( info and info.name == name and info.spellID ) then tooltip:SetOwner(UIParent, "ANCHOR_NONE");
return C_Spell.GetSpellTexture(info.spellID); tooltip:SetInventoryItem( unit, 16);
for i=1, 23 do
local text = getglobal("MSBT_TooltipTextLeft"..i):GetText();
if ( not text ) then
break;
elseif (text and strlower(text) == buff) then
tooltip:Hide();
return "main",me, mc;
end
end end
tooltip:Hide();
elseif ( oy ) then
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
tooltip:SetInventoryItem( unit, 17);
for i=1, 23 do
local text = getglobal("MSBT_TooltipTextLeft"..i):GetText();
if ( not text ) then
break;
elseif (text and strlower(text) == buff) then
tooltip:Hide();
return "off", oe, oc;
end
end
tooltip:Hide();
end end
if ( item ) then return end
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
tooltip:SetTrackingSpell();
local b = textleft1:GetText();
if ( b and strlower(b) == buff ) then
tooltip:Hide();
return "track",b;
end
local c=nil;
for i=1, 32 do
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
tooltip:SetUnitBuff(unit, i);
b = textleft1:GetText();
tooltip:Hide();
if ( b and strlower(b) == buff ) then
return "buff", i, b;
elseif ( c==b ) then
break;
end
--c = b;
end
c=nil;
for i=1, 16 do
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
tooltip:SetUnitDebuff(unit, i);
b = textleft1:GetText();
tooltip:Hide();
if ( b and strlower(b) == buff ) then
return "debuff", i, b;
elseif ( c==b) then
break;
end
--c = b;
end
tooltip:Hide();
end end
-- ********************************************************************************** -- **********************************************************************************
@@ -3,12 +3,12 @@
## Title: Mik's Scrolling Battle Text ## Title: Mik's Scrolling Battle Text
## Notes: Scrolls battle information around the character model. ## Notes: Scrolls battle information around the character model.
## Notes-ruRU: Прокрутка информации боя вокруг модели персонажа. ## Notes-ruRU: Прокрутка информации боя вокруг модели персонажа.
## Dependencies: !!!ClassicAPI
## OptionalDeps: SW_FixLogStrings ## OptionalDeps: SW_FixLogStrings
## SavedVariables: MikSBT_Save ## SavedVariables: MikSBT_Save
Libs\AceLibrary\AceLibrary.lua Libs\AceLibrary\AceLibrary.lua
Libs\AceLocale-2.2\AceLocale-2.2.lua Libs\AceLocale-2.2\AceLocale-2.2.lua
Libs\BabbleSpell-2.2\Babble-Spell-2.2.lua
MikScrollingBattleText-enUS.lua MikScrollingBattleText-enUS.lua
MikScrollingBattleText-frFR.lua MikScrollingBattleText-frFR.lua
@@ -11,6 +11,15 @@
</Scripts> </Scripts>
</Frame> </Frame>
<!-- Tooltip -->
<GameTooltip name="MSBT_Tooltip" frameStrata="TOOLTIP" hidden="true" parent="UIParent" inherits="GameTooltipTemplate">
<Scripts>
<OnLoad>
this:SetOwner(WorldFrame, "ANCHOR_NONE");
</OnLoad>
</Scripts>
</GameTooltip>
<!-- Incoming Scroll Area --> <!-- Incoming Scroll Area -->
<Frame name="MSBTFrameIncoming" toplevel="true" enableMouse="false" parent="UIParent" frameStrata="HIGH" hidden="true"> <Frame name="MSBTFrameIncoming" toplevel="true" enableMouse="false" parent="UIParent" frameStrata="HIGH" hidden="true">
<Size> <Size>
+13 -17
View File
@@ -18,12 +18,9 @@ MikSBT.WINDOW_TITLE = "Mik's Scrolling Battle Text " .. MikSBT.VERSION_STRING ..
MikSBT.COMMAND = "/msbt"; MikSBT.COMMAND = "/msbt";
local BS = AceLibrary("Babble-Spell-2.2")
local L = AceLibrary("AceLocale-2.2"):new(MikSBT.MOD_NAME) local L = AceLibrary("AceLocale-2.2"):new(MikSBT.MOD_NAME)
-- Resolves a spell's localized name from its ID via ClassicAPI (C_Spell), replacing
-- the old Babble-Spell localization library. Any rank's spell ID yields the same name.
local function SpellName(id) return C_Spell.GetSpellName(id) or "" end
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
-- English (Default) -- English (Default)
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
@@ -129,7 +126,6 @@ MikSBT.AVAILABLE_FONTS = {
[30] = {Name="PT-Sans-Narrow-Regular", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\PT-Sans-Narrow-Regular.ttf"}, [30] = {Name="PT-Sans-Narrow-Regular", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\PT-Sans-Narrow-Regular.ttf"},
[31] = {Name="Simhei", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\simhei.ttf"}, [31] = {Name="Simhei", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\simhei.ttf"},
[32] = {Name="Archangelsk", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\archangelsk.ttf"}, [32] = {Name="Archangelsk", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\archangelsk.ttf"},
[32] = {Name="Numen", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\Numen.ttf"},
}; };
end end
@@ -209,7 +205,7 @@ MikSBT.DEFAULT_CONFIG = {
CreationVersion = MikSBT.VERSION_NUMBER, CreationVersion = MikSBT.VERSION_NUMBER,
ShowPartialEffects = true, ShowPartialEffects = true,
ShowOverheals = true, ShowOverheals = true,
ShowGameDamage = false, ShowGameDamage = true,
UseStickyCrits = true, UseStickyCrits = true,
ShowAllManaGains = false, ShowAllManaGains = false,
LowHealthSound = true, LowHealthSound = true,
@@ -1138,7 +1134,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_EXECUTE = { MSBT_TRIGGER_EXECUTE = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(5308).."!", -- Execute Message = BS["Execute"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1155,7 +1151,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_HAMMER_OF_WRATH = { MSBT_TRIGGER_HAMMER_OF_WRATH = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(24275).."!", -- Hammer of Wrath Message = BS["Hammer of Wrath"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1172,7 +1168,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_COUNTER_ATTACK = { MSBT_TRIGGER_COUNTER_ATTACK = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(19306).."!", -- Counterattack Message = BS["Counterattack"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1191,7 +1187,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_MONGOOSE_BITE = { MSBT_TRIGGER_MONGOOSE_BITE = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(1495).."!", -- Mongoose Bite Message = BS["Mongoose Bite"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1210,7 +1206,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_CLEARCAST = { MSBT_TRIGGER_CLEARCAST = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(16246).."!", -- Clearcasting Message = BS["Clearcasting"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1221,14 +1217,14 @@ MikSBT.DEFAULT_CONFIG = {
Classes = {MAGE=true,SHAMAN=true}, Classes = {MAGE=true,SHAMAN=true},
TriggerType = 6, TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, SpellName(16246))}, -- Clearcasting (ID verified vs Spell.dbc) SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, BS["Clearcasting"])},
}, },
Texture = "Interface\\Icons\\spell_shadow_manaburn" Texture = "Interface\\Icons\\spell_shadow_manaburn"
}, },
MSBT_TRIGGER_RIPOSTE = { MSBT_TRIGGER_RIPOSTE = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(14251).."!", -- Riposte Message = BS["Riposte"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
@@ -1257,14 +1253,14 @@ MikSBT.DEFAULT_CONFIG = {
TriggerSettings = { TriggerSettings = {
TriggerType = 6, TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, string.gsub(SpellName(8512), "-", "%%-"))}, -- Windfury Totem (ID verified vs Spell.dbc). "Vous gagnez Totem Furie-des-vents" -- escape char ! SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, string.gsub(BS["Windfury Totem"], "-", "%%-"))}, --"Vous gagnez Totem Furie-des-vents" -- escape char !
}, },
Texture = "Interface\\Icons\\spell_nature_cyclone" Texture = "Interface\\Icons\\spell_nature_cyclone"
}, },
MSBT_TRIGGER_NIGHTFALL = { MSBT_TRIGGER_NIGHTFALL = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(18094).."!", -- Nightfall (talent) Message = BS["Nightfall"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=0.709, g=0, b=0.709}, Color = {r=0.709, g=0, b=0.709},
@@ -1275,14 +1271,14 @@ MikSBT.DEFAULT_CONFIG = {
Classes = {WARLOCK=true}, Classes = {WARLOCK=true},
TriggerType = 6, TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"}, TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, SpellName(17941))}, -- Shadow Trance (ID verified vs Spell.dbc) SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, BS["Shadow Trance"])},
}, },
Texture = "Interface\\Icons\\spell_shadow_twilight" Texture = "Interface\\Icons\\spell_shadow_twilight"
}, },
MSBT_TRIGGER_OVERPOWER = { MSBT_TRIGGER_OVERPOWER = {
EventSettings = { EventSettings = {
Show = true, Show = true,
Message = SpellName(7384).."!", -- Overpower Message = BS["Overpower"].."!",
IsSticky = true, IsSticky = true,
FontSettings = { FontSettings = {
Color = {r=1, g=1, b=0}, Color = {r=1, g=1, b=0},
+17 -17
View File
@@ -4,10 +4,6 @@ A World of Warcraft 1.12 (Vanilla) addon that displays scrolling combat text aro
**Interface:** 11200 | **Version:** 4.43 **Interface:** 11200 | **Version:** 4.43
## Requirements
- **ClassicAPI** — a client-side DLL that backports modern WoW API calls to the 1.12 client (no companion addon required). MSBT relies on it for `C_Spell.GetSpellName`, `C_Item.GetItemName`/`GetItemIcon`, `ItemLocation`, and `CreateColor`/`GetRGB` — used for spell-name lookups, item-icon resolution, and damage-type text coloring. These are not optional fast paths; the addon expects them to be present.
## Features ## Features
- Scrolling combat text across three display areas: **Incoming** (right), **Outgoing** (left), and **Notification** (center) - Scrolling combat text across three display areas: **Incoming** (right), **Outgoing** (left), and **Notification** (center)
@@ -64,28 +60,32 @@ Interface/
| `/msbt debug` | Toggle debug mode | | `/msbt debug` | Toggle debug mode |
| `/msbt help` | Show command usage | | `/msbt help` | Show command usage |
## ClassicAPI Combat Log Integration ## Nampower / SuperWoW / UnitXP SP3 Integration
MSBT reads structured combat data from ClassicAPI's `COMBAT_LOG_EVENT_UNFILTERED` instead of relying on string-based combat log parsing alone, for significantly better performance in heavy combat scenarios (raids, AoE, battlegrounds). When these enhanced client mods are detected, MSBT automatically switches from string-based combat log parsing to structured event handling for significantly better performance in heavy combat scenarios (raids, AoE, battlegrounds).
### What Changes ### What Changes
- **ClassicAPI combat log**: Registers for the unfiltered combat log (`SPELL_DAMAGE`, `SWING_DAMAGE`, `SPELL_HEAL`, `SPELL_ENERGIZE`, `SPELL_MISSED`, `SPELL_AURA_APPLIED`, `ENVIRONMENTAL_DAMAGE`, `PARTY_KILL`, etc.) which carries pre-parsed amounts, GUIDs, crit flags, miss types and spell info. Redundant `CHAT_MSG_*` events are unregistered to avoid duplicates. No opt-in CVars are needed. - **Nampower**: Registers for structured events (`SPELL_DAMAGE_EVENT_SELF`, `AUTO_ATTACK_SELF`, `SPELL_HEAL_ON_SELF`, etc.) that provide pre-parsed combat data. Redundant `CHAT_MSG_*` events are unregistered to avoid duplicates. Enables `NP_EnableAutoAttackEvents`, `NP_EnableSpellHealEvents`, and `NP_EnableSpellEnergizeEvents` CVars.
- **SpellId icons**: SpellIds from combat log events resolve icons directly through ClassicAPI's `GetSpellInfo`, bypassing Babble-Spell dictionary lookups and tooltip scanning. - **SuperWoW**: Provides O(1) unit lookups by name via `UnitExists(name)` (replacing O(n) raid/party iteration) and `SpellInfo(spellId)` for spell icon resolution.
- **UnitXP SP3**: Detected for compatibility; used for GUID-based unit resolution.
### Removed: SuperWoW / UnitXP SP3 / Nampower
SuperWoW, UnitXP SP3 and Nampower integration has been removed in favor of ClassicAPI (for spell/item lookups, GUIDs and structured combat events). ClassicAPI is a hard dependency (see the `.toc`).
### Fallback ### Fallback
`CHAT_MSG_*` parsing stays registered for everything with no combat log equivalent (honor, reputation, skill, XP, item enchantments, some power gains/losses) and as a fallback until each combat log event actually fires. When none of these mods are present, the addon falls back to the original string-parsing pipeline with no changes in behavior.
### Verification
```lua
-- Check detection status in-game:
/run MikSBT.Print("NP="..tostring(MikCEH.hasNampower).." SW="..tostring(MikCEH.hasSuperWoW).." UXP="..tostring(MikCEH.hasUnitXP))
```
## Performance Optimizations ## Performance Optimizations
- **Upvalue caching**: Frequently called standard library functions (`string.find`, `string.gsub`, `table.insert`, `table.getn`, `GetTime`, etc.) are cached as local variables - **Upvalue caching**: Frequently called standard library functions (`string.find`, `string.gsub`, `table.insert`, `table.getn`, `GetTime`, etc.) are cached as local variables
- **Dispatch table**: Combat event routing uses O(1) table lookup instead of an if/elseif chain - **Dispatch table**: Combat event routing uses O(1) table lookup instead of an if/elseif chain
- **SpellId icon cache**: SpellIds from combat log events resolve icons directly through ClassicAPI and are cached, bypassing Babble-Spell dictionary lookups and tooltip scanning - **SpellId icon cache**: When spellIds are available (via Nampower/SuperWoW), icons are resolved directly and cached, bypassing Babble-Spell dictionary lookups and tooltip scanning
- **Event throttling**: UNIT_HEALTH and UNIT_MANA trigger checks are throttled to 150ms intervals - **Event throttling**: UNIT_HEALTH and UNIT_MANA trigger checks are throttled to 150ms intervals
- **Table recycling**: `MikTRO` (Table Recycler Object) pools and reuses table allocations to reduce garbage collection pressure - **Table recycling**: `MikTRO` (Table Recycler Object) pools and reuses table allocations to reduce garbage collection pressure
@@ -102,9 +102,9 @@ SuperWoW, UnitXP SP3 and Nampower integration has been removed in favor of Class
### Event Processing Pipeline ### Event Processing Pipeline
``` ```
WoW CHAT_MSG_* events (or ClassicAPI COMBAT_LOG_EVENT_UNFILTERED) WoW CHAT_MSG_* events (or Nampower structured events)
-> MikCEH.OnEvent() / MikCEH.OnCombatLogEvent() -> MikCEH.OnEvent() / MikCEH.OnNampowerEvent()
-> ParseCombatEvents() dispatch table (or combat log handler) -> ParseCombatEvents() dispatch table (or Nampower handler)
-> Creates CombatEventData tables -> Creates CombatEventData tables
-> MikSBT.CombatEventsHandler() -> MikSBT.CombatEventsHandler()
-> Formats text with templates (%a=amount, %n=name, %s=spell, %t=type) -> Formats text with templates (%a=amount, %n=name, %s=spell, %t=type)