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

All About Variables

Level 20
Joined
Jan 6, 2008
Messages
2,627

attachment.php


NOTE: I used Jass Newgen Pack for the triggers, if you cant do something thats inside this tutorial, you might need to download and use Jass Newgen Pack.

FAQ about Variables

You need to be creative with Variables, and understand them.

Variables are used for storing stuff. Variables are important for a smooth and efficient operation of your maps. They are nessessary for preventing leaks attached to the wait command. So if you are going to use a wait command and then do actions with a Unit, Destructible, Item, Floating Text, Special effects or other, you have to set temparary variables to prevent leaks, so you have to do it like this:
  • Variable Initalization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set TempPoint = (Point(0.00, 0.00))
      • Unit - Create 1 Footman for Player 1 (Red) at TempLoc facing 90.00 degrees
      • Set TempUnit = (Last created unit)
      • Wait 2.00 seconds
      • Unit - Explode TempUnit
      • Custom script: call RemoveLocation(udg_TempPoint)
Remember: You will learn about Location leaks Later.
So it gets stored and cant be failed if another unit gets created before it explodes.
So to sum up the FAQ in some few words:
Variables stores the Unit or what you are using so you can use it later without making the trigger leak.

Variable List

Well, basicly here i will make an image of every single Variable you can find.

attachment.php
attachment.php
attachment.php
attachment.php
attachment.php
attachment.php
attachment.php
attachment.php
attachment.php
attachment.php

Now that you know that, lets continue :p

Use of Arrays

Now, arrays are all about storing stuff, and make every single thing do something, or just make it cleaner, it could be used like the example below:
Now im using Unit Group, Unit, Integer and Region variables, The unit variable has an array of 100, and a simple loop.
Note: This will make it ALOT easier than setting the units manually.

  • Set TempRegion = Region 000 <gen>
  • Set TempUnit_Group = (Units in TempRegion)
  • Unit Group - Pick every unit in TempUnit_Group and do (Actions)
    • Loop - Actions
      • Set TempInteger = (TempInteger + 1)
      • Set TempUnit2[TempInteger] = (Picked unit)
  • Custom script: call DestroyGroup(udg_TempUnit_Group)
Now, we actually stored all the units in TempRegion to the number TempInteger gives them, since i said the array is on 100, we need a loop that goes to 100 for doing an action for all the units.
The variables are TempPoint, Ability,
Now, this is the whole trigger ive got. This orders all the units in the region to Blink.

BAD VERSION
  • Bad Version
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Unit - Add Blink to Mountain King 0001 <gen>
      • Unit - Order Mountain King 0001 <gen> to Night Elf Warden - Blink (Random point in (Playable map area))
      • Unit - Add Blink to Mountain King 0018 <gen>
      • Unit - Order Mountain King 0018 <gen> to Night Elf Warden - Blink (Random point in (Playable map area))
      • Unit - Add Blink to Mountain King 0032 <gen>
      • Unit - Order Mountain King 0032 <gen> to Night Elf Warden - Blink (Random point in (Playable map area))
      • -------- And so on --------
      • Wait 2.00 seconds
      • Unit - Remove Blink from Mountain King 0001 <gen>
      • Unit - Remove Blink from Mountain King 0018 <gen>
      • Unit - Remove Blink from Mountain King 0032 <gen>
      • -------- And so on --------
GOOD VERSION
  • Variable Initalization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Visibility - Create an initially Enabled visibility modifier for Player 1 (Red) emitting Visibility across (Playable map area)
      • Set TempPoint = (Point(0.00, 0.00))
      • Unit - Create 1 Footman for Player 1 (Red) at TempPoint facing 90.00 degrees
      • Set TempUnit = (Last created unit)
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Set TempRegion = Region 000 <gen>
      • Set TempUnit_Group = (Units in TempRegion)
      • Unit Group - Pick every unit in TempUnit_Group and do (Actions)
        • Loop - Actions
          • Set TempInteger = (TempInteger + 1)
          • Set TempUnit2[TempInteger] = (Picked unit)
      • Custom script: call DestroyGroup(udg_TempUnit_Group)
      • Set TempAbility = Blink
      • For each (Integer A) from 1 to TempInteger, do (Actions)
        • Loop - Actions
          • Unit - Add TempAbility to TempUnit2[(Integer A)]
          • Set TempPoint = (Random point in (Playable map area))
          • Unit - Order TempUnit2[(Integer A)] to Night Elf Warden - Blink TempPoint
          • Custom script: call RemoveLocation(udg_TempPoint)
      • Wait 2.00 seconds
      • For each (Integer A) from 1 to TempInteger, do (Actions)
        • Loop - Actions
          • Unit - Remove TempAbility from TempUnit2[(Integer A)]
