• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

match units within trigger

Status
Not open for further replies.
Level 4
Joined
Dec 10, 2015
Messages
85
Hello,
I want to create a trigger that makes buildings spawn units.
I know how to do it. But the way I would do it is by making a trigger for each building/unit. Each building-type spawn a different unit-type. For example, Warrior Camp spawn Warriors, Spearman Camp spawn Spearman, etc..
So, is there a way to match units-type between them, like Warriors with Warrior Camp, and make only one trigger like :
For each VarX, create a unit of type VarY
where VarX is a building and VarY is the unit type that match the building.

So, is there a way to do that, or do i need to make a trigger for each building/unit match?
 
Yes. Pick all units in playable map. If (picked unit) is a Warrior Camp then create one Warrior for owner of picked unit at position of picked unit, if else then if unit is a Shaman Camp then create one Shaman at position of picked unit. Remember to remove leaks though. If you don't know how to remove leaks read the tutorial in my signature.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,201
So, is there a way to match units-type between them, like Warriors with Warrior Camp, and make only one trigger like :
For each VarX, create a unit of type VarY
where VarX is a building and VarY is the unit type that match the building.
Yes there is a way to do this. Use a hashtable to map the spawned unit type to the spawner unit type. This is done by storing the spawned unit type integer at a parent index of the spawner unit type with an arbitrary key for a child. This may require pure JASS due to stupid limitations with GUI.

After doing this you iterate through all spawners on the map and then look up the spawned unit type using the hashtable and their unit type. You then create the spawned unit type near the spawner building. The hashtable lookup is of complexity O(1) so you could easily have hundreds of spawner types without the trigger slowing down in any way. The hashtable can be used for different mappings of a similar type If desired.

Another way would be a linear search, this is kind of what Legal_Ease suggested. Instead of an ugly and error prone multiple selection structure you could use 2 unit type arrays and then loop through them until you find the matching unit type (a linear search). This is easy to implement however it has very bad scaling, with a complexity of O(n) so may start to give performance problems and even op limit problems when in the 100s range.

A more elegant form of what Legal_Ease suggested would be to construct a binary search tree. This can be done hard coded in nested selection statements or programmatically with an array. The advantage of this is that it has a complexity of O(log2(n)) which means it scales very well so will not suffer performance problems. The problem is constructing hard-coded trees can be error prone and poorly maintainable by hand. Algorithmic construction can be used for an array implementation however this can be quite tricky for newbie programmers to implement reliably.

Overall the hashtable solution is the easiest to implement and fastest to execute so I would highly recommend it. The only down side is that it does require the use of custom script or JASS directly.
 
Last edited:
Level 15
Joined
Jul 9, 2008
Messages
1,552
here is a very basic way of doning it

NOTE:remove the unit group leak and point leak

  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set BULDING[1] = Farm
      • Set BULDING[2] = Barracks
      • Set UNIT[1] = Rifleman
      • Set UNIT[2] = Footman
  • Spawns
    • Events
      • Time - Every 2.00 seconds of game time
    • Conditions
    • Actions
      • For each (Integer count) from 1 to 2, do (Actions)
        • Loop - Actions
          • Unit Group - Pick every unit in (Units in (Playable map area) matching ((Unit-type of (Matching unit)) Equal to BULDING[count])) and do (Actions)
            • Loop - Actions
              • Unit - Create 1 UNIT[count] for (Owner of (Picked unit)) at (Position of (Picked unit)) facing Default building facing degrees
 
Level 12
Joined
May 22, 2015
Messages
1,051
Well, I guess I'll have to do a trigger for each building/unit set, since I don't have any JASS skills :(
Thanks all
Don't lose hope! You don't need JASS for this trigger. The main thing is that, making it work for one building-unit combo will make it VERY easy to make it work for ALL building-unit combos. millzy's triggers will do the trick and they're presented very nicely so you can copy them easily. If you have questions about his triggers, feel free to ask :)

The only thing to fix in his triggers is the unit group leak, but that will be one simple line to add in the end. I learned from this post: http://world-editor-tutorials.thehelper.net/cat_usersubmit.php?view=27219 but don't hesitate to ask for help.


I would do this with hashtables, but it may take time to learn how to use them. I don't remember the GUI syntax (only code in JASS now), but I could look it up to try to write GUI triggers using hashtables.
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
What you need is a trigger that runs on map init.
That trigger creates a new hashtable and stores the last created hashtable in a hashtable variable.

After that, you are going to store the unit type of the unit you want to create for each building in the hashtable using the unit type of the building that has to create those units as key.

Then you can have another trigger that loads the value stored in the hashtable and create a new unit using that unit type.

This is probably the most easy solution in GUI.

There is only one problem that you cant store unit type id in a hashtable nor use it as key... at least not in GUI.
In essence, this variable type is the same as an integer, it just has a special meaning.
So what you can do is set an integer variable to the value of the unit type variable.
This however must be done in a custom script.

EDIT:
  • Spawn Init
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Hashtable - Create a hashtable
      • Set SpawnHashtable = (Last created hashtable)
      • -------- - --------
      • Set TempUnitType[0] = Barracks
      • Set TempUnitType[1] = Footman
      • Custom script: set udg_TempInteger[0] = udg_TempUnitType[0]
      • Custom script: set udg_TempInteger[1] = udg_TempUnitType[1]
      • Hashtable - Save TempInteger[1] as 0 of TempInteger[0] in SpawnHashtable
      • -------- - --------
      • Set TempUnitType[0] = Arcane Sanctum
      • Set TempUnitType[1] = Priest
      • Custom script: set udg_TempInteger[0] = udg_TempUnitType[0]
      • Custom script: set udg_TempInteger[1] = udg_TempUnitType[1]
      • Hashtable - Save TempInteger[1] as 0 of TempInteger[0] in SpawnHashtable
  • Spawn Units
    • Events
      • Whatever
    • Conditions
    • Actions
      • Unit Group - Pick every unit in SpawnBuildings and do (Actions)
        • Loop - Actions
          • Set TempUnitType[0] = (Unit-type of (Picked unit))
          • Custom script: set udg_TempInteger[0] = udg_TempUnitType[0]
          • Set TempInteger[1] = (Load 0 of TempInteger[0] from SpawnHashtable)
          • Custom script: set udg_TempUnitType[1] = udg_TempInteger[1]
          • -------- - --------
          • Set TempLocation[0] = (Position of (Picked unit))
          • Unit - Create 1 TempUnitType[1] for (Owner of (Picked unit)) at TempLocation[0] facing Default building facing degrees
          • Custom script: call RemoveLocation(udg_TempLocation[0])
 
Last edited:
Status
Not open for further replies.
Top