Revision 57

This commit is contained in:
Robin 2021-01-13 15:05:23 +01:00
commit 5e77c77a83
12 changed files with 1042 additions and 0 deletions

6
.gitmodules vendored Normal file
View File

@ -0,0 +1,6 @@
[submodule "Libs/LibCombatlog"]
path = Libs/LibCombatlog
url = https://git.grml.de/rilgamon/LibCombatlog.git
[submodule "Common"]
path = Common
url = https://git.grml.de/rilgamon/Common.git

1
Common Submodule

@ -0,0 +1 @@
Subproject commit 762c59c6c6abc6ecaa71f3e36bb2c6dd16b8e0ed

11
DaVis.toc Normal file
View File

@ -0,0 +1,11 @@
## Interface: 90002
## X-Curse-Project-ID: 304317
## X-Repository: https://svn.grml.de/DaVis
## Title: DaVis
## Notes: Damage Visualization
## Author: Rilgamon
## SavedVariables: DaVisDB
## OptionalDeps: Ace3, zzLibCommon, LibCombatlog
## X-WoWI-ID: 24823
Common\common.xml
pack.xml

1
Libs/LibCombatlog Submodule

@ -0,0 +1 @@
Subproject commit b20f7ecfb0b98006d158ed372d0025fb9ec887bc

261
core.lua Normal file
View File

