Skip to content

Commit

Permalink
add focus castbar
Browse files Browse the repository at this point in the history
  • Loading branch information
wardz committed Jan 19, 2020
1 parent 05e2e4f commit 777f593
Show file tree
Hide file tree
Showing 7 changed files with 190 additions and 13 deletions.
4 changes: 4 additions & 0 deletions .luacheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,8 @@ globals = {
"GetTime",
"UIParent",
"floor",
"UnitName",
"UnitIsPlayer",
"UnitClass",
"RAID_CLASS_COLORS",
}
42 changes: 33 additions & 9 deletions ClassicCastbars/ClassicCastbars.lua
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ local BLINDING_LIGHT = GetSpellInfo(23733)
local BERSERKING = GetSpellInfo(20554)

function addon:CheckCastModifier(unitID, cast)
if unitID == "focus" then return end
if not self.db.pushbackDetect or not cast then return end
if cast.unitGUID == self.PLAYER_GUID then return end -- modifiers already taken into account with CastingInfo()
if unaffectedCastModsSpells[cast.spellID] then return end
Expand Down Expand Up @@ -217,6 +218,29 @@ function addon:CastPushback(unitGUID)
end
end

SLASH_CCFOCUS1 = "/focus"
SLASH_CCFOCUS2 = "/castbarfocus"
SlashCmdList["CCFOCUS"] = function()
local tarGUID = UnitGUID("target")
if tarGUID then
activeGUIDs.focus = tarGUID
addon:StopCast("focus", true)
addon:StartCast(tarGUID, "focus")
addon:SetFocusDisplay(UnitName("target"))
else
SlashCmdList["CCFOCUSCLEAR"]()
end
end

SLASH_CCFOCUSCLEAR1 = "/clearfocus"
SlashCmdList["CCFOCUSCLEAR"] = function()
if activeGUIDs.focus then
activeGUIDs.focus = nil
addon:StopCast("focus", true)
addon:SetFocusDisplay(nil)
end
end

local function GetSpellCastInfo(spellID)
local _, _, icon, castTime = GetSpellInfo(spellID)
if not castTime then return end
Expand Down Expand Up @@ -274,6 +298,7 @@ function addon:PLAYER_ENTERING_WORLD(isInitialLogin)
wipe(activeTimers)
wipe(activeFrames)
PoolManager:GetFramePool():ReleaseAll() -- also wipes castbar._data
self:SetFocusDisplay(nil)

if self.db.party.enabled and IsInGroup() then
self:GROUP_ROSTER_UPDATE()
Expand Down Expand Up @@ -310,9 +335,6 @@ function addon:PLAYER_LOGIN()
ClassicCastbarsDB.player = nil
end

-- Added focus variables by accident at some point
if ClassicCastbarsDB.focus then ClassicCastbarsDB.focus = nil end

