local L = AceLibrary("AceLocale-2.2"):new("NampowerSettings") -- No Nampower v2, no need for settings local has_v2_nampower = pcall(GetCVar, "NP_QueueCastTimeSpells") if not has_v2_nampower then DEFAULT_CHAT_FRAME:AddMessage(L["|cffffcc00Nampower v2|cffffaaaa not present hiding settings."]) return end Nampower = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0", "AceDebug-2.0", "AceModuleCore-2.0", "AceConsole-2.0", "AceDB-2.0", "AceHook-2.1") Nampower:RegisterDB("NampowerSettingsDB") Nampower:RegisterDefaults("profile", { per_character_settings = false, show_queued_spell = false, queued_spell_posx = 0, queued_spell_posy = 0, queued_spell_size = 16, queued_spell_enable_mouse = true, }) Nampower.frame = CreateFrame("Frame", "Nampower", UIParent) function Nampower:HasMinimumVersion(major, minor, patch) if GetNampowerVersion then local installedMajor, installedMinor, installedPatch = GetNampowerVersion() if installedMajor > major then return true elseif installedMajor == major and installedMinor > minor then return true elseif installedMajor == major and installedMinor == minor and installedPatch >= patch then return true end end return false end -- check if they have the latest nampower dll if not Nampower:HasMinimumVersion(2, 8, 6) then DEFAULT_CHAT_FRAME:AddMessage(L["|cffffcc00Nampower update available.|cffffcc00 Some settings may be hidden until you update. Replace your existing nampower.dll with the latest from https://gitea.com/avitasia/nampower/releases"]) end -- setup queued spell frame Nampower.queued_spell = CreateFrame("Frame", "Queued Spell", UIParent) Nampower.queued_spell:SetFrameStrata("HIGH") Nampower.queued_spell.texture = Nampower.queued_spell:CreateTexture(nil, "OVERLAY") Nampower.queued_spell.texture:SetAllPoints() Nampower.queued_spell.texture:SetTexCoord(.08, .92, .08, .92) Nampower.queued_spell.texture:SetTexture("Interface\\Icons\\Spell_Nature_HealingWaveLesser") -- set test texture -- setup dragging Nampower.queued_spell:RegisterForDrag("LeftButton") Nampower.queued_spell:SetMovable(true) Nampower.queued_spell:SetScript("OnDragStart", function() this:StartMoving() end) local function saveQueuedSpellPosition() Nampower.db.profile.queued_spell_posx = Nampower.queued_spell:GetLeft() Nampower.db.profile.queued_spell_posy = Nampower.queued_spell:GetTop() end Nampower.queued_spell:SetScript("OnDragStop", function() this:StopMovingOrSizing() saveQueuedSpellPosition() end) local ON_SWING_QUEUED = 0 local ON_SWING_QUEUE_POPPED = 1 local NORMAL_QUEUED = 2 local NORMAL_QUEUE_POPPED = 3 local NON_GCD_QUEUED = 4 local NON_GCD_QUEUE_POPPED = 5 local function spellQueueEvent(eventCode, spellId) if eventCode == NORMAL_QUEUED or eventCode == NON_GCD_QUEUED then local _, _, texture = SpellInfo(spellId) -- superwow function Nampower.queued_spell.texture:SetTexture(texture) Nampower.queued_spell:Show() elseif eventCode == NORMAL_QUEUE_POPPED or eventCode == NON_GCD_QUEUE_POPPED then Nampower.queued_spell:Hide() end end local function toggleEventListener() if Nampower.db.profile.show_queued_spell then if SpellInfo then Nampower:RegisterEvent("SPELL_QUEUE_EVENT", spellQueueEvent) else DEFAULT_CHAT_FRAME:AddMessage(L["Superwow required to display queued spells."]) if Nampower:IsEventRegistered("SPELL_QUEUE_EVENT") then Nampower:UnregisterEvent("SPELL_QUEUE_EVENT") end end else if Nampower:IsEventRegistered("SPELL_QUEUE_EVENT") then Nampower:UnregisterEvent("SPELL_QUEUE_EVENT") end end end -- used when turning on per character settings function Nampower:SavePerCharacterSettings() for settingKey, settingData in pairs(Nampower.cmdtable.args) do if string.find(settingKey, "NP_") == 1 then settingData.set(settingData.get()) -- trigger the set function for each setting with the current value end end for settingKey, settingData in pairs(Nampower.cmdtable.args.queue_windows.args) do if string.find(settingKey, "NP_") == 1 then settingData.set(settingData.get()) -- trigger the set function for each setting with the current value end end for settingKey, settingData in pairs(Nampower.cmdtable.args.advanced_options.args) do if string.find(settingKey, "NP_") == 1 then settingData.set(settingData.get()) -- trigger the set function for each setting with the current value end end end function Nampower:ApplySavedSettings() for settingKey, settingData in pairs(Nampower.cmdtable.args) do -- only apply settings that are prefixed with NP_ if string.find(settingKey, "NP_") == 1 then if Nampower.db.profile[settingKey]~= nil then settingData.set(Nampower.db.profile[settingKey]) end end end for settingKey, settingData in pairs(Nampower.cmdtable.args.queue_windows.args) do -- only apply settings that are prefixed with NP_ if string.find(settingKey, "NP_") == 1 then if Nampower.db.profile[settingKey]~= nil then settingData.set(Nampower.db.profile[settingKey]) end end end for settingKey, settingData in pairs(Nampower.cmdtable.args.advanced_options.args) do -- only apply settings that are prefixed with NP_ if string.find(settingKey, "NP_") == 1 then if Nampower.db.profile[settingKey]~= nil then settingData.set(Nampower.db.profile[settingKey]) end end end end function Nampower:OnEnable() Nampower.queued_spell:EnableMouse(Nampower.db.profile.queued_spell_enable_mouse) -- set scale local x = Nampower.db.profile.queued_spell_posx local y = Nampower.db.profile.queued_spell_posy local size = Nampower.db.profile.queued_spell_size -- set saved position Nampower.queued_spell:ClearAllPoints() Nampower.queued_spell:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", x, y) Nampower.queued_spell:SetWidth(size) Nampower.queued_spell:SetHeight(size) Nampower.queued_spell:Hide() -- if per character settings are enabled, apply them if Nampower.db.profile.per_character_settings then Nampower:ApplySavedSettings() end toggleEventListener() end Nampower.cmdtable = { type = "group", handler = Nampower, args = { per_character_settings = { type = "toggle", name = L["Enable Per Character Settings"], desc = L["Whether to use per character settings for all of the NP_ settings. This will cause settings saved in your character's NampowerSettings.lua to override any global settings in Config.wtf."], order = 1, get = function() return Nampower.db.profile.per_character_settings end, set = function(v) if v ~= Nampower.db.profile.per_character_settings then Nampower.db.profile.per_character_settings = v if v == true then Nampower:SavePerCharacterSettings() end end end, }, NP_QueueCastTimeSpells = { type = "toggle", name = L["Queue Cast Time Spells"], desc = L["Whether to enable spell queuing for spells with a cast time"], order = 5, get = function() return GetCVar("NP_QueueCastTimeSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QueueCastTimeSpells = v if v == true then SetCVar("NP_QueueCastTimeSpells", "1") else SetCVar("NP_QueueCastTimeSpells", "0") end end, }, NP_QueueInstantSpells = { type = "toggle", name = L["Queue Instant Spells"], desc = L["Whether to enable spell queuing for instant cast spells tied to gcd"], order = 10, get = function() return GetCVar("NP_QueueInstantSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QueueInstantSpells = v if v == true then SetCVar("NP_QueueInstantSpells", "1") else SetCVar("NP_QueueInstantSpells", "0") end end, }, NP_QueueOnSwingSpells = { type = "toggle", name = L["Queue On Swing Spells"], desc = L["Whether to enable on swing spell queuing"], order = 15, get = function() return GetCVar("NP_QueueOnSwingSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QueueOnSwingSpells = v if v == true then SetCVar("NP_QueueOnSwingSpells", "1") else SetCVar("NP_QueueOnSwingSpells", "0") end end, }, NP_QueueChannelingSpells = { type = "toggle", name = L["Queue Channeling Spells"], desc = L["Whether to enable channeling spell queuing"], order = 20, get = function() return GetCVar("NP_QueueChannelingSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QueueChannelingSpells = v if v == true then SetCVar("NP_QueueChannelingSpells", "1") else SetCVar("NP_QueueChannelingSpells", "0") end end, }, NP_QueueTargetingSpells = { type = "toggle", name = L["Queue Targeting Spells"], desc = L["Whether to enable terrain targeting spell queuing"], order = 25, get = function() return GetCVar("NP_QueueTargetingSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QueueTargetingSpells = v if v == true then SetCVar("NP_QueueTargetingSpells", "1") else SetCVar("NP_QueueTargetingSpells", "0") end end, }, NP_QueueSpellsOnCooldown = { type = "toggle", name = L["Queue Spells Coming Off Cooldown"], desc = L["Whether to enable spell queuing for spells coming off cooldown"], order = 30, get = function() return GetCVar("NP_QueueSpellsOnCooldown") == "1" end, set = function(v) Nampower.db.profile.NP_QueueSpellsOnCooldown = v if v == true then SetCVar("NP_QueueSpellsOnCooldown", "1") else SetCVar("NP_QueueSpellsOnCooldown", "0") end end, }, spacera = { type = "header", name = " ", order = 31, }, queue_windows = { type = "group", name = L["Queue Windows"], desc = L["How much time in ms you have before a cast ends to queue different types of spells"], order = 40, args = { NP_SpellQueueWindowMs = { type = "range", name = L["Spell Queue Window (ms)"], desc = L["The window in ms before a cast finishes where the next will get queued"], order = 40, min = 0, max = 5000, step = 50, get = function() return GetCVar("NP_SpellQueueWindowMs") end, set = function(v) Nampower.db.profile.NP_SpellQueueWindowMs = v SetCVar("NP_SpellQueueWindowMs", v) end, }, NP_OnSwingBufferCooldownMs = { type = "range", name = L["On Swing Buffer Cooldown (ms)"], desc = L["The cooldown time in ms after an on swing spell before you can queue on swing spells"], order = 45, min = 0, max = 5000, step = 50, get = function() return GetCVar("NP_OnSwingBufferCooldownMs") end, set = function(v) Nampower.db.profile.NP_OnSwingBufferCooldownMs = v SetCVar("NP_OnSwingBufferCooldownMs", v) end, }, NP_ChannelQueueWindowMs = { type = "range", name = L["Channel Queue Window (ms)"], desc = L["The window in ms before a channel finishes where the next will get queued"], order = 50, min = 0, max = 5000, step = 50, get = function() return GetCVar("NP_ChannelQueueWindowMs") end, set = function(v) Nampower.db.profile.NP_ChannelQueueWindowMs = v SetCVar("NP_ChannelQueueWindowMs", v) end, }, NP_TargetingQueueWindowMs = { type = "range", name = L["Targeting Queue Window (ms)"], desc = L["The window in ms before a terrain targeting spell finishes where the next will get queued"], order = 55, min = 0, max = 5000, step = 50, get = function() return GetCVar("NP_TargetingQueueWindowMs") end, set = function(v) Nampower.db.profile.NP_TargetingQueueWindowMs = v SetCVar("NP_TargetingQueueWindowMs", v) end, }, NP_CooldownQueueWindowMs = { type = "range", name = L["Cooldown Queue Window (ms)"], desc = L["The window in ms before a spell coming off cooldown finishes where the next will get queued"], order = 60, min = 0, max = 5000, step = 50, get = function() return GetCVar("NP_CooldownQueueWindowMs") end, set = function(v) Nampower.db.profile.NP_CooldownQueueWindowMs = v SetCVar("NP_CooldownQueueWindowMs", v) end, } }, }, spacerb = { type = "header", name = " ", order = 50, }, advanced_options = { type = "group", name = L["Advanced options"], desc = L["Collection of various advanced options"], order = 60, args = { NP_DoubleCastToEndChannelEarly = { type = "toggle", name = L["Double Cast to End Channel Early"], desc = L["Whether to allow double casting a spell within 350ms to end channeling on the next tick. Takes into account your ChannelLatencyReductionPercentage."], order = 33, get = function() return GetCVar("NP_DoubleCastToEndChannelEarly") == "1" end, set = function(v) Nampower.db.profile.NP_DoubleCastToEndChannelEarly = v if v == true then SetCVar("NP_DoubleCastToEndChannelEarly", "1") else SetCVar("NP_DoubleCastToEndChannelEarly", "0") end end, }, NP_InterruptChannelsOutsideQueueWindow = { type = "toggle", name = L["Interrupt Channels Outside Queue Window"], desc = L["Whether to allow interrupting channels (the original client behavior) when trying to cast a spell outside the channeling queue window"], order = 70, get = function() return GetCVar("NP_InterruptChannelsOutsideQueueWindow") == "1" end, set = function(v) Nampower.db.profile.NP_InterruptChannelsOutsideQueueWindow = v if v == true then SetCVar("NP_InterruptChannelsOutsideQueueWindow", "1") else SetCVar("NP_InterruptChannelsOutsideQueueWindow", "0") end end, }, NP_RetryServerRejectedSpells = { type = "toggle", name = L["Retry Server Rejected Spells"], desc = L["Whether to retry spells that are rejected by the server for these reasons: SPELL_FAILED_ITEM_NOT_READY, SPELL_FAILED_NOT_READY, SPELL_FAILED_SPELL_IN_PROGRESS"], order = 100, get = function() return GetCVar("NP_RetryServerRejectedSpells") == "1" end, set = function(v) Nampower.db.profile.NP_RetryServerRejectedSpells = v if v == true then SetCVar("NP_RetryServerRejectedSpells", "1") else SetCVar("NP_RetryServerRejectedSpells", "0") end end, }, NP_QuickcastTargetingSpells = { type = "toggle", name = L["Quickcast Targeting Spells"], desc = L["Whether to enable quick casting for ALL spells with terrain targeting"], order = 105, get = function() return GetCVar("NP_QuickcastTargetingSpells") == "1" end, set = function(v) Nampower.db.profile.NP_QuickcastTargetingSpells = v if v == true then SetCVar("NP_QuickcastTargetingSpells", "1") else SetCVar("NP_QuickcastTargetingSpells", "0") end end, }, NP_ReplaceMatchingNonGcdCategory = { type = "toggle", name = L["Replace Matching Non GCD Category"], desc = L["Whether to replace any queued non gcd spell when a new non gcd spell with the same non zero StartRecoveryCategory is cast. Most trinkets and spells are category 0 which are ignored by this setting. The primary use case is to switch which potion you have queued."], order = 110, get = function() return GetCVar("NP_ReplaceMatchingNonGcdCategory") == "1" end, set = function(v) Nampower.db.profile.NP_ReplaceMatchingNonGcdCategory = v if v == true then SetCVar("NP_ReplaceMatchingNonGcdCategory", "1") else SetCVar("NP_ReplaceMatchingNonGcdCategory", "0") end end, }, NP_OptimizeBufferUsingPacketTimings = { type = "toggle", name = L["Optimize Buffer Using Packet Timings"], desc = L["Whether to attempt to optimize your buffer using your latency and server packet timings"], order = 115, get = function() return GetCVar("NP_OptimizeBufferUsingPacketTimings") == "1" end, set = function(v) Nampower.db.profile.NP_OptimizeBufferUsingPacketTimings = v if v == true then SetCVar("NP_OptimizeBufferUsingPacketTimings", "1") else SetCVar("NP_OptimizeBufferUsingPacketTimings", "0") end end, }, NP_MinBufferTimeMs = { type = "range", name = L["Minimum Buffer Time (ms)"], desc = L["The minimum buffer delay in ms added to each cast"], order = 80, min = 0, max = 300, step = 1, get = function() return GetCVar("NP_MinBufferTimeMs") end, set = function(v) Nampower.db.profile.NP_MinBufferTimeMs = v SetCVar("NP_MinBufferTimeMs", v) end, }, NP_NonGcdBufferTimeMs = { type = "range", name = L["Non GCD Buffer Time (ms)"], desc = L["The buffer delay in ms added AFTER each cast that is not tied to the gcd"], order = 85, min = 0, max = 300, step = 1, get = function() return GetCVar("NP_NonGcdBufferTimeMs") end, set = function(v) Nampower.db.profile.NP_NonGcdBufferTimeMs = v SetCVar("NP_NonGcdBufferTimeMs", v) end, }, NP_MaxBufferIncreaseMs = { type = "range", name = L["Max Buffer Increase (ms)"], desc = L["The maximum amount of time in ms to increase the buffer by when the server rejects a cast"], order = 90, min = 0, max = 100, step = 5, get = function() return GetCVar("NP_MaxBufferIncreaseMs") end, set = function(v) Nampower.db.profile.NP_MaxBufferIncreaseMs = v SetCVar("NP_MaxBufferIncreaseMs", v) end, }, NP_ChannelLatencyReductionPercentage = { type = "range", name = L["Channel Latency Reduction (%)"], desc = L["The percentage of your latency to subtract from the end of a channel duration to optimize cast time while hopefully not losing any ticks"], order = 125, min = 0, max = 100, step = 1, get = function() return GetCVar("NP_ChannelLatencyReductionPercentage") end, set = function(v) Nampower.db.profile.NP_ChannelLatencyReductionPercentage = v SetCVar("NP_ChannelLatencyReductionPercentage", v) end, } }, }, spacerc = { type = "header", name = " ", order = 70, }, queued_spell_options = { type = "group", name = L["Queued Spell Display Options"], desc = L["Options for displaying an icon for the queued spell"], order = 80, args = { enabled = { type = "toggle", name = L["Display queued spell icon"], desc = L["Whether to display an icon of the queued spell"], order = 5, get = function() return Nampower.db.profile.show_queued_spell end, set = function(v) Nampower.db.profile.show_queued_spell = v toggleEventListener() end, }, size = { type = "range", name = L["Icon size"], desc = L["Change the spell icon size"], order = 10, min = 8, max = 48, step = 1, get = function() return Nampower.db.profile.queued_spell_size end, set = function(v) Nampower.db.profile.queued_spell_size = v Nampower.queued_spell:SetWidth(v) Nampower.queued_spell:SetHeight(v) end, }, draggable = { type = "toggle", name = L["Allow dragging"], desc = L["Whether to allow interaction with the queued spell icon so you can move it around"], order = 15, get = function() return Nampower.db.profile.queued_spell_enable_mouse end, set = function(v) Nampower.db.profile.queued_spell_enable_mouse = v Nampower.queued_spell:EnableMouse(v) end, }, reset_position = { type = "execute", name = L["Reset Position"], desc = L["Reset the position of the queued spell icon"], order = 20, func = function() local scale = Nampower.queued_spell:GetEffectiveScale() Nampower.queued_spell:ClearAllPoints() Nampower.queued_spell:SetPoint("TOPLEFT", UIParent, "BOTTOMLEFT", 500 / scale, 500 / scale) saveQueuedSpellPosition() end, }, test = { type = "execute", name = L["Show/Hide for positioning"], desc = L["Test the queued spell icon and position it to your liking"], order = 25, func = function() if Nampower.queued_spell:IsVisible() then Nampower.queued_spell:Hide() else Nampower.queued_spell:Show() end end, }, }, }, spacer6 = { type = "header", name = " ", order = 90, }, NP_PreventRightClickTargetChange = { type = "toggle", name = L["Prevent Right Click Target Change"], desc = L["Whether to prevent right-clicking from changing your current target when in combat. If you don't have a target right click will still change your target even with this on. This is mainly to prevent accidentally changing targets in combat when trying to adjust your camera."], order = 100, get = function() return GetCVar("NP_PreventRightClickTargetChange") == "1" end, set = function(v) Nampower.db.profile.NP_PreventRightClickTargetChange = v if v == true then SetCVar("NP_PreventRightClickTargetChange", "1") else SetCVar("NP_PreventRightClickTargetChange", "0") end end, }, }, } if Nampower:HasMinimumVersion(2, 8, 6) then Nampower.cmdtable.args.NP_NameplateDistance = { type = "range", name = L["Nameplate Distance"], desc = L["The distance in yards to show nameplates"], order = 110, min = 5, max = 200, step = 1, get = function() return GetCVar("NP_NameplateDistance") end, set = function(v) Nampower.db.profile.NP_NameplateDistance = v SetCVar("NP_NameplateDistance", v) end, } end local deuce = Nampower:NewModule("Nampower Options Menu") deuce.hasFuBar = IsAddOnLoaded("FuBar") and FuBar deuce.consoleCmd = not deuce.hasFuBar NampowerOptions = AceLibrary("AceAddon-2.0"):new("AceDB-2.0", "FuBarPlugin-2.0") NampowerOptions.name = "FuBar - Nampower" NampowerOptions.hasIcon = "Interface\\Icons\\inv_misc_book_04" NampowerOptions.defaultMinimapPosition = 180 NampowerOptions.independentProfile = true NampowerOptions.hideWithoutStandby = false NampowerOptions:RegisterDB("NampowerSettingsDB") NampowerOptions.OnMenuRequest = Nampower.cmdtable local args = AceLibrary("FuBarPlugin-2.0"):GetAceOptionsDataTable(NampowerOptions) for k, v in pairs(args) do if NampowerOptions.OnMenuRequest.args[k] == nil then NampowerOptions.OnMenuRequest.args[k] = v end end