@ -0,0 +1,261 @@
local name, addon = ...
addon.cTip = CreateFrame("GameTooltip",name.."Tooltip",nil,"GameTooltipTemplate")
local defaults,dmginc,options,db,guid = {},{}
local prefix = {"SWING","RANGE","SPELL","SPELL_PERIODIC","SPELL_BUILDING","ENVIRONMENTAL"}
local suffix = {"DAMAGE","HEAL"}
local subevents = {}
local spamDelay = 10
local spamShow = false
local realm = GetRealmName()
local tank = UnitName("player")
local taunts = {
['355'] = true, -- Warrior taunt
['49576'] = true, -- DK death grip
['56222'] = true, -- DK dark command
['62124'] = true, -- Paladin hand of reckoning
['31789'] = true, -- Paladin righteous defense
['6795'] = true, -- Druid growl
['20736'] = true, -- Hunter distracting shot
['2649'] = true,-- Hunter pet growl rank 1
['17735'] = true, -- Warlock pet suffering rank 1
['115543'] = true, -- Monk Glyph of the ox
['115546'] = true, -- Monk provoke
}
local InCombatGUIDS = {}
local dontspam = {
['2649'] = true,-- Hunter pet growl rank 1
['17735'] = true, -- Warlock pet suffering rank 1
}
local spammer = {}
local L = GetLocale() == 'deDE' and {
['New Tank'] = function(tank)
return string.format("Neuer Tank: |cffffff00%s|r",tank)
end,
["Taunted Fail"] = function(src,dest,spell)
dest = dest or ""
return string.format("|cffff0000Achtung!|r Spott von %s auf %s fehlgeschlagen (%s).",src or "",dest or "",spell or "")
end,
["Taunted"] = function(src,dest,spell)
dest = dest or ""
return string.format("%s hat %s mit %s gespottet.",src,dest,spell)
end,
['Tank'] = "Tank",
} or {
['New Tank'] = function(tank)
return string.format("New Tank: |cffffff00%s|r",tank)
end,
["Taunted Fail"] = function(src,dest,spell)
dest = dest or ""
return string.format("|cffff0000Danger!|r Taunt of %s failed on %s (%s).",src or "",dest or "",spell or "")
end,
["Taunted"] = function(src,dest,spell) dest = dest or ""
return string.format("%s taunted %s using %s.",src,dest,spell)
end,
['Tank'] = "Tank",
}
for _,a in pairs(prefix) do
for _,b in pairs(suffix) do
subevents[#subevents + 1] = format("%s_%s",a,b)
end
end
subevents[#subevents + 1] = "SPELL_CAST_START"
subevents[#subevents + 1] = "SPELL_CAST_SUCCESS"
subevents[#subevents + 1] = "SPELL_MISSED"
local f = CreateFrame("Frame",name,UIParent)
f.width = 350
f.height = 140
f:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
f:SetSize(f.width, f.height)
-- Make movable/resizable
f:SetMovable(true)
f:SetResizable(enable)
f:SetMinResize(100, 100)
f:RegisterForDrag("LeftButton")
f:EnableMouse(true)
f:EnableMouseWheel(true)
f:SetScript("OnDragStart", f.StartMoving)
f:SetScript("OnDragStop", f.StopMovingOrSizing)
f:RegisterEvent("PLAYER_REGEN_DISABLED")
f:RegisterEvent("PLAYER_REGEN_ENABLED")
f:SetScript("OnEvent", function(self, event)
if(event=="PLAYER_REGEN_ENABLED") then
InCombatGUIDS = {}
else
addon:resetBars(dmginc)
end
end)
addon.davisframe = f
local function getPref(pref)
return db[pref[#pref]]
end
local function setPref(pref,value)
db[pref[#pref]] = value
end
local function NameIsTank(tank)
if(IsInRaid()) then
for i = 1,MAX_RAID_MEMBERS do
local name, _, _, _, _, _, _, _, _, role, _, combatRole = GetRaidRosterInfo(i)
if(name and (role == "maintank" or combatRole == 'TANK')) then
local c,r = UnitName(format("raid%i",i))
r = r or realm
if(c and r and format("%s-%s",c,r) == tank) then
return true
end
end
end
else
for i = 1,4 do
local isTank, isHeal, isDPS = UnitGroupRolesAssigned(format("party$i",i))
if(isTank) then
local c,r = UnitName(format("party$i",i))
r = r or realm
if(c and r and format("%s-%s",c,r) == tank) then
return true
end
end
end
return UnitGroupRolesAssigned("player")
end
end
function addon:CLParse(data, prefix, suffix)
-- local event,timestamp, eventtype, hideCaster, sourceGUID, sourceName, sourceFlags, sourceRaidFlags, destGUID, destName, destFlags, destRaidFlags, spellId,spellName,spellSchool = ...
-- 16 amount overkill school resisted blocked absorbed critical glancing crushing isOffHand multistrike
-- data = {...}
-- local prefix, suffix = unpack(addon:SplitCLEvent(data[3]))
if(data[3] == "SPELL_CAST_SUCCESS" or data[3] == "SPELL_MISSED") then
local name = tostring(data[6])
if not (UnitPlayerOrPetInParty(name) or UnitPlayerOrPetInRaid(name) or UnitIsUnit("player",name) or UnitIsUnit("pet",name)) then return end
if(taunts[tostring(data[13])]) then
if(data[3] == "SPELL_CAST_SUCCESS") then
spammer[name] = spammer[name] or { ['count'] = 0, ['lastMessage'] = - spamDelay}
spammer[name]['count'] = spammer[name]['count'] + 1
if(spammer[name]['count'] > spammer[name]['lastMessage'] + spamDelay) then
spamShow = true
spammer[name]['lastMessage'] = spammer[name]['count']
end
if NameIsTank(name) and addon['db']['profile']['ignoreTanks'] then return end
if(not dontspam[tostring(data[13])] or spamShow) then
-- addon['Print'](L["Taunted"](name,data[10],data[14]))
local coloredName,class = UnitClass(name)
if(class) then
coloredName = addon:classcolor(name,class)
end
addon:AddScrollMessage(L["Taunted"](GetPlayerLink(name,("[%s]"):format(coloredName)),data[10],GetSpellLink(data[13])))
end
spamShow = false
else
-- addon['Print'](L["Taunted Fail"](name,data[10],data[14]))
addon:AddScrollMessage(L["Taunted Fail"](name,data[10],GetSpellLink(data[13])))
-- scroll:AddMessage(L["Taunted Fail"](name,data[10],GetSpellLink(data[13])))
end
end
elseif(data[3] == "SPELL_CAST_START") then
local spells = addon:GetHeals()
local isHostile = bit.band(data[11],COMBATLOG_OBJECT_REACTION_HOSTILE)
local isNPC = bit.band(data[11],COMBATLOG_OBJECT_TYPE_NPC)
local isHostileS = bit.band(data[7],COMBATLOG_OBJECT_REACTION_HOSTILE)
local isNPCS = bit.band(data[7],COMBATLOG_OBJECT_TYPE_NPC)
if(spells[data[13]]) then
-- print("iNPC"..tostring(isNPC)..tostring(isNPCS)..GetSpellLink(data[13])..tostring(data[6])..tostring(data[10]))
end
if(spells[data[13]] and isHostile and tonumber(isNPCS)>0) then
-- local name, text, texture, startTimeMS, endTimeMS, isTradeSkill, castID, notInterruptible, spellId = UnitCastingInfo("unit")
addon:AddScrollMessage(("%s %s %s"):format(addon:colorize("Healalarm spellcast started","22ff44"),data[6],GetSpellLink(data[13])))
PlaySound(31754)
end
else
if(guid == data[9]) then
if(suffix == "DAMAGE") then
local offset = prefix == 'SWING' and 13 or 16
-- print(sp[#sp - 1],data[13],data[14],data[15],data[16],offset)
local isPhysical = bit.band(data[15],0x1)
local store = isPhysical>0 and "SWING" or "SPELL"
dmginc[store] = dmginc[store] or {
['amount'] = 0,
-- ['resisted'] = 0,
['blocked'] = 0,
['absorbed'] = 0,
}
if(prefix=="ENVIRONMENTAL" and data[13]=="Falling") then
dmginc[store]['amount'] = dmginc[store]['amount'] + tonumber(data[14] or 0)
else
dmginc[store]['amount'] = dmginc[store]['amount'] + tonumber(data[offset] or 0)
-- dmginc[store]['resisted'] = dmginc[store]['resisted'] + tonumber(data[offset+3] or 0)
dmginc[store]['blocked'] = dmginc[store]['blocked'] + tonumber(data[offset+4] or 0)
dmginc[store]['absorbed'] = dmginc[store]['absorbed'] + tonumber(data[offset+5] or 0)
end
addon:updateBars(dmginc)
end
elseif(suffix == "DAMAGE") then
local isHostile = bit.band(data[11],COMBATLOG_OBJECT_REACTION_HOSTILE)
local isNPC = bit.band(data[11],COMBATLOG_OBJECT_TYPE_NPC)
if(data[9] and isHostile>0 and isNPC>0) then
if(not InCombatGUIDS[data[9]]) then
InCombatGUIDS[data[9]] = true
if(data[5] == guid or UnitPlayerOrPetInRaid(data[6]) or UnitPlayerOrPetInParty(data[6])) then
-- print(data[13], #data)
if(#data == 25) then
addon:AddScrollMessage(format("%s %s pulled %s with %s",addon:colorize("WhoPulled?","ffff44"),data[6],data[10],GetSpellLink(data[13]) or data[13]))
else
addon:AddScrollMessage(format("%s %s pulled %s",addon:colorize("WhoPulled?","ffff44"),data[6],data[10]))
-- print("bodypull")
-- print(unpack(data))
end
end
end
end
else
if(suffix == "HEAL") then
local isHostile = bit.band(data[11],COMBATLOG_OBJECT_REACTION_HOSTILE)
local isNPC = bit.band(data[11],COMBATLOG_OBJECT_TYPE_NPC)
if(data[6] and isHostile>0 and isNPC>0) then
addon:AddHealer(data[6],data[13])
if(InCombatLockdown()) then
addon:AddScrollMessage(("%s %s %s"):format(addon:colorize("Healalarm ","ff0000"),data[6],GetSpellLink(data[13])))
end
end
end
end
end
end
local function toggle(self, button)
if(button=="RightButton") then
if(InterfaceOptionsFrame:IsVisible() and not InCombatLockdown()) then
InterfaceOptionsFrame:Hide()
else
InterfaceOptionsFrame_OpenToCategory(name)
InterfaceOptionsFrame_OpenToCategory(name) -- Twice because of a bug in InterfaceOptionsFrame_OpenToCategory
end
else
if(addon.scrollframe:IsVisible()) then
addon.scrollframe:Hide()
else
addon.scrollframe:Show()
end
end
end
local function init()
LibStub("LibCombatLog"):Embed(addon)
addon:RegisterCLEvent(subevents,"CLParse")
options = addon:InitConfig(name, true, {
['type'] = "data source",
['OnClick'] = toggle,
['icon'] = "Interface\\Icons\\spell_holy_renew"
}, getPref, setPref)
db = addon['db']['profile'][name]
addon:AddConfigEntry(name, 'toggle', 'ignoreTanks', 'Ignore Tanks', 'Dont show taunts of tanks.', 1)
guid = UnitGUID("player")
end
addon:startup(name, name, init, true, defaults)

77
dmgbars.lua Normal file
View File

@ -0,0 +1,77 @@
local name, addon = ...
local texts = {
['SWING'] = {},
['SPELL'] = {},
}
local bars = {
['SWING'] = {
['amount'] = CreateFrame("StatusBar",nil,addon.scrollframe),
-- ['resisted'] = CreateFrame("StatusBar",nil,addon.scrollframe),
['blocked'] = CreateFrame("StatusBar",nil,addon.scrollframe),
['absorbed'] = CreateFrame("StatusBar",nil,addon.scrollframe),
},
['SPELL'] = {
['amount'] = CreateFrame("StatusBar",nil,addon.scrollframe),
-- ['resisted'] = CreateFrame("StatusBar",nil,addon.scrollframe),
['blocked'] = CreateFrame("StatusBar",nil,addon.scrollframe),
['absorbed'] = CreateFrame("StatusBar",nil,addon.scrollframe),
}
}
local function valchange(self)
local a = tonumber(self:GetValue())==0 and self:Hide() or self:Show()
end
local c = 1
local last = addon.scrollframe
for k,v in pairs(bars) do
for a,b in pairs(v) do
b:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
b:GetStatusBarTexture():SetHorizTile(false)
b:SetValue(100)
b:SetWidth(100)
b:SetHeight(10)
b:SetScript("OnValueChanged", valchange)
if(c==1) then
b:SetPoint("TOPLEFT",last,"TOPRIGHT",0,-80)
else
b:SetPoint("BOTTOMLEFT",last,"TOPLEFT",0,0)
end
texts[k][a] = b:CreateFontString(nil, "OVERLAY", "TextStatusBarText")
texts[k][a]:ClearAllPoints()
texts[k][a]:SetAllPoints(b)
texts[k][a]:SetText(a.." 0")
last = b
c = nil
end
end
bars['SWING']['amount']:SetStatusBarColor(1, 1, 0)
--bars['SWING']['resisted']:SetStatusBarColor(.2, .8, .3)
bars['SWING']['blocked']:SetStatusBarColor(.4, .8, .3)
bars['SWING']['absorbed']:SetStatusBarColor(.6, .8, .3)
bars['SPELL']['amount']:SetStatusBarColor(0, 0, 1)
--bars['SPELL']['resisted']:SetStatusBarColor(.2, .8, .3)
bars['SPELL']['blocked']:SetStatusBarColor(.4, .8, .3)
bars['SPELL']['absorbed']:SetStatusBarColor(.6, .8, .3)
function addon:updateBars(dmginc)
local total = 0
for k,v in pairs(dmginc) do
total = total + (dmginc[k] and dmginc[k]['amount'] or 0)
end
for k,v in pairs(bars) do
for a,b in pairs(v) do
local maxval = dmginc[k] and dmginc[k]['amount'] or 0
b:SetMinMaxValues(0, a=='amount' and total or maxval)
b:SetValue(dmginc[k] and dmginc[k][a] or 100)
texts[k][a]:SetText(a .. " " .. (dmginc[k] and dmginc[k][a] or 0))
end
end
end
function addon:resetBars(dmginc)
for k,v in pairs(dmginc) do
for a,b in pairs(v) do
dmginc[k][a] = 0
end
end
self:updateBars(dmginc)
end

172
healalarm.lua Normal file
View File

@ -0,0 +1,172 @@
local name,addon = ...
local healers = {}
local spells = {}
local ha,db,hi
local soundlist = { -- https://de.wowhead.com/sound=79829/7-1-5-brawlers-guild-mushroom-laughter-dqv
18871
}
local hw = CreateFrame("Frame",name.."Healwarning",addon.scrollframe)
hw:SetWidth(32)
hw:SetHeight(32)
hw:SetScript("OnEnter", function(self)
addon.cTip:SetOwner(self, "BOTTOMRIGHT");
addon.cTip:ClearLines()
addon.cTip:AddLine("Healerlist")
for k in pairs(healers) do
addon.cTip:AddLine(k)
end
addon.cTip:Show()
end)
hw:SetScript("OnLeave", function()
addon.cTip:Hide()
end)
hw:SetPoint("BOTTOMRIGHT",addon.scrollframe,"TOPRIGHT")
local tex = hw:CreateTexture()
tex:SetTexture("Interface\\Icons\\spell_holy_renew")
tex:SetAllPoints(hw)
hw:Hide()
hw:RegisterEvent("PLAYER_REGEN_ENABLED")
hw:SetScript("OnEvent",function(self)
self:Hide()
end)
function addon:ShowHeal()
hw:Show()
end
function addon:HideHeal()
hw:Hide()
end
local lastPlayed = 0
function addon:AddHealer(healerName,spellID)
if(not UnitInParty(healerName)) then
healers[healerName] = healers[healerName] or {}
db['healdb'][healerName] = db['healdb'][healerName] or {}
if(not InCombatLockdown()) then return end
if(spellID) then
if(lastPlayed<GetTime()) then
local willPlay, soundHandle = PlaySound(soundlist[1],"Master",false)
if(willPlay) then
C_Timer.After(2,function() if(soundHandle) then StopSound(soundHandle,2) end end)
end
lastPlayed = GetTime() + 4
end
spells[spellID] = true
db['healdb'][healerName]['spells'] = db['healdb'][healerName]['spells'] or {}
db['healdb'][healerName]['info'] = db['healdb'][healerName]['info'] or {}
healers[healerName]['spells'] = healers[healerName]['spells'] or {}
local mapID = C_Map.GetBestMapForUnit("player")
db['healdb'][healerName]['spells'][spellID] = db['healdb'][healerName]['spells'][spellID] or {}
if(mapID) then
db['healdb'][healerName]['info'][mapID] = db['healdb'][healerName]['info'][mapID] or C_Map.GetMapInfo(mapID)
end
healers[healerName]['spells'][spellID] = true
end
end
self:ShowHeal()
ha:Show()
addon:UpdateUnits()
end
function addon:GetHealers()
return healers
end
function addon:GetHeals()
return spells
end
function addon:GetNumHealers()
local n = 0
for k,v in pairs(healers) do
n = n + 1
end
return n
end
function addon:GetAreaHealers(mapID)
local list = {}
if(mapID) then
for k,v in pairs(db['healdb']) do
if(v['info']) then
for a,b in pairs(v['info']) do
if(a==mapID) then
list[#list+1] = k
end
end
end
end
end
return list
end
addon.inits[#addon.inits + 1] = function()
db = addon['db']['profile'][name] or {}
db['healdb'] = db['healdb'] or {}
for k,v in pairs(db['healdb']) do
v['spells'] = v['spells'] or {}
for a,b in pairs(v['spells']) do
spells[a] = true
end
end
hi = addon:AddInfoButton(12883,function(self)
addon.cTip:SetOwner(self, "BOTTOMRIGHT");
addon.cTip:ClearLines()
local mapID = C_Map.GetBestMapForUnit("player")
if(mapID) then
local cnt = 0
local mapInfo = C_Map.GetMapInfo(mapID)
addon.cTip:AddLine(mapInfo["name"])
local list = addon:GetAreaHealers(mapID)
for k,v in pairs(list) do
addon.cTip:AddLine(v)
end
if(#list>0) then
addon.cTip:Show()
end
else
addon.cTip:Hide()
end
end,function(self)
addon.cTip:Hide()
end)
hi:SetScript("OnEvent", function(self,event)
local mapID,list = C_Map.GetBestMapForUnit("player"),{}
if(mapID) then
list = addon:GetAreaHealers(mapID)
end
if(#list>0) then
self:Show()
else
self:Hide()
end
if(GetZonePVPInfo()=='sactuary') then -- hide in sanctuary
addon.scrollframe:Hide()
else
local mapID = C_Map.GetBestMapForUnit("player")
if(mapID) then
local info = C_Map.GetMapInfo(mapID)
if(info and (info['mapID'] == 1161 or info['mapID'] == 1165)) then -- hide in dazar'alor / boralus
addon.scrollframe:Hide()
end
end
end
end)
hi:RegisterEvent("ZONE_CHANGED")
hi:RegisterEvent("ZONE_CHANGED_INDOORS")
hi:RegisterEvent("ZONE_CHANGED_NEW_AREA")
hi:RegisterEvent("NEW_WMO_CHUNK")
hi:RegisterEvent("PLAYER_REGEN_ENABLED")
hi:GetScript("OnEvent")(hi,"FIRE")
ha = addon:AddInfoButton(139, function(self)
addon.cTip:SetOwner(self, "BOTTOMRIGHT");
addon.cTip:ClearLines()
addon.cTip:AddLine("Healerlist")
for k in pairs(healers) do
addon.cTip:AddLine(k)
end
addon.cTip:Show()
end,function(self)
addon.cTip:Hide()
end)
if(addon:GetNumHealers()>0) then
ha:Show()
else
ha:Hide()
end
end

117
infobuttons.lua Normal file
View File

@ -0,0 +1,117 @@
local name, addon = ...
local buttons = {}
local btnfuncs = {}
function btnfuncs:Show()
end
function btnfuncs:Hide()
end
function btnfuncs:OnEnter()
GameTooltip:SetOwner(self,"ANCHOR_CURSOR")
GameTooltip:ClearLines()
GameTooltip:SetSpellByID(self.spellID)
GameTooltip:Show()
end
function btnfuncs:OnLeave()
GameTooltip:Hide()
end
local last
local function update()
local vis = 1
for num, btn in pairs(buttons) do
-- print(num, btn:GetName())
btn:ClearAllPoints()
if(btn:IsVisible()) then
if(vis == 1) then
vis = 2
if(addon.scrollframe:IsVisible()) then
btn:SetPoint("TOPLEFT", addon.scrollframe, "BOTTOMLEFT",10,0)
else
btn:SetPoint("TOPLEFT", addon.scrollframe, "TOPLEFT",10,-4)
end
else
btn:SetPoint("LEFT", last, "RIGHT",10,0)
end
last = btn
end
end
end
addon.UpdateInfoButtons = update
local function NewInfoButton(spellID)
buttons[#buttons + 1] = CreateFrame("Button", name.."Button"..(#buttons + 1), UIParent, "ActionButtonTemplate")
return buttons[#buttons]
end
function addon:AddInfoButton(spellID, ttshow, tthide)
if(spellID) then
local f = NewInfoButton(spellID)
f:SetSize(36,36)
f:SetScale(0.75)
f.spellID = spellID
f:SetFrameStrata("LOW")
f:SetScript("OnHide", update)
f:SetScript("OnShow", update)
f:SetScript("OnEnter", type(ttshow)=='function' and ttshow or btnfuncs.OnEnter)
f:SetScript("OnLeave", type(tthide)=='function' and tthide or btnfuncs.OnLeave)
-- f:SetAttribute("type","spell")
-- f:SetAttribute("spell",f.spellID)
local spellInfo = {GetSpellInfo(f.spellID)}
_G[format("%sIcon",f:GetName())]:SetTexture(spellInfo[3])
spellInfo = nil
f.Update = update
f:Show()
update()
return f
end
end
local rebirth = {}
function rebirth:Update()
local nm = self:GetName()
local ct = _G[format("%sCount",nm)]
local cd = _G[format("%sCooldown",nm)]
if(not cd or not ct) then return end
cd:SetReverse(true)
local currentCharges, maxCharges, cooldownStart, cooldownDuration = GetSpellCharges(self.spellID)
if(currentCharges) then
if(cooldownStart) then
CooldownFrame_Set(cd, cooldownStart, cooldownDuration,1)
else
CooldownFrame_Set(cd,0,0,0)
end
end
ct:SetText(currentCharges and currentCharges or 0)
end
addon.inits[#addon.inits + 1] = function()
local rb = addon:AddInfoButton(20484)
rb.Update = rebirth.Update
rb:RegisterEvent("PLAYER_REGEN_ENABLED")
rb:RegisterEvent("PLAYER_REGEN_DISABLED")
rb:RegisterEvent("PLAYER_DEAD")
rb:RegisterEvent("GROUP_ROSTER_UPDATE")
rb:HookScript("OnEvent", function(self, event, ...)
if(event=="PLAYER_REGEN_ENABLED") then
self:UnregisterEvent("SPELL_UPDATE_CHARGES")
elseif(event=="GROUP_ROSTER_UPDATE") then
if(IsInRaid()) then
self:Show()
else
self:Hide()
end
elseif(event=="PLAYER_DEAD") then
if(not self:IsEventRegistered("SPELL_UPDATE_CHARGES")) then
self:RegisterEvent("SPELL_UPDATE_CHARGES")
end
elseif(event=="PLAYER_REGEN_DISABLED") then
self:RegisterEvent("SPELL_UPDATE_CHARGES")
end
self:Update()
end)
if(IsInGroup()) then
rb:Show()
else
rb:Hide()
end
update()
end

6
license.txt Normal file
View File

@ -0,0 +1,6 @@
The following license excludes the libraries (Libs) included. See the libraries directory or website.
This AddOn is public domain. That means you can change it, rename it or paint it yellow.
My name (Rilgamon) is valid only for WoWInterface.com and curse.com.
If you use/offer this addon on another website please remove my name.
If you want to give me credit you can replace it with a link to my profile on WoWInterface.com.

9
pack.xml Normal file
View File

@ -0,0 +1,9 @@
<Ui xsi:schemaLocation="http://www.blizzard.com/wow/ui/ ..\FrameXML\UI.xsd">
<Script file="Libs/LibCombatlog/LibCombatlog.lua"/>
<Script file="infobuttons.lua"/>
<Script file="core.lua"/>
<Script file="scrollinfo.lua"/>
<Script file="dmgbars.lua"/>
<Script file="healalarm.lua"/>
<Script file="units.lua"/>
</Ui>

93
scrollinfo.lua Normal file
View File

@ -0,0 +1,93 @@
local name, addon = ...
local function chatHoverIn(cf,link,text)
local typ = string.match(link, "^(.-):")
if(typ == "spell") then
GameTooltip:SetOwner(UIParent, "ANCHOR_CURSOR")
GameTooltip:SetHyperlink(link)
ShowUIPanel(GameTooltip)
elseif(typ == "player") then
local typ, name = string.match(link, "^(.-):(.*).*")
if(name) then
GameTooltip:SetOwner(UIParent, "ANCHOR_CURSOR")
GameTooltip:SetUnit(name)
ShowUIPanel(GameTooltip)
-- GameTooltip:Hide()
end
end
end
local function chatHoverOut()
GameTooltip:Hide()
-- HideUIPanel(GameTooltip)
end
local frame = CreateFrame("Frame", name.."ScrollInfoBD", addon.davisframe, BackdropTemplateMixin and "BackdropTemplate" or nil)
frame.width = 350
frame.height = 140
frame:SetFrameStrata("BACKGROUND")
frame:SetAllPoints(addon.davisframe)
--frame:SetSize(frame.width, frame.height)
frame:SetBackdrop({
bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background",
edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Border",
tile = true,
tileSize = 32,
edgeSize = 32,
insets = { left = 8, right = 8, top = 8, bottom = 8 }
})
frame:SetBackdropColor(0, 0, 0, 1)
frame:SetScript("OnHide", function(self) if(not InCombatLockdown()) then self:GetParent():EnableMouse(false) end addon:UpdateInfoButtons() end)
frame:SetScript("OnShow", function(self) if(not InCombatLockdown()) then self:GetParent():EnableMouse(true) end addon:UpdateInfoButtons() end)
frame:Show()
local scroll = CreateFrame("ScrollingMessageFrame", name.."ScrollInfo", frame, BackdropTemplateMixin and "BackdropTemplate" or nil)
scroll:SetFontObject(GameFontNormal)
scroll:SetTextColor(1, 1, 1, 1)
scroll:SetHyperlinksEnabled(true)
scroll:SetSize(frame:GetWidth() - 60,frame:GetHeight() - 30)
scroll:SetPoint("TOPLEFT",frame,"TOPLEFT",10,-10)
scroll:SetJustifyH("LEFT")
scroll:SetFading(false)
scroll:SetMaxLines(300)
scroll:SetScript("OnHyperlinkEnter",chatHoverIn)
scroll:SetScript("OnHyperlinkLeave",chatHoverOut)
scroll:Clear()
scroll:Show()
frame.scroll = scroll
local closeButton = CreateFrame("Button",name.."CloseButton",frame,"UIPanelCloseButton")
closeButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -4, -4)
closeButton:SetFrameStrata("MEDIUM")
local scrollBar = CreateFrame("Slider", nil, frame, "UIPanelScrollBarTemplate")
scrollBar:SetPoint("TOPRIGHT", closeButton, "BOTTOMRIGHT", -1, -12)
scrollBar:SetSize(30, frame:GetHeight() - 76)
scrollBar:SetMinMaxValues(0, 99)
scrollBar:SetValueStep(1)
scrollBar.scrollStep = 1
frame.scrollBar = scrollBar
scrollBar:SetScript("OnValueChanged", function(self, value)
scroll:SetScrollOffset(select(2, scrollBar:GetMinMaxValues()) - value)
end)
scrollBar:SetValue(select(2, scrollBar:GetMinMaxValues()))
frame:SetScript("OnMouseWheel", function(self, delta)
local cur_val = scrollBar:GetValue()
local min_val, max_val = scrollBar:GetMinMaxValues()
if delta < 0 and cur_val < max_val then
cur_val = math.min(max_val, cur_val + 1)
scrollBar:SetValue(cur_val)
elseif delta > 0 and cur_val > min_val then
cur_val = math.max(min_val, cur_val - 1)
scrollBar:SetValue(cur_val)
end
end)
addon.scrollframe = frame
function addon:AddScrollMessage(msg)
if(not frame:IsVisible()) then
frame:Show()
end
scroll:AddMessage(date("[%H:%M]")..msg)
end

288
units.lua Normal file
View File

@ -0,0 +1,288 @@
local name,addon = ...
local units = {}
units[#units+1] = CreateFrame("Button",name..'player',UIParent, BackdropTemplateMixin and "SecureUnitButtonTemplate BackdropTemplate" or "SecureUnitButtonTemplate")
units[#units]:SetAttribute("unit","playertarget")
for a = 1,4 do
local unit = "party"..a.."target"
local b = CreateFrame("Button",name..unit,UIParent, BackdropTemplateMixin and "SecureUnitButtonTemplate BackdropTemplate" or "SecureUnitButtonTemplate")
b:SetAttribute("unit",unit)
units[#units+1] = b
end
local guids = {}
local tanks = {}
local function getUnitName(unit)
if(not unit) then return end
local c,r = UnitName(unit)
if(not c) then return end
if(r and r~='') then
return format("%s-%s",c,r)
else
local realm = GetRealmName()
if(realm) then
return format("%s-%s",c,realm)
else
return c
end
end
end
local function setTanks()
wipe(tanks)
local tank = nil
if(GetNumGroupMembers()) then
for i = 1,MAX_RAID_MEMBERS do
local name, _, _, _, _, _, _, _, _, role, _, combatRole = GetRaidRosterInfo(i)
if(name and (role == "maintank" or combatRole == 'TANK')) then
tanks[#tanks+1] = getUnitName("raid"..i)
end
end
else
for i = 1,4 do
local isTank, isHeal, isDPS = UnitGroupRolesAssigned("party"..i)
if(isTank) then
tanks[#tanks+1] = getUnitName("party"..i)
end
end
end
if(#tanks < 1) then
tanks[#tanks+1] = getUnitName("player")
end
end
function addon:RAID_ROSTER_UPDATE(event, ...)
end
local function updateRaidTarget(self)
local unit = self:GetAttribute("unit")
local icon=GetRaidTargetIndex(unit)
local a,b,c,d
local b = 0
if UnitExists(unit) and icon then
if(icon<5) then
a = icon
c = 0
else
a = icon - 4
c = 0.25
end
a = 0.25 * a
b = a - 0.25
d = c + 0.25
self.raidiconframe.tex:SetTexCoord(b,a,c,d)
self.raidiconframe:Show()
local guid = UnitGUID(unit)
if(guids[guid] ~= icon) then
guids[guid] = icon
addon:AddScrollMessage("|TInterface\\TargetingFrame\\UI-RaidTargetingIcon_"..icon..":0|t on "..UnitName(unit))
end
else
self.raidiconframe:Hide()
end
end
local function isTank(unit)
setTanks()
local uname = getUnitName(unit)
for k,v in pairs(tanks) do
if(uname == v) then return true end
end
end
local function updateThreat(self,event,tunit,...)
if(addon:IsClassic()) then return end
local unit = self:GetAttribute("unit")
if(UnitExists(unit)) then
if(tunit) then
if(isTank(tunit)) then
-- print("isTank "..getUnitName(tunit)..tostring(#tanks))
end
local stat = isTank(tunit) and UnitThreatSituation(tunit,unit) or UnitThreatSituation(unit)
if(stat) then
self:SetBackdropBorderColor(GetThreatStatusColor(stat))
end
end
end
if(event=="PLAYER_REGEN_ENABLED") then
self:SetBackdropBorderColor(1,1,1,.5)
end
end
local function updateHealth(self, event, unit, ...)
if(event=="UNIT_TARGET") then
unit = unit.."target"
updateRaidTarget(self)
updateThreat(self,event,unit,...)
elseif(event=="PLAYER_REGEN_ENABLED" or event=="PLAYER_REGEN_DISABLED") then
updateThreat(self,event,unit,...)
elseif(event=="UNIT_THREAT_LIST_UPDATE" or event=="UNIT_THREAT_SITUATION_UPDATE") then
updateThreat(self,event,unit,...)
elseif(event=="RAID_TARGET_UPDATE") then
for _,u in pairs(units) do
updateRaidTarget(u)
end
return
end
if(unit and UnitIsUnit(self:GetAttribute("unit"), unit)) then
local h = UnitHealth(unit)
local m = UnitHealthMax(unit)
local healers = addon:GetHealers()
local d = m/100
if(d > 0) then
local p = h / d
self['text']:SetText(addon:colorize(format("%.0f%%",p),healers[UnitName(unit)] and "00ff00" or "ffffff"))
else
self['text']:SetText(addon:colorize(format("%.0f%%",0),healers[UnitName(unit)] and "00ff00" or "ffffff"))
end
end
end
function addon:UpdateUnits()
for _,u in pairs(units) do
local unit = u:GetAttribute("unit")
updateHealth(u, "UNIT_HEALTH", unit)
end
end
local function showUnit(self)
GameTooltip:SetOwner(UIParent,"ANCHOR_CURSOR")
-- GameTooltip:SetPoint("BOTTOMRIGHT", UIParent, "BOTTOMRIGHT",-40,40)
GameTooltip:SetUnit(self:GetAttribute("unit"))
ShowUIPanel(GameTooltip)
end
local function hideUnit(self)
GameTooltip:Hide()
end
local a = 20
ClickCastFrames = ClickCastFrames or {}
for _, u in pairs(units) do
u:SetWidth(40)
u:SetHeight(20)
u:ClearAllPoints()
u:SetPoint("BOTTOMLEFT",addon.davisframe,"TOPLEFT",a,12)
u:SetBackdrop({
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
tile = true,
tileSize = 1,
edgeFile = "Interface/Buttons/WHITE8x8",
edgeSize = 1,
insets = { left = 0, right = 0, top = 0, 0 }
})
u:SetBackdropBorderColor(1,1,1,1)
u:SetBackdropColor(0,0,0,.5)
u:RegisterUnitEvent("UNIT_HEALTH", u:GetAttribute("unit"))
u:RegisterUnitEvent("UNIT_TARGET", u:GetAttribute("unit"))
u:RegisterEvent("RAID_TARGET_UPDATE")
if(not addon:IsClassic()) then
u:RegisterUnitEvent("UNIT_THREAT_LIST_UPDATE", u:GetAttribute("unit"))
u:RegisterUnitEvent("UNIT_THREAT_SITUATION_UPDATE", u:GetAttribute("unit"))
end
u:RegisterEvent("PLAYER_REGEN_ENABLED")
u:RegisterEvent("PLAYER_REGEN_DISABLED")
u:HookScript("OnEvent", updateHealth)
u:HookScript("OnEnter", showUnit)
u:HookScript("OnLeave", hideUnit)
local c = u:CreateFontString(nil,"OVERLAY","CombatLogFont")
c:ClearAllPoints()
c:SetAllPoints(u)
c:SetJustifyH("CENTER")
c:SetText("100")
u['text'] = c
ClickCastFrames[u] = true
RegisterUnitWatch(u)
a = a + u:GetWidth()
local ri = CreateFrame("FRAME",nil,u, BackdropTemplateMixin and "BackdropTemplate" or nil)
ri:SetSize(16,16)
ri:SetPoint("BOTTOM",u,"TOP")
ri.tex = ri:CreateTexture(nil,"OVERLAY")
ri.tex:SetTexture("Interface\\TargetingFrame\\UI-RaidTargetingIcons")
ri.tex:SetAllPoints(ri)
u.raidiconframe = ri
updateRaidTarget(u)
end
local group = {
"player","party1","party2","party3","party4"
}
a = 20
local function hbShow(self)
local r,g,b = GetClassColor(select(2,UnitClass(self.unit)))
self:SetStatusBarColor(r,g,b,1)
end
local function pbShow(self)
local powerType, powerToken, altR, altG, altB = UnitPowerType(self.unit)
local info = PowerBarColor[powerToken]
if(info) then
self:SetStatusBarColor(info.r, info.g, info.b,1)
end
end
local function colorUpdate(self,event,unit,powertype)
if(event == "GROUP_ROSTER_UPDATE") then
local r,g,b = GetClassColor(select(2,UnitClass(self.unit)))
self:SetStatusBarColor(r,g,b,1)
elseif(unit and unit == self.unit) then
if(event == "UNIT_HEALTH" or event == "UNIT_HEALTH_FREQUENT" or event == "UNIT_MAXHEALTH" or event == "PLAYER_ENTERING_WORLD") then
self:SetValue(UnitHealth(unit) / (UnitHealthMax(unit)/100))
elseif(event == "UNIT_POWER_UPDATE" or event == "UNIT_POWER_FREQUENT" or event == "UNIT_MAXPOWER" or event == "PLAYER_ENTERING_WORLD") then
self:SetValue(UnitPower(unit) / (UnitPowerMax(unit)/100))
pbShow(self)
end
end
end
for _,unit in pairs(group) do
local u = CreateFrame("Button",name..unit,UIParent, BackdropTemplateMixin and "SecureUnitButtonTemplate BackdropTemplate" or "SecureUnitButtonTemplate")
u:SetAttribute("unit",unit)
u:SetSize(40,10)
u:ClearAllPoints()
u:SetPoint("BOTTOMLEFT",addon.davisframe,"TOPLEFT",a,0)
-- u:HookScript("OnEnter", showUnit)
-- u:HookScript("OnLeave", hideUnit)
u:SetBackdrop({
bgFile = "Interface/Tooltips/UI-Tooltip-Background",
tile = true,
tileSize = 1,
edgeSize = 1,
edgeFile = "Interface/Buttons/WHITE8X8",
insets = { left = 0, right = 0, top = 0, 0 }
})
u:SetBackdropBorderColor(.3,.3,.3,.3)
u:SetBackdropColor(0,0,0,.5)
ClickCastFrames[u] = true
RegisterUnitWatch(u)
local s = CreateFrame("StatusBar", "$PARENThealthbar", u)
s:RegisterEvent("GROUP_ROSTER_UPDATE")
s:RegisterUnitEvent("UNIT_HEALTH", unit)
-- s:RegisterEvent("UNIT_HEALTH_FREQUENT")
s:RegisterUnitEvent("UNIT_MAXHEALTH", unit)
s.unit = unit
s:SetFrameStrata("BACKGROUND")
s:SetSize(40,5)
s:SetPoint("TOPLEFT",u,"TOPLEFT",0 ,0)
s:SetMinMaxValues(0,100)
s:SetOrientation("HORIZONTAL")
s:SetValue(100)
s:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
s:GetStatusBarTexture():SetHorizTile(false)
s:GetStatusBarTexture():SetVertTile(false)
s:SetScript("OnEvent", colorUpdate)
s:SetScript("OnShow", hbShow)
hbShow(s)
local h = CreateFrame("StatusBar", "$PARENTpowerbar", u)
h:RegisterEvent("GROUP_ROSTER_UPDATE")
h:RegisterEvent("PLAYER_ENTERING_WORLD")
h:RegisterUnitEvent("UNIT_POWER_UPDATE", unit)
-- h:RegisterEvent("UNIT_POWER_FREQUENT")
h:RegisterUnitEvent("UNIT_MAXPOWER", unit)
h:SetScript("OnEvent", colorUpdate)
h.unit = unit
h:SetFrameStrata("BACKGROUND")
h:SetSize(40,5)
h:SetPoint("TOPLEFT",u,"TOPLEFT",0 ,-5)
h:SetMinMaxValues(0,100)
h:SetOrientation("HORIZONTAL")
h:SetValue(100)
h:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
h:GetStatusBarTexture():SetHorizTile(false)
h:GetStatusBarTexture():SetVertTile(false)
h:SetScript("OnShow", pbShow)
pbShow(h)
a = a + u:GetWidth()
end