-- Copy any settings from defaults if they don't exist in current profile
self.db = CopyDefaults(namespace.defaultConfig, ClassicCastbarsDB)
self.db.version = namespace.defaultConfig.version
Expand Down Expand Up @@ -571,12 +593,14 @@ addon:SetScript("OnUpdate", function(self, elapsed)
if refresh < 0 then
if next(activeGUIDs) then
for unitID, unitGUID in pairs(activeGUIDs) do
local cast = activeTimers[unitGUID]
-- Only stop cast for players since some mobs runs while casting, also because
-- of lag we have to only stop it if the cast has been active for atleast 0.25 sec
if cast and cast.isPlayer and currTime - cast.timeStart > 0.25 then
if not castStopBlacklist[cast.spellName] and GetUnitSpeed(unitID) ~= 0 then
self:DeleteCast(unitGUID)
if unitID ~= "focus" then
local cast = activeTimers[unitGUID]
-- Only stop cast for players since some mobs runs while casting, also because
-- of lag we have to only stop it if the cast has been active for atleast 0.25 sec
if cast and cast.isPlayer and currTime - cast.timeStart > 0.25 then
if not castStopBlacklist[cast.spellName] and GetUnitSpeed(unitID) ~= 0 then
self:DeleteCast(unitGUID)
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions ClassicCastbars/core/AnchorManager.lua
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ function AnchorManager:GetAnchor(unitID)
return cache[unitID]
end

if unitID == "player" then
-- special case for player casting bar
if unitID == "player" or unitID == "focus" then
-- special case for player/focus casting bar
return UIParent
end

Expand Down
27 changes: 27 additions & 0 deletions ClassicCastbars/core/Data.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1789,6 +1789,33 @@ namespace.defaultConfig = {
statusBackgroundColor = { 0, 0, 0, 0.535 },
},

focus = {
enabled = true,
width = 150,
height = 15,
iconSize = 16,
showCastInfoOnly = false,
showTimer = false,
showIcon = true,
autoPosition = false,
castFont = _G.STANDARD_TEXT_FONT,
castFontSize = 10,
castStatusBar = "Interface\\TargetingFrame\\UI-StatusBar",
castBorder = "Interface\\CastingBar\\UI-CastingBar-Border-Small",
hideIconBorder = false,
position = { "TOPLEFT", 275, -260 },
iconPositionX = -5,
iconPositionY = 0,
borderColor = { 1, 1, 1, 1 },
statusColor = { 1, 0.7, 0, 1 },
statusColorChannel = { 0, 1, 0, 1 },
textColor = { 1, 1, 1, 1 },
textPositionX = 0,
textPositionY = 0,
frameLevel = 10,
statusBackgroundColor = { 0, 0, 0, 0.535 },
},

party = {
enabled = false,
width = 120,
Expand Down
101 changes: 101 additions & 0 deletions ClassicCastbars/core/Frames.lua
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ local min = _G.math.min
local max = _G.math.max
local ceil = _G.math.ceil
local UnitExists = _G.UnitExists
local InCombatLockdown = _G.InCombatLockdown

function addon:GetCastbarFrame(unitID)
-- PoolManager:DebugInfo()
Expand Down Expand Up @@ -344,3 +345,103 @@ function addon:SkinPlayerCastbar()
self:SetCastbarStyle(CastingBarFrame, nil, db)
self:SetCastbarFonts(CastingBarFrame, nil, db)
end

function addon:CreateOrUpdateSecureFocusButton(text)
if not self.FocusButton then
-- Create an invisible secure click trigger above the nonsecure castbar frame
self.FocusButton = CreateFrame("Button", "FocusCastbar", nil, "SecureActionButtonTemplate")
self.FocusButton:SetAttribute("type", "macro")
--self.FocusButton:SetAllPoints(self.FocusFrame)
--self.FocusButton:SetSize(ClassicCastbarsDB.focus.width + 5, ClassicCastbarsDB.focus.height + 35)
end

local db = ClassicCastbarsDB.focus
self.FocusButton:SetPoint(db.position[1], UIParent, db.position[2], db.position[3])
self.FocusButton:SetSize(db.width + 5, db.height + 35)

self.FocusButton:SetAttribute("macrotext", "/targetexact " .. text)
self.FocusFrame.Text:SetText(text)
end

local NewTimer = _G.C_Timer.NewTimer
local focusTargetTimer
local focusTargetResetTimer

function addon:SetFocusDisplay(text)
if focusTargetTimer and not focusTargetTimer:IsCancelled() then
focusTargetTimer:Cancel()
focusTargetTimer = nil
end
if focusTargetResetTimer and not focusTargetResetTimer:IsCancelled() then
focusTargetResetTimer:Cancel()
focusTargetResetTimer = nil
end

if not text then -- clear focus
if self.FocusFrame then
self.FocusFrame.Text:SetText("")
end

if self.FocusButton then
if not InCombatLockdown() then
self.FocusButton:SetAttribute("macrotext", "")
else
-- If we're in combat try to check every 4s if we left combat and can update secure frame
local function ClearFocusTarget()
if not InCombatLockdown() then
addon.FocusButton:SetAttribute("macrotext", "")
else
focusTargetResetTimer = NewTimer(4, ClearFocusTarget)
end
end
focusTargetResetTimer = NewTimer(4, ClearFocusTarget)
end
end

return
end

if not self.FocusFrame then
-- Create a new unsecure frame to display focus text. We dont reuse the castbar frame as we want to
-- display this text even when the castbar is hidden
self.FocusFrame = CreateFrame("Frame", nil, UIParent)
self.FocusFrame:SetSize(ClassicCastbarsDB.focus.width + 5, ClassicCastbarsDB.focus.height + 35)
self.FocusFrame.Text = self.FocusFrame:CreateFontString(nil, "ARTWORK", "GameFontNormalLargeOutline")
self.FocusFrame.Text:SetPoint("CENTER", self.FocusFrame, 0, 20)
end

if UnitIsPlayer("target") then
self.FocusFrame.Text:SetTextColor(RAID_CLASS_COLORS[select(2, UnitClass("target"))]:GetRGBA())
else
self.FocusFrame.Text:SetTextColor(1, 0.819, 0, 1)
end

local isInCombat = InCombatLockdown()
if not isInCombat then
self:CreateOrUpdateSecureFocusButton(text)
else
-- If we're in combat try to check every 4s if we left combat and can update secure frame
local function UpdateFocusTarget()
if not InCombatLockdown() then
addon:CreateOrUpdateSecureFocusButton(text)
else
focusTargetTimer = NewTimer(4, UpdateFocusTarget)
end
end

focusTargetTimer = NewTimer(4, UpdateFocusTarget)
end

-- HACK: quickly create the focus castbar if it doesnt exist and hide it.
-- This is just to make anchoring easier for self.FocusFrame on first usage
if not activeFrames.focus then
local pos = ClassicCastbarsDB.focus.position
local castbar = self:GetCastbarFrame("focus")
castbar:ClearAllPoints()
castbar:SetParent(UIParent)
castbar:SetPoint(pos[1], UIParent, pos[2], pos[3])
end

self.FocusFrame.Text:SetText(isInCombat and text .. " (|cffff0000P|r)" or text)
self.FocusFrame:SetPoint("CENTER", activeFrames.focus, 0, 0)
end
13 changes: 11 additions & 2 deletions ClassicCastbars_Options/ClassicCastbars_Options.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ local function CreateUnitTabGroup(unitID, localizedUnit, order)
desc = L.TOGGLE_CASTBAR_TOOLTIP,
width = "full", -- these have to be full to not truncate text in non-english locales
type = "toggle",
hidden = unitID == "focus",
confirm = function()
return unitID == "player" and ClassicCastbarsDB[unitID].enabled and L.REQUIRES_RESTART or false
end,
Expand All @@ -76,7 +77,7 @@ local function CreateUnitTabGroup(unitID, localizedUnit, order)
name = L.AUTO_POS_BAR,
desc = unitID ~= "player" and L.AUTO_POS_BAR_TOOLTIP or "",
type = "toggle",
hidden = unitID == "nameplate" or unitID == "party",
hidden = unitID == "nameplate" or unitID == "party" or unitID == "focus",
disabled = ModuleIsDisabled,
},
showTimer = {
Expand Down Expand Up @@ -119,9 +120,15 @@ local function CreateUnitTabGroup(unitID, localizedUnit, order)
ClassicCastbarsDB.movementDetect = value
end,
get = function() return ClassicCastbarsDB.movementDetect end,
hidden = unitID == "player",
hidden = unitID == "player" or unitID == "focus",
disabled = ModuleIsDisabled,
},
notes = {
order = 8,
hidden = unitID ~= "focus",
name = "\n|cffffff00 - /focus\n\n - /clearfocus\n\n - /click FocusCastbar|r\n\n Note that focus castbar is experimental and also work in progress.",
type = "description",
},
},
},