Look, now the Wait is UnLeakable, since we already stored the ability and the units, so it doesnt leak. The wait needs to be there, since the unit needs some time to cast it

So to tell what arrays are used for in a sentece:
An array allows one variable to store more than one set of data.

Leaks

Leaks are horrible, you could say they are some kind of infection to the maps since they cause lag and errors.
I will post the common leaks here.
The most known leaks are ofcourse
  • Custom script: call RemoveLocation(udg_PointVariableName!)
  • Custom script: call DestroyGroup(udg_Unit_GroupVariableName!)
And for the GUI Functions that can be Destroyed via GUI needs to be stored in a variable IF you do not use a wait command for the destroying of the thing you created, let's say Special effect, you can just delete the last created.

Example:
BAD VERSION
  • Bad Version
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Set TempPoint = (Position of TempUnit)
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Wait 4.00 seconds
      • Special Effect - Destroy (Last created special effect)
GOOD VERSION

  • Special Effect
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Set TempPoint = (Position of TempUnit)
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Set TempSpecial_Effect = (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempPoint)
      • Wait 4.00 seconds
      • Special Effect - Destroy TempSpecial_Effect
ALSO A GOOD WAY
  • Special Effect
    • Events
      • Time - Elapsed game time is 1.00 seconds
    • Conditions
    • Actions
      • Set TempPoint = (Position of TempUnit)
      • Special Effect - Create a special effect at TempPoint using Abilities\Spells\Human\ThunderClap\ThunderClapCaster.mdl
      • Special Effect - Destroy (Last created special effect)
      • Custom script: call RemoveLocation(udg_TempPoint)

MPI Variables

Now, this part is actually very easy, you just need to use the Number code in the array Player Number of Triggering Player/Owner of Triggering Unit and so on. The same about the units, you could use something like this:

WRONG WAY
  • Bad Version
    • Events
      • Unit - A unit enters Region 000 <gen>
    • Conditions
    • Actions
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Owner of (Triggering unit)) Equal to Player 1 (Red)
        • Then - Actions
          • Set TempUnit3[1] = (Triggering unit)
        • Else - Actions
      • -------- And all the players --------
      • -------- Do your actions like this --------
      • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
        • If - Conditions
          • (Owner of (Triggering unit)) Equal to Player 1 (Red)
        • Then - Actions
          • -------- Actions --------
        • Else - Actions
GOOD WAY
First we need to set the actions, this is a good trick.
  • Set MPI
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • -------- Setup the type of the actions you want to add in MPI --------
      • -------- Im gonna add a different String that can be used as a floating text for every players --------
      • Set TempString[1] = LUL
      • Set TempString[2] = Im'a Player 2
      • Set TempString[3] = Play0r 3 in da Hause
      • Set TempString[4] = Im fat
      • Set TempString[5] = someone up for laughing??
      • Set TempString[6] = And just make this for every player
  • MPI
    • Events
      • Unit - A unit enters Region 000 <gen>
    • Conditions
    • Actions
      • Set TempUnit3[(Player number of (Owner of (Triggering unit)))] = (Entering unit)
      • For each (Integer A) from (Player number of (Owner of (Triggering unit))) to (Player number of (Owner of (Triggering unit))), do (Actions)
        • Loop - Actions
          • -------- Variable Setup Functions --------
          • Floating Text - Create floating text that reads TempString[(Integer A)] above TempUnit3[(Integer A)] with Z offset 0.00, using font size 10.00, color (100.00%, 100.00%, 100.00%), and 0.00% transparency
          • Set TempFloating_Text[(Integer A)] = (Last created floating text)
          • Floating Text - Set the velocity of TempFloating_Text[(Integer A)] to 64.00 towards 90.00 degrees
          • Floating Text - Change TempFloating_Text[(Integer A)]: Enable suspend state
          • Floating Text - Change TempFloating_Text[(Integer A)]: Disable permanence
          • Floating Text - Change the lifespan of TempFloating_Text[(Integer A)] to 5.00 seconds
          • Floating Text - Change the fading age of TempFloating_Text[(Integer A)] to 4.00 seconds

