diff --git a/DKCrutch.lua b/DKCrutch.lua
index 05092f4..e3570d2 100755
--- a/DKCrutch.lua
+++ b/DKCrutch.lua
@@ -1,5 +1,5 @@
-------------------------------------------------------------------------------
--- DKCrutch 0.9.5
+-- DKCrutch 0.9.6
--
-- Death Knight rune tracker and ability advisor
-------------------------------------------------------------------------------
@@ -8,7 +8,7 @@ DKCrutch = {Locals = {}}
local L = DKCrutch.Locals
-DKCrutch.versionNumber = '0.9.5'
+DKCrutch.versionNumber = '0.9.6'
DKCrutch.talent = ""
DKCrutch.talentUnsure = true
DKCrutch.DebugMode = false
@@ -164,6 +164,89 @@ function DKCrutch.events.PLAYER_LOGIN()
DKCrutch.eventFrame:UnregisterEvent("PLAYER_LOGIN")
end
+function DKCrutch:SetSwingBarWidth(element, time, speed, maxwidth)
+ DKCrutch:Debug("SetSwingBarWidth" .. " t: " .. time .." s:" .. speed , maxwidth)
+ local width = ( time / speed * maxwidth );
+ if ( width < 1 ) then
+ width = 1;
+ elseif ( width > maxwidth ) then
+ width = maxwidth;
+ end
+ element:SetValue(width);
+end
+
+function DKCrutch:GetSwingSpeed(element)
+ local mainhand,offhand = UnitAttackSpeed("player");
+ if ( DKCrutch.dualWield ) and ( element.SLOT == GetInventorySlotInfo("SecondaryHandSlot") ) then
+ return(offhand);
+ else
+ return(mainhand);
+ end
+end
+
+function DKCrutch:SetSwingSpeed(element, speed)
+ if ( speed == nil ) then
+ element.speed = DKCrutch:GetSwingSpeed(element);
+ if ( element.speed == nil ) then
+ element:Hide();
+ return(nil);
+ end
+ else
+ element.speed = speed;
+ end
+ _,_,element.latency = GetNetStats();
+ element.latency = element.latency / 1000;
+ DKCrutch:Debug("SwingFrame l: " .. element.latency .." s:" .. element.speed , element.maxwidth)
+ DKCrutch:SetSwingBarWidth(element, element.latency, element.speed, element.maxwidth);
+end
+
+function DKCrutch:ResetSwingFrame(element)
+ element:SetScript("OnUpdate", nil);
+ element.lastupdate = 0;
+ element.maxwidth = 128;
+ element.elapsed = 0;
+ DKCrutch:SetSwingSpeed(element);
+ element:SetMinMaxValues(0, element.maxwidth);
+ element:SetValue(0);
+ element.active = nil;
+ element:Show();
+ element.vanish = 0;
+end
+
+function DKCrutch.VanishFrame(element,elapsed)
+ DKCrutch:Debug("VanishFrame", elapsed)
+ if ( element.vanish > 0 ) then
+ element.vanish = element.vanish - elapsed;
+ if ( element.vanish <= 0 ) then
+ element:SetScript("OnUpdate", nil);
+ element:Hide();
+ end
+ end
+end
+
+function DKCrutch.UpdateSwingFrame(element,elapsed)
+ -- performance throttle
+ element.lastupdate = element.lastupdate + elapsed;
+ if ( element.lastupdate < 0.03 ) then
+ return(nil);
+ end
+ element.elapsed = element.elapsed + element.lastupdate;
+ element.lastupdate = 0;
+
+ -- flag the swing timer as inactive early to help account for lag
+ if ( element.elapsed > (element.speed - element.latency ) ) then
+ element.active = nil;
+ end
+
+ if ( element.elapsed > element.speed ) then
+ DKCrutch:ResetSwingFrame(element);
+ element.vanish = 2.5;
+ element:SetScript("OnUpdate", DKCrutch.VanishFrame);
+ end
+
+ DKCrutch:SetSwingBarWidth(element, element.elapsed, element.speed, element.maxwidth);
+end
+
function DKCrutch.events.COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaster, srcGUID, srcName, srcFlags, srcRaidFlags, dstGUID, dstName, dstFlags, dstRaidFlags, spellId, spellName, spellSchool, damage, ...)
if(DKCrutchDB.enabled) and (srcName == DKCrutch.playerName) then
DKCrutch:Update()
@@ -171,6 +254,13 @@ function DKCrutch.events.COMBAT_LOG_EVENT_UNFILTERED(timestamp, event, hideCaste
-- enemy count for AoE advise and multiple player in combat (for aggro warning)
DKCrutch:CountPerson(timestamp, event, srcGUID, srcName, srcFlags, dstGUID, dstName, dstFlags)
end
+ if (not DKCrutchDB.swingDisable) then
+ if ( string.sub(event,1,5) == "SWING" ) and ( srcGUID == UnitGUID("player") ) then
+ -- reset the swing frame to 0
+ DKCrutch:ResetSwingFrame(DKCrutch.swingFrame);
+ DKCrutch.swingFrame:SetScript("OnUpdate", DKCrutch.UpdateSwingFrame);
+ end
+ end
end
end
@@ -211,11 +301,29 @@ function DKCrutch:OnLoad()
-- load defaults, if first start
DKCrutch:InitSettings()
+ -- create config panel
+ DKCrutch:CreateConfig()
+
-- add slash command
- SlashCmdList["DKCrutch"] = DKCrutch.Options
+ SlashCmdList["DKCrutch"] = function(msg)
+ if (msg=='debug') then
+ if (DKCrutch.DebugMode) then
+ DKCrutch:Debug("Debug ended", GetTime())
+ end
+ DKCrutch.DebugMode = not ( DKCrutch.DebugMode )
+ local debugStatus = "disabled"
+ if (DKCrutch.DebugMode) then
+ debugStatus = "enabled. Using frame: " .. DKCrutch.DebugChat:GetID()
+ DKCrutch:Debug("Debug started", GetTime())
+ end
+ DEFAULT_CHAT_FRAME:AddMessage("DKCrutch Debug " .. debugStatus)
+ else
+ DKCrutch:Debug("Config panel ", DKCrutch.configPanel.name)
+ InterfaceOptionsFrame_OpenToCategory(DKCrutch.configPanel)
+ InterfaceOptionsFrame_OpenToCategory(DKCrutch.configPanel)
+ end
+ end
SLASH_DKCrutch1 = "/dkc"
-
- DKCrutch:CreateConfig()
-- check if talent is elemental
DKCrutch:detectTalent()
@@ -258,23 +366,6 @@ function DKCrutch:Debug(statictxt,msg)
end
end
-function DKCrutch.Options(msg)
- if (msg=='debug') then
- if (DKCrutch.DebugMode) then
- DKCrutch:Debug("Debug ended", GetTime())
- end
- DKCrutch.DebugMode = not ( DKCrutch.DebugMode )
- local debugStatus = "disabled"
- if (DKCrutch.DebugMode) then
- debugStatus = "enabled. Using frame: " .. DKCrutch.DebugChat:GetID()
- DKCrutch:Debug("Debug started", GetTime())
- end
- DEFAULT_CHAT_FRAME:AddMessage("DKCrutch Debug " .. debugStatus)
- else
- InterfaceOptionsFrame_OpenToCategory(getglobal("DKCrutchConfigPanel"))
- end
-end
-
function DKCrutch:detectTalent()
local spec = GetSpecialization()
@@ -668,11 +759,11 @@ end
function DKCrutch:AdviseFrostAbilityDW() -- Frost DK DualWield priority
-- spell advisor
local spell = ""
- local obcd,cd
+ local obcd,cd,enabled,_
-- Pillar of Frost if not on CD
- cd = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Pillar of Frost"])
- if (cd) and (cd<=1) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Pillar of Frost"])
+ if (enabled ~= nil) and (cd) and (cd<=1) then
return "Pillar of Frost"
end
@@ -718,8 +809,8 @@ function DKCrutch:AdviseFrostAbilityDW() -- Frost DK DualWield priority
-- Priority 2: Soul Reaper
-- Soul Reaper, if target health < 35%, or 45% if has t15 4pcs
if (DKCrutch.SpellList["Soul Reaper"]) then
- cd, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
- if (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
+ if (enabled ~= nil) and (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
return "Soul Reaper"
end
end
@@ -798,11 +889,11 @@ end
function DKCrutch:AdviseFrostAbility()
-- spell advisor
local spell = ""
- local obcd,cd
+ local obcd,cd,enabled,_
-- Pillar of Frost if not on CD
- cd = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Pillar of Frost"])
- if (cd) and (cd<=1) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Pillar of Frost"])
+ if (enabled ~= nil) and (cd) and (cd<=1) then
return "Pillar of Frost"
end
@@ -846,8 +937,8 @@ function DKCrutch:AdviseFrostAbility()
-- Soul Reaper, if target health < 35%, or 45% if has t15 4pcs
if (DKCrutch.SpellList["Soul Reaper"]) then
- cd, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
- if (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
+ if (enabled ~= nil) and (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
return "Soul Reaper"
end
end
@@ -976,15 +1067,15 @@ function DKCrutch:AdviseUnholyAbility()
-- Soul Reaper, if target health < 35%
if (DKCrutch.SpellList["Soul Reaper"]) then
- cd, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
- if (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Soul Reaper"])
+ if (enabled ~= nil) and (cd) and (cd<=0) and (UnitHealthMax("target")>0) and ((UnitHealth("target")/UnitHealthMax("target")<0.35) or ((UnitHealth("target")/UnitHealthMax("target")<0.45) and (DKCrutch.hasT15_4pcs))) then
return "Soul Reaper"
end
end
-- Dark Transform, if has pet and available
- cd, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Dark Transformation"])
- if (cd) and (cd<=0) and (IsUsableSpell(DKCrutch.SpellList["Dark Transformation"])) and ( PetHasActionBar() ) then
+ cd, _, enabled = DKCrutch:GetSpellCooldownRemaining(DKCrutch.SpellList["Dark Transformation"])
+ if (enabled ~= nil) and (cd) and (cd<=0) and (IsUsableSpell(DKCrutch.SpellList["Dark Transformation"])) and ( PetHasActionBar() ) then
return "Dark Transformation"
end
diff --git a/DKCrutch_GUI.lua b/DKCrutch_GUI.lua
index 486a406..2a8fb11 100755
--- a/DKCrutch_GUI.lua
+++ b/DKCrutch_GUI.lua
@@ -139,6 +139,8 @@ function DKCrutch:ApplySettings()
DKCrutch.runicFrame:SetMovable(false)
DKCrutch.debuffFrame:EnableMouse(false)
DKCrutch.debuffFrame:SetMovable(false)
+ DKCrutch.swingFrame:EnableMouse(false)
+ DKCrutch.swingFrame:SetMovable(false)
end
end
if ( DKCrutchDB.enabled ) then
@@ -173,6 +175,11 @@ function DKCrutch:ApplySettings()
else
DKCrutch.displayFrame:Hide()
end
+ if (not DKCrutchDB.swingDisabled) then
+ DKCrutch.swingFrame:Show()
+ else
+ DKCrutch.swingFrame:Hide()
+ end
end
else
DKCrutch.eventFrame:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED")
@@ -186,6 +193,7 @@ function DKCrutch:ApplySettings()
DKCrutch.weaponFrame:Hide()
DKCrutch.runicFrame:Hide()
DKCrutch.debuffFrame:Hide()
+ DKCrutch.swingFrame:Hide()
end
end
if (DKCrutch.displayFrame) then
@@ -201,6 +209,8 @@ function DKCrutch:ApplySettings()
DKCrutch.runicFrame:SetScale(DKCrutchDB.runic.scale)
DKCrutch.debuffFrame:SetAlpha(DKCrutchDB.debuff.alpha)
DKCrutch.debuffFrame:SetScale(DKCrutchDB.debuff.scale)
+ DKCrutch.swingFrame:SetAlpha(DKCrutchDB.swing.alpha or 1)
+ DKCrutch.swingFrame:SetScale(DKCrutchDB.swing.scale or 1)
end
end
@@ -442,13 +452,48 @@ function DKCrutch:CreateConfig()
local weaponDisableBtn = DKCrutch:CreateCheckButton(L.CONFIG_DISABLE_WEAPON, DKCrutch.configPanel, DKCrutchDB, "weaponDisabled", false)
weaponDisableBtn:SetPoint('TOPLEFT', 10, -418)
+ local swingScale = DKCrutch:CreateSlider(L.CONFIG_SWING_SCALE, DKCrutch.configPanel, .25, 3, .1)
+ swingScale:SetScript('OnShow', function(self)
+ self.onShow = true
+ self:SetValue(DKCrutchDB.swing.scale)
+ self.onShow = nil
+ end)
+ swingScale:SetScript('OnValueChanged', function(self, value)
+ self.valText:SetText(format('%.1f', value))
+ if not self.onShow then
+ DKCrutchDB.swing.scale=value
+ DKCrutch.swingFrame:SetScale(value)
+ end
+ end)
+ swingScale:SetPoint("TOPLEFT",10,-458)
+ swingScale:Show()
+
+ local swingAlpha = DKCrutch:CreateSlider(L.CONFIG_SWING_ALPHA, DKCrutch.configPanel, .0, 1, .1)
+ swingAlpha:SetScript('OnShow', function(self)
+ self.onShow = true
+ self:SetValue(DKCrutchDB.swing.alpha)
+ self.onShow = nil
+ end)
+ swingAlpha:SetScript('OnValueChanged', function(self, value)
+ self.valText:SetText(format('%.1f', value))
+ if not self.onShow then
+ DKCrutchDB.swing.alpha=value
+ DKCrutch.swingFrame:SetAlpha(value)
+ end
+ end)
+ swingAlpha:SetPoint("TOPLEFT",200,-458)
+ swingAlpha:Show()
+
+ local swingDisableBtn = DKCrutch:CreateCheckButton(L.CONFIG_DISABLE_SWING, DKCrutch.configPanel, DKCrutchDB, "swingDisabled", false)
+ swingDisableBtn:SetPoint('TOPLEFT', 10, -478)
+
local ResetBtn = DKCrutch:CreateButton(L.CONFIG_RESET_POSITIONS, DKCrutch.configPanel)
ResetBtn:SetWidth(160)
ResetBtn:SetHeight(22)
ResetBtn:SetScript('OnClick', function()
DKCrutch:ResetPosition()
end)
- ResetBtn:SetPoint("TOPLEFT",10,-448)
+ ResetBtn:SetPoint("TOPLEFT",10,-508)
ResetBtn:Show()
DKCrutch.configPanel.okay = function()
@@ -474,6 +519,49 @@ function DKCrutch:CreateConfig()
self.onHide = true
self.onHide = nil
end)
+ -- Fix broken InterfaceOptionsFrame_OpenToCategory function
+ -- Bail out if already loaded and up to date
+ local MAJOR, MINOR = "InterfaceOptionsFix", 1
+ if _G[MAJOR] and _G[MAJOR].version >= MINOR then return end
+
+ -- Reuse the existing frame or create a new one
+ local frame = _G[MAJOR] or CreateFrame("Frame", MAJOR, _G.InterfaceOptionsFrame)
+ frame.version = MINOR
+
+ -- Hook once and the call the possibly upgraded methods
+ if not frame.Saved_InterfaceOptionsFrame_OpenToCategory then
+ -- Save the unhooked function
+ frame.Saved_InterfaceOptionsFrame_OpenToCategory = _G.InterfaceOptionsFrame_OpenToCategory
+ hooksecurefunc("InterfaceOptionsFrame_OpenToCategory", function(...)
+ return frame:InterfaceOptionsFrame_OpenToCategory(...)
+ end)
+
+ -- Please note that the frame is a child of InterfaceOptionsFrame, so OnUpdate won't called before InterfaceOptionsFrame is shown
+ frame:SetScript('OnUpdate', function(_, ...)
+ return frame:OnUpdate(...)
+ end)
+ end
+
+ -- This will be called twice on first open :
+ -- 1) with the panel which is actually wanted,
+ -- 2) with the "Control" panel from InterfaceOptionsFrame_OnShow (this is what actually cause the bug).
+ function frame:InterfaceOptionsFrame_OpenToCategory(panel)
+ self.panel = panel
+ end
+
+ function frame:OnUpdate()
+ local panel = self.panel
+
+ -- Clean up
+ self:SetScript('OnUpdate', nil)
+ self:Hide()
+ self.panel = nil
+ self.InterfaceOptionsFrame_OpenToCategory = function() end
+
+ -- Call the original InterfaceOptionsFrame_OpenToCategory with the last panel
+ self.Saved_InterfaceOptionsFrame_OpenToCategory(panel)
+ end
+
-- Add the panel to the Interface Options
InterfaceOptions_AddCategory(DKCrutch.configPanel)
end
@@ -533,6 +621,15 @@ function DKCrutch:ResetDB()
["relativePoint"] = "CENTER",
}
end
+ if (not DKCrutchDB.swing) or (force) then
+ DKCrutchDB.swing = {
+ ["x"] = -20,
+ ["y"] = 180,
+ ["scale"] = 1,
+ ["alpha"] = 1,
+ ["relativePoint"] = "CENTER",
+ }
+ end
if (force) then
DKCrutchDB.locked = false
DKCrutchDB.enabled = true
@@ -541,6 +638,7 @@ function DKCrutch:ResetDB()
DKCrutchDB.weaponDisabled = false
DKCrutchDB.runicDisabled = false
DKCrutchDB.debuffDisabled = false
+ DKCrutchDB.swingDisabled = false
end
end
@@ -593,6 +691,9 @@ function DKCrutch:ResetPosition()
DKCrutchDB.debuff.x = 0
DKCrutchDB.debuff.y = 180
DKCrutchDB.debuff.relativePoint = "CENTER"
+ DKCrutchDB.swing.x = -20
+ DKCrutchDB.swing.y = 180
+ DKCrutchDB.swing.relativePoint = "CENTER"
DKCrutch.displayFrame:ClearAllPoints()
DKCrutch.displayFrame:SetPoint(DKCrutchDB.runes.relativePoint,DKCrutchDB.runes.x,DKCrutchDB.runes.y)
@@ -604,6 +705,8 @@ function DKCrutch:ResetPosition()
DKCrutch.weaponFrame:SetPoint(DKCrutchDB.weapon.relativePoint,DKCrutchDB.weapon.x,DKCrutchDB.weapon.y)
DKCrutch.debuffFrame:ClearAllPoints()
DKCrutch.debuffFrame:SetPoint(DKCrutchDB.debuff.relativePoint,DKCrutchDB.debuff.x,DKCrutchDB.debuff.y)
+ DKCrutch.swingFrame:ClearAllPoints()
+ DKCrutch.swingFrame:SetPoint(DKCrutchDB.swing.relativePoint,DKCrutchDB.swing.x,DKCrutchDB.swing.y)
end
function DKCrutch:MakeDraggable(frame,store)
@@ -653,6 +756,7 @@ function DKCrutch:ShowHideFrames( visible )
DKCrutch.weaponFrame:Show();
DKCrutch.runicFrame:Show();
DKCrutch.debuffFrame:Show();
+ DKCrutch.swingFrame:Show();
else
DKCrutch.displayFrame:Hide();
DKCrutch.advisorFrame:Hide();
@@ -660,6 +764,7 @@ function DKCrutch:ShowHideFrames( visible )
DKCrutch.weaponFrame:Hide();
DKCrutch.runicFrame:Hide();
DKCrutch.debuffFrame:Hide();
+ DKCrutch.swingFrame:Hide();
end
end
@@ -670,6 +775,7 @@ function DKCrutch:UnLockFrames()
DKCrutch:MakeDraggable(DKCrutch.weaponFrame,"weapon")
DKCrutch:MakeDraggable(DKCrutch.runicFrame,"runic")
DKCrutch:MakeDraggable(DKCrutch.debuffFrame,"debuff")
+ DKCrutch:MakeDraggable(DKCrutch.swingFrame,"swing")
end
function DKCrutch:CreateGUI()
@@ -868,6 +974,23 @@ function DKCrutch:CreateGUI()
debuffFrame:SetPoint(DKCrutchDB.debuff.relativePoint,DKCrutchDB.debuff.x,DKCrutchDB.debuff.y)
DKCrutch.debuffFrame = debuffFrame
+
+ local swingFrame = CreateFrame("StatusBar", "DKCrutchSwingFrame", UIParent)
+ swingFrame:SetFrameStrata("BACKGROUND")
+ swingFrame:SetWidth(128)
+ swingFrame:SetHeight(8)
+ swingFrame:SetBackdrop({
+ bgFile = "Interface\\Tooltips\\UI-Tooltip-Background", tile = true, tileSize = 32,
+ })
+ swingFrame:SetOrientation("HORIZONTAL")
+ swingFrame:SetMinMaxValues(0, 128)
+ swingFrame:SetValue(0)
+ swingFrame:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
+ swingFrame:SetStatusBarColor(0,0,0,1)
+ swingFrame:SetAlpha(DKCrutchDB.swing.alpha or 1)
+ swingFrame:SetPoint(DKCrutchDB.swing.relativePoint or "CENTER",DKCrutchDB.swing.x or -20,DKCrutchDB.swing.y or 180)
+
+ DKCrutch.swingFrame = swingFrame
if (not DKCrutchDB.locked) then
DKCrutch:UnLockFrames()
diff --git a/locales/enUS.lua b/locales/enUS.lua
index af547c2..a346e6d 100755
--- a/locales/enUS.lua
+++ b/locales/enUS.lua
@@ -25,4 +25,7 @@ if GetLocale() then
L.CONFIG_WEAPON_SCALE = "Weapon proc tracker scale"
L.CONFIG_WEAPON_ALPHA = "Weapon proc tracker alpha"
L.CONFIG_DISABLE_WEAPON = "Disable weapon proc tracker"
+ L.CONFIG_SWING_SCALE = "Swing frame scale"
+ L.CONFIG_SWING_ALPHA = "Swing frame alpha"
+ L.CONFIG_DISABLE_SWING = "Disable swing frame"
end
\ No newline at end of file