• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

Overcoming the 5 hero ability limitation

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Do you intend to have 4 or 5 skills in the hero skill menu? Because having only 4 would allow you to dedicate the 5th slot to a "Open Menu" button.

So your Hero's Abilities field would have:
Normal (placeholder), Normal (placeholder), Normal (placeholder), Ulti (placeholder), Learn New Skill (new)

Then upon learning the skill you can open the Dialog:
  • Dialog Open
    • Events
      • Unit - A unit Learns a skill
    • Conditions
      • (Learned Hero Skill) Equal to Learn New Skill
    • Actions
      • Hero - Modify unspent skill points of (Triggering unit): Add 1 points
      • Dialog - Clear Dialog1
      • Dialog - Change the title of Dialog1 to Which one you pick?
      • Dialog - Create a dialog button for Dialog1 labelled Siphon Mana
      • Set VariableSet Yes = (Last created dialog Button)
      • Dialog - Create a dialog button for Dialog1 labelled Defend
      • Set VariableSet No = (Last created dialog Button)
      • Dialog - Show Dialog1 for Player 1 (Red)
Not sure if the Skill Point thing would cause problems.
 
Level 12
Joined
Jul 5, 2014
Messages
551
Do you intend to have 4 or 5 skills in the hero skill menu? Because having 4 would allow you to dedicate the 5th slot to a "Open Menu" button.
4 skills. But where would the open menu show up? I'd need to identify choices for all 4 skills, not just this one. Btw, elapsed time dialog didn't bug out the skill, so it has to be something about placeholder interaction.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I have it working rather nicely, like this:

This is the hidden Channel ability that you can Learn (your 5th hero skill);
1721870628960.png

After clicking it (learning it) the dialog menu is shown:
1721870662474.png

Then you can unlock the skill, in this case I clicked Siphon Mana:
1721870929144.png

The trigger now refunds the wasted Skill Point and ensures that the Ability remains at Level 1:
  • Dialog Open
    • Events
      • Unit - A unit Learns a skill
    • Conditions
      • (Learned Hero Skill) Equal to Learn New Skill
    • Actions
      • Hero - Modify unspent skill points of (Triggering unit): Add 1 points
      • Unit - Decrease level of Learn New Skill for (Triggering unit)
      • Dialog - Clear Dialog1
      • Dialog - Change the title of Dialog1 to Which one you pick?
      • Dialog - Create a dialog button for Dialog1 labelled Siphon Mana
      • Set VariableSet Yes = (Last created dialog Button)
      • Dialog - Create a dialog button for Dialog1 labelled Defend
      • Set VariableSet No = (Last created dialog Button)
      • Dialog - Show Dialog1 for Player 1 (Red)
1721870824486.png

1721870742602.png
1721870758506.png
 
Level 12
Joined
Jul 5, 2014
Messages
551
I have it working rather nicely, like this:

This is the hidden Channel ability that you can Learn (your 5th hero skill);
View attachment 481233
After clicking it (learning it) the dialog menu is shown:
View attachment 481234
Then you can unlock the skill, in this case I clicked Siphon Mana:
View attachment 481239
The trigger now refunds the wasted Skill Point and ensures that the Ability remains at Level 1:
  • Dialog Open
    • Events
      • Unit - A unit Learns a skill
    • Conditions
      • (Learned Hero Skill) Equal to Learn New Skill
    • Actions
      • Hero - Modify unspent skill points of (Triggering unit): Add 1 points
      • Unit - Decrease level of Learn New Skill for (Triggering unit)
      • Dialog - Clear Dialog1
      • Dialog - Change the title of Dialog1 to Which one you pick?
      • Dialog - Create a dialog button for Dialog1 labelled Siphon Mana
      • Set VariableSet Yes = (Last created dialog Button)
      • Dialog - Create a dialog button for Dialog1 labelled Defend
      • Set VariableSet No = (Last created dialog Button)
      • Dialog - Show Dialog1 for Player 1 (Red)
View attachment 481238
View attachment 481236View attachment 481237
Yes, it works for a single choice. But there's 3 more where the player has to choose and they likely don't want to instantly choose. And they'd have to see what these skills are to know what they pick at next level. So, we have 8 skills and the player must choose 4 but preferably, they should know what's going to be on position 0, 1, 2 and 3. That's why I tried messing with the dummy skills.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Yes, it works for a single choice. But there's 3 more where the player has to choose and they likely don't want to instantly choose. And they'd have to see what these skills are to know what they pick at next level. So, we have 8 skills and the player must choose 4 but preferably, they should know what's going to be on position 0, 1, 2 and 3. That's why I tried messing with the dummy skills.
I see, I thought it could all be shown/handled in the Dialog.

Unfortunately, there's no way to have more than 5 abilities inside of that Hero Skill Menu.

