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

[Trigger] Simplify Shop reroll

Level 13
Joined
Feb 5, 2018
Messages
567
The general idea what I am trying to acheive is to have 8 shop slots and each slot rolls invidually. I have set up charge gold and lumber abilities in OE with unit icons.

Now I wouldn't like to have infinite number of If/Then/Else calls since there will be many units available.

In addition, would it be better for the rarities to have
1. Multiple copies of the different rarity abilities in the roll system or
2. First roll the shop slot via trigger for common, uncommon, rare, epic, legendary and then roll the units from the rarity.

At least this system works, but it will be too bloated if I run it with this. So how could I simplify this?

  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- SETTING UP SLOT 1 UNITS --------
      • Set VariableSet Slot1Units[1] = Footman (Slot 1)
      • Set VariableSet Slot1Units[2] = Rifleman (Slot 1)
      • -------- SETTING UP SLOT 2 UNITS --------
      • Set VariableSet Slot2Units[1] = Footman (Slot 2)
      • Set VariableSet Slot2Units[2] = Rifleman (Slot 2)
      • -------- SETTING UP SLOT 3 UNITS --------
      • Set VariableSet Slot3Units[1] = Footman (Slot 3)
      • Set VariableSet Slot3Units[2] = Rifleman (Slot 3)
      • -------- SETTING UP SLOT 4 UNITS --------
      • Set VariableSet Slot4Units[1] = Footman (Slot 4)
      • Set VariableSet Slot4Units[2] = Rifleman (Slot 4)
      • -------- SETTING UP SLOT 5 UNITS --------
      • Set VariableSet Slot5Units[1] = Footman (Slot 5)
      • Set VariableSet Slot5Units[2] = Rifleman (Slot 5)
      • -------- SETTING UP SLOT 6 UNITS --------
      • Set VariableSet Slot6Units[1] = Footman (Slot 6)
      • Set VariableSet Slot6Units[2] = Rifleman (Slot 6)
      • -------- SETTING UP SLOT 7 UNITS --------
      • Set VariableSet Slot7Units[1] = Footman (Slot 7)
      • Set VariableSet Slot7Units[2] = Rifleman (Slot 7)
      • -------- SETTING UP SLOT 8 UNITS --------
      • Set VariableSet Slot8Units[1] = Footman (Slot 8)
      • Set VariableSet Slot8Units[2] = Rifleman (Slot 8)
      • Set VariableSet MaxShopUnits = 2

  • Shop Reroll
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Reroll
    • Actions
      • Unit - Create 1 Shop for Player 1 (Red) at (Position of Town Hall 0000 <gen>) facing Default building facing degrees
      • Set VariableSet Shop = (Last created unit)
      • Set VariableSet ShopRoll[1] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[2] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[3] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[4] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[5] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[6] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[7] = (Random integer number between 1 and MaxShopUnits)
      • Set VariableSet ShopRoll[8] = (Random integer number between 1 and MaxShopUnits)
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ShopRoll[1] Equal to 1
        • Then - Actions
          • Unit - Add Footman (Slot 1) to Shop
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ShopRoll[1] Equal to 2
            • Then - Actions
              • Unit - Add Rifleman (Slot 1) to Shop
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ShopRoll[2] Equal to 1
        • Then - Actions
          • Unit - Add Footman (Slot 2) to Shop
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ShopRoll[2] Equal to 2
            • Then - Actions
              • Unit - Add Rifleman (Slot 2) to Shop
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ShopRoll[3] Equal to 1
        • Then - Actions
          • Unit - Add Footman (Slot 3) to Shop
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ShopRoll[3] Equal to 2
            • Then - Actions
              • Unit - Add Rifleman (Slot 3) to Shop
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • ShopRoll[4] Equal to 1
        • Then - Actions
          • Unit - Add Footman (Slot 4) to Shop
        • Else - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • ShopRoll[4] Equal to 2
            • Then - Actions
              • Unit - Add Rifleman (Slot 4) to Shop
            • Else - Actions
      • -------- ETC UNTIL WE REACH SHOPROLL 8 --------
      • Selection - Select Shop for (Owner of (Triggering unit))
      • Unit - Add a 10.00 second Generic expiration timer to Shop
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,869
If all of your Abilities use the same X/Y button positions (0, 0) they will be placed on the command card in the order of adding them.

