commit 8bdf839b68b524ba5e72d8f200f2db6aff41e647 Author: Robin Date: Wed Jan 13 15:50:31 2021 +0100 Revision 38 diff --git a/Clickzz.toc b/Clickzz.toc new file mode 100644 index 0000000..050e9dc --- /dev/null +++ b/Clickzz.toc @@ -0,0 +1,9 @@ +## Interface: 90002 +## Title: Clickzz +## Notes: Clickcasting for Unitframes +## Author: Rilgamon +## X-WoWI-ID: 25674 +## SavedVariables: ClickzzDB +## OptionalDeps: Ace3, BrokerPack, zzLibCommon +Common\common.xml +pack.xml diff --git a/core.lua b/core.lua new file mode 100644 index 0000000..7768ee4 --- /dev/null +++ b/core.lua @@ -0,0 +1,346 @@ +local name, addon = ... +local parentName = addon['parentName'] or "BrokerPack" +local childName = "Clickzz" +local eventframe, db +local options +local mouseButtons = {'LEFTBUTTON','RIGHTBUTTON','WHEEL',"BUTTON4","BUTTON5"} +local buffButtons = {'Buff1', 'Buff2', 'Buff3', 'Debuff1', 'Debuff2', 'Debuff3', 'DispelDebuff1', 'DispelDebuff2', 'DispelDebuff3'} +local modifier = {'none','shift','ctrl','alt'} +ClickCastFrames = ClickCastFrames or {} +local castFrames = ClickCastFrames +local ldbicon = LibStub:GetLibrary("LibDBIcon-1.0") +local function OnClick(self, button) + if(IsShiftKeyDown() and button == "LeftButton") then + addon['db']['global']['ldbicons'][childName]['hide'] = not addon['db']['global']['ldbicons'][childName]['hide'] + if(ldbicon) then + if(addon['db']['global']['ldbicons'][childName]['hide']) then + ldbicon:Hide(childName) + else + ldbicon:Show(childName) + end + end + else + if(InterfaceOptionsFrame:IsVisible() and not InCombatLockdown()) then + InterfaceOptionsFrame:Hide() + else + InterfaceOptionsFrame_OpenToCategory(childName) + InterfaceOptionsFrame_OpenToCategory(childName) -- Twice because of a bug in InterfaceOptionsFrame_OpenToCategory + end + end +end +local function unregisterAttrs(frame) + if(InCombatLockdown()) then return end + frame['attrs'] = frame['attrs'] or {} + for key, value in pairs(frame['attrs']) do + frame:SetAttribute(key, nil) + frame['attrs'][key] = nil + end +end +local function registerAttrs(frame, key, value) + if(InCombatLockdown()) then + eventframe:RegisterEvent("PLAYER_REGEN_ENABLED") + else + frame['attrs'] = frame['attrs'] or {} + frame['attrs'][key] = value + frame:SetAttribute(key, value) + end +end +local function buffButtonSwitch(frame, switch) + local fName = frame:GetName() + if(strsub(fName, 1, 7) == 'Compact') then + for i = 1, #buffButtons do + local buffBtn = _G[format("%s%s", fName, buffButtons[i])] + + if(buffBtn) then + buffBtn:EnableMouse(switch) + end + end + end +end +local function disableFrame(frame) + if(InCombatLockdown()) then + eventframe:RegisterEvent("PLAYER_REGEN_ENABLED") + return + end + if(frame and frame:GetName()) then + buffButtonSwitch(frame, true) + unregisterAttrs(frame) + registerAttrs(frame, 'type', 'target') + registerAttrs(frame, 'type2', 'togglemenu') + castFrames[frame] = nil + end +end +local function gettype(v, attr) + local r = format("%s%i", attr, v['btn']) + if(v['mod'] ~= 1) then + r = format("%s-%s", v['modName'],r) + end + return r +end +local function regAtt(frame, v) + registerAttrs(frame, gettype(v, 'harmbutton'), format("nuke%i",v['btn'])) + registerAttrs(frame, gettype(v, 'helpbutton'), format("heal%i",v['btn'])) + registerAttrs(frame, gettype(v, 'type-heal'), 'spell') + registerAttrs(frame, gettype(v, 'type-nuke'), 'spell') + registerAttrs(frame, gettype(v, 'spell-nuke'), v['spell']) + registerAttrs(frame, gettype(v, 'spell-heal'), v['dualSpell'] and v['spellHeal'] or v['spell']) +end +local function enableFrame(frame, force) + if(InCombatLockdown()) then + eventframe:RegisterEvent("PLAYER_REGEN_ENABLED") + if(not force) then return end + end + if(frame['unit'] and strsub(frame['unit'], 1, 9) == 'nameplate') then +-- print('nameplate ignored', frame['unit']) + return + end + if(frame and frame:GetName()) then +-- disableFrame(frame) + buffButtonSwitch(frame, false) + frame:RegisterForClicks('AnyDown') + for k,v in pairs(db['clicks']) do + regAtt(frame, v) + end + castFrames[frame] = true + end +end +local firstRun = true +local function enableAllFrames() + local frames = { + 'PlayerFrame', 'TargetFrame', 'TargetFrameToT', 'FocusFrame', 'FocusFrameToT','PetFrame', + } + for n = 1, 8 do + for i = 1, 5 do + if(n==1) then + if(i<5) then + frames[#frames + 1] = format("PartyMemberFrame%i",i) + frames[#frames + 1] = format("PartyMemberFrame%iPetFrame",i) + frames[#frames + 1] = format("Boss%iTargetFrame",i) + end + frames[#frames + 1] = format("CompactPartyFrameMember%i",i) + end + frames[#frames + 1] = format("CompactRaidGroup%iMember%i",n,i) + end + end + for k,v in pairs(castFrames) do + if(v) then + local frame = k:GetName() + local skip = false + for n = 1, #frames do + if(frames[n] == frame) then + skip = true + break + end + end + if(not skip and frame) then + frames[#frames + 1] = frame + end + end + end + for k,frame in ipairs(frames) do + if(_G[frame]) then + enableFrame(_G[frame], firstRun) + else +-- print('skip', frame) + end + end + firstRun = false +end +local function OnText(message) + addon:OnText(childName, message) +end +local racialSpells = {} -- Beta returns the old names with C_AlliedRaces.GetAllRacialAbilitiesFromID(raceID) +local function isRacialSpell(spellIcon) -- Replace spellIcon with spellName once the bug is fixed +-- local name, rank, icon, castTime, minRange, maxRange, spellId = GetSpellInfo(spellName) +-- print('start',spellIcon) + for k, v in pairs(racialSpells) do +-- local nameR, rankR, iconR, castTimeR, minRangeR, maxRangeR, spellIdR = GetSpellInfo(v) +-- print(' check',v) + if(v == spellIcon) then + return true + end + end +end +local function buildRacialSpells() + local raceName, raceFile, raceID = UnitRace('player') + local res = C_AlliedRaces.GetAllRacialAbilitiesFromID(raceID) + if(res) then + for k, v in pairs(C_AlliedRaces.GetAllRacialAbilitiesFromID(raceID)) do + if(type(v)=='table') then + if(not IsPassiveSpell(v['name']) and not isRacialSpell(v['icon'])) then -- Replace icon with name once the bug is fixed + racialSpells[#racialSpells+1] = v['icon'] -- Replace icon with name once the bug is fixed + end + end + end + end +end +local function buildSpells(self) + if(InCombatLockdown()) then + self:RegisterEvent("PLAYER_REGEN_ENABLED") + return + end + local currentSpec = GetSpecialization() + if currentSpec then + local classInfo = C_CreatureInfo.GetClassInfo(select(3,UnitClass('player'))) + buildRacialSpells() + local _, currentSpecName = GetSpecializationInfo(currentSpec) + db['spells'] = {} + for tabIndex = 1, GetNumSpellTabs() do + local name, texture, offset, numEntries, isGuild, offspecID = GetSpellTabInfo(tabIndex) + if(name == currentSpecName or name == classInfo['className'] or tabIndex==1) then + if(offspecID==0) then + for spellIndex = offset + 1, offset + numEntries do + local skillType, special = GetSpellBookItemInfo(spellIndex, BOOKTYPE_SPELL) + if(skillType=="SPELL" and not IsPassiveSpell(spellIndex, BOOKTYPE_SPELL)) then + local spellName, spellSubName = GetSpellBookItemName(spellIndex, BOOKTYPE_SPELL) +-- print(spellName,spellSubName,IsPassiveSpell(spellIndex, BOOKTYPE_SPELL), raceSpell) + local _, _, icon = GetSpellInfo(spellName) + if(not IsAttackSpell(spellName)) then + if(spellSubName and spellSubName ~= "" and not isRacialSpell(icon)) then +-- db['spells'][special] = format("%s (%s)",spellName, spellSubName) + db['spells'][special] = spellName -- Fix when C_AlliedRaces.GetAllRacialAbilitiesFromID(raceID) returns a value + else + db['spells'][special] = spellName + end + end + end + end + end + end + end + end +end +local function OnEvent(self, event, ...) + if(event=="PLAYER_REGEN_ENABLED") then + self:UnregisterEvent(event) + elseif(event=="SPELLS_CHANGED") then + if(InCombatLockdown()) then + self:RegisterEvent("PLAYER_REGEN_ENABLED") + return + end + end + buildSpells(self) + enableAllFrames(self) +end +local function selectSpell() + local list = {} + for spellId, spellName in pairs(db['spells']) do + list[#list+1] = spellName + end + sort(list) + return list +end +local function remClick(pref) + addon['options']['args'][childName]['args']["activeClickzz"]['args'][pref[#pref-1]] = nil + db['clicks'][strsub(pref[#pref-1],10)] = nil + enableAllFrames() +end +local function buildMenu() + for clickName,v in pairs(db['clicks']) do + local grpName = v['btnName'] + if(v['mod'] ~= 1) then + grpName = format("%s-%s",strupper(v['modName']),grpName) + end + local clickNum = format("clickNum-%s", clickName) + local grp = addon:AddConfigEntry(childName,"group",clickNum,grpName,'',1,true,nil,nil,nil,options['args'][childName]['args']["activeClickzz"]) + addon:AddConfigEntry(childName,"execute","remClick",'Remove',nil,9,remClick,nil,nil,nil,options['args'][childName]['args']["activeClickzz"]['args'][clickNum]) + addon:AddConfigEntry(childName,"toggle","dualSpell",'Dual','Set damage and heal spell on same click',8,nil,nil,nil,nil,options['args'][childName]['args']["activeClickzz"]['args'][clickNum]) + addon:AddConfigEntry(childName,"select","selectSpell",'Spell',nil,7,selectSpell,nil,nil,nil,options['args'][childName]['args']["activeClickzz"]['args'][clickNum]) + if(v['dualSpell']) then + addon:AddConfigEntry(childName,"select","selectSpell2",'Heal Spell',nil,6,selectSpell,nil,nil,nil,options['args'][childName]['args']["activeClickzz"]['args'][clickNum]) + end + end +end +local function getPref(pref) + if(pref[#pref] == 'selectSpell') then + local spells = selectSpell() + for i = 1, #spells do + if(spells[i] == db['clicks'][strsub(pref[#pref-1],10)]['spell']) then + return i + end + end + elseif(pref[#pref] == 'selectSpell2') then + local spells = selectSpell() + for i = 1, #spells do + if(spells[i] == db['clicks'][strsub(pref[#pref-1],10)]['spellHeal']) then + return i + end + end + elseif(pref[#pref] == 'dualSpell') then + return db['clicks'][strsub(pref[#pref-1],10)]['dualSpell'] + end + return db[pref[#pref]] +end +local function setPref(pref,value) + if(pref[#pref] == 'selectSpell') then + local spells = selectSpell() + db['clicks'][strsub(pref[#pref-1],10)]['spell'] = spells[value] + enableAllFrames() + return + elseif(pref[#pref] == 'dualSpell') then + db['clicks'][strsub(pref[#pref-1],10)]['dualSpell'] = value + buildMenu() + return + elseif(pref[#pref] == 'selectSpell2') then + local spells = selectSpell() + db['clicks'][strsub(pref[#pref-1],10)]['spellHeal'] = spells[value] + enableAllFrames() + return + end + db[pref[#pref]] = value +end +local function addClick() + local mod = tonumber(db['modType']) + if(modifier[mod]) then + local clickName + local btn = tonumber(db['mouseButton']) + local mf = modifier[mod] + local bf = mouseButtons[btn] + if(mod==1) then + clickName = format("type%i", btn) + else + clickName = format("%s-type%i", mf, btn) + end + db['clicks'][clickName] = db['clicks'][clickName] or { + ['btnName'] = bf, + ['modName'] = mf, + ['btn'] = btn, + ['mod'] = mod + } + buildMenu() + enableAllFrames() + end +end +hooksecurefunc("CompactUnitFrame_SetUnit", function(self, unit) + if(InCombatLockdown()) then + eventframe:RegisterEvent("PLAYER_REGEN_ENABLED") + return + end + if(unit and not castFrames[self]) then + enableFrame(self,firstRun) + end +end) +do + + addon['preloads'][#addon['preloads'] + 1] = function(...) + db = addon['db']['profile'][childName] + eventframe = addon:RegisterFunc({'SPELLS_CHANGED','GROUP_ROSTER_UPDATE','RAID_ROSTER_UPDATE'},"OnEvent",OnEvent) + enableAllFrames() + end + addon:startup(name, childName, function() + options = addon:InitConfig(childName, true, { + ['type'] = "launcher", -- 'data source | launcher' + ['OnClick'] = OnClick + }, getPref, setPref) + addon:AddConfigEntry(childName,"select","modType",'Modifier',nil,1,modifier,nil,nil,nil,options['args'][childName]) + addon:AddConfigEntry(childName,"select","mouseButton",'Mousebutton',nil,2,mouseButtons,nil,nil,nil,options['args'][childName]) + addon:AddConfigEntry(childName,"execute","addClick",'Add Click',nil,3,addClick,nil,nil,nil,options['args'][childName]) + addon:AddConfigEntry(childName,"group","activeClickzz","Active Clickzz",'',4,true,nil,nil,nil,options['args'][childName]) + buildMenu() + end, nil, { + ['spells'] = {}, + ['clicks'] = {}, + ['mouseButton'] = 1, + ['modType'] = 1 + }) +end \ No newline at end of file diff --git a/icon2.tga b/icon2.tga new file mode 100644 index 0000000..89d81ab Binary files /dev/null and b/icon2.tga differ diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..b9e992f --- /dev/null +++ b/license.txt @@ -0,0 +1,6 @@ +The following license excludes the libraries (Libs) included. See the libraries directory or website. + +This AddOn is public domain. That means you can change it, rename it or paint it yellow. +My name (Rilgamon) is valid only for WoWInterface.com and curse.com. +If you use/offer this addon on another website please remove my name. +If you want to give me credit you can replace it with a link to my profile on WoWInterface.com. \ No newline at end of file diff --git a/pack.xml b/pack.xml new file mode 100644 index 0000000..0f7eacc --- /dev/null +++ b/pack.xml @@ -0,0 +1,3 @@ + +