But I think what you may want to try is this:
  • Create four unique Placeholder abilities.
  • Assign each Spellbook a unique Placeholder.
  • Ensure that the Hero never actually casts the Placeholder ability! For some reason he wants to do this after learning it. Or rather, he tries to cast the "real" ability.
 
Level 12
Joined
Jul 5, 2014
Messages
551
I see, I thought it could all be shown/handled in the Dialog.

Unfortunately, there's no way to have more than 5 abilities inside of that Hero Skill Menu.

But I think what you may want to try is this:
  • Create four unique Placeholder abilities.
  • Assign each Spellbook a unique Placeholder.
  • Ensure that the Hero never actually casts the Placeholder ability! For some reason he wants to do this after learning it. Or rather, he tries to cast the "real" ability.
And where should I have that spellbook? All slots are occupied. Unless you mean it can be placed inside the "learn skill area".

Or do you mean I should have spellbook at each hero skill position with the two choices inside?
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
And where should I have that spellbook? All slots are occupied. Unless you mean it can be placed inside the "learn skill area".
I think I found a solution you'll like.

It's a similar setup to the original map, except that you'll want to create four PLACEHOLDER abilities instead of two.
Each of these will represent a different Hotkey -> Q, W, E, R.
It's extremely important that you give them the following Rawcodes:

Q = APL0
W = APL1
E = APL2
R = APL3

This is important because we're going to detect when they're clicked using Orders and the Rawcode determines the Issued Order ID.

So the PLACEHOLDER abilities are pretty much the same as before except you have four of them now:
1721881667522.png
1721883936959.png

But you need to make sure that their Levels/Required Level fields match the other Abilities that will replace them. Also, the (R) ability will represent your Ultimate so it will likely be different than the other 3. This is important because these settings will limit the "real" abilities.

You will also want to modify their Art - Button positions to match so the Icons don't jump around in the menu.
(Q): Research (X) = 0
(W): Research (X) = 1
(E): Research (X) = 2
(R): Research (X) = 3

The "Give" abilities are very similar to the original design except that they need to reference the correct Q/W/E/R ability instead of Normal/Ultimate:
1721882203776.png

So (Q) abilities go with the (Q - PLACEHOLDER), (W) abilities go with the (W - PLACEHOLDER), etc.

Then much like the original design you'll want to add the PLACEHOLDER abilities to your Hero's ability list:
1721882271795.png


Here's the hard part, the triggers. You will want to create these AFTER setting up the Object Editor data. Also, remember to create the Variables first:
This first trigger detects when your Hero clicks one of the PLACEHOLDER abilities in the Hero Skill Menu. It does this using Orders which was necessary for me to interrupt the "learning process". This allows me to detect when you click one of these PLACEHOLDER abilities without it actually getting learned. I then open up the Dialog menu and allow you to choose one of two skills, which is very similar to the setup we've been using (add/remove spellbook):
  • Hero Skill Dialog Open 1
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Owner of (Triggering unit)) Equal to Player 1 (Red)
      • (Unspent skill points of (Triggering unit)) Greater than 0
    • Actions
      • Custom script: local integer id = GetIssuedOrderId()
      • -------- --------
      • Set Skill_Dialog_Hero = (Triggering unit)
      • Set Skill_Dialog_Player = (Owner of Skill_Dialog_Hero)
      • Set Skill_Dialog_Hotkey = ?
      • -------- --------
      • -------- Pressed the (Q) ability in the Hero Skill Menu: --------
      • Custom script: if id == 1095781424 then
      • Set Skill_Dialog_Hotkey = Q
      • -------- --------
      • -------- Pressed the (W) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781425 then
      • Set Skill_Dialog_Hotkey = W
      • -------- --------
      • -------- Pressed the (E) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781426 then
      • Set Skill_Dialog_Hotkey = E
      • -------- --------
      • -------- Pressed the (R) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781427 then
      • Set Skill_Dialog_Hotkey = R
      • Custom script: endif
      • -------- --------
      • -------- Interrupt the Hero's issued order to prevent it from actually learning the skill: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Not equal to ?
        • Then - Actions
          • Unit - Pause (Triggering unit)
          • Unit - Order (Triggering unit) to Stop.
          • Unit - Unpause (Triggering unit)
        • Else - Actions
          • Skip remaining actions
      • -------- --------
      • -------- Prevent the rest of this trigger from running while a Dialog is already open (safety check): --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Is_Open Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • Set Skill_Dialog_Is_Open = True
      • -------- --------
      • -------- This trigger runs some important Actions for getting things ready: --------
      • Trigger - Run Hero Skill Dialog Prep 2 <gen> (ignoring conditions)
      • -------- --------
      • -------- Determine which trigger to run based on the Ability and Hero: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to Q
        • Then - Actions
          • Trigger - Run Paladin Learn Q <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to W
        • Then - Actions
          • Trigger - Run Paladin Learn W <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to E
        • Then - Actions
          • Trigger - Run Paladin Learn E <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to R
        • Then - Actions
          • Trigger - Run Paladin Learn R <gen> (checking conditions)
        • Else - Actions
      • -------- --------
      • -------- Create the Dialog: --------
      • For each (Integer Skill_Dialog_Loop) from 1 to 2, do (Actions)
        • Loop - Actions
          • Dialog - Create a dialog button for Skill_Dialog labelled (Name of Skill_Dialog_Ability[Skill_Dialog_Loop])
          • Set Skill_Dialog_Button[Skill_Dialog_Loop] = (Last created dialog Button)
      • Dialog - Change the title of Skill_Dialog to Select your skill o...
      • Dialog - Show Skill_Dialog for Skill_Dialog_Player