Samples


More samples will be added later, feel free to add some samples, please read these samples and you will understand more.

My inventory setup sample, Not finished, almost done with 1 item.
  • InvItems
    • Events
      • Map initialization
    • Conditions
    • Actions
      • -------- 1hSwords --------
        • Do Multiple ActionsFor each (Integer A) from 1 to 1, do (Actions)
          • Loop - Actions
            • -------- Searing Blade --------
            • Set ITEMOneHandedSword[1] = Searing Blade
            • Set DestructibleITEMOneHandSword[1] = Searing Blade
            • Set Item1hSwordDescript[1] = Searing Blade|n|n|c0000FFFFClass:|r 1 Handed Sword|n|n|c0080FF00Requirements|r|n|c00FF8000Level:|r 0|n|c00FF8000Skills needed:|r None|n|c00FF8000Stats:|r 14 Damage, 8 Strength|n|n|c0080FF00Description|r|nA magical blade formed by dwarves.
            • Set ItemOnehandDmg[1] = 14
            • Set Item1hSwordAbilityStats[1] = 8 Strength
            • Set ItemOneHandFxPath[1] = war3mapImported\Searathil.mdx
            • Set ItemOnehandDmgSecondSlot[1] = 14
            • Set Item1hSwordAbilityStatsSecondS[1] = 8 Strength
            • Set ItemOneHandSwordReqlvl[1] = 1
            • -------- ' --------
And the Equip trigger, i do NOT need to edit that one, so i only need to setup more triggers.

  • Do Multiple ActionsFor each (Integer A) from 1 to 1000, do (Actions)
    • Loop - Actions
      • -------- 1h Sword 1st slot --------
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • WeaponUsed[1] Equal to (==) False
            • (Hero level of Unit[1]) Equal to (==) ItemOneHandSwordReqlvl[(Integer A)]
          • Then - Actions
            • Unit - Remove ItemOneHandSwordUsedabi[1] from Unit[1]
            • Unit - Remove ItemOneHandSwordUsedabi[2] from Unit[1]
            • Unit - Add Item1hSwordAbilityStats[(Integer A)] to Unit[1]
            • Set ItemOneHandSwordUsedabi[2] = Item1hSwordAbilityStats[(Integer A)]
            • Special Effect - Destroy ItemOneHandFx[1]
            • Special Effect - Destroy ItemOneHandFx[2]
            • Hero - Learn skill for Unit[1]: Item1hSwordAbilityStats[(Integer A)]
            • Special Effect - Create a special effect attached to the left,hand of Unit[1] using ItemOneHandFxPath[(Integer A)]
            • Set ItemOneHandFx[1] = (Last created special effect)
            • Special Effect - Create a special effect attached to the left,hand of Unit[2] using ItemOneHandFxPath[(Integer A)]
            • Set ItemOneHandFx[2] = (Last created special effect)
            • Set WeaponUsed[1] = True
          • Else - Actions
      • -------- 1h Sword 2th slot --------
        • Multiple FunctionsIf (All Conditions are True) then do (Then Actions) else do (Else Actions)
          • If - Conditions
            • (Hero level of Unit[1]) Equal to (==) ItemOneHandSwordReqlvl[(Integer A)]
            • WeaponUsed[2] Equal to (==) False
          • Then - Actions
            • Unit - Remove ItemOneHandSwordUsedabi[3] from Unit[1]
            • Unit - Remove ItemOneHandSwordUsedabi[4] from Unit[1]
            • Set ItemOneHandSwordUsedabi[3] = Item1hSwordAbilityStats[(Integer A)]
            • Unit - Add Item1hSwordAbilityStatsSecondS[(Integer A)] to Unit[1]
            • Set ItemOneHandSwordUsedabi[4] = Item1hSwordAbilityStats[(Integer A)]
            • Special Effect - Destroy ItemOneHandFx[4]
            • Special Effect - Destroy ItemOneHandFx[3]
            • Special Effect - Create a special effect attached to the right,hand of Unit[1] using ItemOneHandFxPath[(Integer A)]
            • Set ItemOneHandFx[3] = (Last created special effect)
            • Special Effect - Create a special effect attached to the right,hand of Unit[2] using ItemOneHandFxPath[(Integer A)]
            • Set ItemOneHandFx[4] = (Last created special effect)
            • Set WeaponUsed[2] = True
          • Else - Actions