Here's a nice system for organizing all of this.
  • Ability Shop Setup Part 1
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • -------- How many total rarity types do you have? (This should match the highest rarity value used here): --------
      • Set VariableSet Ability__Total_Rarities = 5
      • -------- --------
      • -------- These act as [indexes] to categorize our rarity-related data. We will reference these later: --------
      • Set VariableSet Rarity_COMMON = 1
      • Set VariableSet Rarity_UNCOMMON = 2
      • Set VariableSet Rarity_RARE = 3
      • Set VariableSet Rarity_EPIC = 4
      • Set VariableSet Rarity_LEGENDARY = 5
      • -------- --------
      • -------- Let's create some optional strings to display our rarities by name and color: --------
      • Set VariableSet Ability__Rarity_Strings[Rarity_COMMON] = |cffc0c0c0Common|r
      • Set VariableSet Ability__Rarity_Strings[Rarity_UNCOMMON] = |cff80ff80Uncommon|r
      • Set VariableSet Ability__Rarity_Strings[Rarity_RARE] = |cff8080ffRare|r
      • Set VariableSet Ability__Rarity_Strings[Rarity_EPIC] = |cffff00ffEpic|r
      • Set VariableSet Ability__Rarity_Strings[Rarity_LEGENDARY] = |cffd45e19Legendary|r
      • -------- --------
      • Trigger - Run Ability Shop Setup Part 2 <gen> (checking conditions)
  • Ability Shop Setup Part 2
    • Events
    • Conditions
    • Actions
      • -------- How many total ability types do you have? (This should match the very last [index] used here): --------
      • Set VariableSet Ability__Total_Types = 5
      • -------- --------
      • -------- Setup ability types, which rarity category they belong to, and their weight which determines chance to roll them (higher number = more likely): --------
      • Set VariableSet Ability_Type[1] = Footman (Ability - Shop)
      • Set VariableSet Ability_Rarity[1] = Rarity_COMMON
      • Set VariableSet Ability_Weight[1] = 10
      • -------- --------
      • Set VariableSet Ability_Type[2] = Rifleman (Ability - Shop)
      • Set VariableSet Ability_Rarity[2] = Rarity_UNCOMMON
      • Set VariableSet Ability_Weight[2] = 10
      • -------- --------
      • Set VariableSet Ability_Type[3] = Knight (Ability - Shop)
      • Set VariableSet Ability_Rarity[3] = Rarity_RARE
      • Set VariableSet Ability_Weight[3] = 10
      • -------- --------
      • Set VariableSet Ability_Type[4] = Siege Engine (Ability - Shop)
      • Set VariableSet Ability_Rarity[4] = Rarity_EPIC
      • Set VariableSet Ability_Weight[4] = 10
      • -------- --------
      • Set VariableSet Ability_Type[5] = Gryphon Rider (Ability - Shop)
      • Set VariableSet Ability_Rarity[5] = Rarity_LEGENDARY
      • Set VariableSet Ability_Weight[5] = 10
      • -------- --------
      • Trigger - Run Ability Shop Setup Part 3 <gen> (checking conditions)
  • Ability Shop Setup Part 3
    • Events
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set VariableSet Ability__Shop_Hashtable = (Last created hashtable)
      • -------- --------
      • For each (Integer Ability__LoopA) from 1 to Ability__Total_Types, do (Actions)
        • Loop - Actions
          • -------- Convert the Ability Type into an Integer so that we can Save it into our Hashtable: --------
          • Custom script: set udg_Ability__ID = udg_Ability_Type[udg_Ability__LoopA]
          • -------- --------
          • -------- Increase the range of this rarity category by the Ability Weight. This will be used later to get a random Ability from this rarity category: --------
          • Set VariableSet Ability__Rarity_Range[0] = (Ability__Rarity_Range[Ability_Rarity[Ability__LoopA]] + 1)
          • Set VariableSet Ability__Rarity_Range[Ability_Rarity[Ability__LoopA]] = (Ability__Rarity_Range[Ability_Rarity[Ability__LoopA]] + Ability_Weight[Ability__LoopA])
          • -------- --------
          • -------- Save the Ability's ID into the Hashtable at [indexes] ranging from X to Y based on our previously updated range: --------
          • For each (Integer Ability__LoopB) from Ability__Rarity_Range[0] to Ability__Rarity_Range[Ability_Rarity[Ability__LoopA]], do (Actions)
            • Loop - Actions
              • Hashtable - Save Ability__ID as Ability__LoopB of Ability_Rarity[Ability__LoopA] in Ability__Shop_Hashtable.
              • Game - Display to (All players) for 30.00 seconds the text: ((Saved + ((Name of Ability_Type[Ability__LoopA]) + ( at index + (String(Ability__LoopB))))) + ( ( + (Ability__Rarity_Strings[Ability_Rarity[Ability__LoopA]] + ))))
