📄 damagemeters.lua
字号:
-- This function should house code that needs to run after variables have been loaded
-- but before the mod starts updating.
function DamageMeters_OnLoadComplete()
local dmiCount = DMI_MAX;
local plugin, savedDMI;
for plugin, savedDMI in DamageMeters_pluginDMITable do
if (savedDMI > dmiCount) then
dmiCount = savedDMI;
end
end
local bPluginsMissing = false;
--DMPrintD("DamageMeters_pluginDMITable loaded:");
--DM_DUMP_RECURSIVE(DamageMeters_pluginDMITable, "[root]", "");
-- go through list of saved plugin data
for plugin, savedDMI in DamageMeters_pluginDMITable do
-- if no plugin for data
if (nil == DamageMeters_PLUGINS[plugin]) then
DMPrintD("Clearing saved data for not-loaded plugin "..plugin..", dmi = "..savedDMI);
-- delete plugin data
DamageMeters_DeleteDMIData(savedDMI, dmiCount);
dmiCount = dmiCount - 1;
-- renumber saved plugin indexes
DamageMeters_pluginDMITable[plugin] = nil;
for plugin2, savedDMI2 in DamageMeters_pluginDMITable do
DamageMeters_pluginDMITable[plugin2] = savedDMI2 - 1;
end
bPluginsMissing = true;
else
DMPrintD("Plugin >"..plugin.."< has saved data and is assigned DMI "..savedDMI);
-- save dmi into the plugin table
DamageMeters_PLUGINS[plugin].dmi = savedDMI;
end
end
-- go through the list of plugins
DamageMeters_pluginDMITable = {};
for plugin, pluginStruct in DamageMeters_PLUGINS do
-- assign new dmis for any that still dont have any
if (pluginStruct.dmi == nil) then
dmiCount = dmiCount + 1;
pluginStruct.dmi = dmiCount;
DMPrintD("Plugin "..plugin.." has no saved data. Was assigned DMI "..dmiCount);
end
-- build the new DamageMeters_pluginDMITable
DamageMeters_pluginDMITable[plugin] = pluginStruct.dmi;
-- Inform the plugin of its new dmi.
pluginStruct.pfnAssignDMI(pluginStruct.dmi);
pluginStruct.quantDefs.dmi = pluginStruct.dmi;
end
--DMPrintD("DamageMeters_pluginDMITable after load:");
--DM_DUMP_RECURSIVE(DamageMeters_pluginDMITable, "[root]", "");
DMI_MAX = dmiCount;
DMPrintD("DMI_MAX after loading plugins = "..DMI_MAX);
--------------
-- Clean up other variables that may have depended on missing plugins.
if (bPluginsMissing) then
if (DamageMeters_quantity > DamageMeters_Quantity_MAX) then
DMPrintD("Plugins missing, and fixing out of range DamageMeters_quantity.");
DamageMeters_quantity = DamageMeters_Quantity_MAX;
else
DMPrintD("DamageMeters_quantity within range.");
end
end
end
function DamageMeters_InParty()
local inParty = false;
local p = GetNumPartyMembers();
local r = GetNumRaidMembers();
if ((p + r) > 0) then
inParty = true;
end
return inParty;
end
function DamageMeters_UpdateVisibility(userCaused)
local inParty = DamageMeters_InParty();
if (inParty and not DamageMeters_currentlyInParty) then
DMPrintD("DM: Joined party.");
if (DamageMeters_flags[DMFLAG_clearWhenJoinParty]) then
DamageMeters_Clear()
end
end
DamageMeters_currentlyInParty = inParty;
if (DamageMeters_flags[DMFLAG_visibleOnlyInParty]) then
if (inParty and not DamageMetersFrame:IsVisible()) then
DMPrintD("DMFLAG_visibleOnlyInParty, inParty, and not DamageMetersFrame:IsVisible() - calling _Show()");
DamageMeters_Show();
elseif (not inParty and DamageMetersFrame:IsVisible()) then
DMPrintD("DMFLAG_visibleOnlyInParty, not inParty, and DamageMetersFrame:IsVisible() - calling _Hide()");
DamageMeters_Hide();
end
elseif (userCaused) then
if (not DamageMetersFrame:IsVisible()) then
DamageMeters_Show();
end
end
end
function DamageMeters_UpdateCount()
local newCount = DamageMeters_barCount;
if (DMVIEW_MAX == DamageMeters_viewMode) then
newCount = DamageMeters_BARCOUNT_MAX;
elseif (DMVIEW_MIN == DamageMeters_viewMode) then
newCount = 1;
else
if (DamageMeters_autoCountLimit > 0) then
newCount = table.getn(DamageMeters_tables[DMT_VISIBLE]);
if (newCount > DamageMeters_autoCountLimit) then
newCount = DamageMeters_autoCountLimit;
elseif (newCount == 0) then
newCount = 1;
end
end
end
if (newCount ~= DamageMeters_barCount) then
DamageMeters_barCount = newCount;
DMPrintD("Frame dirty: count changed.");
DamageMeters_frameNeedsToBeGenerated = true;
end
end
function DamageMeters_UpdateDebugTimers()
local now = GetTime();
-- /script DMPrint(GetTime().." - "..DamageMeters_lastDebugTime.." = "..(GetTime() - DamageMeters_lastDebugTime));
if (DamageMeters_lastDebugTime < 0) then
DamageMeters_lastDebugTime = now;
local timer;
for timer = 1, DMPROF_COUNT do
DamageMeters_debugTimers[timer] = {};
DamageMeters_debugTimers[timer].time = 0;
DamageMeters_debugTimers[timer].count = 0;
DamageMeters_debugTimers[timer].peak = 0;
end
end
local debugTime = now - DamageMeters_lastDebugTime;
if (debugTime > 1.0) then
DamageMeters_lastDebugTime = now;
local timer;
if (DamageMeters_debugEnabled) then
if (DMTIMERMODE == 1) then
local msg = string.format("(%.2f) ", debugTime);
for timer = 1, DMPROF_COUNT do
msg = msg..string.format("%s=%d(%d) ", DMPROF_NAMES[timer], DamageMeters_debugTimers[timer].time, DamageMeters_debugTimers[timer].count);
end
DMPrint(msg, nil, true);
elseif (DMTIMERMODE == 2) then
local msg = "";
local uCount = ceil(DamageMeters_debugTimers[DMPROF_UPDATE].time / 10);
local pCount = ceil(DamageMeters_debugTimers[DMPROF_PARSEMESSAGE].time / 10);
local aCount = ceil(DamageMeters_debugTimers[DMPROF_ADDVALUE].time / 10);
local bCount = ceil(DamageMeters_debugTimers[DMPROF_BARS].time / 10);
msg = msg.."|cFFFF0000"..string.rep("U", uCount);
msg = msg.."|cFF00FF00"..string.rep("P", pCount);
msg = msg.."|cFF60FF60"..string.rep("A", aCount);
msg = msg.."|cFF0000FF"..string.rep("B", bCount);
DMPrint(msg, nil, true);
elseif (DMTIMERMODE == 3) then
local msPerFrame = 1000 / GetFramerate();
local msg = string.format("Frames (%.2f) ", debugTime);
for timer = 1, DMPROF_COUNT do
msg = msg..string.format("%s=%.2f(%d) ",
DMPROF_NAMES[timer],
DamageMeters_debugTimers[timer].time / msPerFrame,
DamageMeters_debugTimers[timer].count);
end
DMPrint(msg, nil, true);
elseif (DMTIMERMODE == 4) then
local totalTime = 0;
local msPerFrame = 1000 / GetFramerate();
for timer = 1, DMPROF_COUNT do
totalTime = totalTime + DamageMeters_debugTimers[timer].time;
end
local debugMS = floor(debugTime * 1000);
local msg = string.format("%.2f Frames @ %.2f FPS | %4d / %4d ms = %.2f%%",
totalTime / msPerFrame,
GetFramerate(),
totalTime,
debugMS,
100 * totalTime / debugMS);
DMPrint(msg, nil, true);
end
end
for timer = 1, DMPROF_COUNT do
if (DamageMeters_debugTimers[timer].peak < DamageMeters_debugTimers[timer].time) then
DamageMeters_debugTimers[timer].peak = DamageMeters_debugTimers[timer].time;
end
DamageMeters_debugTimers[timer].time = 0;
DamageMeters_debugTimers[timer].count = 0;
end
end
end
function DMPEAKINFO()
local msg = "";
local timer;
local total = 0;
for timer = 1, DMPROF_COUNT do
msg = msg..string.format("%s=%d ", DMPROF_NAMES[timer], DamageMeters_debugTimers[timer].peak);
end
DMPrint(msg);
end
-- Call this when the table is dirty to "clean" it.
-- Do sorting and such here.
function DamageMeters_UpdateTables()
if (DM_Bypass["Update Tables"] == true) then
return;
end
--DMPrintD(GetTime()..": Update Tables called.", nil, true);
DamageMeters_StartDebugTimer(DMPROF_SORT);
-- Determine totals -first-, as some quantities (ie. Dande-Rating) require totals in order to
-- calculate their own values.
DamageMeters_DetermineTotals();
-- Sort
DamageMeters_DoSort(DamageMeters_tables[DMT_VISIBLE], DamageMeters_quantity);
DamageMeters_tablesDirty = false;
-- Determine ranks for Titan display.
-- Eventually the rank table could be used to index into the main table, rather than sorting the
-- main table itself. Would add some indirection but would keep us from having to shuffle that
-- table around. Dunno which way is faster, honestly.
DamageMeters_DetermineRanks(DMT_ACTIVE, true);
DamageMeters_StopDebugTimer(DMPROF_SORT);
end
function DamageMetersFrame_OnUpdate()
----------------------
if (DM_Bypass["Generate AddValues"] == true) then
DamageMeters_StartDebugTimer(DMPROF_PARSEMESSAGE);
DamageMeters_AddDamage("CHAT_MSG_COMBAT_SELF_HITS", UnitName("player"), "[Test]", 0, DM_HIT, DamageMeters_Relation_SELF, "[Stress Test]");
DamageMeters_StartDebugTimer(DMPROF_PARSEMESSAGE);
DamageMeters_AddHealing("CHAT_MSG_SPELL_SELF_BUFF", UnitName("player"), UnitName("player"), 0, DM_HIT, DamageMeters_Relation_SELF, DamageMeters_Relation_SELF, "[Stress Test]")
end
if (DM_Bypass["Generate Events"] == true) then
--DamageMeters_ParseMessage("You hit Bob for 0.", "CHAT_MSG_COMBAT_SELF_HITS");
--DamageMeters_ParseMessage("Bob hits you for 0.", "CHAT_MSG_COMBAT_CREATURE_VS_SELF_HITS");
DamageMeters_ParseMessage("Your TestSpell heals you for 0.", "CHAT_MSG_SPELL_SELF_BUFF");
DamageMeters_ParseMessage("Your TestSpell heals you for 0.", "CHAT_MSG_SPELL_SELF_BUFF");
DamageMeters_ParseMessage("Your TestSpell heals you for 0.", "CHAT_MSG_SPELL_SELF_BUFF");
end
----------------------
-- Debug Start
DamageMeters_StartDebugTimer(DMPROF_UPDATE);
local updateBars = false;
local currentTime = GetTime();
local elapsed = currentTime - DamageMeters_lastUpdateTime;
if (DamageMeters_debug4.showGCInfo) then
local gcAmt, gcLimit = gcinfo();
if (DM_Bypass["Constant Update"] == true) then
DamageMeters_tablesDirty = 1;
end
local first = false;
if (DM_lastgcAmt == nil) then
DM_lastgcAmt = 0;
DM_gcDelta = 0;
first = true;
end
local delta = max(0, gcAmt - DM_lastgcAmt);
DM_gcDelta = max(DM_gcDelta, delta);
DM_gcDelta = min(DM_gcDelta, 50);
DamageMeters_sendMsgQueueBar:Show();
DamageMeters_sendMsgQueueBar:SetMinMaxValues(0, 50);
DamageMeters_sendMsgQueueBar:SetValue(ceil(DM_gcDelta));
DM_gcDelta = max(0, DM_gcDelta - 0.5);
DM_lastgcAmt = gcAmt;
if (first) then
DM_gcDelta = 0;
end
DamageMeters_processMsgQueueBar:Show();
DamageMeters_processMsgQueueBar:SetMinMaxValues(0, gcLimit);
DamageMeters_processMsgQueueBar:SetValue(gcAmt);
end
-- If we have queued chain heals, process them now.
if (DamageMeters_queuedChainHealCount > 0) then
if (DamageMeters_queuedChainHealCount > 3) then
-- If we have an unreasonable number, nuke them
DamageMeters_queuedChainHealCount = 0;
else
--DMPrintD("Processing queued chain heals, total = "..DamageMeters_queuedChainHealCount);
local activeIndex = DamageMeters_GetPlayerIndex(UnitName("Player"), DMT_ACTIVE);
local fightIndex = DamageMeters_GetPlayerIndex(UnitName("Player"), DMT_FIGHT);
if (not activeIndex or not fightIndex) then
-- If the player has no index, maybe we had a clear happen between the heal being queued
-- and this tick: just clear it.
DamageMeters_queuedChainHealCount = 0;
else
local hitCount = 1;
while (DamageMeters_queuedChainHealCount > 0) do
-- Add events for the additional chain heals, but don't add the values again to
-- the totals. Also, mark the events with a * at the end to tell other bits of
-- code not to count this one.
local spell = "Chain Heal "..hitCount.."*";
-- index, quantity, spell, amount, crit, relationship
DamageMeters_AddEvent(DMT_ACTIVE,
activeIndex,
DamageMeters_Quantity_HEALING,
spell,
DamageMeters_queuedChainHealValue[DamageMeters_queuedChainHealCount],
DamageMeters_queuedChainHealCrit[DamageMeters_queuedChainHealCount],
DamageMeters_Relation_SELF,
nil );
DamageMeters_AddEvent(DMT_FIGHT,
fightIndex,
DamageMeters_Quantity_HEALING,
spell,
DamageMeters_queuedChainHealValue[DamageMeters_queuedChainHealCount],
DamageMeters_queuedChainHealCrit[DamageMeters_queuedChainHealCount],
DamageMeters_Relation_SELF,
nil );
DamageMeters_queuedChainHealCount = DamageMeters_queuedChainHealCount - 1;
hitCount = hitCount + 1;
end
end
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -