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

Shop mechanics

Level 3
Joined
Aug 8, 2022
Messages
29
I want to create a shop that randomly selects 3 items from the item pool, allowing the player to pick one for free, after which the other two become unavailable untill next randomization. Additionally, items should function like skills, where the player selects a unit to receive the item. The shop will check all dependencies, and only if the selected unit meets the requirements, it will receive the item. Yet i have no idea how should i make it.
 
Level 3
Joined
Jul 5, 2022
Messages
15
As far as I can see, you can only achieve this via triggers.

Let's imagine that you want to create some set of "Tier 1" weapons (and then maybe upgrade their tier during the game via restock) in some shop and check if those are suited for melee or ranged type of character.

Important! Before we begin triggering, we should place some shop to the map and give it "Sell Items (Asid)" ability to their list of "Abilities - Normal", otherwise the "Neutral Building - Add item" action won't work.

Now for the triggers:

First you'll need some array item-type vars for your items, and you need to set them up:
  • SetVariables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet itemMeleeT1[1] = Sword Tier1
      • Set VariableSet itemMeleeT1[2] = Axe Tier 1
      • Set VariableSet itemMeleeT1[3] = Claws Tier1
      • Set VariableSet itemRangedT1[1] = Bow Tier 1
      • Set VariableSet itemRangedT1[2] = Moon Glavie Tier 1
      • Set VariableSet itemRangedT1[3] = Throwing Dagger Tier 1

Then let's place them into our shop:
  • AddItemsT1
    • Events
      • Time - Elapsed game time is 0.10 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 3, do (Actions)
        • Loop - Actions
          • Neutral Building - Add itemMeleeT1[(Integer A)] to Goblin Merchant 0000 <gen> with 1 in stock and a max stock of 1
          • Neutral Building - Add itemRangedT1[1] to Goblin Merchant 0000 <gen> with 1 in stock and a max stock of 1
      • Trigger - Turn off (This trigger)

