From 148fc5b104c9a909d6f92e0203c6c13d3e92e327 Mon Sep 17 00:00:00 2001 From: Kkthnx <40672673+Kkthnx@users.noreply.github.com> Date: Sat, 4 Jan 2025 17:37:57 -0500 Subject: [PATCH] Apply @DaleHuntGB code and improve on it as well. We will now check for additional conditions. If we enter combat while unlocked, the frame will be hidden and will return to its previous position once out of combat. We have also added a frameAnchorPoint to properly save the frame's position. Previously, there was a rare bug where the frame would mirror to the opposite side of the saved position. Finally, if the user types /lu unlock while already unlocked or /lu lock while already locked, they will now receive appropriate feedback. --- LevelUpFX/Config/Settings.lua | 51 +++++++++++ LevelUpFX/LevelUpFX.lua | 155 +++++++++++++++++++++++--------- LevelUpFX/LevelUpFX_Classic.toc | 4 +- 3 files changed, 168 insertions(+), 42 deletions(-) diff --git a/LevelUpFX/Config/Settings.lua b/LevelUpFX/Config/Settings.lua index 8903e83..be9e97d 100644 --- a/LevelUpFX/Config/Settings.lua +++ b/LevelUpFX/Config/Settings.lua @@ -33,6 +33,57 @@ namespace:RegisterSettings("LevelUpFXDB", { valueStep = 0.1, valueFormat = "%.1f", -- Format value to 1 decimal place }, + { + key = "frameAnchorPoint", + type = "menu", + title = "Anchor Point", + tooltip = "Select the anchor point for the level-up notification frame.", + default = "CENTER", + options = { + { value = "TOPLEFT", label = "Top Left" }, + { value = "TOP", label = "Top" }, + { value = "TOPRIGHT", label = "Top Right" }, + { value = "LEFT", label = "Left" }, + { value = "CENTER", label = "Center" }, + { value = "RIGHT", label = "Right" }, + { value = "BOTTOMLEFT", label = "Bottom Left" }, + { value = "BOTTOM", label = "Bottom" }, + { value = "BOTTOMRIGHT", label = "Bottom Right" }, + }, + }, + { + key = "frameAnchorX", + type = "slider", + title = "X Position", + tooltip = "Adjust the horizontal position of the level-up notification frame.", + default = 0, + minValue = GetScreenWidth() * -1, + maxValue = GetScreenWidth(), + valueStep = 1, + valueFormat = "%d", + }, + { + key = "frameAnchorY", + type = "slider", + title = "Y Position", + tooltip = "Adjust the vertical position of the level-up notification frame.", + default = 400, + minValue = GetScreenHeight() * -1, + maxValue = GetScreenHeight(), + valueStep = 1, + valueFormat = "%d", + }, + { + key = "popupDuration", + type = "slider", + title = "Popup Duration", + tooltip = "Adjust the duration of the level-up notification popup.", + default = 2, + minValue = 1, + maxValue = 5, + valueStep = 1, + valueFormat = "%d", + }, }) namespace:RegisterOptionCallback("enableAddon", function(value) diff --git a/LevelUpFX/LevelUpFX.lua b/LevelUpFX/LevelUpFX.lua index 2e4abb7..3cb43a6 100644 --- a/LevelUpFX/LevelUpFX.lua +++ b/LevelUpFX/LevelUpFX.lua @@ -2,9 +2,22 @@ local _, namespace = ... -- Reference to the currently displayed frame namespace.currentFrame = nil +local isMoving = false +local wasMovingBeforeCombat = false + +-- Get Frame Position, Save to Settings +local function GetFramePosition(frame) + local point, _, _, x, y = frame:GetPoint() + local anchorX = math.floor(x) + local anchorY = math.floor(y) + namespace:SetOption("frameAnchorPoint", point) + namespace:SetOption("frameAnchorX", anchorX) + namespace:SetOption("frameAnchorY", anchorY) + print("Frame Position Set - Point: " .. point .. " | xPos: " .. anchorX .. " | yPos: " .. anchorY) +end -- Function to create and show the level-up message -local function ShowLevelUpMessage(level, statGains) +local function ShowLevelUpMessage(level, statGains, isMoving) if not namespace:GetOption("enableAddon") then return end @@ -17,7 +30,9 @@ local function ShowLevelUpMessage(level, statGains) -- Create the main frame for the level-up display local frame = CreateFrame("Frame", nil, UIParent) frame:SetSize(600, 150) -- Adjusted width to accommodate horizontal layout - frame:SetPoint("CENTER", 0, 400) + local point = namespace:GetOption("frameAnchorPoint") or "CENTER" + local xPos, yPos = namespace:GetOption("frameAnchorX"), namespace:GetOption("frameAnchorY") + frame:SetPoint(point, xPos, yPos) frame:SetScale(namespace:GetOption("frameScale")) -- Apply scale from settings namespace.currentFrame = frame -- Save reference to the current frame @@ -84,55 +99,115 @@ local function ShowLevelUpMessage(level, statGains) end -- Fade-out animation - local fadeOutAnimation = frame:CreateAnimationGroup() - local fadeOut = fadeOutAnimation:CreateAnimation("Alpha") - fadeOut:SetFromAlpha(1) - fadeOut:SetToAlpha(0) - fadeOut:SetDuration(2) -- 2 seconds to fade out - fadeOut:SetStartDelay(4) -- Delay before fading - fadeOut:SetSmoothing("OUT") - fadeOutAnimation:SetScript("OnFinished", function() - frame:Hide() - end) - - -- Show the frame and start the animation - frame:Show() - fadeOutAnimation:Play() - - -- Perform the "CHEER" emote if enabled - if namespace:GetOption("cheerOnLevelUp") then + if not isMoving then + local fadeOutAnimation = frame:CreateAnimationGroup() + local fadeOut = fadeOutAnimation:CreateAnimation("Alpha") + fadeOut:SetFromAlpha(1) + fadeOut:SetToAlpha(0) + local popupDuration = namespace:GetOption("popupDuration") + fadeOut:SetDuration(popupDuration) + fadeOut:SetStartDelay(4) -- Delay before fading + fadeOut:SetSmoothing("IN_OUT") -- Use "IN_OUT" for smoother transition + fadeOutAnimation:SetScript("OnFinished", function() + frame:Hide() + end) + frame:Show() + fadeOutAnimation:Play() + else + -- Allow Dragging During `isMoving` + frame:SetMovable(true) + frame:EnableMouse(true) + frame:RegisterForDrag("LeftButton") + frame:SetScript("OnDragStart", function(self) + self:StartMoving() + self:ClearAllPoints() + end) + frame:SetScript("OnDragStop", function(self) + self:StopMovingOrSizing() + GetFramePosition(self) + end) + frame:Show() + end + + -- Perform the "CHEER" emote if enabled and not moving + if not isMoving and namespace:GetOption("cheerOnLevelUp") then if math.random() < 0.5 then DoEmote("CHEER") end end - -- Send chat emote if enabled - if namespace:GetOption("chatEmoteOnLevelUp") then + -- Send chat emote if enabled and not moving + if not isMoving and namespace:GetOption("chatEmoteOnLevelUp") then SendChatMessage("has reached level " .. level .. "!", "EMOTE") end end -- Event handler -namespace:RegisterEvent("PLAYER_LEVEL_UP", function(_, level, _, _, _, strengthDelta, agilityDelta, staminaDelta, intellectDelta, spiritDelta) - local statGains = { - Strength = strengthDelta or 0, - Agility = agilityDelta or 0, - Stamina = staminaDelta or 0, - Intellect = intellectDelta or 0, - Spirit = spiritDelta or 0, - } - ShowLevelUpMessage(level, statGains) +namespace:RegisterEvent( + "PLAYER_LEVEL_UP", + function(_, level, _, _, _, strengthDelta, agilityDelta, staminaDelta, intellectDelta, spiritDelta) + local statGains = { + Strength = strengthDelta or 0, + Agility = agilityDelta or 0, + Stamina = staminaDelta or 0, + Intellect = intellectDelta or 0, + Spirit = spiritDelta or 0, + } + ShowLevelUpMessage(level, statGains) + end +) + +-- Combat event handlers +namespace:RegisterEvent("PLAYER_REGEN_DISABLED", function() + if isMoving then + wasMovingBeforeCombat = true + isMoving = false + if namespace.currentFrame then + namespace.currentFrame:StopMovingOrSizing() + GetFramePosition(namespace.currentFrame) + namespace.currentFrame:Hide() + end + end +end) + +namespace:RegisterEvent("PLAYER_REGEN_ENABLED", function() + if wasMovingBeforeCombat then + wasMovingBeforeCombat = false + ShowLevelUpMessage(60, { Strength = 5, Agility = 5, Stamina = 5, Intellect = 5, Spirit = 5 }, true) + end end) -- Slash command for testing -namespace:RegisterSlash("/leveluptest", function(msg) - local testLevel = tonumber(msg) or math.random(2, 60) - local statGains = { - Strength = math.random(0, 5), - Agility = math.random(0, 5), - Stamina = math.random(0, 5), - Intellect = math.random(0, 5), - Spirit = math.random(0, 5), - } - ShowLevelUpMessage(testLevel, statGains) +namespace:RegisterSlash("/lu", function(msg) + if msg == "test" then + local testLevel = tonumber(msg) or math.random(2, 60) + local statGains = { + Strength = math.random(0, 5), + Agility = math.random(0, 5), + Stamina = math.random(0, 5), + Intellect = math.random(0, 5), + Spirit = math.random(0, 5), + } + ShowLevelUpMessage(testLevel, statGains, false) + elseif msg == "unlock" then + if isMoving then + print("Frame is already unlocked.") + else + ShowLevelUpMessage(60, { Strength = 5, Agility = 5, Stamina = 5, Intellect = 5, Spirit = 5 }, true) + isMoving = true + end + elseif msg == "lock" then + if not isMoving then + print("Frame is already locked.") + else + isMoving = false + if namespace.currentFrame then + namespace.currentFrame:StopMovingOrSizing() + GetFramePosition(namespace.currentFrame) + namespace.currentFrame:Hide() + end + end + else + print("Usage: /lu test [level] | /lu unlock | /lu lock") + end end) diff --git a/LevelUpFX/LevelUpFX_Classic.toc b/LevelUpFX/LevelUpFX_Classic.toc index f031c4b..bd2ab84 100644 --- a/LevelUpFX/LevelUpFX_Classic.toc +++ b/LevelUpFX/LevelUpFX_Classic.toc @@ -2,8 +2,8 @@ ## Name: LevelUpFX ## Title: |cff5bc0beLevelUpFX|r ## Notes: Celebrate your level-ups with style! Displays a animated message and stats gained whenever you level up in World of Warcraft Classic Era.|n|n|cff669DFFDeveloper|cffffffff:|r |nJosh "|CFF7b8489Kkthnx|r" Russell|n|n|cff009cdePayPal|r|cffffffff:|r |n|cffffffffwww.paypal.me/KkthnxTV|r|n|n|cfff96854Patreon|r|cffffffff:|r |n|cffffffffwww.patreon.com/Kkthnx|r -## Author: Josh "Kkthnx" Russell -## Version: 1.0.1 +## Author: Josh "Kkthnx" Russell, DaleHuntGB +## Version: 1.0.2 ## IconTexture: 236567 ## SavedVariables: LevelUpFXDB ## X-Support: Classic