Expand Down Expand Up @@ -409,6 +416,7 @@ local function GetOptionsTable()
nameplate = CreateUnitTabGroup("nameplate", L.NAMEPLATE, 2),
party = CreateUnitTabGroup("party", L.PARTY, 3),
player = CreateUnitTabGroup("player", L.PLAYER, 4),
focus = CreateUnitTabGroup("focus", _G.FOCUS or "Focus", 5),

resetAllSettings = {
order = 3,
Expand All @@ -424,6 +432,7 @@ local function GetOptionsTable()
ClassicCastbars_TestMode:OnOptionChanged("nameplate")
ClassicCastbars_TestMode:OnOptionChanged("party")
ClassicCastbars_TestMode:OnOptionChanged("player")
ClassicCastbars_TestMode:OnOptionChanged("focus")

if shouldReloadUI then
ReloadUI()
Expand Down
12 changes: 12 additions & 0 deletions changelog.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
v1.2.3:
- War Stomp now has pushback registered again. (Thought it didn't at first)
- Add experimental focus castbar. Typing "/focus" will focus your current target and add an extra castbar for that specific unit that is always visible even if you
no longer have that unit targetted. You may click this castbar to target your focus, however, this only works if you set the focus
when out of combat. (If you change focus in combat it will display a red "P" next to the name until you leave combat.)
Note that if mobs have the exact same name it will target the nearest one you're facing.
You can also use "/click FocusCastbar" in macros to target the focus.
You can type /clearfocus to clear your focus (or just "/focus" again while not having a target).
You can unlock & move this frame in the options like the other castbars.
Keep in mind this focus is heavily restricted due to API limitations, and that the max combat log range is 50 yards.


v1.2.2:
- Casting speed buff detection is now also always included for enemies if you have the addon ClassicAuraDurations enabled and "Full Aura Replacement" toggled on.
- Fix rare lua error on castbar stopped.
Expand Down

0 comments on commit 777f593

Please sign in to comment.