Thread Tools Display Modes
02-13-15, 07:02 AM   #1
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Semi-automatically change talents

I'm working on an add-on that will remind people to change their talents before specific boss fights (by their personal choice, of course). Is there a way to automate any part of the talent switching process?
(The holy grail here would be creating a button that says Click Here To Learn These 4 Talents, but I've been unable to find a way to do that)
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
02-13-15, 07:35 AM   #2
Choonstertwo
A Chromatic Dragonspawn
 
Choonstertwo's Avatar
AddOn Author - Click to view addons
Join Date: Jan 2011
Posts: 194
Ro posted a talent-swapping macro here, but apparently it's not always reliable when trying to switch multiple talent tiers at once.

You could use a secure action button with type = macro and dynamically build up a macro for each tier you need to swap.
  Reply With Quote
02-13-15, 09:02 AM   #3
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Hmmm... that thread implies that it's possible to switch one talent with an add-on, but doesn't say how. Does it mean the way to do this via add-on is, as you said, to make a secure button which creates and calls that sort of talent swapping macro?

Also I'm starting to think it might be best to not fully automate it anyway, but to list the talents that you presumably want to learn and put a button next to each.
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
02-13-15, 09:08 AM   #4
Dorwido
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Apr 2006
Posts: 54
should be possible:
http://wow.gamepedia.com/World_of_Wa...lent_Functions

have a look at the last 3 there.
__________________
Auction Analytics
http://www.wowauction.org/
  Reply With Quote
02-13-15, 11:34 AM   #5
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by Dorwido View Post
should be possible:
http://wow.gamepedia.com/World_of_Wa...lent_Functions

have a look at the last 3 there.
None of these functions are usable from add-ons, or even from macros :/

[Edit]
And while I'm at it, how can I open the talents frame programmatically?
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!

Last edited by Malsomnus : 02-13-15 at 11:44 AM.
  Reply With Quote
02-13-15, 01:13 PM   #6
elcius
A Cliff Giant
AddOn Author - Click to view addons
Join Date: Sep 2011
Posts: 75
You can call LearnTalents, you don't even need a hardware event for it.
All the issues are from RemoveTalent, which is not only locked to hardware events, but can only be called from blizzard code.
The only calls to the function and made in the StaticPopup handlers in Blizzard_TalentUI.lua, trigged in PlayerTalentFrameTalent_OnClick, only called by the OnClick handler for PlayerTalentButtonTemplate in Blizzard_TalentUI.xml.
The talent UI needs to be loaded though a hardware event to avoid taint, the easiest way to do that is to toggle the frame though a double /click TalentMicroButton.

Eventually you'll end up with something like this:
Code:
/stopmacro [combat]
/click TalentMicroButton
/click TalentMicroButton
/click PlayerTalentFrameTalentsTalentRowXTalentY -- talent you want to learn (row/col)
/click StaticPopup1Button1 -- should probaly had some checking for which popup is actually the talent one.
/click PlayerTalentFrameTalentsTalentRowXTalentY -- repeat as needed....
/click StaticPopup1Button1
...
/run LearnTalents(a,b,c,d,e,...) -- will need to be a slightly delayed call to give the server time to process the unlearns

Last edited by elcius : 02-13-15 at 01:16 PM.
  Reply With Quote
02-13-15, 01:14 PM   #7
Dorwido
A Wyrmkin Dreamwalker
AddOn Author - Click to view addons
Join Date: Apr 2006
Posts: 54
Thought cause it is flagged as noncombat and not as protected it works, but while removetalent is protected learntalents is not, just tested that.
__________________
Auction Analytics
http://www.wowauction.org/
  Reply With Quote
02-13-15, 02:35 PM   #8
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by elcius View Post
Eventually you'll end up with something like this:
Code:
/stopmacro [combat]
/click TalentMicroButton
/click TalentMicroButton
/click PlayerTalentFrameTalentsTalentRowXTalentY -- talent you want to learn (row/col)
/click StaticPopup1Button1 -- should probaly had some checking for which popup is actually the talent one.
/click PlayerTalentFrameTalentsTalentRowXTalentY -- repeat as needed....
/click StaticPopup1Button1
...
/run LearnTalents(a,b,c,d,e,...) -- will need to be a slightly delayed call to give the server time to process the unlearns
I explained in the other thread that the game generally won't let you unlearn multiple talents at once, you will get "another action is in progress" error if you try to make one large macro like that.

Occasionally it does let you swap more than one at a time, the problem is that since it's completely inconsistent you can't rely on it correctly changing out your talents.
  Reply With Quote
02-13-15, 02:44 PM   #9
SDPhantom
A Pyroguard Emberseer
 
SDPhantom's Avatar
AddOn Author - Click to view addons
Join Date: Jul 2006
Posts: 2,308
You could probably dispatch the LearnTalents() call to a C_Timer.After() function.
Code:
/run C_Timer.After(1,function() LearnTalents(a,b,c,d,e,...) end)
The first argument to C_Timer.After() is how many seconds to delay running the function defined as the second argument.
__________________
WoWInterface AddOns
"All I want is a pretty girl, a decent meal, and the right to shoot lightning at fools."
-Anders (Dragon Age: Origins - Awakening)
  Reply With Quote
02-13-15, 02:59 PM   #10
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Alright, here's a video showing how much this doesn't work: http://youtu.be/T15HLHGL8Js

It takes 4 clicks to get it to unlearn all 7 talents because it tends to only swap up to 2 at a time, interestingly it seems to prefer the first and last ones in the macro to actually change and ignores the rest.

Last edited by semlar : 02-13-15 at 03:54 PM.
  Reply With Quote
02-13-15, 03:46 PM   #11
Banknorris
A Chromatic Dragonspawn
 
Banknorris's Avatar
AddOn Author - Click to view addons
Join Date: Oct 2014
Posts: 153
Originally Posted by SDPhantom View Post
You could probably dispatch the LearnTalents() call to a C_Timer.After() function.
Code:
/run C_Timer.After(1,function() LearnTalents(a,b,c,d,e,...) end)
The first argument to C_Timer.After() is how many seconds to delay running the function defined as the second argument.
Delaying LearnTalents is not enough since the problem is to unlearn, you can remove the LearnTalents all together and it will still not unlearn all talents. I would say the best approach is to do a "gnomesequencer style", pressing one button per talent. Not as good as a one press but still better than doing manually.

Last edited by Banknorris : 02-13-15 at 04:00 PM.
  Reply With Quote
02-13-15, 05:46 PM   #12
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by Banknorris View Post
I would say the best approach is to do a "gnomesequencer style", pressing one button per talent. Not as good as a one press but still better than doing manually.
Yep, that's the current plan. When the player approaches a raid boss he had saved specific talents for, it'll pop up a list of the missing talents, with a Learn This button next to each. This has the extra advantage of allowing the player to easily use only some of the talents.
Now I just need to figure out a) how to bind a secure action button to a dynamically created macro, and b) what sort of interface would make sense for picking those talents to begin with
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
02-13-15, 07:42 PM   #13
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
It's likely going to be more complicated than that because there is a time delay before you can change another talent, if you spam a button like that it's going to skip some of the talents because it will advance to the next item in the sequence regardless of whether it succeeded or not.
  Reply With Quote