This is a demo trigger showcasing how you can use the system to get a random Ability Type from a random Rarity Category:
  • Demo Get Random Ability
    • Events
      • Player - Player 1 (Red) types a chat message containing r as An exact match
    • Conditions
    • Actions
      • -------- Get a random Ability Rarity (you probably want to make this use a formula): --------
      • Set VariableSet Ability_Rarity[0] = (Random integer number between 1 and Ability__Total_Rarities)
      • -------- --------
      • -------- Get a random [index] from within the Rarity Range (higher weight values are more likely to be picked): --------
      • Set VariableSet Ability_Weight[0] = (Random integer number between 1 and Ability__Rarity_Range[Ability_Rarity[0]])
      • -------- --------
      • -------- Get the Integer ID of the associated Ability Type from our Hashtable using our random [index]: --------
      • Set VariableSet Ability__ID = (Load Ability_Weight[0] of Ability_Rarity[0] from Ability__Shop_Hashtable.)
      • -------- --------
      • -------- Convert the Ability ID into an Ability Type variable that we can easily use: --------
      • Custom script: set udg_Ability_Type[0] = udg_Ability__ID
      • -------- --------
      • -------- We now have the Ability, let's do something with it: --------
      • Unit - Add Ability_Type[0] to Ability Shop 0000 <gen>
      • Game - Display to (All players) for 30.00 seconds the text: ((Loaded + ((Name of Ability_Type[0]) + ( at index + (String(Ability_Weight[0]))))) + ( ( + (Ability__Rarity_Strings[Ability_Rarity[0]] + ))))
Of course you can modify this to get a specific Rarity or make the random Rarity use a formula so that Legendaries for instance are less likely to be chosen.

I used a Hashtable to save the different Ability Types into their own Rarity Categories. They also use a Weight system to make Ability Types from within the same category have higher or lower odds of being randomly chosen. This is useful because you may want some Legendary abilities to be more "rare" than other Legendary abilities. This is a similar design to how Items work in an ARPG like Diablo, a Stone of Jordan is far less likely to drop than a Nagelring, despite them both being in the "Unique" category.

Of course it's missing some useful features like getting a random Ability that hasn't been chosen yet and associating the Unit-Type with the Ability-Type. The latter is a pretty easy addition, just add an Ability_Unit_Type[] array to go along with your other Ability_ variables.
  • Set VariableSet Ability_Type[1] = Footman (Ability - Shop)
  • Set VariableSet Ability_Unit[1] = Footman
  • Set VariableSet Ability_Rarity[1] = Rarity_COMMON
  • Set VariableSet Ability_Weight[1] = 10
 

Attachments

  • Ability Shop 1.w3m
    21.8 KB · Views: 3
Last edited:
Level 13
Joined
Feb 5, 2018
Messages
567
If all of your Abilities use the same X/Y button positions (0, 0) they will be placed on the command card in the order of adding them.
Yes, hence I made in the OE the abilities for each slot with Q,W,E,R, and so on. I guess it might be possible to change the hotkeys with the new native functions introtruced in 1.31+? So while adding to a slot we could change the hotkeys in the order they are being added.

This is looking very nice, I will go with this and try messing around a bit, thank you very much. :)
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,869
Yes, hence I made in the OE the abilities for each slot with Q,W,E,R, and so on. I guess it might be possible to change the hotkeys with the new native functions introtruced in 1.31+? So while adding to a slot we could change the hotkeys in the order they are being added.

