/
local DR_POLYMORPH = 0 |
local DR_STUN = 1 |
local DR_STUN_PROC = 2 |
local DR_FEAR = 3 |
local DR_HORROR = 4 |
local DR_ROOT = 5 |
local DR_ROOT_PROC = 6 |
local DR_CYCLONE = 7 |
local DR_SLEEP = 8 |
local DR_CHARM = 9 |
local DR_KIDNEY_SHOT = 10 |
LibDiminishingSpells = { |
[5211] = 8983, |
[6798] = 8983, |
[8983] = { -- bash |
cat = DR_STUN, |
pve = false, |
}, |
[339] = 26989, |
[1062] = 26989, |
[5195] = 26989, |
[5196] = 26989, |
[9852] = 26989, |
[9853] = 26989, |
[26989] = { -- entangling roots |
cat = DR_ROOT, |
pve = false, |
}, |
[19975] = 27010, |
[19974] = 27010, |
[19973] = 27010, |
[19972] = 27010, |
[19971] = 27010, |
[19970] = 27010, |
[27010] = { -- nature's grasp |
cat = DR_ROOT_PROC, |
pve = false, |
}, |
[2637] = 18658, |
[18657] = 18658, |
[18658] = { -- hibernate |
cat = DR_SLEEP, |
pve = false, |
}, |
[33786] = { -- cyclone |
cat = DR_CYCLONE, |
pve = true, |
}, |
[16922] = { -- celestial focus |
cat = DR_STUN_PROC, |
pve = true, |
}, |
[19185] = { -- entrapment |
cat = DR_ROOT_PROC, |
pve = true, |
}, |
[118] = 12826, |
[12824] = 12826, |
[12825] = 12826, |
[28271] = 12826, |
[28272] = 12826, |
[12826] = { -- polymorph |
cat = DR_POLYMORPH, |
pve = false, |
}, |
[122] = 27088, |
[865] = 27088, |
[6131] = 27088, |
[10230] = 27088, |
[33395] = 27088, |
[27088] = { -- frost nova |
cat = DR_ROOT, |
pve = false, |
}, |
[12355] = { -- impact |
cat = DR_STUN_PROC, |
pve = true, |
}, |
[12494] = { -- frostbite |
cat = DR_ROOT_PROC, |
pve = false, |
}, |
[853] = 10308, |
[5588] = 10308, |
[5589] = 10308, |
[10308] = { -- hammer of justice |
cat = DR_STUN, |
pve = true, |
}, |
[20170] = { -- seal of justice stun proc |
cat = DR_STUN_PROC, |
pve = true, |
}, |
[8122] = 10890, |
[8124] = 10890, |
[10888] = 10890, |
[10890] = { -- psychic scream |
cat = DR_FEAR, |
pve = false, |
}, |
[13181] = { -- gnomish mind control cap |
cat = DR_CHARM, |
pve = false, |
}, |
[605] = 10912, |
[10911] = 10912, |
[10912] = { -- mind control |
cat = DR_CHARM, |
pve = false, |
}, |
[15269] = { -- blackout |
cat = DR_STUN_PROC, |
pve = true, |
}, |
[6770] = 11297, |
[2070] = 11297, |
[11297] = { -- sap |
cat = DR_POLYMORPH, |
pve = false, |
}, |
[1776] = 38764, |
[1777] = 38764, |
[8629] = 38764, |
[11285] = 38764, |
[11286] = 38764, |
[38764] = { -- gouge |
cat = DR_POLYMORPH, |
pve = false, |
}, |
[2094] = { -- blind |
cat = DR_CYCLONE, |
pve = true, |
}, |
[1833] = { -- cheap shot |
cat = DR_STUN, |
pve = true, |
}, |
[408] = 8643, |
[8643] = { -- kidney shot |
cat = DR_KIDNEY_SHOT, |
pve = true, |
}, |
[5530] = { -- mace spec |
cat = DR_STUN_PROC, |
pve = true, |
}, |
[5782] = 6215, |
[6213] = 6215, |
[6215] = { -- fear |
cat = DR_FEAR, |
pve = false, |
}, |
[6358] = { -- seduction |
cat = DR_FEAR, |
pve = false, |
}, |
[5484] = 17928, |
[17928] = { -- howl of terror |
cat = DR_FEAR, |
pve = false, |
}, |
[6789] = 27223, |
[17925] = 27223, |
[17926] = 27223, |
[27223] = { -- death coil |
cat = DR_HORROR, |
pve = false, |
}, |
[30283] = 30414, |
[30413] = 30414, |
[30414] = { -- shadowfury |
cat = DR_STUN, |
pve = true, |
}, |
[7922] = { -- charge stun |
cat = DR_STUN, |
pve = true, |
}, |
[20253] = 25274, |
[20614] = 25274, |
[20615] = 25274, |
[25273] = 25274, |
[30153] = 25274, |
[30195] = 25274, |
[30197] = 25274, |
[25274] = { -- intercept stun |
cat = DR_STUN, |
pve = true, |
}, |
[12809] = { -- concussion blow |
cat = DR_STUN, |
pve = true, |
}, |
} |
-- $Id: LibStub.lua 48018 2007-09-03 01:50:17Z mikk $ |
-- LibStub is a simple versioning stub meant for use in Libraries. http://www.wowace.com/wiki/LibStub for more info |
-- LibStub is hereby placed in the Public Domain |
-- Credits: Kaelten, Cladhaire, ckknight, Mikk, Ammo, Nevcairiel, joshborke |
local LIBSTUB_MAJOR, LIBSTUB_MINOR = "LibStub", 2 -- NEVER MAKE THIS AN SVN REVISION! IT NEEDS TO BE USABLE IN ALL REPOS! |
local LibStub = _G[LIBSTUB_MAJOR] |
-- Check to see is this version of the stub is obsolete |
if not LibStub or LibStub.minor < LIBSTUB_MINOR then |
LibStub = LibStub or {libs = {}, minors = {} } |
_G[LIBSTUB_MAJOR] = LibStub |
LibStub.minor = LIBSTUB_MINOR |
-- LibStub:NewLibrary(major, minor) |
-- major (string) - the major version of the library |
-- minor (string or number ) - the minor version of the library |
-- |
-- returns nil if a newer or same version of the lib is already present |
-- returns empty library object or old library object if upgrade is needed |
function LibStub:NewLibrary(major, minor) |
assert(type(major) == "string", "Bad argument #2 to `NewLibrary' (string expected)") |
minor = assert(tonumber(strmatch(minor, "%d+")), "Minor version must either be a number or contain a number.") |
local oldminor = self.minors[major] |
if oldminor and oldminor >= minor then return nil end |
self.minors[major], self.libs[major] = minor, self.libs[major] or {} |
return self.libs[major], oldminor |
end |
-- LibStub:GetLibrary(major, [silent]) |
-- major (string) - the major version of the library |
-- silent (boolean) - if true, library is optional, silently return nil if its not found |
-- |
-- throws an error if the library can not be found (except silent is set) |
-- returns the library object if found |
function LibStub:GetLibrary(major, silent) |
if not self.libs[major] and not silent then |
error(("Cannot find a library instance of %q."):format(tostring(major)), 2) |
end |
return self.libs[major], self.minors[major] |
end |
-- LibStub:IterateLibraries() |
-- |
-- Returns an iterator for the currently registered libraries |
function LibStub:IterateLibraries() |
return pairs(self.libs) |
end |
setmetatable(LibStub, { __call = LibStub.GetLibrary }) |
end |
local MAJOR_VERSION = "LibDiminishing-1.0" |
local MINOR_VERSION = tonumber(("$Rev: 1 $"):match("%d+")) |
local lib = LibStub:NewLibrary(MAJOR_VERSION, MINOR_VERSION) |
--local lib = {} |
if not lib then |
return |
end |
lib.targets = lib.targets or {} |
lib.listeners = lib.listeners or { |
start = { }, |
finish = { }, |
} |
if not lib.frame then |
lib.frame = CreateFrame("Frame") |
end |
local spells = LibDiminishingSpells |
local DR_POLYMORPH = 0 |
local DR_STUN = 1 |
local DR_STUN_PROC = 2 |
local DR_FEAR = 3 |
local DR_HORROR = 4 |
local DR_ROOT = 5 |
local DR_ROOT_PROC = 6 |
local DR_CYCLONE = 7 |
local DR_SLEEP = 8 |
local DR_CHARM = 9 |
local DR_KIDNEY_SHOT = 10 |
local DR_MAX = 11 |
lib.DR_POLYMORPH = DR_POLYMORPH |
lib.DR_STUN = DR_STUN |
lib.DR_STUN_PROC = DR_STUN_PROC |
lib.DR_FEAR = DR_FEAR |
lib.DR_HORROR = DR_HORROR |
lib.DR_ROOT = DR_ROOT |
lib.DR_ROOT_PROC = DR_ROOT_PROC |
lib.DR_CYCLONE = DR_CYCLONE |
lib.DR_SLEEP = DR_SLEEP |
lib.DR_CHARM = DR_CHARM |
lib.DR_KIDNEY_SHOT = DR_KIDNEY_SHOT |
local COMBATLOG_OBJECT_AFFILIATION_MINE = COMBATLOG_OBJECT_AFFILIATION_MINE |
local COMBATLOG_OBJECT_AFFILIATION_PARTY = COMBATLOG_OBJECT_AFFILIATION_PARTY |
local COMBATLOG_OBJECT_AFFILIATION_RAID = COMBATLOG_OBJECT_AFFILIATION_RAID |
local COMBATLOG_OBJECT_REACTION_HOSTILE = COMBATLOG_OBJECT_REACTION_HOSTILE |
local COMBATLOG_OBJECT_CONTROL_PLAYER = COMBATLOG_OBJECT_CONTROL_PLAYER |
local COMBATLOG_OBJECT_CONTROL_NPC = COMBATLOG_OBJECT_CONTROL_NPC |
local GROUP_AFFILIATION = bit.bor(COMBATLOG_OBJECT_AFFILIATION_PARTY, COMBATLOG_OBJECT_AFFILIATION_RAID, COMBATLOG_OBJECT_AFFILIATION_MINE) |
local function p(msg) |
DEFAULT_CHAT_FRAME:AddMessage(tostring(msg)) |
end |
function lib:AddStartListener(func) |
table.insert(self.listeners.start, func) |
end |
function lib:AddFinishListener(func) |
table.insert(self.listeners.finish, func) |
end |
function lib:RemoveStartListener(func) |
local found = table.foreachi(self.listeners.start, function(i, v) |
return func == v and i or nil |
end) |
if found then |
table.remove(self.listeners.start, found) |
end |
end |
function lib:RemoveFinishListener(func) |
local found = table.foreachi(self.listeners.finish, function(i, v) |
return func == v and i or nil |
end) |
if found then |
table.remove(self.listeners.finish, found) |
end |
end |
function lib:GetSpellCat(spellId) |
local spell = spells[spellId] or nil |
if type(spell) == "number" then |
spell = spells[spell] |
end |
return spell |
end |
function lib:GetGUIDCatStatus(guid, cat) |
if not self.targets[guid] or not self.targets[guid][cat] then |
return 0, 1, nil |
else |
local unitCat = self.targets[guid][cat] |
return unitCat.count, unitCat.factor, unitCat.remaining |
end |
end |
function lib:GetGUIDStatus(guid) |
if not self.targets[guid] then |
return nil |
end |
return pairs(self.targets[guid]) |
end |
function lib:GetUnitCatStatus(unitid, cat) |
local guid = UnitGUID(unitid) |
return self:GetGUIDCatStatus(guid) |
end |
function lib:GetUnitStatus(unitid) |
local guid = UnitGUID(unitid) |
return self:GetGUIDStatus(guid) |
end |
local function OnCombatEvent(timestamp, eventType, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags, ...) |
if eventType == "SPELL_AURA_REMOVED" then |
local spellId, spellName, spellSchool, auraType = ... |
--p(spellName) |
local spell = spells[spellId] or nil |
if type(spell) == "number" then |
spell = spells[spell] |
end |
if not spell then return end |
local pve = (bit.band(dstFlags, COMBATLOG_OBJECT_CONTROL_NPC) == COMBATLOG_OBJECT_CONTROL_NPC) |
if pve and not spell.pve then |
return |
end |
lib.targets[dstGUID] = lib.targets[dstGUID] or {} |
if not lib.targets[dstGUID][spell.cat] then |
lib.targets[dstGUID][spell.cat] = { count = 1, factor = 0.5, } |
elseif lib.targets[dstGUID][spell.cat].count < 3 then |
lib.targets[dstGUID][spell.cat].count = lib.targets[dstGUID][spell.cat].count + 1 |
lib.targets[dstGUID][spell.cat].factor = (lib.targets[dstGUID][spell.cat].factor * 0.5 > 0.2 and 0.25) or 0 |
end |
local curTime = GetTime() |
lib.targets[dstGUID][spell.cat].remaining = 15 |
lib.targets[dstGUID][spell.cat].last = GetTime() |
table.foreachi(lib.listeners.start, function(i, func) |
func(dstGUID, spell.cat, lib.targets[dstGUID][spell.cat].count, lib.targets[dstGUID][spell.cat].factor) |
end) |
local ispve = "no" |
if pve then |
ispve = "yes" |
end |
--p("Spell end: " .. spellName .. " at " .. timestamp .. " (" .. GetTime() .. ") - count at " .. lib.targets[dstGUID][spell.cat].count .. " in pve? " .. ispve) |
end |
end |
local updateInterval = 0.2 |
local sinceUpdate = 0 |
local function OnUpdate(this, delta) |
sinceUpdate = sinceUpdate + delta |
while (sinceUpdate > updateInterval) do |
local curTime = GetTime() |
table.foreach(lib.targets, function(guid, v) |
local count = 0 |
for cat = 0, DR_MAX do |
if v[cat] then |
v[cat].remaining = curTime - v[cat].last |
if v[cat].remaining <= 0 then |
v[cat] = nil |
--p(i .. " + " .. cat .. " timed out") |
table.foreachi(lib.listeners.finish, function(i, func) |
func(guid, cat) |
end) |
else |
count = count + 1 |
end |
end |
end |
if count == 0 then |
lib.targets[i] = nil |
--p(i .. " timed out") |
end |
end) |
sinceUpdate = sinceUpdate - updateInterval |
end |
end |
local function OnEvent(this, event, ...) |
--p("OnEvent: " .. event) |
if event == "COMBAT_LOG_EVENT_UNFILTERED" then |
OnCombatEvent(...) |
end |
end |
lib.frame:SetScript("OnUpdate", OnUpdate) |
lib.frame:SetScript("OnEvent", OnEvent) |
lib.frame:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED") |
<Ui xmlns="http://www.blizzard.com/wow/ui/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.blizzard.com/wow/ui/ |
..\FrameXML\UI.xsd"> |
<Script file="Spells.lua" /> |
<Script file="LibDiminishing-1.0.lua" /> |
</Ui> |
## Interface: 20400 |
## Title: Lib: Diminishing-1.0 |
## Notes: Diminishing returns monitoring library |
## Author: Adept (an.adept@gmail.com) |
## Version: 1.0 |
## X-Category: Library |
## X-License: MIT |
LibStub.lua |
lib.xml |