This trigger ensures that you replace the correct PLACEHOLDER ability and also prepares the Dialog menu for creation:
  • Hero Skill Dialog Prep 2
    • Events
    • Conditions
    • Actions
      • -------- Disable every ability to prevent conflicts: --------
      • Player - Disable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
      • -------- --------
      • -------- Enable the one ability we pressed: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to Q
        • Then - Actions
          • Player - Enable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Skill_Dialog_Hotkey Equal to W
            • Then - Actions
              • Player - Enable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Skill_Dialog_Hotkey Equal to E
                • Then - Actions
                  • Player - Enable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Skill_Dialog_Hotkey Equal to R
                    • Then - Actions
                      • Player - Enable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
                    • Else - Actions
      • -------- --------
      • -------- Clear the dialog before showing it again: --------
      • Dialog - Clear Skill_Dialog
  • Hero Skill Dialog Click 3
    • Events
      • Dialog - A dialog button is clicked for Skill_Dialog
    • Conditions
    • Actions
      • For each (Integer Skill_Dialog_Loop) from 1 to 2, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Clicked dialog button) Equal to Skill_Dialog_Button[Skill_Dialog_Loop]
            • Then - Actions
              • Unit - Add Skill_Dialog_Ability[Skill_Dialog_Loop] to Skill_Dialog_Hero
              • Unit - Remove Skill_Dialog_Ability[Skill_Dialog_Loop] from Skill_Dialog_Hero
            • Else - Actions
      • -------- --------
      • Player - Enable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
      • -------- --------
      • Set Skill_Dialog_Is_Open = False
Now here's the example that I'm using in my demo map. I make the Paladin's (Q) PLACEHOLDER ability learn either Critical Strike or Mana Shield. I then make his (W) PLACEHOLDER ability learn either Impale or Wind Walk. Note that I didn't finish implementing (E) and (R) because it was extra work and the concept was already proven to work:
  • Paladin Learn Q
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = Give Critical Strike (Q)
      • Set Skill_Dialog_Ability[2] = Give Mana Shield (Q)
  • Paladin Learn W
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = Give Impale (W)
      • Set Skill_Dialog_Ability[2] = Give Wind Walk (W)
  • Paladin Learn E
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = ...
      • Set Skill_Dialog_Ability[2] = ...
  • Paladin Learn R
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = ...
      • Set Skill_Dialog_Ability[2] = ...
The variables being used here:
1721882537802.png
 

Attachments

  • Custom Hero Skill Menu.w3x
    22.3 KB · Views: 3
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
I think I found a solution you'll like.

It's a similar setup to the original map, except that you'll want to create four PLACEHOLDER abilities instead of two.
Each of these will represent a different Hotkey -> Q, W, E, R.
It's extremely important that you give them the following Rawcodes:

Q = APL0
W = APL1
E = APL2
R = APL3

This is important because we're going to detect when they're clicked using Orders and the Rawcode determines the Issued Order ID.

So the PLACEHOLDER abilities are pretty much the same as before except you have four of them now:
View attachment 481248View attachment 481253
But you need to make sure that their Levels/Required Level fields match the other Abilities that will replace them. Also, the (R) ability will represent your Ultimate so it will likely be different than the other 3. This is important because these settings will limit the "real" abilities.

You will also want to modify their Art - Button positions to match so the Icons don't jump around in the menu.
(Q): Research (X) = 0
(W): Research (X) = 1
(E): Research (X) = 2
(R): Research (X) = 3

The "Give" abilities are very similar to the original design except that they need to reference the correct Q/W/E/R ability instead of Normal/Ultimate:
View attachment 481249
So (Q) abilities go with the (Q - PLACEHOLDER), (W) abilities go with the (W - PLACEHOLDER), etc.

Then much like the original design you'll want to add the PLACEHOLDER abilities to your Hero's ability list:
View attachment 481250