This is looking very nice, I will go with this and try messing around a bit, thank you very much. :)
You cannot change Hotkeys unfortunately. You may have to stick with the old method of making a unique copy of each Ability, one for each Hotkey.

HOWEVER, depending on what you're trying to accomplish, you could take advantage of the new native functions to make this work. The idea would be to have 8 Charge Gold abilities, one representing each Hotkey. Then when your Shop rolls it's second ability for example, you would add the corresponding Charge Gold ability (Hotkey [W] I imagine). Then you would modify the newly added ability's Icon, Tooltip, Gold/Lumber Costs, and other important data fields to display the proper information for the Unit-Type that it's supposed to represent. You could also store this data in an Array/Hashtable so you know that Player X's [W] ability represents a Footman. That way when you cast the Ability you can easily get the associated Unit-Type which I imagine is your end goal.
 
Last edited:
Level 13
Joined
Feb 5, 2018
Messages
567
HOWEVER, depending on what you're trying to accomplish you could take advantage of the new native functions to make this work. The idea would be to have 8 Charge Gold abilities, one representing each Hotkey. Then when your Shop rolls it's second ability for example, you would add the corresponding Ability (Hotkey W I image). Then you would modify it's Ability Icon, Tooltip, and other data fields to display the proper information for that Ability.
Intriguing, but probably way too complex for me. It will be hard enough to get this system you made up and running for the 8 slots.
You cannot change Hotkeys unfortunately. You'll may have to stick with the old method of making a unique copy of each Ability, one for each Hotkey.
Oh, thats fine.
 
Level 13
Joined
Feb 5, 2018
Messages
567
Im on the prepice of making this a working piece of art. I have a few issues. I tried creating 8 slots like this:

  • For each (Integer ShopRoll) from 1 to 8, do (Actions)
    • Loop - Actions
      • Set VariableSet Ability_Rarity[ShopRoll] = (Random integer number between 1 and Ability__Total_Rarities)
      • Set VariableSet Ability_Weight[ShopRoll] = (Random integer number between 1 and Ability__Rarity_Range[Ability_Rarity[ShopRoll]])
      • Set VariableSet Ability__ID = (Load Ability_Weight[ShopRoll] of Ability_Rarity[ShopRoll] from Ability__Shop_Hashtable.)
      • Custom script: set udg_Ability_Type[udg_ShopRoll] = udg_Ability__ID
      • Unit - Add Ability_Type[ShopRoll] to Shop
      • Game - Display to (All players) for 30.00 seconds the text: ((Loaded + ((Name of Ability_Type[ShopRoll]) + ( at index + (String(Ability_Weight[ShopRoll]))))) + ( ( + (Ability__Rarity_Strings[Ability_Rarity[ShopRoll]] + ))))
It does roll and create the abilites and also shows correct one loading, but it creates somewhere between 1-5 abilites instead of all of the 8.

For some reason (which I didnt quite understand) this system doesn't create multiples of the same ability. For example it always rolls only one of each ability into the shop. This can be by passed by creating multiple copies of the same ability in the OE, which I guess is a good enough work around.

Also if it rolls and empty index slot, the shop won't have enough units/abilites to buy. I don't unfortunately know how to fix this.

I also tried to hard force the slots without looping like this:
  • Test
    • Events
    • Conditions
    • Actions
      • -------- Slot 1 --------
      • Set VariableSet Ability_Rarity[0] = (Random integer number between 1 and Ability__Total_Rarities)
      • Set VariableSet Ability_Weight[0] = (Random integer number between 1 and Ability__Rarity_Range[Ability_Rarity[0]])
      • Set VariableSet Ability__ID = (Load Ability_Weight[0] of Ability_Rarity[0] from Ability__Shop_Hashtable.)
      • Custom script: set udg_Ability_Type[0] = udg_Ability__ID
      • Unit - Add Ability_Type[0] to Shop
      • -------- Slot 2 --------
      • Set VariableSet Ability_Rarity[1] = (Random integer number between 1 and Ability__Total_Rarities)
      • Set VariableSet Ability_Weight[1] = (Random integer number between 1 and Ability__Rarity_Range[Ability_Rarity[1]])
      • Set VariableSet Ability__ID = (Load Ability_Weight[1] of Ability_Rarity[1] from Ability__Shop_Hashtable.)
      • Custom script: set udg_Ability_Type[1] = udg_Ability__ID
      • Unit - Add Ability_Type[1] to Shop
      • -------- Slot 3 --------
      • -------- and so on all the way to slot 8 --------
      • -------- It didn't quite work so I nuked it before this thread --------
