• 🏆 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!

Unit Variable & Comparisons

Status
Not open for further replies.
Level 1
Joined
Apr 23, 2020
Messages
2
Hello all,

I'm starting to pick up WC3 map editing, so go easy on me.

I reviewed most "how-to" guides out there related to variables, but I'm still confused with the assignments & comparisons. I am trying to achieve this......

IF
Completed Structure = PREDEFINED STRUCTURE
THEN
DO ACTION



Here's what my code looks like

Code:
Define UNIT
    Events
        Map initialization
    Conditions
        NONE
    Actions
        Set VariableSet UNIT_1 = ???
        Set VariableSet UNIT_2 = ???

I tried two approaches with defining the UNIT_1 and UNIT_2 by using pre-placed units on map and using unit groups, but neither gave me the result I desired in the code below;

Code:
Resistance Engine
    Events
        Unit - A unit Finishes construction
    Conditions
        NONE
    Actions
        Set VariableSet FocalBLDG = (Constructed structure)
        If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            If - Conditions
                FocalBLDG Equal to UNIT_1
            Then - Actions
                Trigger - Run A_COMP <gen> (checking conditions)
            Else - Actions
                If (All Conditions are True) then do (Then Actions) else do (Else Actions)
                    If - Conditions
                        FocalBLDG Equal to UNIT_2
                    Then - Actions
                        Trigger - Run B_COMP <gen> (checking conditions)
                    Else - Actions
                        ETC


If I used unit groups, unit comparisons sometimes work and sometimes doesn't.
If I used the pre-placed units, it must remain in the map or it stops working. (leak)



so this way I can confirm that the specific building gets specific abilities based on its type. Any pointers would be greatly appreciated!

-Luf
 

Uncle

Warcraft Moderator
Level 64
Joined
Aug 10, 2018
Messages
6,543
You want to use the Unit-Type variable.

Also: How To Post Your Trigger

Here's how you can easily trigger your desired effects. I'm using Arrays/For Loops to make things a lot easier and more organized. They're very simple to use once you get the hang of them.
So at the map initialization we define our variables. In this case we're creating an Array of Unit-Types and Triggers. Arrays are useful because instead of having to create a new Unit-Type variable for every-single-structure, we can create one Unit-Type variable with an Array enabled, and use it's Index (The number in the brackets []) to basically allow you to use 1 Variable for many different values. Using Arrays will cut your variable usage down IMMENSELY and save you a major headache.
  • Define Variables
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set VariableSet UnitType[1] = Farm
      • Set VariableSet UnitType[2] = Barracks
      • Set VariableSet UnitType[3] = Scout Tower
      • -------- --------
      • Set VariableSet Trigger[1] = Farm Finishes <gen>
      • Set VariableSet Trigger[2] = Barracks Finishes <gen>
      • Set VariableSet Trigger[3] = Scout Tower Finishes <gen>
      • -------- --------
      • Set VariableSet TotalStructures = 3
Then we reference these newly defined Variables in our Finishes Construction trigger. Here we're using a For Loop, which will run the Actions you add to it Z amount of times, from X to Y. In this case X = 1, Y = 3 (TotalStructures), and Z = 3 (Z is the Range). Integer A is an Integer that counts from X to Y, so in this case it starts out at 1, and then goes to 2, and then finally ends at 3.

So what this trigger does is ask the question "Is the unit-type of our constructed structure equal to UnitType[1], [2], or [3]? If it returns True for any of those, it runs the corresponding Trigger. If it's UnitType[2] (Barracks), then it runs Trigger[2] (Barracks Finishes <gen>).
  • Finish Construction
    • Events
      • Unit - A unit Finishes construction
    • Conditions
    • Actions
      • For each (Integer A) from 1 to TotalStructures, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • (Unit-type of (Constructed structure)) Equal to UnitType[(Integer A)]
            • Then - Actions
              • Trigger - Run Trigger[(Integer A)] (ignoring conditions)
            • Else - Actions