Here's the hard part, the triggers. You will want to create these AFTER setting up the Object Editor data. Also, remember to create the Variables first:
This first trigger detects when your Hero clicks one of the PLACEHOLDER abilities in the Hero Skill Menu. It does this using Orders which was necessary for me to interrupt the "learning process". This allows me to detect when you click one of these PLACEHOLDER abilities without it actually getting learned. I then open up the Dialog menu and allow you to choose one of two skills, which is very similar to the setup we've been using (add/remove spellbook):
  • Hero Skill Dialog Open 1
    • Events
      • Unit - A unit Is issued an order with no target
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Owner of (Triggering unit)) Equal to Player 1 (Red)
      • (Unspent skill points of (Triggering unit)) Greater than 0
    • Actions
      • Custom script: local integer id = GetIssuedOrderId()
      • -------- --------
      • Set Skill_Dialog_Hero = (Triggering unit)
      • Set Skill_Dialog_Player = (Owner of Skill_Dialog_Hero)
      • Set Skill_Dialog_Hotkey = ?
      • -------- --------
      • -------- Pressed the (Q) ability in the Hero Skill Menu: --------
      • Custom script: if id == 1095781424 then
      • Set Skill_Dialog_Hotkey = Q
      • -------- --------
      • -------- Pressed the (W) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781425 then
      • Set Skill_Dialog_Hotkey = W
      • -------- --------
      • -------- Pressed the (E) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781426 then
      • Set Skill_Dialog_Hotkey = E
      • -------- --------
      • -------- Pressed the (R) ability in the Hero Skill Menu: --------
      • Custom script: elseif id == 1095781427 then
      • Set Skill_Dialog_Hotkey = R
      • Custom script: endif
      • -------- --------
      • -------- Interrupt the Hero's issued order to prevent it from actually learning the skill: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Not equal to ?
        • Then - Actions
          • Unit - Pause (Triggering unit)
          • Unit - Order (Triggering unit) to Stop.
          • Unit - Unpause (Triggering unit)
        • Else - Actions
          • Skip remaining actions
      • -------- --------
      • -------- Prevent the rest of this trigger from running while a Dialog is already open (safety check): --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Is_Open Equal to True
        • Then - Actions
          • Skip remaining actions
        • Else - Actions
      • Set Skill_Dialog_Is_Open = True
      • -------- --------
      • -------- This trigger runs some important Actions for getting things ready: --------
      • Trigger - Run Hero Skill Dialog Prep 2 <gen> (ignoring conditions)
      • -------- --------
      • -------- Determine which trigger to run based on the Ability and Hero: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to Q
        • Then - Actions
          • Trigger - Run Paladin Learn Q <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to W
        • Then - Actions
          • Trigger - Run Paladin Learn W <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to E
        • Then - Actions
          • Trigger - Run Paladin Learn E <gen> (checking conditions)
        • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to R
        • Then - Actions
          • Trigger - Run Paladin Learn R <gen> (checking conditions)
        • Else - Actions
      • -------- --------
      • -------- Create the Dialog: --------
      • For each (Integer Skill_Dialog_Loop) from 1 to 2, do (Actions)
        • Loop - Actions
          • Dialog - Create a dialog button for Skill_Dialog labelled (Name of Skill_Dialog_Ability[Skill_Dialog_Loop])
          • Set Skill_Dialog_Button[Skill_Dialog_Loop] = (Last created dialog Button)
      • Dialog - Change the title of Skill_Dialog to Select your skill o...
      • Dialog - Show Skill_Dialog for Skill_Dialog_Player