After that if some hero buys an item, we should check if he's bought the proper item and remove all items from the shop. To check if hero is ranged or melee we'll look into his "Acquisition Range" which should be 500 for melee and 600 or more for ranged heroes.
This one looks messy, but gets the job done. Maybe someone could help to optimize it.
  • CheckItemRequirements
    • Events
      • Unit - A unit Sells an item (from shop)
    • Conditions
    • Actions
      • Set VariableSet boolCheckPassed = False
      • For each (Integer A) from 1 to 3, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • (Item-type of (Sold Item)) Equal to itemMeleeT1[(Integer A)]
                      • (Unit: (Buying unit)'s Real Field: Acquisition Range ('uacq')) Less than or equal to 500.00
                  • And - All (Conditions) are true
                    • Conditions
                      • (Item-type of (Sold Item)) Equal to itemRangedT1[(Integer A)]
                      • (Unit: (Buying unit)'s Real Field: Acquisition Range ('uacq')) Greater than or equal to 600.00
            • Then - Actions
              • Set VariableSet boolCheckPassed = True
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • boolCheckPassed Equal to True
        • Then - Actions
          • For each (Integer B) from 1 to 3, do (Actions)
            • Loop - Actions
              • Neutral Building - Remove itemRangedT1[(Integer B)] from Goblin Merchant 0000 <gen>
              • Neutral Building - Remove itemMeleeT1[(Integer B)] from Goblin Merchant 0000 <gen>
        • Else - Actions
          • Sound - Play Error <gen>
          • Game - Display to (Player group((Owner of (Buying unit)))) the text: Wrong item type!
          • Item - Remove (Sold Item)
          • -------- Refund resources if needed --------
 
Last edited:
Level 3
Joined
Aug 8, 2022
Messages
29
As far as I can see, you can only achieve this via triggers.

Let's imagine that you want to create some set of "Tier 1" weapons (and then maybe upgrade their tier during the game via restock) in some shop and check if those are suited for melee or ranged type of character.

Important! Before we begin triggering, we should place some shop to the map and give it "Sell Items (Asid)" ability to their list of "Abilities - Normal", otherwise the "Neutral Building - Add item" action won't work.

Now for the triggers:

First you'll need some array item-type vars for your items, and you need to set them up:
  • SetVariables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet itemMeleeT1[1] = Sword Tier1
      • Set VariableSet itemMeleeT1[2] = Axe Tier 1
      • Set VariableSet itemMeleeT1[3] = Claws Tier1
      • Set VariableSet itemRangedT1[1] = Bow Tier 1
      • Set VariableSet itemRangedT1[2] = Moon Glavie Tier 1
      • Set VariableSet itemRangedT1[3] = Throwing Dagger Tier 1

Then let's place them into our shop:
  • AddItemsT1
    • Events
      • Time - Elapsed game time is 0.10 seconds
    • Conditions
    • Actions
      • For each (Integer A) from 1 to 3, do (Actions)
        • Loop - Actions
          • Neutral Building - Add itemMeleeT1[(Integer A)] to Goblin Merchant 0000 <gen> with 1 in stock and a max stock of 1
          • Neutral Building - Add itemRangedT1[1] to Goblin Merchant 0000 <gen> with 1 in stock and a max stock of 1
      • Trigger - Turn off (This trigger)

After that if some hero buys an item, we should check if he's bought the proper item and remove all items from the shop. To check if hero is ranged or melee we'll look into his "Acquisition Range" which should be 500 for melee and 600 or more for ranged heroes.
This one looks messy, but gets the job done. Maybe someone could help to optimize it.
  • CheckItemRequirements
    • Events
      • Unit - A unit Sells an item (from shop)
    • Conditions
    • Actions
      • Set VariableSet boolCheckPassed = False
      • For each (Integer A) from 1 to 3, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • Or - Any (Conditions) are true
                • Conditions
                  • And - All (Conditions) are true
                    • Conditions
                      • (Item-type of (Sold Item)) Equal to itemMeleeT1[(Integer A)]
                      • (Unit: (Buying unit)'s Real Field: Acquisition Range ('uacq')) Less than or equal to 500.00
                  • And - All (Conditions) are true
                    • Conditions
                      • (Item-type of (Sold Item)) Equal to itemRangedT1[(Integer A)]
                      • (Unit: (Buying unit)'s Real Field: Acquisition Range ('uacq')) Greater than or equal to 600.00
            • Then - Actions
              • Set VariableSet boolCheckPassed = True
            • Else - Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • boolCheckPassed Equal to True
        • Then - Actions
          • For each (Integer B) from 1 to 3, do (Actions)
            • Loop - Actions
              • Neutral Building - Remove itemRangedT1[(Integer B)] from Goblin Merchant 0000 <gen>
              • Neutral Building - Remove itemMeleeT1[(Integer B)] from Goblin Merchant 0000 <gen>
        • Else - Actions
          • Sound - Play Error <gen>
          • Game - Display to (Player group((Owner of (Buying unit)))) the text: Wrong item type!
          • Item - Remove (Sold Item)
          • -------- Refund resources if needed --------
The idea is to create a random item spawn system, with a skills system to ensure that only the intended player can use their shop and make sure that only assigned units will get them. For example, you have a group of 5 units—3 Grunts, 1 Rider, and 1 Headhunter. You roll the shop and get to choose from 3 items: a Big Axe that only Grunts can use, Claws that anyone can use, or a Spiked Collar that only the Rider can use. You pick one of them, after which you’ll need to reroll the shop to get a new selection of 3 out of 15+ items.
 

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
The idea is to create a random item spawn system, with a skills system to ensure that only the intended player can use their shop and make sure that only assigned units will get them. For example, you have a group of 5 units—3 Grunts, 1 Rider, and 1 Headhunter. You roll the shop and get to choose from 3 items: a Big Axe that only Grunts can use, Claws that anyone can use, or a Spiked Collar that only the Rider can use. You pick one of them, after which you’ll need to reroll the shop to get a new selection of 3 out of 15+ items.
I'd recommend being more specific where you run into issues with the implementation. Are you trying to do it in some way which does not work? Perhaps you are not familiar with Warcraft 3 elements and thus cannot build the logic needed for such system? Where is it that you run into issues?
 
Level 3
Joined
Aug 8, 2022
Messages
29
I'd recommend being more specific where you run into issues with the implementation. Are you trying to do it in some way which does not work? Perhaps you are not familiar with Warcraft 3 elements and thus cannot build the logic needed for such system? Where is it that you run into issues?
I'm new to the editor, and I know this system is complicated, so I'm hoping to find a complete solution. I'm trying to merge ideas from Direct Strike, Castle Fight, and War of Races with some of my own adjustments. I've already implemented most of the core mechanics—unit building, spawning, income, and middle control—but I have no idea how to make this shop.
 

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
I'm new to the editor, and I know this system is complicated, so I'm hoping to find a complete solution. I'm trying to merge ideas from Direct Strike, Castle Fight, and War of Races with some of my own adjustments. I've already implemented most of the core mechanics—unit building, spawning, income, and middle control—but I have no idea how to make this shop.
Let's begin with this. Are you creating your map using GUI or JASS or LUA? Since that heavily impacts how this system should be explained.

By itself a shop that randomizes items should not be that complex.
 
Level 3
Joined
Aug 8, 2022
Messages
29
Let's begin with this. Are you creating your map using GUI or JASS or LUA? Since that heavily impacts how this system should be explained.

By itself a shop that randomizes items should not be that complex.
No coding, only triggers. Technically, it won’t even be a shop—just a building with random skills that should be usable based on requirements.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
No coding, only triggers. Technically, it won’t even be a shop—just a building with random skills that should be usable based on requirements.
Just to clarify (being nitpicky here).

A map has to use JASS or LUA, there's no way around it. JASS is the default scripting language and LUA is a newer language introduced in patch 1.31.

GUI stands for graphical user interface, which is a visual way for you to create game logic. In the case of the Trigger Editor, all of the windows, drop down menus, lists, etc. are part of that interface.

So in your case you're using GUI and your programming language is set to JASS.

Also, creating triggers in GUI is basically just coding with an extra step. Understand that all of your triggers are converted into code when it comes time to play your map. So technically you've been coding all of this time, congratulations ;) When I learned that it really motivated me to try my hand at coding.
 
Last edited:
Level 3
Joined
Aug 8, 2022
Messages
29
Just to clarify (being nitpicky here).

A map has to use JASS or LUA, there's no way around it. JASS is the default scripting language and LUA is a newer language introduced in patch 1.31.

GUI stands for graphical user interface, which is a visual way for you to create game logic. In the case of the Trigger Editor, all of the windows, drop down menus, lists, etc. are part of that interface.

So in your case you're using GUI and your programming language is set to JASS.

Also, creating triggers in GUI is basically just coding with an extra step. Understand that all of your triggers are converted into code when it comes time to play your map. So technically you've been coding all of this time, congratulations ;) When I learned that it really motivated me to try my hand at coding.
Thanks, Uncle! Long time no see 🙂 That means I'm using JASS, but I still didn’t get the answer I'm looking for.
 

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
Thanks, Uncle! Long time no see 🙂 That means I'm using JASS, but I still didn’t get the answer I'm looking for.
Well, depending on how exactly the shop can be interacted with, the system can be created in different ways.

From what I gathered from your previous posts you have a shop that offers a selection of semi-randomized items for a specified group of units.

Thus, you first need to detect the available units (this depends on how many there can be and how they access the store).
Then you'd need to specify the randomization based on the unit types in the detected units and roll for the randomized items.
Afterwhich the player can actually attempt to buy the items and then you'd check if certain conditions are met.

Basically I'd start by using abilities representing items in the shop and add/remove them according to the units selected (I do not know how you want it to work still - are the items always visible, or randomized based on units in range or certain region or what?).
Abilities are usually easier to manipulate than items - and when the specified requirements are met, you'd grant the specified unit the specified item.
 
Level 3
Joined
Aug 8, 2022
Messages
29
Well, depending on how exactly the shop can be interacted with, the system can be created in different ways.

From what I gathered from your previous posts you have a shop that offers a selection of semi-randomized items for a specified group of units.

Thus, you first need to detect the available units (this depends on how many there can be and how they access the store).
Then you'd need to specify the randomization based on the unit types in the detected units and roll for the randomized items.
Afterwhich the player can actually attempt to buy the items and then you'd check if certain conditions are met.

Basically I'd start by using abilities representing items in the shop and add/remove them according to the units selected (I do not know how you want it to work still - are the items always visible, or randomized based on units in range or certain region or what?).
Abilities are usually easier to manipulate than items - and when the specified requirements are met, you'd grant the specified unit the specified item.
They don't need to detect units, items should be fully random. You have a building zone with a shop, upgrade buildings, and a worker that 'builds' units. The shop regenerates 1 mana per second up to a maximum of 300, which I’ve already set up. Now, the shop needs a Reroll button that costs 60 mana. After pressing it, three random items are rolled. You click on an item, then on the target you want to receive the item; if all requirements are met, the unit gets the item. All items in the shop then disappear, so you need to press the reroll button again to get new ones.
 

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
Create an ability (for example based on Channel) and add it to the shop. This acts as the trigger that fires the rerolling that the player can activate. Detect the cast of the ability through triggers.
  • Unit - A unit Starts the effect of an ability
And follow it up by a condition that the cast ability is the reroll ability of the shop:
  • (Ability being cast) Equal to Reroll
Based on this event and condition pair you then reroll the items in the store - meaning, removing the old items (if they still exist) and adding in the new randomized items:
  • Neutral Building - Add The RandomItemType to The Shop with 1 in stock and a max stock of 1
The action above would add the specified item (Randomized Item) to the shop. Naturally, we also need to specify what the random item is, which can be done through a integer and an array item type variables. Upon map initialization, you can assign RandomItem[x] to equal a specific item type, where the x is a specified number. For example:
  • Set VariableSet RandomItemType[1] = Apple
  • Set VariableSet RandomItemType[2] = Orange
  • Set VariableSet RandomItemType[3] = Pear
  • Set VariableSet RandomItemType[4] = Kiwi
In the example above RandomItemType[2] would refer to an orange and the numbers can go as high as you want - from 1 to 4 (like above) or from 1 to 200. Upon the shop randomization you simply randomize the item type to be added through a variable set call:
  • Set VariableSet Random = (Random integer number between 1 and 4)
  • Neutral Building - Add The RandomItemType[Random] to The Shop with 1 in stock and a max stock of 1
This trigger would add a Apple, Orange, Pear or Kiwi to the shop, randomized upon the shop reroll. Before adding the new round of items to the store, you will want to remove all previous items from the shop:
  • For each (Integer A) from 1 to 4, do (Actions)
    • Loop - Actions
      • Neutral Building - Remove RandomItemType[Integer A] from the Shop
The above code runs a loop, removing the item types 1-4, which correspond to the previously set fruits. You would also want to call the same item type removal when an item is sold from the shop.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
I believe he will want to use an Ability to represent the Items, otherwise, he won't be able to do this:
You click on an item, then on the target you want to receive the item; if all requirements are met, the unit gets the item.
However, there is no such ability that has both Resource Costs and Unit-targeting, the only option is the Charge Gold and Lumber ability which is Instant.

So the "buyer" should probably get set ahead of time, like via Unit Selection Events or a separate "Select Hero" ability. The trigger could also try to pick the closest Hero at the time of purchasing if no "buyer" was set.

On cast -> Loop over the Ability-Array and determine the [index] of the ability being cast -> Run any requirements associated with that ability -> If conditions are met, create the item by plugging in the earlier [index] into the Item-Array. Else, refund the Resource Costs and throw an Error.
 
Last edited:

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
I believe he will want to use an Ability to represent the Items, otherwise, he won't be able to do this:

However, there is no such ability that has both Resource Costs and Unit-targeting, the only option is the Charge Gold and Lumber ability which is Instant.

So the "buyer" should probably get set ahead of time, like via Unit Selection Events or a separate "Select Hero" ability. The trigger could also try to pick the closest Hero at the time of purchasing if no "buyer" was set.
Ah, forgot about that part. He can use the "Shop Sells an Item" trigger and detect which item type is sold and to which unit and then run corresponding actions.
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,877
Ah, forgot about that part. He can use the "Shop Sells an Item" trigger and detect which item type is sold and to which unit and then run corresponding actions.
That's an option, but that would cause the "Acquires an Item" and "Loses an Item" Events to run, which may have undesirable side effects.

It might be better to avoid the Item creation entirely if it fails.

Of course the need for an Ability per Item would add some extra complexity.
 

Remixer

Map Reviewer
Level 33
Joined
Feb 19, 2011
Messages
2,112
That's an option, but that would cause the "Acquires an Item" and "Loses an Item" Events to run, which may have undesirable side effects.

It might be better to avoid the Item creation entirely if it fails.

Of course the need for an Ability per Item would add some extra complexity.
I'd actually argue against, since we already need to monitor the Sells an Item (from shop), since we want to remove all the available items from the shop whenever one of the items is bought.
  • Unit - A unit Sells an item (from a shop)
Gives us the shop that sells the item as well as the unit that is the buying unit (essentially the target of the transaction, which we also need). Thus, using the purchase event we get all the references: the item sold, the shop and the buying unit.

Were we to take the ability approach (which is also an option) we would have to create a way to get the target unit of the transaction - essentially mimic Select Patron ability artificially to check the requirements on that unit before attempting to artificially create and give him the item.
 
Level 3
Joined
Aug 8, 2022
Messages
29
I believe he will want to use an Ability to represent the Items, otherwise, he won't be able to do this:

However, there is no such ability that has both Resource Costs and Unit-targeting, the only option is the Charge Gold and Lumber ability which is Instant.

So the "buyer" should probably get set ahead of time, like via Unit Selection Events or a separate "Select Hero" ability. The trigger could also try to pick the closest Hero at the time of purchasing if no "buyer" was set.

On cast -> Loop over the Ability-Array and determine the [index] of the ability being cast -> Run any requirements associated with that ability -> If conditions are met, create the item by plugging in the earlier [index] into the Item-Array. Else, refund the Resource Costs and throw an Error.
Items should be free anyway, only limitation is the reroll frequency so there is no problem with that.
 
Level 3
Joined
Aug 8, 2022
Messages
29
I'd actually argue against, since we already need to monitor the Sells an Item (from shop), since we want to remove all the available items from the shop whenever one of the items is bought.
  • Unit - A unit Sells an item (from a shop)
Gives us the shop that sells the item as well as the unit that is the buying unit (essentially the target of the transaction, which we also need). Thus, using the purchase event we get all the references: the item sold, the shop and the buying unit.

Were we to take the ability approach (which is also an option) we would have to create a way to get the target unit of the transaction - essentially mimic Select Patron ability artificially to check the requirements on that unit before attempting to artificially create and give him the item.It probably should be a
I'd actually argue against, since we already need to monitor the Sells an Item (from shop), since we want to remove all the available items from the shop whenever one of the items is bought.
  • Unit - A unit Sells an item (from a shop)
Gives us the shop that sells the item as well as the unit that is the buying unit (essentially the target of the transaction, which we also need). Thus, using the purchase event we get all the references: the item sold, the shop and the buying unit.

Were we to take the ability approach (which is also an option) we would have to create a way to get the target unit of the transaction - essentially mimic Select Patron ability artificially to check the requirements on that unit before attempting to artificially create and give him the item.
It should probably be an ability, otherwise, allies would be able to use each other’s shops, which isn’t good.
 
Last edited by a moderator:
Level 3
Joined
Aug 8, 2022
Messages
29
Can you clarify what are the conditions that need to be met when the unit should be able to buy the item?
The only general condition is that the unit belongs to the player, while other requirements—like 'any unit,' 'specific unit,' 'only flying,' 'only melee,' and so on—would depend on the item so i guess the simplest way would be to make a list of which units can receive each item.
 
Top