Now, thats my inventory sample.



~Slaydon
 

Attachments

  • Header.png
    Header.png
    141.1 KB · Views: 205
  • Variables 1.png
    Variables 1.png
    107.4 KB · Views: 198
  • Variables 2.png
    Variables 2.png
    66.2 KB · Views: 193
  • Variables 3.png
    Variables 3.png
    68.3 KB · Views: 216
  • Variables 4.png
    Variables 4.png
    67.6 KB · Views: 178
  • Variables 5.png
    Variables 5.png
    63.2 KB · Views: 197
  • Variables 6.png
    Variables 6.png
    64.2 KB · Views: 181
  • Variables 7.png
    Variables 7.png
    62.4 KB · Views: 195
  • Variables 8.png
    Variables 8.png
    62.3 KB · Views: 189
  • Variables 9.png
    Variables 9.png
    63.8 KB · Views: 193
  • Variables 10.png
    Variables 10.png
    34 KB · Views: 178
Last edited:
Level 18
Joined
Mar 13, 2009
Messages
1,411
For the first trigger (that adds Blink) is it really needed to set a TempRegion and a TempAbility?
Maybe you could use hidden tags for the triggers so it wont stretch my screen by the way ^^
 
Level 20
Joined
Jan 6, 2008
Messages
2,627
well, yes but you could simply do this to pick all the units in a region of type:
  • TEST
    • Events
    • Conditions
    • Actions
      • Set Tempgroup[1] = (Units in Tempregion)
      • Unit Group - Pick every unit in Tempgroup[1] and do (Actions)
        • Loop - Actions
          • Set Tempgroup[2] = (Units of type Footman)
          • Unit Group - Pick every unit in Tempgroup[2] and do (Actions)
            • Loop - Actions
              • -------- Set the Unit (Picked Unit --------
          • Custom script: call DestroyGroup(udg_Tempgroup[2]
      • Custom script: call DestroyGroup(udg_Tempgroup[1]
 

Rmx

Rmx

Level 19
Joined
Aug 27, 2007
Messages
1,164
Teach them if the spell is instant, then it should be MUI.

Also the Thunder clap .. special effect.. [ Good version and bad version ] ARE super BAD.

The [ also good version ] is the best, the thunder clap should be immediatly destroyed why that non sense wait ?
 

Rmx

Rmx

Level 19
Joined
Aug 27, 2007
Messages
1,164
well, if you want to have an ever lasting special effect, its good, and who said it had to be Thunder clap, it could be anything

The thunder clap have a DEATH animation. so if you destroy it immediatly the animation will still show.

These type of waits are usually done for Flame strike special effect, that needs the w8 to show up.

There is no lasting special effect if you destroy it Oo " are you okay "
 

Rmx

Rmx

Level 19
Joined
Aug 27, 2007
Messages
1,164
well, i know that most of the animations wont require a wait, but if we are using a blade for an instance, then we would need to store it and delete it when it gets deleted.

Let me quote myself.

hese type of waits are usually done for Flame strike special effect, that needs the w8 to show up or any other noce Death animation effect.

this what you are trying to explain :D
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Variable List:
Just get rid of it. Nobody reads through this kind of lists. Just tell them what pattern you follow ("Temp" + type of variable) and that's all. Or make a separate list of variables in each example you give. The naming also sucks IMO. TempUnit_Group? the hell is that underscore doing in there? If you're going to use underscores, use it to separate "Temp" from "UnitGroup"...

Use of array:
Why the hell would you use an array in here? There's a unit group variable for a reason? You pick every unit in the group, add it to a unit array and then loop twice through the array? That's some real non-performing shit you're doing there. How about you just pick every unit in the group, add the ability, wait 2 seconds, pick every unit again and remove the ability? It's way faster, it doesn't require obscure use of arrays and is shorter and more readable. And easier to make MPI.

Leaks:

1. The most known leaks are ofcourse
uh... a "location" or a "group" leaks. RemoveLocation() is a function, not a variable.
2. give me 1 good reason why the "Good version" is any better than the "Worse version"?
3. Your leak part is really badly covered. One of the frequently asked questions is how array leaks work and how to get "Integer A" or "Player number of triggering player" to work.

MPI:
For each (Integer A) from (Player number of (Owner of (Triggering unit))) to (Player number of (Owner of (Triggering unit))), do (Actions)
what the fuck is this? Right now I see "wrong way" and "even worse way".
 
Top