Had too long of a break on mapping.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,869
A unit cannot have more than one copy of the same ability (aside from stacking item abilities), so when you add a duplicate nothing happens.

Anyway, don't change the index in your Test trigger to [1], keep it at [0]. Otherwise, you're overwriting the data that was stored there in your Setup trigger.

I reused those "setup" variables in my demo trigger because I knew that index [0] was unused and therefore safe to modify. I was sparing myself from having to create new variables. So you probably want to do something like this instead to avoid the confusion:
  • -------- Slot 1 --------
  • Set VariableSet Random_Rarity = (Random integer number between 1 and Ability__Total_Rarities)
  • Set VariableSet Random_Index = (Random integer number between 1 and Ability__Rarity_Range[Random_Rarity])
  • Set VariableSet Ability__ID = (Load Random_Index of Random_Rarity from Ability__Shop_Hashtable.)
  • Custom script: set udg_Random_Ability = udg_Ability__ID
  • Unit - Add Random_Ability to Shop
  • -------- Slot 2 --------
  • Set VariableSet Random_Rarity = (Random integer number between 1 and Ability__Total_Rarities)
  • Set VariableSet Random_Index = (Random integer number between 1 and Ability__Rarity_Range[Random_Rarity])
  • Set VariableSet Ability__ID = (Load Random_Index of Random_Rarity from Ability__Shop_Hashtable.)
  • Custom script: set udg_Random_Ability = udg_Ability__ID
  • Unit - Add Random_Ability to Shop
Again, this trigger does work, it's just that you can't have duplicates of the same Charge Gold ability.
 
Last edited:
Level 13
Joined
Feb 5, 2018
Messages
567
A unit cannot have more than one copy of the same ability (aside from stacking item abilities), so when you add a duplicate nothing happens.
Ah true. Forgot about that. So, we create an absurd amount of copies of the common units then to have more of them available then.

And also my mistake, the indexes are not empty. So after creating the copies of the abilities would you go with the loop trigger I linked or with the below method of typing the slots invidually.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,869
Unfortunately, I didn't think about that as something that was needed, I made a lot of assumptions in my design.

Anyway, one idea would be to use a Stock system so that when a duplicate is detected you would add +1 to the stock of that ability. Then when you cast the ability you would subtract 1 from the Stock and check if you need to Remove it (assuming you want it to work this way). Not sure about the art for that, though. Shame you can't add the little Charges icon to an ability (without custom UI shenanigans).

Also, your For Loop could look like this:
  • For each (Integer ShopRoll) from 1 to 8, do (Actions)
    • Loop - Actions
      • Set VariableSet Random_Rarity = (Random integer number between 1 and Ability__Total_Rarities)
      • Set VariableSet Random_Index = (Random integer number between 1 and Ability__Rarity_Range[Random_Rarity])
      • Set VariableSet Ability__ID = (Load Random_Index of Random_Rarity from Ability__Shop_Hashtable.)
      • Custom script: set udg_Random_Ability = udg_Ability__ID
      • Unit - Add Random_Ability to Shop
      • Game - Display to (All players) for 30.00 seconds the text: ((Loaded + ((Name of Random_Ability) + ( at index + (String(Random_Index))))) + ( ( + (Ability__Rarity_Strings[Random_Rarity] + ))))
Much cleaner with these new "Random" variables.

The Stock logic could be added into that trigger as well, something like:
If ability is new -> Add it to the unit. Else if ability is a duplicate -> Increase stock by 1.

Edit:
Thinking about all of this, it might make more sense to rely on buying Unit-Types directly rather than using Abilities. That would give you access to the Stock/Stock Maximum fields. I've made a system like this in the past, it wasn't too difficult, but I do recall having to use some tricks to get it working properly. If you're interested I could try to dig it up.
 
Last edited:
Top