Here are the triggers that are referenced in the Define Variables trigger. This is where you interact with your constructed structure, adding abilities to it for example.
  • Farm Finishes
    • Events
    • Conditions
    • Actions
      • Game - Display to (All players) for 30.00 seconds the text: Farm constructed
      • Unit - Add Aerial Shackles to (Constructed structure)
  • Barracks Finishes
    • Events
    • Conditions
    • Actions
      • Game - Display to (All players) for 30.00 seconds the text: Barracks constructed
      • Unit - Add Berserk to (Constructed structure)
      • Unit - Add Dispel Magic to (Constructed structure)
  • Scout Tower Finishes
    • Events
    • Conditions
    • Actions
      • Game - Display to (All players) for 30.00 seconds the text: Scout Tower constru...
      • Unit - Add Bloodlust to (Constructed structure)
      • Unit - Add Breath of Frost to (Constructed structure)
      • Unit - Add Cloud to (Constructed structure)
So instead of having 10+ If Then Else statements in a row, making an ugly and confusing trigger, you can keep everything organized like this.


Whenever you want to add a new Structure to this:

Create a new trigger that's dedicated to your new Structure, like I did with Farm Finishes. Then configure the variables in the Define Variables trigger and add your new Structure/Trigger to it.

So you would copy and paste UnitType[] and Trigger[] and set their values to the appropriate Structure/Trigger, and make sure to change their Index [The number in the brackets] using the same pattern I was using, so your 4th Structure/Trigger would be [4]. Then update the TotalStructures variable to be equal to the total amount of Structures this system uses.


And here I explain Unit/Unit Groups variables:
Unit variables are used for specific units that already exist, so you can keep track of them easily.

Unit Groups are used to contain units so that they can be easily referenced later on. They're also useful for other things. Here's some examples:

The "Pick every unit" function creates a Unit Group containing units chosen by you. In this example the Unit Group contains "Units of type Footman". So it puts ALL of the Footman in your map inside this group. Then the Loop - Actions run, doing whatever Actions you add to it. In this case I kill the picked unit. The picked unit will always be equal to 1 of the units in the Unit Group. It runs these Loop - Actions once for EACH unit in the group, so every single Footman will be set as the "Picked unit" and killed. The order that it picks units is random as far as I know.
  • Unit Group - Pick every unit in (Units of type Footman) and do (Actions)
    • Loop - Actions
      • Unit - Kill (Picked unit)
And here's an example of using a Unit Group variable. I created a Unit Group variable called DontAttack, with the goal that units contained in this Group cannot be attacked (it prevents basic right-click attacks at least). How you add units to the group is up to you, in this case I add any existing pre-placed Footman at Map Initialization, and I add any newly created Footman to it as well (when they Enter the map).
  • Add to Unit Group 1
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit Group - Pick every unit in (Units of type Footman) and do (Actions)
        • Loop - Actions
          • Unit Group - Add (Picked unit) to DontAttack
  • Add to Unit Group 2
    • Events
      • Unit - A unit enters (Entire map)
    • Conditions
      • (Unit-type of (Triggering unit)) Equal to Footman
    • Actions
      • Unit Group - Add (Triggering unit) to DontAttack
Then I created the trigger that prevents the attacks. So when a unit is attacked, I check if it's contained in the DontAttack Unit Group, and then order the Attacking unit to stop (interrupting it), if this comes back True.
  • Dont Attack
    • Events
      • Unit - A unit Is attacked
    • Conditions
      • ((Attacked unit) is in DontAttack.) Equal to True
    • Actions
      • Unit - Order (Attacking unit) to Stop.
If you want to remove a unit from a Unit Group it's fairly simple:
  • Unit Group - Remove (Triggering unit) from DontAttack
Keep in mind that dead units will remain in a Unit Group, so you'll probably want to remove dying units from the group.
  • Remove Example
    • Events
      • Unit - A unit Dies
    • Conditions
      • ((Triggering unit) is in DontAttack Equal to True
    • Actions
      • Unit Group - Remove (Triggering unit) from DontAttack
 

Attachments

  • Array Example.w3m
    17.4 KB · Views: 34
Last edited:
Level 1
Joined
Apr 23, 2020
Messages
2
I see my mistake now. Your explanation & code examples is just perfect :)

I misunderstood what Unit Group & Types did and struggled a bit there. Time to get working on my map now thanks to you!
 
Status
Not open for further replies.
Top