02-14-15, 10:46 AM   #14
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
I can't manage to make a working macro for changing even one talent. It seems that unlearning a talent and learning another one simply won't happen from a single button press, no matter what.
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
02-14-15, 12:09 PM   #15
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Malsomnus View Post
I can't manage to make a working macro for changing even one talent. It seems that unlearning a talent and learning another one simply won't happen from a single button press, no matter what.
I do it in my addon AutoConfirmTalents, if you're interested.
  Reply With Quote
02-14-15, 02:52 PM   #16
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Originally Posted by semlar View Post
I do it in my addon AutoConfirmTalents, if you're interested.
I don't understand all of the code (specifically the attributes *macrotext31and macrotext1, what do those mean?), but it seems like this only saves you all the extra button presses.
What I'm looking for is a way to make a button unlearn a talent, pick another talent, and press the Learn button, all at once. I can't seem to write a macro that'll make that happen, and I have no idea why.
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote
02-14-15, 08:27 PM   #17
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by Malsomnus View Post
I don't understand all of the code (specifically the attributes *macrotext31and macrotext1, what do those mean?) ...
Some basics:
Code:
button:SetAttribute("type", "spell")
button:SetAttribute("spell", "Frostbolt")
^ This button will cast Frostbolt no matter which mouse button you click on it.

Code:
button:SetAttribute("type", "spell")
button:SetAttribute("type1", "Frostbolt")
button:SetAttribute("type2", "Fireball")
^ This button will cast Frostbolt when left-clicked (button1) or Fireball when right-clicked (button2).

Code:
button:SetAttribute("type", "macro")
button:SetAttribute("macrotext", "/cast Frostbolt")
^ Same as example #1, but using a macro command instead of a spell.

Code:
button:SetAttribute("type", "macro")
button:SetAttribute("macrotext1", "Frostbolt")
button:SetAttribute("macrotext2", "Fireball")
^ Same as example #2, but using macro commands instead of spells.

In Semlar's code:

Code:
macro:RegisterForClicks('AnyUp', 'AnyDown')
^ This tells the button to respond to both mousedown and mouseup events.

Code:
macro:SetAttribute('downbutton', 'Button31')
^ This tells the button to treat all mousedown events as if they were triggered by pressing button31. WoW supports up to 32 mouse buttons, but I don't think any of the "gaming" mice it supports actually have 32 buttons (???) so the only real use for these high-numbered buttons is in secure attribute trickery like this.

Code:
macro:WrapScript(macro, 'OnClick', [[ <snip> ]])
^ This provides secure snippets to be run before and/or after the button's original OnClick handler. In this case, only a "before" snippet is given. Basically this is setting a PreClick script, but using the secure handler API instead. (See here for the internal implementation.)

