diff --git a/oUF_Simple/core/functions.lua b/oUF_Simple/core/functions.lua
index 6151c16..7e01aa6 100644
--- a/oUF_Simple/core/functions.lua
+++ b/oUF_Simple/core/functions.lua
@@ -183,6 +183,28 @@ local function CreateAltPowerBar(self)
end
L.F.CreateAltPowerBar = CreateAltPowerBar
+--CreateSwing
+local function CreateSwing(self)
+ if not self.cfg.swing or not self.cfg.swing.enabled then return end
+ --statusbar
+ local s = CreateFrame("Frame", nil, self.Power)
+ s.texture = L.C.textures.statusbar
+ s.textureBG = L.C.textures.statusbarBG
+ s.color = self.cfg.swing.color
+ s.colorBG = self.cfg.swing.colorBG
+ s.disableRanged = self.cfg.swing.disableRanged
+ s.disableMelee = self.cfg.swing.disableMelee
+ --bg
+ local bg = s:CreateTexture(nil, "BACKGROUND")
+ -- bg:SetTexture(L.C.textures.statusbar)
+ -- bg:SetColorTexture()
+ bg:SetAllPoints()
+ s.bg = bg
+ s:SetAllPoints()
+ return s
+end
+L.F.CreateSwing = CreateSwing
+
--CreateAbsorbBar
local function CreateAbsorbBar(self)
--like health the absorb bar cannot be disabled
diff --git a/oUF_Simple/core/style.lua b/oUF_Simple/core/style.lua
index 92067c5..d21ccf3 100644
--- a/oUF_Simple/core/style.lua
+++ b/oUF_Simple/core/style.lua
@@ -32,6 +32,7 @@ local function CreateStyle(self)
-- self.rClassBar = L.F.CreateClassBar(self)
-- self.AlternativePower = L.F.CreateAltPowerBar(self)
-- self.AdditionalPower = L.F.CreateAdditionalPowerBar(self)
+ self.Swing = L.F.CreateSwing(self)
self.Debuffs = L.F.CreateDebuffs(self)
self.Buffs = L.F.CreateBuffs(self)
self.RaidTargetIndicator = L.F.CreateRaidMark(self)
diff --git a/oUF_Simple/modules/oUF_Swing.lua b/oUF_Simple/modules/oUF_Swing.lua
new file mode 100644
index 0000000..81377d4
--- /dev/null
+++ b/oUF_Simple/modules/oUF_Swing.lua
@@ -0,0 +1,527 @@
+------------------------
+-- oUF_Swing, by p3lim
+-- NDui MOD
+-------------------------
+local A, L = ...
+local oUF = L.oUF or oUF
+if not oUF then return end
+
+local strfind = string.find
+local GetTime = GetTime
+local GetInventoryItemID = GetInventoryItemID
+local UnitAttackSpeed = UnitAttackSpeed
+local UnitRangedDamage = UnitRangedDamage
+local CombatLogGetCurrentEventInfo = CombatLogGetCurrentEventInfo
+local UnitGUID = UnitGUID
+local IsPlayerMoving = IsPlayerMoving
+local UnitCastingInfo = UnitCastingInfo
+
+local meleeing, rangeing, lasthit
+local MainhandID = GetInventoryItemID("player", 16)
+local OffhandID = GetInventoryItemID("player", 17)
+local RangedID = GetInventoryItemID("player", 18)
+local AUTO_CAST_TIME = .65
+local delayTime = 0
+
+local function SwingStopped(element)
+ local bar = element.__owner
+ local swing = bar.Twohand
+ local swingMH = bar.Mainhand
+ local swingOH = bar.Offhand
+
+ if swing:IsShown() then return end
+ if swingMH:IsShown() then return end
+ if swingOH:IsShown() then return end
+
+ bar:Hide()
+end
+
+local function UpdateBarMinMaxValues(self)
+ self:SetMinMaxValues(0, self.max - self.min)
+end
+
+local function UpdateBarValue(self, value)
+ self:SetValue(value)
+
+ if self.Text then
+ if self.__owner.OverrideText then
+ self.__owner.OverrideText(self, value)
+ else
+ local decimal = rangeing and "%.2f" or "%.1f"
+ self.Text:SetFormattedText(decimal, self.max - self.min - value)
+ end
+ end
+end
+
+local function delayUpdate(self)
+ local now = GetTime()
+ local isMoving = IsPlayerMoving()
+ if not isMoving then
+ local elapsed = now - delayTime
+ if elapsed > AUTO_CAST_TIME then
+ delayTime = 0
+ self:Hide()
+ self:SetScript("OnUpdate", nil)
+ meleeing = false
+ rangeing = false
+ else
+ UpdateBarValue(self, elapsed + self.swingTime)
+ end
+ else
+ delayTime = now
+ UpdateBarValue(self, self.swingTime)
+ end
+end
+
+local OnDurationUpdate
+do
+ local checkelapsed = 0
+ local slamelapsed = 0
+ local slamtime = 0
+ local slam = GetSpellInfo(1464)
+ function OnDurationUpdate(self, elapsed)
+ local now = GetTime()
+
+ if meleeing then
+ if checkelapsed > .02 then
+ -- little hack for detecting melee stop
+ -- improve... dw sucks at this point -.-
+ if lasthit + self.speed + slamtime < now then
+ self:Hide()
+ self:SetScript("OnUpdate", nil)
+ SwingStopped(self)
+ meleeing = false
+ rangeing = false
+ end
+ checkelapsed = 0
+ else
+ checkelapsed = checkelapsed + elapsed
+ end
+ end
+
+ local spell = UnitCastingInfo("player")
+ if slam == spell then
+ -- slamelapsed: time to add for one slam
+ slamelapsed = slamelapsed + elapsed
+ -- slamtime: needed for meleeing hack (see some lines above)
+ slamtime = slamtime + elapsed
+ else
+ -- after slam
+ if slamelapsed ~= 0 then
+ self.min = self.min + slamelapsed
+ self.max = self.max + slamelapsed
+ slamelapsed = 0
+ end
+
+ local currentValue = now - self.min
+ local swingTime = self.max - self.min - AUTO_CAST_TIME
+ local isMoving = IsPlayerMoving()
+
+ if rangeing and currentValue >= swingTime and isMoving then
+ self.swingTime = swingTime
+ self:SetScript("OnUpdate", delayUpdate)
+ else
+ if now > self.max then
+ if meleeing then
+ if lasthit then
+ self.min = self.max
+ self.max = self.max + self.speed
+ UpdateBarMinMaxValues(self)
+ slamtime = 0
+ end
+ else
+ delayTime = 0
+ self:Hide()
+ self:SetScript("OnUpdate", nil)
+ meleeing = false
+ rangeing = false
+ end
+ else
+ UpdateBarValue(self, currentValue)
+ end
+ end
+
+ self.__owner.bg:SetShown(rangeing)
+ end
+ end
+end
+
+local function MeleeChange(self, _, unit)
+ if unit ~= "player" then return end
+ if not meleeing then return end
+
+ local bar = self.Swing
+ local swing = bar.Twohand
+ local swingMH = bar.Mainhand
+ local swingOH = bar.Offhand
+
+ local NewMainhandID = GetInventoryItemID("player", 16)
+ local NewOffhandID = GetInventoryItemID("player", 17)
+ local now = GetTime()
+ local mhspeed, ohspeed = UnitAttackSpeed("player")
+
+ if MainhandID ~= NewMainhandID or OffhandID ~= NewOffhandID then
+ if ohspeed then
+ swing:Hide()
+ swing:SetScript("OnUpdate", nil)
+
+ swingMH.min = now
+ swingMH.max = swingMH.min + mhspeed
+ swingMH.speed = mhspeed
+ swingMH:Show()
+ UpdateBarMinMaxValues(swingMH)
+ swingMH:SetScript("OnUpdate", OnDurationUpdate)
+
+ swingOH.min = now
+ swingOH.max = swingOH.min + ohspeed
+ swingOH.speed = ohspeed
+ if mhspeed ~= ohspeed then
+ swingOH:Show()
+ UpdateBarMinMaxValues(swingOH)
+ swingOH:SetScript("OnUpdate", OnDurationUpdate)
+ else
+ swingOH:Hide()
+ swingOH:SetScript("OnUpdate", nil)
+ end
+ else
+ swing.min = now
+ swing.max = swing.min + mhspeed
+ swing.speed = mhspeed
+ swing:Show()
+ UpdateBarMinMaxValues(swing)
+ swing:SetScript("OnUpdate", OnDurationUpdate)
+
+ swingMH:Hide()
+ swingMH:SetScript("OnUpdate", nil)
+ swingOH:Hide()
+ swingOH:SetScript("OnUpdate", nil)
+ end
+
+ lasthit = now
+ MainhandID = NewMainhandID
+ OffhandID = NewOffhandID
+ else
+ if ohspeed then
+ if swingMH.speed and swingMH.speed ~= mhspeed then
+ local percentage = ((swingMH.max or 10) - now) / (swingMH.speed)
+ swingMH.min = now - mhspeed * (1 - percentage)
+ swingMH.max = now + mhspeed * percentage
+ UpdateBarMinMaxValues(swingMH)
+ swingMH.speed = mhspeed
+ end
+ if swingOH.speed and swingOH.speed ~= ohspeed then
+ local percentage = ((swingOH.max or 10)- now) / (swingOH.speed)
+ swingOH.min = now - ohspeed * (1 - percentage)
+ swingOH.max = now + ohspeed * percentage
+ UpdateBarMinMaxValues(swingOH)
+ swingOH.speed = ohspeed
+ end
+ else
+ if swing.max and swing.speed ~= mhspeed then
+ local percentage = (swing.max - now) / (swing.speed)
+ swing.min = now - mhspeed * (1 - percentage)
+ swing.max = now + mhspeed * percentage
+ UpdateBarMinMaxValues(swing)
+ swing.speed = mhspeed
+ end
+ end
+ end
+end
+
+local function RangedChange(self, _, unit)
+ if unit ~= "player" then return end
+ if not rangeing then return end
+
+ local bar = self.Swing
+ local swing = bar.Twohand
+
+ local NewRangedID = GetInventoryItemID("player", 18)
+ local now = GetTime()
+ local speed = UnitRangedDamage("player")
+
+ if RangedID ~= NewRangedID then
+ swing.speed = UnitRangedDamage(unit)
+ swing.min = now
+ swing.max = swing.min + swing.speed
+ swing:Show()
+ UpdateBarMinMaxValues(swing)
+ swing:SetScript("OnUpdate", OnDurationUpdate)
+ else
+ if swing.speed ~= speed then
+ local percentage = (swing.max - now) / (swing.speed)
+ swing.min = now - speed * (1 - percentage)
+ swing.max = now + speed * percentage
+ swing.speed = speed
+ end
+ end
+end
+
+local function Ranged(self, _, unit, _, spellID)
+ if unit ~= "player" then return end
+ if spellID ~= 75 and spellID ~= 5019 then return end
+
+ local bar = self.Swing
+ local swing = bar.Twohand
+ local swingMH = bar.Mainhand
+ local swingOH = bar.Offhand
+
+ meleeing = false
+ rangeing = true
+ bar:Show()
+
+ swing.speed = UnitRangedDamage(unit)
+ swing.min = GetTime()
+ swing.max = swing.min + swing.speed
+ swing:Show()
+ UpdateBarMinMaxValues(swing)
+ swing:SetScript("OnUpdate", OnDurationUpdate)
+ bar.bg:SetWidth(AUTO_CAST_TIME / (swing.max - swing.min) * bar:GetWidth())
+
+ swingMH:Hide()
+ swingMH:SetScript("OnUpdate", nil)
+ swingOH:Hide()
+ swingOH:SetScript("OnUpdate", nil)
+end
+
+local function Melee(self)
+ local _, subevent, _, GUID = CombatLogGetCurrentEventInfo()
+ if GUID ~= UnitGUID("player") then return end
+ if not strfind(subevent, "SWING") then return end
+
+ local bar = self.Swing
+ local swing = bar.Twohand
+ local swingMH = bar.Mainhand
+ local swingOH = bar.Offhand
+
+ -- calculation of new hits is in OnDurationUpdate
+ -- workaround, cant differ between mainhand and offhand hits
+ local now = GetTime()
+
+ if not meleeing then
+ bar:Show()
+ swing:Hide()
+ swingMH:Hide()
+ swingOH:Hide()
+
+ swing:SetScript("OnUpdate", nil)
+ swingMH:SetScript("OnUpdate", nil)
+ swingOH:SetScript("OnUpdate", nil)
+
+ local mhspeed, ohspeed = UnitAttackSpeed("player")
+ if ohspeed then
+ swingMH.min = now
+ swingMH.max = swingMH.min + mhspeed
+ swingMH.speed = mhspeed
+ swingMH:Show()
+ UpdateBarMinMaxValues(swingMH)
+ swingMH:SetScript("OnUpdate", OnDurationUpdate)
+
+ swingOH.min = now
+ swingOH.max = swingOH.min + ohspeed
+ swingOH.speed = ohspeed
+ if mhspeed ~= ohspeed then
+ swingOH:Show()
+ UpdateBarMinMaxValues(swingOH)
+ swingOH:SetScript("OnUpdate", OnDurationUpdate)
+ end
+ else
+ swing.min = now
+ swing.max = swing.min + mhspeed
+ swing.speed = mhspeed
+ swing:Show()
+ UpdateBarMinMaxValues(swing)
+ swing:SetScript("OnUpdate", OnDurationUpdate)
+ end
+
+ meleeing = true
+ rangeing = false
+ end
+
+ lasthit = now
+end
+
+local function ParryHaste(self)
+ local _, subevent, _, _, _, _, tarGUID, _, missType = CombatLogGetCurrentEventInfo()
+
+ if tarGUID ~= UnitGUID("player") then return end
+ if not meleeing then return end
+ if not strfind(subevent, "MISSED") then return end
+ if missType ~= "PARRY" then return end
+
+ local bar = self.Swing
+ local swing = bar.Twohand
+ local swingMH = bar.Mainhand
+ local swingOH = bar.Offhand
+
+ local _, dualwield = UnitAttackSpeed("player")
+ local now = GetTime()
+
+ -- needed calculations, so the timer doesnt jump on parryhaste
+ if dualwield then
+ local percentage = (swingMH.max - now) / swingMH.speed
+
+ if percentage > .6 then
+ swingMH.max = now + swingMH.speed * .6
+ swingMH.min = now - (swingMH.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swingMH)
+ elseif percentage > .2 then
+ swingMH.max = now + swingMH.speed * .2
+ swingMH.min = now - (swingMH.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swingMH)
+ end
+
+ percentage = (swingOH.max - now) / swingOH.speed
+
+ if percentage > .6 then
+ swingOH.max = now + swingOH.speed * .6
+ swingOH.min = now - (swingOH.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swingOH)
+ elseif percentage > .2 then
+ swingOH.max = now + swingOH.speed * .2
+ swingOH.min = now - (swingOH.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swingOH)
+ end
+ else
+ local percentage = (swing.max - now) / swing.speed
+
+ if percentage > .6 then
+ swing.max = now + swing.speed * .6
+ swing.min = now - (swing.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swing)
+ elseif percentage > .2 then
+ swing.max = now + swing.speed * .2
+ swing.min = now - (swing.max - now) * percentage / (1 - percentage)
+ UpdateBarMinMaxValues(swing)
+ end
+ end
+end
+
+local function Ooc(self)
+ local bar = self.Swing
+ -- strange behaviour sometimes...
+ meleeing = false
+ rangeing = false
+
+ if not bar.hideOoc then return end
+ bar:Hide()
+ bar.Twohand:Hide()
+ bar.Mainhand:Hide()
+ bar.Offhand:Hide()
+end
+
+local function Enable(self, unit)
+ local bar = self.Swing
+
+ if bar and unit == "player" then
+ local normTex = bar.texture or [=[Interface\TargetingFrame\UI-StatusBar]=]
+ local bgTex = bar.textureBG or [=[Interface\TargetingFrame\UI-StatusBar]=]
+ local r, g, b, a, r2, g2, b2, a2
+
+ if bar.color then
+ r, g, b, a = unpack(bar.color)
+ else
+ r, g, b, a = 1, 1, 1, 1
+ end
+
+ if bar.colorBG then
+ r2, g2, b2, a2 = unpack(bar.colorBG)
+ else
+ r2, g2, b2, a2 = 0, 0, 0, 1
+ end
+
+ if not bar.Twohand then
+ bar.Twohand = CreateFrame("StatusBar", nil, bar)
+ bar.Twohand:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+ bar.Twohand:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", 0, 0)
+ bar.Twohand:SetStatusBarTexture(normTex)
+ bar.Twohand:SetStatusBarColor(r, g, b, a)
+ bar.Twohand:SetFrameLevel(20)
+ bar.Twohand:Hide()
+ bar.Twohand.bg = bar.Twohand:CreateTexture(nil, "BACKGROUND")
+ bar.Twohand.bg:SetAllPoints(bar.Twohand)
+ bar.Twohand.bg:SetTexture(bgTex)
+ bar.Twohand.bg:SetVertexColor(r2, g2, b2, a2)
+ end
+ bar.Twohand.__owner = bar
+
+ if not bar.Mainhand then
+ bar.Mainhand = CreateFrame("StatusBar", nil, bar)
+ bar.Mainhand:SetPoint("TOPLEFT", bar, "TOPLEFT", 0, 0)
+ bar.Mainhand:SetPoint("BOTTOMRIGHT", bar, "RIGHT", 0, 0)
+ bar.Mainhand:SetStatusBarTexture(normTex)
+ bar.Mainhand:SetStatusBarColor(r, g, b, a)
+ bar.Mainhand:SetFrameLevel(20)
+ bar.Mainhand:Hide()
+ bar.Mainhand.bg = bar.Mainhand:CreateTexture(nil, "BACKGROUND")
+ bar.Mainhand.bg:SetAllPoints(bar.Mainhand)
+ bar.Mainhand.bg:SetTexture(bgTex)
+ bar.Mainhand.bg:SetVertexColor(r2, g2, b2, a2)
+ end
+ bar.Mainhand.__owner = bar
+
+ if not bar.Offhand then
+ bar.Offhand = CreateFrame("StatusBar", nil, bar)
+ bar.Offhand:SetPoint("TOPLEFT", bar, "LEFT", 0, 0)
+ bar.Offhand:SetPoint("BOTTOMRIGHT", bar, "BOTTOMRIGHT", 0, 0)
+ bar.Offhand:SetStatusBarTexture(normTex)
+ bar.Offhand:SetStatusBarColor(r, g, b, a)
+ bar.Offhand:SetFrameLevel(20)
+ bar.Offhand:Hide()
+ bar.Offhand.bg = bar.Offhand:CreateTexture(nil, "BACKGROUND")
+ bar.Offhand.bg:SetAllPoints(bar.Offhand)
+ bar.Offhand.bg:SetTexture(bgTex)
+ bar.Offhand.bg:SetVertexColor(r2, g2, b2, a2)
+ end
+ bar.Offhand.__owner = bar
+
+ if bar.Text then
+ bar.Twohand.Text = bar.Text
+ bar.Twohand.Text:SetParent(bar.Twohand)
+ end
+ if bar.TextMH then
+ bar.Mainhand.Text = bar.TextMH
+ bar.Mainhand.Text:SetParent(bar.Mainhand)
+ end
+ if bar.TextOH then
+ bar.Offhand.Text = bar.TextOH
+ bar.Offhand.Text:SetParent(bar.Offhand)
+ end
+ if bar.OverrideText then
+ bar.Twohand.OverrideText = bar.OverrideText
+ bar.Mainhand.OverrideText = bar.OverrideText
+ bar.Offhand.OverrideText = bar.OverrideText
+ end
+ if not bar.disableRanged then
+ self:RegisterEvent("UNIT_SPELLCAST_SUCCEEDED", Ranged)
+ self:RegisterEvent("UNIT_RANGEDDAMAGE", RangedChange)
+ end
+ if not bar.disableMelee then
+ self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", Melee, true)
+ self:RegisterEvent("COMBAT_LOG_EVENT_UNFILTERED", ParryHaste, true)
+ self:RegisterEvent("UNIT_ATTACK_SPEED", MeleeChange)
+ end
+ self:RegisterEvent("PLAYER_REGEN_ENABLED", Ooc, true)
+
+ return true
+ end
+end
+
+local function Disable(self)
+ local bar = self.Swing
+ if bar then
+ if not bar.disableRanged then
+ self:UnregisterEvent("UNIT_SPELLCAST_SUCCEEDED", Ranged)
+ self:UnregisterEvent("UNIT_RANGEDDAMAGE", RangedChange)
+ end
+ if not bar.disableMelee then
+ self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED", Melee)
+ self:UnregisterEvent("COMBAT_LOG_EVENT_UNFILTERED", ParryHaste)
+ self:UnregisterEvent("UNIT_ATTACK_SPEED", MeleeChange)
+ end
+ self:UnregisterEvent("PLAYER_REGEN_ENABLED", Ooc)
+
+ bar:Hide()
+ end
+end
+
+oUF:AddElement("Swing", nil, Enable, Disable)
\ No newline at end of file
diff --git a/oUF_Simple/oUF_Simple.toc b/oUF_Simple/oUF_Simple.toc
index 8fe567e..248ed3d 100644
--- a/oUF_Simple/oUF_Simple.toc
+++ b/oUF_Simple/oUF_Simple.toc
@@ -7,6 +7,7 @@
## modules\rAbsorbBar.lua
## modules\rClassBar.lua
modules\oUF_DebuffHighlight.lua
+modules\oUF_Swing.lua
core\init.lua
core\functions.lua
diff --git a/oUF_SimpleConfig/player.lua b/oUF_SimpleConfig/player.lua
index 869f350..fa8f6ec 100644
--- a/oUF_SimpleConfig/player.lua
+++ b/oUF_SimpleConfig/player.lua
@@ -68,6 +68,14 @@ L.C.player = {
font = L.C.fonts.expressway,
},
},
+ --swing
+ swing = {
+ enabled = true,
+ color = {1,0.7,0,0.5},
+ colorBG = {0,0,0,0},
+ disableRanged = false,
+ disableMelee = false,
+ },
--raidmark
raidmark = {
enabled = true,