From 5388c6a862cffb3d4050677fd234aa6b27450a26 Mon Sep 17 00:00:00 2001 From: Taracque Date: Thu, 20 Feb 2014 14:03:17 +0100 Subject: [PATCH] Added Swing timer (works for 2hd weapons only now) --- DKCrutch.lua | 163 ++++++++++++++++++++++++++++++++++++++++++------------ DKCrutch_GUI.lua | 125 ++++++++++++++++++++++++++++++++++++++++- locales/enUS.lua | 3 + 3 files changed, 254 insertions(+), 37 deletions(-) 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 -- 1.7.9.5