Code:
self:SetAttribute('*macrotext31', '/click ' .. parent .. ' ' .. button .. '\n/click StaticPopup1Button1')
^ This tells the button what to do when it receives a click from button31. Since we're in (effectively) a PreClick script, the current mousedown event hasn't been handled yet.

Code:
self:SetAttribute('macrotext1', '/click PlayerTalentFrameTalentsLearnButton\n/use [nomounted] !Trap Launcher')
^ This tells the button what to do when it recieves a click from button1. (I have no idea why Trap Launcher is mentioned here though!)

This is what occurs when this button is left-clicked:

1. The "before" wrapper snippet is run.

2. The "what to do when clicked with button31" attribute is set to a macro that clicks on the currently hovered talent or glyph button (if you look elsewhere in the code you'll see that the "macro" button is parented to those OnEnter) and then accepts the current static popup.

3. The "what to do when clicked with button1" attribute is set to a macro that clicks the "Learn Talents" button. (Just going to ignore Trap Launcher.)

4. The mousedown event is received.

5. The button arg is remapped to button31.

6. The "what to do when clicked with button31" attribute is invoked, causing its macro to run. The talent is clicked and the popup is accepted.

7. The mouseup event is received.

8. The "what to do when clicked with button1" attribute is invoked, causing its macro to run. The "Learn Talents" button is clicked.

You are correct that it doesn't do exactly what you wanted, but you may be able to use similar principles to accomplish what you want.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
02-14-15, 11:10 PM   #18
semlar
A Pyroguard Emberseer
 
semlar's Avatar
AddOn Author - Click to view addons
Join Date: Sep 2007
Posts: 1,060
Originally Posted by Phanx View Post
Code:
self:SetAttribute('macrotext1', '/click PlayerTalentFrameTalentsLearnButton\n/use [nomounted] !Trap Launcher')
^ This tells the button what to do when it recieves a click from button1. (I have no idea why Trap Launcher is mentioned here though!)
I play a hunter and every time I switch talents it turns off trap launcher, it was driving me insane so I just macroed it into the addon.

Thanks for explaining my code because I don't have the attention span to write all that.

The reason I use two different macrotexts on the button is because one is run when you click the button down (to select the new talent) and the other is run when you release the button which clicks the "learn talents" button.

If LearnTalents is not protected then that isn't necessary and you can simply call that directly when the previous talent is unlearned.

Last edited by semlar : 02-14-15 at 11:26 PM.
  Reply With Quote
02-14-15, 11:42 PM   #19
Phanx
Cat.
 
Phanx's Avatar
AddOn Author - Click to view addons
Join Date: Mar 2006
Posts: 5,617
Originally Posted by semlar View Post
I play a hunter and every time I switch talents it turns off trap launcher, it was driving me insane so I just macroed it into the addon.


Originally Posted by semlar View Post
Thanks for explaining my code because I don't have the attention span to write all that.
I like explaining things. Also, I was supposed to be around to help him with secure button stuff earlier but got roped into helping with some event at work that I'd forgotten about.
__________________
Retired author of too many addons.
Message me if you're interested in taking over one of my addons.
Don’t message me about addon bugs or programming questions.
  Reply With Quote
02-16-15, 04:31 PM   #20
Malsomnus
A Cobalt Mageweaver
AddOn Author - Click to view addons
Join Date: Apr 2013
Posts: 203
Thanks for all the help and explanations

After a lot of experimentation around semlar's code, I technically have a button that switches one talent for me every time I press it. I haven't gotten around to trying to make it work for several talents yet, but here's the code I have so far, in case somebody finds it useful:

Lua Code:
  1. function pickTalent(row,col)
  2.   local s = [[
  3.     /stopmacro [combat]
  4.     /click PlayerTalentFrameTalentsTalentRow%sTalent%s
  5.     /click StaticPopup1Button1
  6.   ]]
  7.   return s:format(row,col)
  8. end
  9.  
  10. f.btn = CreateFrame ("Button", nil, f, 'SecureActionButtonTemplate, SecureHandlerBaseTemplate')
  11. f.btn:RegisterForClicks ("AnyDown")
  12. f.btn:SetAttribute ("type","macro")
  13. f.btn:SetAttribute ('macrotext', pickTalent(1,2))
  14.  
  15. f.btn:SetScript ('PostClick', function()
  16.   C_Timer.After(1, function ()
  17.     PlayerTalentFrameTalentsLearnButton:GetScript("OnClick")(PlayerTalentFrameTalentsLearnButton)
  18.   end)  
  19. end)
__________________
SanityCheck - If you've ever said the words "Sorry, I forgot" then you need this add-on.

Remember, every time you post a comment on an add-on, a kitten gets its wings!
  Reply With Quote

WoWInterface » Developer Discussions » Lua/XML Help » Semi-automatically change talents

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off