This trigger ensures that you replace the correct PLACEHOLDER ability and also prepares the Dialog menu for creation:
  • Hero Skill Dialog Prep 2
    • Events
    • Conditions
    • Actions
      • -------- Disable every ability to prevent conflicts: --------
      • Player - Disable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Disable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
      • -------- --------
      • -------- Enable the one ability we pressed: --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • Skill_Dialog_Hotkey Equal to Q
        • Then - Actions
          • Player - Enable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Skill_Dialog_Hotkey Equal to W
            • Then - Actions
              • Player - Enable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
            • Else - Actions
              • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                • If - Conditions
                  • Skill_Dialog_Hotkey Equal to E
                • Then - Actions
                  • Player - Enable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
                • Else - Actions
                  • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    • If - Conditions
                      • Skill_Dialog_Hotkey Equal to R
                    • Then - Actions
                      • Player - Enable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
                    • Else - Actions
      • -------- --------
      • -------- Clear the dialog before showing it again: --------
      • Dialog - Clear Skill_Dialog
  • Hero Skill Dialog Click 3
    • Events
      • Dialog - A dialog button is clicked for Skill_Dialog
    • Conditions
    • Actions
      • For each (Integer Skill_Dialog_Loop) from 1 to 2, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Clicked dialog button) Equal to Skill_Dialog_Button[Skill_Dialog_Loop]
            • Then - Actions
              • Unit - Add Skill_Dialog_Ability[Skill_Dialog_Loop] to Skill_Dialog_Hero
              • Unit - Remove Skill_Dialog_Ability[Skill_Dialog_Loop] from Skill_Dialog_Hero
            • Else - Actions
      • -------- --------
      • Player - Enable Ability (Q - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (W - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (E - PLACEHOLDER) for Skill_Dialog_Player
      • Player - Enable Ability (R - PLACEHOLDER) for Skill_Dialog_Player
      • -------- --------
      • Set Skill_Dialog_Is_Open = False
Now here's the example that I'm using in my demo map. I make the Paladin's (Q) PLACEHOLDER ability learn either Critical Strike or Mana Shield. I then make his (W) PLACEHOLDER ability learn either Impale or Wind Walk. Note that I didn't finish implementing (E) and (R) because it was extra work and the concept was already proven to work:
  • Paladin Learn Q
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = Give Critical Strike (Q)
      • Set Skill_Dialog_Ability[2] = Give Mana Shield (Q)
  • Paladin Learn W
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = Give Impale (W)
      • Set Skill_Dialog_Ability[2] = Give Wind Walk (W)
  • Paladin Learn E
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = ...
      • Set Skill_Dialog_Ability[2] = ...
  • Paladin Learn R
    • Events
    • Conditions
    • Actions
      • -------- Set the two (or more) abilities to choose from: --------
      • Set Skill_Dialog_Ability[1] = ...
      • Set Skill_Dialog_Ability[2] = ...
The variables being used here:
View attachment 481251
Before trying it out, I have a question: wouldn't it be a simpler solution to set up 4 spellbooks, each with 2 dummy unit abilities? Clicking on one would disable or remove the spellbook (depending on whether disabled abilities interfere with button positions) and replace the not yet learned placeholder with a not yet learned A or B skill.

Edit: I tested out my theory. It seems to work and circumvents the need for dialog but maybe I overlooked something. Here's an updated version of the map with tome of retraining added.
 

Attachments

  • choice test.w3x
    22.3 KB · Views: 4
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
That seems to work great, much better than using a Dialog.

You'll just need some kind of system for handling the Ulti IF you intend for it to have multiple options to choose from. Because as far as I can tell, you can't change the Required Level of a Spellbook or it's Abilities.

Should be simple enough:
  • Hero Unlock Ulti
    • Events
      • Unit - A unit Gains a level
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Hero level of (Triggering unit)) Equal to 6
    • Actions
      • Unit - Remove R choice (Icon Only) from (Triggering unit)
      • Unit - Add R choice to (Triggering unit)
They could have a placeholder ability (Icon Only) that is a passive based on Storm Hammers that occupies the 4th slot until you reach level 6.

Or I suppose you could just interrupt the cast for the Ulti abilities until you're 6:
  • Resurrection Ulti
    • Events
      • Unit - A unit Begins casting an ability
    • Conditions
      • (Ability being cast) Equal to Resurrection (Dummy)
    • Actions
      • If all conditions are true then do (Actions)
        • If - Conditions
          • (Hero level of (Triggering unit)) Greater than or equal to 6
        • Then - Actions
          • Unit - Remove E choice from (Triggering unit)
          • Unit - Add Add Unholy Aura to (Triggering unit)
          • Unit - Remove Add Unholy Aura from (Triggering unit)
          • Hero - Learn skill for (Triggering unit): Unholy Aura
        • Else - Actions
      • Unit - Order (Triggering unit) to Stop.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
That seems to work great, much better than using a Dialog.

You'll just need some kind of system for handling the Ulti IF you intend for it to have multiple options to choose from. Because as far as I can tell, you can't change the Required Level of a Spellbook or it's Abilities.

Should be simply enough:
  • Hero Unlock Ulti
    • Events
      • Unit - A unit Gains a level
    • Conditions
      • ((Triggering unit) is A Hero) Equal to True
      • (Hero level of (Triggering unit)) Equal to 6
    • Actions
      • Unit - Remove R choice (Icon Only) from (Triggering unit)
      • Unit - Add R choice to (Triggering unit)
They could have a placeholder ability (Icon Only) that is a passive based on Storm Hammers that occupies the 4th slot until you reach level 6.
I'll give it a go. I only have one ability that counts as "ultimate" (because it needs level 3). Btw, you have an idea why clicking choice abilities trap the hero in channel? I tried fiddling with animation, follow through, duration but nothing solved it.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I'll give it a go. I only have one ability that counts as "ultimate" (because it needs level 3). Btw, you have an idea why clicking choice abilities trap the hero in channel? I tried fiddling with animation, follow through, duration but nothing solved it.
I updated my post by the way.

Anyway, I'm not sure what you mean. The Choice abilities are the Spellbooks, correct? That doesn't happen for me.

If I remember correctly that only happened when you didn't have the Stop order. Why is this a problem then? (If you're just curious, it's just a weird quirk that comes with us messing with unintended game mechanics that just so happen to work favorably).
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
It does happen, I just set the channel animation to stand and have a stop order issued. If you take out the stop order, the hero is stuck until you order him to stop.
I edited my post again (sent too early) but I'm assuming you're just curious. The answer is:

We're messing around with unintended mechanics and all things considered we're lucky it doesn't crash the game. Stop apparently fixes it so that's good.

MAYBE you have to modify the base Channel ability for it to not happen, in some cases that happens where the game uses data from the original ability rather than the new copy.
 
Level 12
Joined
Jul 5, 2014
Messages
551
I edited my post again (sent too early) but I'm assuming you're just curious. The answer is:

We're messing around with unintended mechanics and all things considered we're lucky it doesn't crash the game. Stop apparently fixes it so that's good.

MAYBE you have to modify the base Channel ability for it to not happen, in some cases that happens where the game uses data from the original ability rather than the new copy.
I like to understand the issues whenever I can. Not a biggie though.

Do you think it worth uploading this test map into the spell&system section once I implemented the ultimate? I found a lot of questions about adding hero abilities with trigger but not many answers, so it may help out people with similar issues. Apart from the many objects, triggering is rather simple.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I like to understand the issues whenever I can. Not a biggie though.

Do you think it worth uploading this test map into the spell&system section once I implemented the ultimate? I found a lot of questions about adding hero abilities with trigger but not many answers, so it may help out people with similar issues. Apart from the many objects, triggering is rather simple.
You could try. A nice system that automates everything would be cool, so you would only need 2-3 triggers to get it all working.

But surely there must be tutorials on this very idea already, sometimes they're just hard to dig up because the search isn't perfect.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Some kind of array?
Array + For Loop is the easiest design to get it up and running quickly.

Step 1: Setup abilities (arrays) in one big config trigger.

Step 2: Detect when a unit casts a Dummy ability and see if it matches an ability from your array.

Something like this:
  • Events
    • Map initialization
  • Conditions
  • Actions
    • -------- Define how many Dummy abilities exist: --------
    • Set HSS_Ability_Count = 2
    • -------- --------
    • -------- Register the first ability: --------
    • Set HSS_Ability_Dummy[1] = Holy Light (Dummy)
    • Set HSS_Ability_Choice[1] = Q choice
    • Set HSS_Ability_Hero[1] = Holy Light (Hero)
    • Set HSS_Ability_Engineering[1] = Add Holy Light (Engineering Upg)
    • -------- --------
    • -------- Register the second ability: --------
    • Set HSS_Ability_Dummy[2] = Defend (Dummy)
    • Set HSS_Ability_Choice[2] = W choice
    • Set HSS_Ability_Hero[2] = Defend (Hero)
    • Set HSS_Ability_Engineering[2] = Add Defend (Engineering Upg)
    • -------- --------
    • -------- continue... --------
  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • ((Triggering unit) is a Hero) Equal to True
  • Actions
    • Set HSS_Cast = (Ability being cast)
    • For each (Integer HSS_Loop) from 1 to HSS_Ability_Count, do (Actions)
      • Loop - Actions
        • -------- Compare HSS_Cast to HSS_Ability_Dummy[HSS_Loop] --------
        • -------- If it's a match then proceed with the Add/Remove/Stop stuff --------
A unit begins casting an ability -> Loop over an Array of the "registered abilities" -> If the ability being cast matches the one from the array -> Then run the necessary logic. At this stage you will have the [index] of the registered ability and any other variable arrays you've associated with it.

It's a bit convoluted so getting the naming conventions down would help a lot.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
Array + For Loop is the easiest design to get it up and running quickly.

Step 1: Setup abilities (arrays) in one big config trigger.

Step 2: Detect when a unit casts a Dummy ability and see if it matches an ability from your array.

Something like this:
  • Events
    • Map initialization
  • Conditions
  • Actions
    • -------- Define how many Dummy abilities exist: --------
    • Set HSS_Ability_Count = 2
    • -------- --------
    • -------- Register the first ability: --------
    • Set HSS_Ability_Dummy[1] = Holy Light (Dummy)
    • Set HSS_Ability_Choice[1] = Q choice
    • Set HSS_Ability_Hero[1] = Holy Light (Hero)
    • Set HSS_Ability_Engineering[1] = Add Holy Light (Engineering Upg)
    • -------- --------
    • -------- Register the second ability: --------
    • Set HSS_Ability_Dummy[2] = Defend (Dummy)
    • Set HSS_Ability_Choice[2] = W choice
    • Set HSS_Ability_Hero[2] = Defend (Hero)
    • Set HSS_Ability_Engineering[2] = Add Defend (Engineering Upg)
    • -------- --------
    • -------- continue... --------
  • Events
    • Unit - A unit Begins casting an ability
  • Conditions
    • ((Triggering unit) is a Hero) Equal to True
  • Actions
    • Set HSS_Cast = (Ability being cast)
    • For each (Integer HSS_Loop) from 1 to HSS_Ability_Count, do (Actions)
      • Loop - Actions
        • -------- Compare HSS_Cast to HSS_Ability_Dummy[HSS_Loop] --------
        • -------- If it's a match then proceed with the Add/Remove/Stop stuff --------
A unit begins casting an ability -> Loop over an Array of the "registered abilities" -> If the ability being cast matches the one from the array -> Then run the necessary logic. At this stage you will have the [index] of the registered ability and any other variable arrays you've associated with it.

It's a bit convoluted so getting the naming conventions down would help a lot.
Why do you call the variable HSS? I don't know what it stands for.

Btw, by setting the ultimate's placeholder to level 6, it will automatically refuse to teach it to hero who don't have the level. It will simply place it to the unlearned spells.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I imagine I was thinking "Hero Skill System" or "Hero Skill Spellbook", something like that. Use whatever acronym you want (or don't). It's just nice to have something that distinguishes your Variables from other user's Variables since there's always the chance for conflicts if you use generic names.
 
Level 12
Joined
Jul 5, 2014
Messages
551
I imagine I was thinking "Hero Skill System" or "Hero Skill Spellbook", something like that. Use whatever acronym you want (or don't). It's just nice to have something that distinguishes your Variables from other user's Variables since there's always the chance for conflicts if you use generic names.
The "for each integer variable" is not exactly clear. There's 8 ability but only 4 spellbooks. So they can't follow the numbers.

Edit: could you clarify the triggers in general? I barely did any loops before so I can't find options through a text summary. And learning hero skill doesn't offer variable.
 
Last edited:

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I haven't read like 50% of this conversation, but did you try to collide multiple spellbooks together like the undeadbuild trick? Might get somewhere, but seems unlikely.
I'm probably misunderstanding that trick but I don't think it applies here. But I think War pretty much has it figured out at this point, we're just at the "polishing" stage now.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
The "for each integer variable" is not exactly clear. There's 8 ability but only 4 spellbooks. So they can't follow the numbers.
I think what you're saying is that the "choice" Spellbooks are going to differ from Hero to Hero. At least that's the only issue I can see. In which case there are many solutions. You can dedicate a chunk of the Array to each Hero:

Paladin = indexes [1] to [8]
Blademaster = indexes [9] to [16]
Thrall = indexes [17] to [24]

  • Events
    • Map initialization
  • Conditions
  • Actions
    • -------- Paladin uses index [1] to [8]: --------
    • Set HSS_Ability_Dummy[1] = Holy Light (Dummy)
    • Set HSS_Ability_Choice[1] = Q choice (Paladin)
    • Set HSS_Ability_Hero[1] = Holy Light (Hero)
    • Set HSS_Ability_Engineering[1] = Add Holy Light (Engineering Upg)
    • -------- --------
    • -------- Register paladin's next ability: --------
    • Set HSS_Ability_Dummy[2] = Divine Shield (Dummy)
    • Set HSS_Ability_Choice[2] = Q choice (Paladin)
    • Set HSS_Ability_Hero[2] = Divine Shield (Hero)
    • Set HSS_Ability_Engineering[2] = Add Divine Shield (Engineering Upg)
    • -------- --------
    • -------- continue adding [3] to [8] --------
    • -------- --------
    • -------- Blademaster uses index [9] to [16]: --------
    • Set HSS_Ability_Dummy[9] = Wind Walk (Dummy)
    • Set HSS_Ability_Choice[9] = Q choice (Blademaster)
    • Set HSS_Ability_Hero[9] = Wind Walk (Hero)
    • Set HSS_Ability_Engineering[9] = Add Wind Walk (Engineering Upg)
    • -------- --------
    • -------- Register blademaster's next ability: --------
    • Set HSS_Ability_Dummy[10] = Critical Strike (Dummy)
    • Set HSS_Ability_Choice[10] = Q choice (Blademaster)
    • Set HSS_Ability_Hero[10] = Critical Strike (Hero)
    • Set HSS_Ability_Engineering[10] = Add Critical Strike (Engineering Upg)
    • -------- --------
    • -------- continue adding [11] to [16] --------
Then when it comes to cycle over the For Loop, your range would depend on the Hero that's doing the casting.
  • -------- Paladin ---------
  • For each (Integer HSS_Loop) from 1 to 8 do (Actions)
    • Loop - Actions
  • -------- Blademaster ---------
  • For each (Integer HSS_Loop) from 9 to 16 do (Actions)
    • Loop - Actions
It'd be nice to use a Hashtable to manage all of this so you can avoid multiple If Then Else statements checking the type of hero. It would also be easier to add more than just 2 abilities per spellbook.

Edit: Forgot to distinguish the Choice abilities in my Variable example.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
I think what you're saying is that the "choice" Spellbooks are going to differ from Hero to Hero. At least that's the only issue I can see. In which case there are many solutions. You can dedicate a chunk of the Array to each Hero:

Paladin = indexes [1] to [8]
Blademaster = indexes [9] to [16]
Thrall = indexes [17] to [24]

  • Events
    • Map initialization
  • Conditions
  • Actions
    • -------- Paladin uses index [1] to [8]: --------
    • Set HSS_Ability_Dummy[1] = Holy Light (Dummy)
    • Set HSS_Ability_Choice[1] = Q choice
    • Set HSS_Ability_Hero[1] = Holy Light (Hero)
    • Set HSS_Ability_Engineering[1] = Add Holy Light (Engineering Upg)
    • -------- --------
    • -------- Register paladin's next ability: --------
    • Set HSS_Ability_Dummy[2] = Divine Shield (Dummy)
    • Set HSS_Ability_Choice[2] = Q choice
    • Set HSS_Ability_Hero[2] = Divine Shield (Hero)
    • Set HSS_Ability_Engineering[2] = Add Divine Shield (Engineering Upg)
    • -------- --------
    • -------- continue adding [3] to [8] --------
    • -------- --------
    • -------- Blademaster uses index [9] to [16]: --------
    • Set HSS_Ability_Dummy[9] = Wind Walk (Dummy)
    • Set HSS_Ability_Choice[9] = Q choice
    • Set HSS_Ability_Hero[9] = Wind Walk (Hero)
    • Set HSS_Ability_Engineering[9] = Add Wind Walk (Engineering Upg)
    • -------- --------
    • -------- Register blademaster's next ability: --------
    • Set HSS_Ability_Dummy[10] = Critical Strike (Dummy)
    • Set HSS_Ability_Choice[10] = Q choice
    • Set HSS_Ability_Hero[10] = Critical Strike (Hero)
    • Set HSS_Ability_Engineering[10] = Add Critical Strike (Engineering Upg)
    • -------- --------
    • -------- continue adding [11] to [16] --------
Then when it comes to cycle over the For Loop, your range would depend on the Hero that's doing the casting.
  • -------- Paladin ---------
  • For each (Integer HSS_Loop) from 1 to 8 do (Actions)
    • Loop - Actions
  • -------- Blademaster ---------
  • For each (Integer HSS_Loop) from 9 to 16 do (Actions)
    • Loop - Actions
It'd be nice to use a Hashtable to manage all of this so you can avoid multiple If Then Else statements checking the type of hero. It would also be easier to add more than just 2 abilities per spellbook.
That just grew super complicated for me to follow. It may uses fewer triggers but the complexity makes it very rough, compared to my simpler versions.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
You're basically just assigning numbers to each hero / ability. It's an elaborate grocery list.

If you cast an ability and it happens to be HSS_Ability_Dummy[2] then we know that it is Divine Shield (Dummy) since that's what was assigned there. This index [2] tells us everything else we need to know -> HSS_Ability_Choice[2], HSS_Ability_Hero[2], HSS_Ability_Engineering[2].

Because all you really need to know is four things:

1) What Dummy ability was cast, which the For Loop figures out.

2) Then what Choice ability is associated with that Dummy ability, so that we can do this:
  • Unit - Remove (Put your choice ability here) from (Triggering unit)
3) Then what Engineering Upgrade ability is associated with that Dummy ability, so that we can do this:
  • Unit - Add (Put your eng upgrade ability here) to (Triggering unit)
  • Unit - Remove (Put your eng upgrade ability here) from (Triggering unit)
