• 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.

Creating idle worker-like button

Level 12
Joined
Jul 5, 2014
Messages
551
I may aim to high on this one and couldn't find anything on the matter (that would work). In my campaign, the player can collect journal fragments for clues and tips. Instead of making them an item or a crude enter message into the chat solution, I considered having an idle worker-like button which the player can click and there they could access to the fragments they collected so far. Is there an option that would work on 1.26?
 
On 1.26, your options may be a bit limited since you don't have access to the custom UI natives.

  1. Option 1 is to re-use the worker icon itself. You simply need to add the "Worker" classification to your dummy journal unit in the object editor (Stats - Unit Classification), and then you'll see the icon appear. You can spawn any number of them to control the number displayed within the icon. However, this has a few drawbacks:
    • This isn't super feasible if you have workers in your map, as you can only have one idle worker icon.
    • You are limited to one idle worker icon (Advanced > Game Interface > Icon - Idle Worker)
    • Clicking on the icon will automatically move the camera to the unit. You can maybe work-around this by setting your dummy unit to have no model, no collision, and to set up a trigger to periodically move the unit's position to your main hero unit (e.g. every 0.05 seconds).
  2. Option 2 is to use a custom hero (similar to the "Backpack" in some custom maps, like Gaia's Retaliation). This has a few advantages compared to the previous approach:
    • Supports multiple icons (and you can have multiple of them)
    • Clicking on the icon won't automatically move the camera (however, double-clicking will--so again you may want to "pin" it to a particular unit via triggers).
    • You can use hero levels to control the number displayed next to the icon (and you can choose not to have any number at all)
    The main downside though is that it'll show extra things like HP on the unit. But in my opinion that is relatively minor.
  3. There is technically a third option--I can't find the exact system anymore (used to be on wc3c.net)--but there were some systems floating around that allowed you to create a UI element by creating a billboarded dummy unit and translating it periodically so it appears in a fixed location on the screen. However, this required a fair amount of model editing and was a pretty tricky system to implement in your map.

Overall I'd recommend option 2, as it is the most flexible and probably the most intuitive for players.
 
Level 12
Joined
Jul 5, 2014
Messages
551
On 1.26, your options may be a bit limited since you don't have access to the custom UI natives.

  1. Option 1 is to re-use the worker icon itself. You simply need to add the "Worker" classification to your dummy journal unit in the object editor (Stats - Unit Classification), and then you'll see the icon appear. You can spawn any number of them to control the number displayed within the icon. However, this has a few drawbacks:
    • This isn't super feasible if you have workers in your map, as you can only have one idle worker icon.
    • You are limited to one idle worker icon (Advanced > Game Interface > Icon - Idle Worker)
    • Clicking on the icon will automatically move the camera to the unit. You can maybe work-around this by setting your dummy unit to have no model, no collision, and to set up a trigger to periodically move the unit's position to your main hero unit (e.g. every 0.05 seconds).
  2. Option 2 is to use a custom hero (similar to the "Backpack" in some custom maps, like Gaia's Retaliation). This has a few advantages compared to the previous approach:
    • Supports multiple icons (and you can have multiple of them)
    • Clicking on the icon won't automatically move the camera (however, double-clicking will--so again you may want to "pin" it to a particular unit via triggers).
    • You can use hero levels to control the number displayed next to the icon (and you can choose not to have any number at all)
    The main downside though is that it'll show extra things like HP on the unit. But in my opinion that is relatively minor.
  3. There is technically a third option--I can't find the exact system anymore (used to be on wc3c.net)--but there were some systems floating around that allowed you to create a UI element by creating a billboarded dummy unit and translating it periodically so it appears in a fixed location on the screen. However, this required a fair amount of model editing and was a pretty tricky system to implement in your map.

Overall I'd recommend option 2, as it is the most flexible and probably the most intuitive for players.
That sounds almost as clunky as using chat message. Isn't there an option for a global ability like icon? Something that's not in the way and not on heroes that could trigger something? The main goal would be that player can access the fragments they collected and be able to re-read it when they want to while not taking up inventory slot.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
That sounds almost as clunky as using chat message. Isn't there an option for a global ability like icon? Something that's not in the way and not on heroes that could trigger something? The main goal would be that player can access the fragments they collected and be able to re-read it when they want to while not taking up inventory slot.
Those are the options. In 1.31+ you can do whatever you want with custom UI, but before that you were super limited.
 
Level 12
Joined
Jul 5, 2014
Messages
551
Those are the options. In 1.31+ you can do whatever you want with custom UI, but before that you were super limited.
Hmm, I have an alternative idea. I'll make a compromise and have an item, like spellbook. In it, there would be channel "spells" and by pressing them, there would pop up a game message with the journal fragment on them. Is this viable? Can I add new ones (or unlock them) every time the hero picks up a new fragment?
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Hmm, I have an alternative idea. I'll make a compromise and have an item, like spellbook. In it, there would be channel "spells" and by pressing them, there would pop up a game message with the journal fragment on them. Is this viable? Can I add new ones (or unlock them) every time the hero picks up a new fragment?
I imagine that would work.

If you wanted to save an item slot you could just add the Spellbook to the Hero directly.

Also, check out some older threads to learn about the different tricks you can do with Spellbook. I believe you can avoid having 100+ variations of it by Disabling/Enabling abilities via triggers. So your Spellbook contains 12 Journal fragment abilities by default, but each is Disabled at map start, then as you unlock the fragments you Enable the associated abilities.
 
Level 12
Joined
Jul 5, 2014
Messages
551
I imagine that would work.

If you wanted to save an item slot you could just add the Spellbook to the Hero directly.

Also, check out some older threads to learn about the different tricks you can do with Spellbook. I believe you can avoid having 100+ variations of it by Disabling/Enabling abilities via triggers. So your Spellbook contains 12 Journal fragment abilities by default, but each is Disabled at map start, then as you unlock the fragments you Enable the associated abilities.
Unfortunately, heroes' command interface is full. I checked the spellbook threads, though I didn't see anyone using it as a journal collection. I could make it work via channel abilities that are disabled initially until you pick up the item unlocking a page. However, apparently I need to change the ID because otherwise all of them activated at once. I think I could just use random spell IDs to separate them but I don't know if it messes with abilities outside the spellbook.

There's also the case of positioning. x,y position don't work and I've seen threads also mention that without a clear solution.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Unfortunately, heroes' command interface is full. I checked the spellbook threads, though I didn't see anyone using it as a journal collection. I could make it work via channel abilities that are disabled initially until you pick up the item unlocking a page. However, apparently I need to change the ID because otherwise all of them activated at once. I think I could just use random spell IDs to separate them but I don't know if it messes with abilities outside the spellbook.

There's also the case of positioning. x,y position don't work and I've seen threads also mention that without a clear solution.
I figured the tooltip of the ability would contain all of the info, so you could rely on passive abilities.

Also, I imagine the abilities are ordered based on how you add them to the Spellbook, so you should still have some control.

Also, it's not difficult to find an unused order id. Plus item abilities won't interfere with command card abilities, so that's not an issue.

But all of this seems like more work than using the Quest menu system.
 
Level 12
Joined
Jul 5, 2014
Messages
551
I figured the tooltip of the ability would contain all of the info, so you could rely on passive abilities.
Hmm, that worth a try, it would definitely cut down the need for triggers and the nuisance of ID.

Also, I imagine the abilities are ordered based on how you add them to the Spellbook, so you should still have some control.
Unfortunately, it doesn't. I've tried playing with that, along with playing with the IDs but unless they follow a different, numerical order, rather than alphabetical, it doesn't make a change either.

But all of this seems like more work than using the Quest menu system.
I'm not sure what that would look like. One quest for each journal fragment? That would definitely swamp the quests, given there are regular quests going on.

Or all within a single quest? That would make navigation tough. There are like 15+ fragments, each with information on them and I have to follow which ones are found and the player should be able to navigate without lengthy scrolling. But if you have an efficient suggestion, I welcome it.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Hmm, that worth a try, it would definitely cut down the need for triggers and the nuisance of ID.


Unfortunately, it doesn't. I've tried playing with that, along with playing with the IDs but unless they follow a different, numerical order, rather than alphabetical, it doesn't make a change either.


I'm not sure what that would look like. One quest for each journal fragment? That would definitely swamp the quests, given there are regular quests going on.

Or all within a single quest? That would make navigation tough. There are like 15+ fragments, each with information on them and I have to follow which ones are found and the player should be able to navigate without lengthy scrolling. But if you have an efficient suggestion, I welcome it.
A single optional quest seems fine, I think? Something like this:
  • Journal Setup
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set Journal_Entry[0] = (You have discovered + ((String(Journal_Entry_Total_Discovered)) + /12 journal entries.))
      • --------
      • -------- Add "as many" journal entries as you'd like (quest space may be limited) --------
      • Set Journal_Entry[1] = Tip #1: Don't die.
      • Set Journal_Entry[2] = Tip #2: Spend your resources.
      • Set Journal_Entry[3] = Tip #3: Donate to my patreon.
      • -------- --------
      • Quest - Create a Optional quest titled Journal Entries with the description Journal_Entry[0], using icon path ReplaceableTextures\CommandButtons\BTNSpellBookBLS.blp
      • Set Journal_Entry_Quest = (Last created quest)
  • Journal Update
    • Events
    • Conditions
    • Actions
      • Set Journal_Entry_Total_Discovered = (Journal_Entry_Total_Discovered + 1)
      • -------- --------
      • Set Journal_Entry[0] = (You have discovered + ((String(Journal_Entry_Total_Discovered)) + /12 journal entries.|n))
      • -------- --------
      • For each (Integer Journal_Entry_Loop) from 1 to 12, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Journal_Entry_Is_Discovered[Journal_Entry_Loop] Equal to True
            • Then - Actions
              • Set Journal_Entry[0] = (Journal_Entry[0] + (Journal_Entry[Journal_Entry_Loop] + |n))
            • Else - Actions
      • -------- --------
      • Quest - Change the description of Journal_Entry_Quest to Journal_Entry[0]
      • Quest - Flash the quest dialog button
Here's a demonstration showing how to enable a specific journal entry and update the Quest to display it:
  • Journal Add Entry Demo
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Antonidas
    • Actions
      • Set Journal_Entry_Is_Discovered[2] = True
      • Trigger - Run Journal Update <gen> (ignoring conditions)
1721681110049.png
 

Attachments

  • Journal Quest 1.w3m
    18.6 KB · Views: 2
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
A single optional quest seems fine, I think? Something like this:
  • Journal Setup
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Set Journal_Entry[0] = (You have discovered + ((String(Journal_Entry_Total_Discovered)) + /12 journal entries.))
      • -------- --------
      • Set Journal_Entry[1] = Tip #1: Don't die.
      • Set Journal_Entry[2] = Tip #2: Spend your resources.
      • Set Journal_Entry[3] = Tip #3: Donate to my patreon.
      • -------- --------
      • Quest - Create a Optional quest titled Journal Entries with the description Journal_Entry[0], using icon path ReplaceableTextures\CommandButtons\BTNSpellBookBLS.blp
      • Set Journal_Entry_Quest = (Last created quest)
  • Journal Update
    • Events
    • Conditions
    • Actions
      • Set Journal_Entry_Total_Discovered = (Journal_Entry_Total_Discovered + 1)
      • -------- --------
      • Set Journal_Entry[0] = (You have discovered + ((String(Journal_Entry_Total_Discovered)) + /12 journal entries.|n))
      • -------- --------
      • For each (Integer Journal_Entry_Loop) from 1 to 12, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Journal_Entry_Is_Discovered[Journal_Entry_Loop] Equal to True
            • Then - Actions
              • Set Journal_Entry[0] = (Journal_Entry[0] + (Journal_Entry[Journal_Entry_Loop] + |n))
            • Else - Actions
      • -------- --------
      • Quest - Change the description of Journal_Entry_Quest to Journal_Entry[0]
      • Quest - Flash the quest dialog button
Here's a demonstration showing how to enable a specific journal entry and update the Quest to display it:
  • Journal Add Entry Demo
    • Events
      • Unit - A unit Dies
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Antonidas
    • Actions
      • Set Journal_Entry_Is_Discovered[2] = True
      • Trigger - Run Journal Update <gen> (ignoring conditions)
View attachment 480878
Unfortunately, I can't open your attachment due to our version difference. However, the two things that immediately came to my mind:

1. I have a Rexxar-like campaign. As such, there's a number of quests, where this particular one can get lost, no?

2. Each of the journal fragments contain text, roughly twice the size of a spell's extended tooltip. With 15+ of these in a single quest, I'm not sure what navigation would be like to find the particular one the player's looking for.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Unfortunately, I can't open your attachment due to our version difference.
I remember, but I try to always share my work for other people that come to this thread.

1. Sure. I imagine you can place it at the very top of the Quest list though.

2. I imagine Quest's have limited text space. Multiple Quests may be necessary to get around this limitation. Perhaps you could have 4 Quests in total and divide the ~16 Journal Entries among them. "Journal Entries 1 - 4", "Journal Entries "5 -8", etc. Color coding the text could help the user distinguish between different entries if you're concerned about the "wall of text" effect.

Anyway, it's your map so go with whatever you think looks and feels best.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
I remember, but I try to always share my work for other people that come to this thread.

1. Sure. I imagine you can place it at the very top of the Quest list though.

2. I imagine Quest space is limited. Multiple Quests may be necessary to get around this limitation. Perhaps you could have 4 Quests in total and divide the ~16 Journal Entries among them. "Journal Entries 1 - 4", "Journal Entries "5 -8", etc. Color coding the text could help the user distinguish between different tips if you're concerned about the "wall of text" effect.
I found something that made things potentially easier. I've read that by setting the spellbook's minimum and maximum spells the same number, it arranges the spells inside the way it's being arranged in the spell list. I don't know if it will stay that way indefinitely but if it does, that solves the arrangement issue.

Considering the space and navigation with the quest, spellbook+passive ability seems the easiest solution. I can even put in there a second spellbook for more space. With this solution, these are the trigger bits are related:

1. Picking up the first journal fragment should give the player the spellbook where the rest goes. I'm guessing a boolean checking for the first journal solves it.

2. Having all fragments inside in disabled form, enabling them when the player find the associated journal fragment is the best way to manipulate things inside spellbook, rather than actually adding the passive ability/fragment to them, right?

3. The item that adds/unlocks each fragment is called "journal fragment". It's basically a powerup book with removed powerup. Since each area holds a specific journal fragment, not a "pick one up and unlock the next", I'm guessing I need one fake powerup book for each fragment in the editor.

4. Whenever I design a trigger, the thing comes to my mind is player who's goofing around to see if he can break it (I did this before). In this case, the player may drops the fragment on the ground, so it's technically not in his possession. I did this in the blood elf campaign with the ring of the archmagi. I think it gave the item to the hero that picked it up then removed the item from the ground. I believe the enable fragment x for player 'user' should still unlock the journal properly although I'm not sure what happens if you drop the spellbook, cross to a different map, pick up the fragment then return to the previous map. Would that cause duplication?

5. Is there a condition that checks for "player owning an item-type" (aka the spellbook)? It may be stashed or not held by the hero who picks up the powerup, so I need to make sure the spellbook won't duplicate because the game checks for the particular hero's inventory.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I found something that made things potentially easier. I've read that by setting the spellbook's minimum and maximum spells the same number, it arranges the spells inside the way it's being arranged in the spell list. I don't know if it will stay that way indefinitely but if it does, that solves the arrangement issue.
You could use my Quest triggers from before to help get an idea of how to achieve all of this. The concept is actually pretty similar, just instead of updating the Quest log with a new String you're enabling an Ability. Same idea, different form of execution.

1. Yes, Boolean variables are always False by default, so use this to your advantage:
  • If all conditions are true then do actions
    • If - Conditions
      • Player_Has_Journal Equal to False
    • Then - Actions
      • Set Player_Has_Journal = True
      • -------- Handle logic for setting up the initial journal --------
    • Else - Actions
      • -------- Handle logic for adding to the journal --------
2. You cannot add an Ability to Spellbook via triggers. At least not on 1.26, as far as I know.

3. If the powerups are preplaced on the map or created via triggers then you could take advantage of their Custom Value to link them to your Array data:
  • Events
    • Time - Elapsed game time is 0.00 seconds
  • Conditions
  • Actions
    • Item - Set the custom value of Journal Fragment 0001 <gen> = 1
    • Item - Set the custom value of Journal Fragment 0002 <gen> = 2
    • Item - Set the custom value of Journal Fragment 0003 <gen> = 3
    • Set Journal_Ability[1] = Journal Fragment (Ability #1)
    • Set Journal_Ability[2] = Journal Fragment (Ability #2)
    • Set Journal_Ability[3] = Journal Fragment (Ability #3)
  • Events
    • Unit - A unit Acquires an item
  • Conditions
    • (Item-type of (Item being manipulated)) Equal to Journal Fragment
  • Actions
    • Player - Enable Journal_Ability[(Custom value of (Item being manipulated))] for (Owner of (Triggering unit))
4. I imagine you would reset everything upon entering a new map and then Load the necessary data using game cache. This would include the Player_Has_Journal boolean. You can also remove any existing Journals on the ground at the start of the game using the Pick Every Item action. So basically: wipe things clean at the start of each map, load what's needed, and apply the loaded data to recreate what's needed. But I'm also no expert on best practices for campaigns.

5. You can just use another Boolean variable. Player_Has_Journal and Journal_Is_Created could be used to manage everything. But yes, you can check the "is equipped" status of an Item by checking if it's Owned by a Player. I believe the Condition will return False if it's on the ground.
  • ((Last created item) is owned) Equal to True
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
2. You cannot add an Ability to Spellbook via triggers. At least not on 1.26, as far as I know.
Then I guess enable/disable ability is the best course of action. I can have all the passives already in the book but the associated fragments are needed to make them visible.

3. If the powerups are preplaced on the map or created via triggers then you could take advantage of their Custom Value to link them to your Array data:

Yes, I've tried that, it works nicely. What about the ones monsters drops it upon death?

5. I didn't see item-type among the conditions tied to player, though I'm suppose it can be immediately put into a variable. I think if I have an irreversible boolean upon the first picking up of the journal, the player doesn't actually even have to own the journal for updates because picking up the powerup enables ability/entry for the player. If they pick up the spellbook again, the next entry will be there anyway.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
3. I don't think there's an Event for a unit dropping items upon death BUT maybe it fires the "Loses an item" Event. Highly doubt it though.

Worst case you could try this:
  • Events
    • Your monster dies
  • Conditions
  • Actions
    • Pick every item within 1000 range of monster and if it's a Journal Fragment with a Custom Value of 0 then Set it's Custom Value to X
But at that point you might as well just trigger the Item creation yourself.

5. It's a Boolean Comparison which you can tell by the value.
 
Level 12
Joined
Jul 5, 2014
Messages
551
3. I don't think there's an Event for a unit dropping items upon death BUT maybe it fires the "Loses an item" Event. Highly doubt it though.

Worst case you could try this:
  • Events
    • Your monster dies
  • Conditions
  • Actions
    • Pick every item within 1000 range of monster and if it's a Journal Fragment with a Custom Value of 0 then Set it's Custom Value to X
But at that point you might as well just trigger the Item creation yourself.

5. It's a Boolean Comparison which you can tell by the value.
Yeah, creating item in the monster's position may gives the impression of dropping.

5. I know your trigger was that, I just thought there may be something like player x owns item-type.

Anyway, thanks for the help, I progressed more than I thought I would.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Yeah, creating item in the monster's position may gives the impression of dropping.

5. I know your trigger was that, I just thought there may be something like player x owns item-type.

Anyway, thanks for the help, I progressed more than I thought I would.
I imagine Blizzard uses the same exact "Create item" function (action) that we use ourselves when a unit "drops items upon death". Unless they have some special extra logic but I doubt it. That's what's great about Warcraft 3, a lot of what Blizzard used to create the Campaign has been exposed to us.

5. I see, I don't think there exists one for Item-Type, only specific Items. But you could use Pick Every Unit Owned By Player + Hero Has Item Of Type to get the same results if you must. Also, they use this word "Hero" as a suggestion most of the time, it generally doesn't have to be a Hero.
 
Last edited:
Level 12
Joined
Jul 5, 2014
Messages
551
I imagine Blizzard uses the same exact "Create item" function (action) that we use ourselves when a unit "drops items upon death". Unless they have some special extra logic but I doubt it. That's what's great about Warcraft 3, a lot of what Blizzard used to create the Campaign has been exposed to us.

5. I see, I don't think there exists one for Item-Type, only specific Items. But you could use Pick Every Unit Owned By Player + Hero Has Item Of Type to get the same results if you must. Also, they use this word "Hero" as a suggestion most of the time, it generally doesn't have to be a Hero.
Can the game cache recognize the unlocked entries aka which one of the disabled abilities are enabled?
 
Top