18 Commits
Author SHA1 Message Date
Brues 862ac4c56a Replace Nampower events with ClassicAPI combat log
- Register COMBAT_LOG_EVENT_UNFILTERED and map 20 subevents to MSBT damage/heal/notification data with GUID-based direction

- Remove Nampower event layer, NP_* CVars, version check and install prompt

- Resolve spell icons through ClassicAPI GetSpellInfo

- Keep CHAT_MSG parsing for honor/rep/skill/XP/item/power lines and as fallback until each log event fires

- Update README integration docs
2026-10-24 22:36:20 -05:00
Brues ea79f083f3 defeats the purpose of the addon and confuses users 2026-07-20 15:38:27 -05:00
Brues 0229b07122 removed Babble 2026-06-23 14:28:20 -05:00
Brues 615c074a3f add ClassicAPI dep 2026-06-23 02:25:27 -05:00
Brues dc88b69103 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 02:19:35 -05:00
Brues 9f88f0bf32 Replace FindBuff tooltip scanning with C_UnitAuras/C_Item
GetAuraIcon resolves buff/debuff icons via C_UnitAuras.GetAuraDataBySpellName (returns the icon directly, no UnitBuff/UnitDebuff follow-up) and temporary weapon-enchant icons via C_Item.GetWeaponEnchantInfo + C_Item.GetEnchantInfo + C_Spell.GetSpellTexture. This drops ~48 tooltip create/scan/hide ops per uncached effect and, unlike the old FindBuff, actually yields an icon for weapon-enchant-named effects. The dead tracking-spell branch is removed, the AddAnimation call site no longer dead-ends on non-matches (falls through to the spellId/Babble/item resolvers), and the now-unused MSBT_Tooltip frame is removed from the XML.
2026-06-23 02:10:07 -05:00
Brues 9d0f945c59 Make FindItemIcon return the icon consistently from both paths
The equipped-slot path returned (slot, nil, icon, count) while the bag path returned just the icon. The sole caller (AddAnimation) uses only the first return value as the texture, so equipped items produced a slot number instead of an icon path. Both paths now return the icon as the first value. Also call FindItemIcon once in the caller instead of three times, folding the no-icon case into the same branch.
2026-06-22 19:15:30 -05:00
Brues 8c35b8b6ad Fix equipped-item match in FindItemIcon and drop the link loop
The equipped-slot check compared itemName to its own lowercase (always matching the first named slot) instead of the searched item; now it compares against item. The separate GetInventoryItemLink/ItemLinkToName loop for slots past INVSLOT_LAST_EQUIPPED is folded into the ItemLocation loop by extending its range by 4.
2026-06-22 19:09:27 -05:00
Brues 6418359865 use IsPlayerGuid from classicapi 2026-06-22 19:00:58 -05:00
Brues f42c2cf6ca Drop spellNameCache; C_Spell.GetSpellName is a cheap DBC read
The cache originally wrapped the SuperWoW/Nampower pcall fallback chain, where it mattered. Now that GetSpellNameFromId is a single C_Spell.GetSpellName call (a single-field DBC + locale read), the cache only saved a boundary crossing and a string-intern hash per repeated lookup -- and Lua 5.0 interns strings, so it never saved allocations. Not worth the extra table and branch.
2026-06-22 18:49:32 -05:00
Brues c095b76d10 Drop hasNampower gate on UnitGUID calls (provided by ClassicAPI)
UnitGUID is supplied by ClassicAPI, so player/pet GUID resolution no longer needs to be conditional on Nampower. Simplifies the player GUID caching (Init + PLAYER_ENTERING_WORLD retry), IsPetGUID, and EnsurePlayerGUID. GetNameFromGUID stays on Nampower's GetUnitField since it resolves NPC names too, which ClassicAPI's player-only UnitNameFromGUID does not cover.
2026-06-22 18:16:22 -05:00
Brues e8b3b81241 Remove SuperWoW and UnitXP SP3 integration
Drops the SuperWoW and UnitXP SP3 detection flags and all their code paths. GUID/unit-name resolution (GetNameFromGUID, IsPetGUID, EnsurePlayerGUID, player GUID caching) now relies solely on Nampower APIs; the spellId icon fast path keeps only its Nampower branch; and GetUnitIDFromName falls back to the raw-combat-logging path and name cache. UnitXP was detection-only and never read. README updated to reflect the removal.
2026-06-22 18:12:51 -05:00
Brues d13a4102b8 Document ClassicAPI requirement; deprecate SuperWoW/UnitXP
Add a Requirements section noting MSBT now depends on the ClassicAPI client DLL for C_Spell/C_Item/ItemLocation/CreateColor. Retitle the integration section to focus on Nampower and mark the SuperWoW and UnitXP SP3 paths as deprecated and slated for removal.
2026-06-22 18:07:57 -05:00
Brues dce8df9e12 Normalize indentation in GetUnorderedCaptureDataTable
Convert the function body from 2-space to single-space (tab-style) indentation to match the surrounding file. No behavior change.
2026-06-22 18:02:34 -05:00
Brues 7502df37cf 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-22 18:02:34 -05:00
Brues bf5be40e78 Use C_Spell/C_Item APIs for spell name and item icon lookups
GetSpellNameFromId now calls C_Spell.GetSpellName instead of the SuperWoW/Nampower pcall chain. FindItemIcon iterates equipped slots and bags via ItemLocation and C_Item.GetItemName/GetItemIcon. AddAnimation hoists strlower(name) into a local lowerName to avoid repeated calls and feeds the lowercased name to FindItemIcon.
2026-06-22 18:00:24 -05:00
Brues 6a9dd18ce0 Use CreateColor for damage type text coloring
Replace the manual {r,g,b} table and hex color-prefix strings with CreateColor-based color objects. GetDamageTypeFontColor now builds each school color via a CreateSpellColor helper that also caches a colorStr markup string, adds a Holy color, and retunes the existing school colors. FormatEventText and AddAnimation consume the new objects (color.colorStr and dtColor:GetRGB()), and the dead GetDamageTypeColor lookup is removed.
2026-06-22 18:00:04 -05:00
Brues 3f08a237de add Numen font 2026-06-22 17:52:29 -05:00
11 changed files with 586 additions and 11271 deletions
+23
View File
@@ -0,0 +1,23 @@
name: Package and release
on:
push:
tags:
- '**'
permissions:
contents: write
jobs:
package:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Package and create GitHub release
uses: BigWigsMods/packager@v2
env:
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
+10
View File
@@ -0,0 +1,10 @@
package-as: MikScrollingBattleText
enable-nolib-creation: no
move-folders:
MikScrollingBattleText/MikScrollingBattleText: MikScrollingBattleText
MikScrollingBattleText/MikScrollingBattleTextOptions: MikScrollingBattleTextOptions
ignore:
- README.md
Binary file not shown.
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+71 -171
View File
@@ -1,4 +1,4 @@
-------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------
-- Title: Mik's Scrolling Battle Text
-- Author: Mik
-- Maintainer: Athene
@@ -133,36 +133,22 @@ NO_ICON_CACHE = {}
-- Cache for spellId-based icon lookups (bypasses Babble-Spell and tooltip scanning).
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).
local damageTypeFontColors
local function GetDamageTypeFontColor(dt)
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 = {
[SPELL_SCHOOL2_CAP] = { r=1.0, g=0.27, b=0.27 }, -- Fire (red)
[SPELL_SCHOOL3_CAP] = { r=0.27, g=1.0, b=0.27 }, -- Nature (green)
[SPELL_SCHOOL4_CAP] = { r=0.27, g=0.53, b=1.0 }, -- Frost (blue)
[SPELL_SCHOOL5_CAP] = { r=0.4, g=0.0, b=0.8 }, -- Shadow (deep purple)
[SPELL_SCHOOL6_CAP] = { r=0.8, g=0.4, b=1.0 }, -- Arcane (purple/pink)
[SPELL_SCHOOL1_CAP] = CreateSpellColor(0.965, 0.976, 0.620), -- Holy
[SPELL_SCHOOL2_CAP] = CreateSpellColor(0.933, 0.490, 0.501), -- Fire
[SPELL_SCHOOL3_CAP] = CreateSpellColor(0.631, 0.858, 0.396), -- Nature
[SPELL_SCHOOL4_CAP] = CreateSpellColor(0.462, 0.792, 0.929), -- Frost
[SPELL_SCHOOL5_CAP] = CreateSpellColor(0.356, 0.290, 0.596), -- Shadow
[SPELL_SCHOOL6_CAP] = CreateSpellColor(0.956, 0.658, 0.894), -- Arcane
}
end
return damageTypeFontColors[dt]
@@ -538,13 +524,6 @@ function MikSBT.Init()
-- Register the triggers with the combat event helper.
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.
MikSBT.SetOptionUserDisabled(MikSBT_Save.UserDisabled)
end
@@ -1145,14 +1124,14 @@ function MikSBT.FormatEventText(animationEvent)
end
outputString = string_gsub(outputString, "-%%a", "\124cffff0000\124h-\124h\124r%%a");
if animationEvent.DamageType then
local color = GetDamageTypeColor(animationEvent.DamageType)
local color = GetDamageTypeFontColor(animationEvent.DamageType)
if color then
outputString = string_gsub(outputString, "%%a", color .. "%%a\124h\124r")
outputString = string_gsub(outputString, "%%a", color.colorStr .. "%%a\124h\124r")
end
end
-- Substitute amount.
if (animationEvent.Amount ~= nil) then
-- Check if there is overheal info
@@ -1343,7 +1322,7 @@ function MikSBT.UpdateProfiles()
if (profile.CreationVersion < 4.1) then
if profile.Triggers.MSBT_TRIGGER_WINDFURY then -- Fix Windfury Trigger
profile.Triggers.MSBT_TRIGGER_WINDFURY.TriggerSettings.SearchPatterns[1] = string.format(AURAADDEDSELFHELPFUL, string_gsub(BS["Windfury Totem"], "-", "%%-"))
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)
end
if profile.Triggers.MSBT_TRIGGER_HAND_OF_JUSTICE then -- Delete Hand of Justice Trigger
@@ -1417,7 +1396,7 @@ function MikSBT.UpdateProfiles()
end
if (profile.CreationVersion < 4.6) then
-- Add missing incoming evade/reflect event settings (needed for Nampower events).
-- Add missing incoming evade/reflect event settings (needed for combat log miss events).
local incomingMissEvents = {
"MSBT_EVENTTYPE_INCOMING_EVADE",
"MSBT_EVENTTYPE_INCOMING_SPELL_EVADE",
@@ -1786,9 +1765,7 @@ function MikSBT.AddAnimation(animationEvent)
if animationEvent.DamageType and animationEvent.EventType then
local dtColor = GetDamageTypeFontColor(animationEvent.DamageType)
if dtColor then
animDisplayInfo.ColorR = dtColor.r
animDisplayInfo.ColorG = dtColor.g
animDisplayInfo.ColorB = dtColor.b
animDisplayInfo.ColorR, animDisplayInfo.ColorG, animDisplayInfo.ColorB = dtColor:GetRGB()
end
end
@@ -1854,57 +1831,36 @@ function MikSBT.AddAnimation(animationEvent)
local sid = animationEvent.SpellId
if spellIdIconCache[sid] then
texture = spellIdIconCache[sid]
elseif MikCEH.hasSuperWoW and SpellInfo then
local ok, _, _, tex = pcall(SpellInfo, sid)
elseif GetSpellInfo then
local ok, _, _, tex = pcall(GetSpellInfo, sid)
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
if animationEvent.EffectName then
local name = string_gsub(animationEvent.EffectName, " %(%d+%)", "")
local lowerName = strlower(name)
-- DEFAULT_CHAT_FRAME:AddMessage(animationEvent.EffectName)
-- DEFAULT_CHAT_FRAME:AddMessage(name)
-- texture = BS:GetSpellIcon(name)
if ICON_CACHE[strlower(name)] then
texture = ICON_CACHE[strlower(name)]
elseif not texture and MikSBT.FindBuff(name) then
local bufftype,index,_ = MikSBT.FindBuff(name)
local icon
if bufftype == "buff" then
icon = UnitBuff("player", index)
ICON_CACHE[strlower(name)] = icon
texture = icon
elseif bufftype == "debuff" then
icon = UnitDebuff("player", index)
ICON_CACHE[strlower(name)] = icon
texture = icon
else
texture = nil
NO_ICON_CACHE[strlower(name)] = 1
end
elseif not texture and MikCEH.hasNampower and GetSpellIdForName then
local ok, sid = pcall(GetSpellIdForName, name)
if ICON_CACHE[lowerName] then
texture = ICON_CACHE[lowerName]
elseif not texture and MikSBT.GetAuraIcon(name) then
texture = MikSBT.GetAuraIcon(name)
ICON_CACHE[lowerName] = texture
elseif not texture and GetSpellInfo then
local ok, sid = pcall(function(n) return select(10, GetSpellInfo(n)) end, 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
local ok2, _, _, tex = pcall(GetSpellInfo, sid)
if ok2 and tex then texture = tex; ICON_CACHE[lowerName] = tex 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
local itemIcon = MikSBT.FindItemIcon(lowerName)
if itemIcon then
texture = itemIcon
ICON_CACHE[lowerName] = itemIcon
else
NO_ICON_CACHE[lowerName] = 1
end
end
end
@@ -1963,106 +1919,50 @@ function ItemLinkToName(link)
end
function MikSBT.FindItemIcon(item)
if ( not item ) then return; end
if ( not item ) then return end
item = string.lower(item);
local link;
for i = 1,23 do
link = GetInventoryItemLink("player",i);
if ( link ) then
if ( item == string.lower(ItemLinkToName(link)) )then
return i, nil, GetInventoryItemTexture('player', i), GetInventoryItemCount('player', i);
for slot = INVSLOT_FIRST_EQUIPPED, INVSLOT_LAST_EQUIPPED + 4 do
local itemLocation = ItemLocation:CreateFromEquipmentSlot(slot)
local itemName = C_Item.GetItemName(itemLocation)
if itemName and item == string.lower(itemName) then
return C_Item.GetItemIcon(itemLocation)
end
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
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
-- **********************************************************************************
-- This function return the buff texture based on
-- it's name.
-- Returns the icon for an active buff/debuff or temporary weapon enchant whose
-- name matches, or nil. Uses ClassicAPI (C_UnitAuras / C_Item) instead of the old
-- tooltip-scanning approach.
-- **********************************************************************************
function MikSBT.FindBuff( obuff, unit, item)
local buff=strlower(obuff);
local tooltip=MSBT_Tooltip;
local textleft1=getglobal(tooltip:GetName().."TextLeft1");
if ( not unit ) then
unit ='player';
end
local my, me, mc, oy, oe, oc = GetWeaponEnchantInfo();
if ( my ) then
tooltip:SetOwner(UIParent, "ANCHOR_NONE");
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
function MikSBT.GetAuraIcon(name, unit)
unit = unit or "player";
-- Buffs and debuffs (helpful then harmful) -- AuraData carries the icon directly.
local aura = C_UnitAuras.GetAuraDataBySpellName(unit, name);
if ( aura and aura.icon ) then return aura.icon end
-- 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
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
if ( hasOff and offID ) then
local info = C_Item.GetEnchantInfo(offID);
if ( info and info.name == name and info.spellID ) then
return C_Spell.GetSpellTexture(info.spellID);
end
tooltip:Hide();
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
-- **********************************************************************************
@@ -1,14 +1,14 @@
## Interface: 11200
## Version: 4.43
## Version: @project-version@
## Title: Mik's Scrolling Battle Text
## Notes: Scrolls battle information around the character model.
## Notes-ruRU: Прокрутка информации боя вокруг модели персонажа.
## Dependencies: !!!ClassicAPI
## OptionalDeps: SW_FixLogStrings
## SavedVariables: MikSBT_Save
Libs\AceLibrary\AceLibrary.lua
Libs\AceLocale-2.2\AceLocale-2.2.lua
Libs\BabbleSpell-2.2\Babble-Spell-2.2.lua
MikScrollingBattleText-enUS.lua
MikScrollingBattleText-frFR.lua
@@ -11,15 +11,6 @@
</Scripts>
</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 -->
<Frame name="MSBTFrameIncoming" toplevel="true" enableMouse="false" parent="UIParent" frameStrata="HIGH" hidden="true">
<Size>
+17 -13
View File
@@ -18,9 +18,12 @@ MikSBT.WINDOW_TITLE = "Mik's Scrolling Battle Text " .. MikSBT.VERSION_STRING ..
MikSBT.COMMAND = "/msbt";
local BS = AceLibrary("Babble-Spell-2.2")
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)
-------------------------------------------------------------------------------
@@ -126,6 +129,7 @@ MikSBT.AVAILABLE_FONTS = {
[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"},
[32] = {Name="Archangelsk", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\archangelsk.ttf"},
[32] = {Name="Numen", Path="Interface\\Addons\\MikScrollingBattleText\\Fonts\\Numen.ttf"},
};
end
@@ -205,7 +209,7 @@ MikSBT.DEFAULT_CONFIG = {
CreationVersion = MikSBT.VERSION_NUMBER,
ShowPartialEffects = true,
ShowOverheals = true,
ShowGameDamage = true,
ShowGameDamage = false,
UseStickyCrits = true,
ShowAllManaGains = false,
LowHealthSound = true,
@@ -1134,7 +1138,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_EXECUTE = {
EventSettings = {
Show = true,
Message = BS["Execute"].."!",
Message = SpellName(5308).."!", -- Execute
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1151,7 +1155,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_HAMMER_OF_WRATH = {
EventSettings = {
Show = true,
Message = BS["Hammer of Wrath"].."!",
Message = SpellName(24275).."!", -- Hammer of Wrath
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1168,7 +1172,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_COUNTER_ATTACK = {
EventSettings = {
Show = true,
Message = BS["Counterattack"].."!",
Message = SpellName(19306).."!", -- Counterattack
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1187,7 +1191,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_MONGOOSE_BITE = {
EventSettings = {
Show = true,
Message = BS["Mongoose Bite"].."!",
Message = SpellName(1495).."!", -- Mongoose Bite
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1206,7 +1210,7 @@ MikSBT.DEFAULT_CONFIG = {
MSBT_TRIGGER_CLEARCAST = {
EventSettings = {
Show = true,
Message = BS["Clearcasting"].."!",
Message = SpellName(16246).."!", -- Clearcasting
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1217,14 +1221,14 @@ MikSBT.DEFAULT_CONFIG = {
Classes = {MAGE=true,SHAMAN=true},
TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, BS["Clearcasting"])},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, SpellName(16246))}, -- Clearcasting (ID verified vs Spell.dbc)
},
Texture = "Interface\\Icons\\spell_shadow_manaburn"
},
MSBT_TRIGGER_RIPOSTE = {
EventSettings = {
Show = true,
Message = BS["Riposte"].."!",
Message = SpellName(14251).."!", -- Riposte
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1253,14 +1257,14 @@ MikSBT.DEFAULT_CONFIG = {
TriggerSettings = {
TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, string.gsub(BS["Windfury Totem"], "-", "%%-"))}, --"Vous gagnez Totem Furie-des-vents" -- escape char !
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, string.gsub(SpellName(8512), "-", "%%-"))}, -- Windfury Totem (ID verified vs Spell.dbc). "Vous gagnez Totem Furie-des-vents" -- escape char !
},
Texture = "Interface\\Icons\\spell_nature_cyclone"
},
MSBT_TRIGGER_NIGHTFALL = {
EventSettings = {
Show = true,
Message = BS["Nightfall"].."!",
Message = SpellName(18094).."!", -- Nightfall (talent)
IsSticky = true,
FontSettings = {
Color = {r=0.709, g=0, b=0.709},
@@ -1271,14 +1275,14 @@ MikSBT.DEFAULT_CONFIG = {
Classes = {WARLOCK=true},
TriggerType = 6,
TriggerEvents = {"CHAT_MSG_SPELL_PERIODIC_SELF_BUFFS"},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, BS["Shadow Trance"])},
SearchPatterns = {string.format(AURAADDEDSELFHELPFUL, SpellName(17941))}, -- Shadow Trance (ID verified vs Spell.dbc)
},
Texture = "Interface\\Icons\\spell_shadow_twilight"
},
MSBT_TRIGGER_OVERPOWER = {
EventSettings = {
Show = true,
Message = BS["Overpower"].."!",
Message = SpellName(7384).."!", -- Overpower
IsSticky = true,
FontSettings = {
Color = {r=1, g=1, b=0},
@@ -1,5 +1,5 @@
## Interface: 11200
## Version: 4.43
## Version: @project-version@
## Title: Mik's Scrolling Battle Text Options
## Notes: Load on demand options for Mik's Scrolling Battle Text
## Notes-ruRU: Настройки для Mik's Scrolling Battle Text
+17 -17
View File
@@ -4,6 +4,10 @@ A World of Warcraft 1.12 (Vanilla) addon that displays scrolling combat text aro
**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
- Scrolling combat text across three display areas: **Incoming** (right), **Outgoing** (left), and **Notification** (center)
@@ -60,32 +64,28 @@ Interface/
| `/msbt debug` | Toggle debug mode |
| `/msbt help` | Show command usage |
## Nampower / SuperWoW / UnitXP SP3 Integration
## ClassicAPI Combat Log Integration
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).
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).
### What Changes
- **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.
- **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.
- **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.
- **SpellId icons**: SpellIds from combat log events resolve icons directly through ClassicAPI's `GetSpellInfo`, bypassing Babble-Spell dictionary lookups and tooltip scanning.
### 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
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))
```
`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.
## Performance Optimizations
- **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
- **SpellId icon cache**: When spellIds are available (via Nampower/SuperWoW), icons are resolved directly and cached, bypassing Babble-Spell dictionary lookups and tooltip scanning
- **SpellId icon cache**: SpellIds from combat log events resolve icons directly through ClassicAPI and are cached, bypassing Babble-Spell dictionary lookups and tooltip scanning
- **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
@@ -102,9 +102,9 @@ When none of these mods are present, the addon falls back to the original string
### Event Processing Pipeline
```
WoW CHAT_MSG_* events (or Nampower structured events)
-> MikCEH.OnEvent() / MikCEH.OnNampowerEvent()
-> ParseCombatEvents() dispatch table (or Nampower handler)
WoW CHAT_MSG_* events (or ClassicAPI COMBAT_LOG_EVENT_UNFILTERED)
-> MikCEH.OnEvent() / MikCEH.OnCombatLogEvent()
-> ParseCombatEvents() dispatch table (or combat log handler)
-> Creates CombatEventData tables
-> MikSBT.CombatEventsHandler()
-> Formats text with templates (%a=amount, %n=name, %s=spell, %t=type)