4) Then what Hero ability is associated with that Dummy ability, so that we can do this:
  • Hero - Learn skill for (Triggering unit): (Put your hero ability here)
But I understand if this is too much. I only suggested this because it'll make your life easier in the long run, but if it's too difficult to get setup then that sort of defeats the purpose.
 
Level 12
Joined
Jul 5, 2014
Messages
551
You're basically just assigning numbers to each hero / ability. It's an elaborate grocery list.

If you cast an ability and it happens to be HSS_Ability_Dummy[2] then we know that it is Divine Shield (Dummy) since that's what was assigned there. This index [2] tells us everything else we need to know -> HSS_Ability_Choice[2], HSS_Ability_Hero[2], HSS_Ability_Engineering[2].

Because all you really need to know is four things:

1) What Dummy ability was cast, which the For Loop figures out.

2) Then what Choice ability is associated with that Dummy ability, so that we can do this:
  • Unit - Remove (Put your choice ability here) from (Triggering unit)
3) Then what Engineering Upgrade ability is associated with that Dummy ability, so that we can do this:
  • Unit - Add (Put your eng upgrade ability here) to (Triggering unit)
  • Unit - Remove (Put your eng upgrade ability here) from (Triggering unit)
4) Then what Hero ability is associated with that Dummy ability, so that we can do this:
  • Hero - Learn skill for (Triggering unit): (Put your hero ability here)
But I understand if this is too much. I only suggested this because it'll make your life easier in the long run, but if it's too difficult to get setup then that sort of defeats the purpose.
I just learned to use arrays with a neat, matching numbers. When I get there, I'm sure I could tidy things up but right now it feels way too elaborate. Plus, if I upload the test map, people with more humble triggering skills would have easier time implementing it to their projects. People with more experience can improve on it anyway.
 
Top