You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

513 lines
14 KiB

-- Neuron is a World of Warcraft® user interface addon.
-- Copyright (c) 2017-2021 Britt W. Yazel
-- Copyright (c) 2006-2014 Connor H. Chenoweth
-- This code is licensed under the MIT license (see LICENSE for details)
local _, addonTable = ...
local Neuron = addonTable.Neuron
---The functions in this file are part of the ActionButton class.
---It was just easier to put them all in their own file for organization.
local ActionButton = Neuron.ActionButton
local macroDrag = {} --this is a table that holds onto the contents of the current macro being dragged
local macroCache = {} --this will hold onto any previous contents of our button
local L = LibStub("AceLocale-3.0"):GetLocale("Neuron")
--------------------------------------
--------------------------------------
--this is the function that fires when you begin dragging an item
function ActionButton:OnDragStart()
if InCombatLockdown() or not self.bar or self.actionID then
return
end
local drag
if not self.bar:GetBarLock() then
drag = true
elseif self.bar:GetBarLock() == "alt" and IsAltKeyDown() then
drag = true
elseif self.bar:GetBarLock() == "ctrl" and IsControlKeyDown() then
drag = true
elseif self.bar:GetBarLock() == "shift" and IsShiftKeyDown() then
drag = true
else
drag = false
end
if drag and self:GetMacroText() ~= "" then
Neuron.dragging = true
if #macroCache==0 then --don't run if we have a cache, we will call it manually on the OnReceiveDrag on the new button
self:SetMouseCursor()
end
self:PickUpMacro()
self:InitializeButton()
self:UpdateAll()
for _,bar in pairs(Neuron.bars) do
if bar.class == "ActionBar" then
bar:ACTIONBAR_SHOWHIDEGRID(true) --show the button grid if we have something picked up (i.e if macroDrag contains something)
end
end
end
end
--This is the function that fires when a button is receiving a dragged item
function ActionButton:OnReceiveDrag()
if InCombatLockdown() then --don't allow moving or changing macros while in combat. This will cause taint
return
end
local cursorType, action1, action2, spellID = GetCursorInfo()
if self:HasAction() then --if our button being dropped onto already has content, we need to cache that content
macroCache[1] = self:GetDragAction()
macroCache[2] = self:GetMacroText()
macroCache[3] = self:GetMacroIcon()
macroCache[4] = self:GetMacroName()
macroCache[5] = self:GetMacroNote()
macroCache[6] = self:GetMacroUseNote()
macroCache[7] = self:GetMacroBlizzMacro()
macroCache[8] = self:GetMacroEquipmentSet()
else
wipe(macroCache)
end
if #macroCache > 0 then --if we have a cache, pickup the current icon before replacing it with the new content
self:SetMouseCursor()
end
if #macroDrag > 0 then --checks to see if the thing we are placing is a Neuron created macro vs something from the spellbook
self:PlaceMacro()
elseif cursorType == "spell" then
self:PlaceSpell(action1, action2, spellID)
elseif cursorType == "item" then
self:PlaceItem(action1, action2)
elseif cursorType == "macro" then
self:PlaceBlizzMacro(action1)
elseif cursorType == "equipmentset" then
self:PlaceBlizzEquipSet(action1)
elseif cursorType == "mount" then
self:PlaceMount(action1, action2)
elseif cursorType == "flyout" then
self:PlaceFlyout(action1, action2)
elseif cursorType == "battlepet" then
self:PlaceBattlePet(action1, action2)
elseif cursorType == "companion" then
self:PlaceCompanion(action1, action2)
elseif cursorType == "petaction" then
self:PlacePetAbility(action1, action2)
end
wipe(macroDrag)
if #macroCache>0 then
self:OnDragStart() --If we picked up a new ability after dropping this one we have to manually call OnDragStart
for _,bar in pairs(Neuron.bars) do
bar:ACTIONBAR_SHOWHIDEGRID(true) --show the button grid if we have something picked up (i.e if macroDrag contains something)
end
else
SetCursor(nil)
ClearCursor() --if we did not pick up a new spell, clear the cursor
Neuron.dragging = false
for _,bar in pairs(Neuron.bars) do
bar:ACTIONBAR_SHOWHIDEGRID() --show the button grid if we have something picked up (i.e if macroDrag contains something)
end
end
self:InitializeButton()
self:UpdateAll()
end
function ActionButton:PostClick() --this is necessary because if you are daisy-chain dragging spells to the bar you wont be able to place the last one due to it not firing an OnReceiveDrag
if #macroDrag>0 then
self:OnReceiveDrag()
end
self:UpdateStatus()
end
--we need to hook to the WorldFrame OnReceiveDrag and OnMouseDown so that we can "let go" of the spell when we drag it off the bar
function ActionButton:WorldFrame_OnReceiveDrag()
--CAREFUL! see brittyazel/Neuron/issues/468
--only do something if there's currently data in macroDrag. Otherwise it is
--just for normal Blizzard behavior.
if #macroDrag > 0 then
SetCursor(nil)
ClearCursor()
Neuron.dragging = false
wipe(macroDrag)
wipe(macroCache)
end
for _,bar in pairs(Neuron.bars) do
bar:ACTIONBAR_SHOWHIDEGRID()
end
end
--------------------------------------
--------------------------------------
function ActionButton:PickUpMacro()
if macroCache[1] then --triggers when picking up an existing button with a button in the cursor
macroDrag = CopyTable(macroCache)
wipe(macroCache) --once macroCache is loaded into macroDrag, wipe it
elseif self:HasAction() then
macroDrag[1] = self:GetDragAction()
macroDrag[2] = self:GetMacroText()
macroDrag[3] = self:GetMacroIcon()
macroDrag[4] = self:GetMacroName()
macroDrag[5] = self:GetMacroNote()
macroDrag[6] = self:GetMacroUseNote()
macroDrag[7] = self:GetMacroBlizzMacro()
macroDrag[8] = self:GetMacroEquipmentSet()
self:SetMacroText()
self:SetMacroIcon()
self:SetMacroName()
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
self.spell = nil
self.spellID = nil
self.item = nil
self:InitializeButton()
end
end
function ActionButton:PlaceMacro()
self:SetMacroText(macroDrag[2])
self:SetMacroIcon(macroDrag[3])
self:SetMacroName(macroDrag[4])
self:SetMacroNote(macroDrag[5])
self:SetMacroUseNote(macroDrag[6])
self:SetMacroBlizzMacro(macroDrag[7])
self:SetMacroEquipmentSet(macroDrag[8])
end
function ActionButton:PlaceSpell(action1, action2, spellID)
local spell
if action1 == 0 then
-- I am unsure under what conditions (if any) we wouldn't have a spell ID
if not spellID or spellID == 0 then
return
else
spell = GetSpellInfo(spellID)
end
else
spell,_= GetSpellBookItemName(action1, action2):lower()
_,spellID = GetSpellBookItemInfo(action1, action2)
end
local spellName , _, icon = GetSpellInfo(spellID)
if not spellName then
if Neuron.spellCache[spell:lower()] then
spellName = Neuron.spellCache[spell:lower()].spellName
icon = Neuron.spellCache[spell:lower()].icon
end
end
self:SetMacroText(self:AutoWriteMacro(spell))
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
self:SetMacroName(spellName)
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
end
function ActionButton:PlacePetAbility(action1, action2)
local spellID = action1
local spellIndex = action2
if spellIndex then --if the ability doesn't have a spellIndex, i.e (passive, follow, defensive, etc, print a warning)
local spellInfoName , _, icon = GetSpellInfo(spellID)
self:SetMacroText(self:AutoWriteMacro(spellInfoName))
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
self:SetMacroName(spellInfoName)
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
else
Neuron:Print(L["DragDrop_Error_Message"])
end
end
function ActionButton:PlaceItem(action1, action2)
local item, link = GetItemInfo(action2)
if link and not Neuron.itemCache[item:lower()] then --add the item to the itemcache if it isn't otherwise in it
local _, itemID = link:match("(item:)(%d+)")
Neuron.itemCache[item:lower()] = itemID
end
if IsEquippableItem(item) then
self:SetMacroText("/equip "..item.."\n/use "..item)
else
self:SetMacroText("/use "..item)
end
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
self:SetMacroName(item)
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
end
function ActionButton:PlaceBlizzMacro(action1)
if action1 == 0 then
return
end
local name, texture, body = GetMacroInfo(action1)
if body then
self:SetMacroText(body)
self:SetMacroName(name)
self:SetMacroIcon(texture)
self:SetMacroBlizzMacro(name)
else
self:SetMacroText()
self:SetMacroName()
self:SetMacroIcon()
self:SetMacroBlizzMacro()
end
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroEquipmentSet()
end
function ActionButton:PlaceBlizzEquipSet(equipmentSetName)
if equipmentSetName == 0 then
return
end
local equipsetNameIndex --cycle through the equipment sets to find the index of the one with the right name
for i = 0,C_EquipmentSet.GetNumEquipmentSets()-1 do
if equipmentSetName == C_EquipmentSet.GetEquipmentSetInfo(i) then
equipsetNameIndex = i
break
end
end
if not equipsetNameIndex then --bail out of we don't find an equipset index (should never happen but just in case
return
end
local name, texture = C_EquipmentSet.GetEquipmentSetInfo(equipsetNameIndex)
if texture then
self:SetMacroText("/equipset "..equipmentSetName)
self:SetMacroName(name)
self:SetMacroIcon(texture)
self:SetMacroEquipmentSet(equipmentSetName)
else
self:SetMacroText()
self:SetMacroName()
self:SetMacroIcon()
self:SetMacroEquipmentSet()
end
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
end
--Hooks mount journal mount buttons on enter to pull spellid from tooltip--
--Based on discussion thread http://www.wowinterface.com/forums/showthread.php?t=49599&page=2
--More dynamic than the manual list that was originally implement
function ActionButton:PlaceMount(action1, action2)
local mountName, mountSpellID, mountIcon = C_MountJournal.GetMountInfoByID(action1)
local mountSpell
if action1 == 0 or not mountSpellID or mountSpellID == 0 then
return
else
mountSpell = GetSpellInfo(mountSpellID)
end
--The Summon Random Mount from the Mount Journal
if action1 == 268435455 then
self:SetMacroText("#autowrite\n/run C_MountJournal.SummonByID(0);")
self:SetMacroIcon("Interface\\ICONS\\ACHIEVEMENT_GUILDPERK_MOUNTUP")
self:SetMacroName("Random Mount")
else
self:SetMacroText(self:AutoWriteMacro(mountSpell))
self:SetMacroIcon() --will pull icon automatically unless explicitly overridden
self:SetMacroName(mountName)
end
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
end
function ActionButton:PlaceCompanion(action1, action2)
if action1 == 0 then
return
end
local _, _, spellID, icon = GetCompanionInfo(action2, action1)
local name = GetSpellInfo(spellID)
if name then
self:SetMacroName(name)
self:SetMacroText(self:AutoWriteMacro(name))
else
self:SetMacroName()
self:SetMacroText()
end
self:SetMacroIcon(icon) --need to set icon here, it won't pull it automatically
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
end
function ActionButton:PlaceBattlePet(action1, action2)
if action1 == 0 then
return
end
local _, _, _, _, _, _, _,petName, petIcon= C_PetJournal.GetPetInfoByPetID(action1)
self:SetMacroText("#autowrite\n/summonpet "..petName)
self:SetMacroIcon(petIcon) --need to set icon here, it won't pull it automatically
self:SetMacroName(petName)
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
end
function ActionButton:PlaceFlyout(action1, action2)
if action1 == 0 then
return
end
local count = #self.bar.buttons
local columns = self.bar.data.columns or count
local rows = count/columns
local point = self:GetPosition(UIParent)
if columns/rows > 1 then
if point:find("BOTTOM") then
point = "b:t:1"
elseif point:find("TOP") then
point = "t:b:1"
elseif point:find("RIGHT") then
point = "r:l:12"
elseif point:find("LEFT") then
point = "l:r:12"
else
point = "r:l:12"
end
else
if point:find("RIGHT") then
point = "r:l:12"
elseif point:find("LEFT") then
point = "l:r:12"
elseif point:find("BOTTOM") then
point = "b:t:1"
elseif point:find("TOP") then
point = "t:b:1"
else
point = "r:l:12"
end
end
self:SetMacroText("/flyout blizz:"..action1..":l:"..point..":c")
self:SetMacroIcon()
self:SetMacroName()
self:SetMacroNote()
self:SetMacroUseNote()
self:SetMacroBlizzMacro()
self:SetMacroEquipmentSet()
self:UpdateFlyout(true)
end
--This is all just to put an icon on the mouse cursor. Sadly we can't use SetCursor, because once you leave the frame the icon goes away. PickupSpell seems to work, but we need a valid spellID
--This trick here is that we ignore what is 'actually' and are just using it for the icon and the sound effects
function ActionButton:SetMouseCursor()
ClearCursor()
if self.spell and self.spellID then
PickupSpell(self.spellID)
if GetCursorInfo() then
return
end
end
if self.item then
PickupItem(self.item) --this is to try to catch any stragglers that might not have a spellID on the button. Things like mounts and such. This only works on currently available items
if GetCursorInfo() then --if this isn't a normal spell (like a flyout) or it is a pet abiity, revert to a question mark symbol
return
end
PickupItem(GetItemInfoInstant(self.item))
if GetCursorInfo() then
return
end
if Neuron.itemCache[self.item:lower()] then --try to pull the spellID from our ItemCache as a last resort
PickupItem(Neuron.itemCache[self.item:lower()])
if GetCursorInfo() then
return
end
end
end
--failsafe so there is 'something' on the mouse cursor
PickupItem(1217) --questionmark symbol
end