Tutorial The Complete Guide to JASS, vJASS, and cJASS

Nestharus

o-o
Reaction score
84
Note to reader
If there is a link in a chapter, like Comments or Variables or Functions, then you should click that link and read everything on that page. Those links are there for a reason. Each link contains an extremely good description to the concept =). Without reading what's on those links, you might get lost. The links are a part of this guide =P.

In Progress
Chapter 1- The Basics
The World Editor
The World Editor is a program used to create maps for Warcraft 3. The program has seven primary tools for map making:

1. The Object Editor (units, items, destructables, doodads, abilities, buffs/effects, upgrades)

2. The Sound Editor

3. The Campaign Editor

4. AI Editor

5. Object Manager

6. Import Manager

7. Terrain Editor

8. Trigger Editor

It also includes advanced tools for modifying gameplay constants and the interface under the advanced drop down menu.

The purpose of this guide is to only explain the Trigger Editor and the languages used for it: JASS, vJASS, and cJASS.
Installing the necessary Tools
First, let's install the necessary components for you to take full advantage of World Editor.

vJASS
vJASS installation should take place first.

Download and open up the attached zip file.
downloadjassnewgenpack.jpg


You should see a single folder in there. Click the folder once to select it and then rename it to jassnewgenpack. Click extract and put it into your Warcraft 3 directory.

Default Paths:
32 Bit- C:\Program Files\Warcraft III
64 Bit- C:\Program Files (x86)\Warcraft III
extractjassnewgen.jpg


Jass Helper (Required)
Download and open Jass Helper. The file is in .7z format.

jasshelperdowload.jpg


First click the jasshelper folder in the file.
openjasshelper.jpg

---------------------------------------------------------------------
extractingjasshelper.jpg


Jass Helper should be extracted to the Jass Helper Folder of your Warcraft 3 directory

Default Paths:
32 Bit- C:\Program Files\Warcraft III\jassnewgenpack\jasshelper
64 Bit- C:\Program Files (x86)\Warcraft III\jassnewgenpack\jasshelper

extractingjasshelper2.jpg


Now move the executable folder in jasshelper. First open up explorer by right clicking the start menu in the bottom left corner of your computer screen and then clicking explore.

explore.jpg


Navigate to your Warcraft 3 Jasshelper directory.

Default Paths:
32 Bit- C:\Program Files\Warcraft III\jassnewgenpack\jasshelper\executable
64 Bit- C:\Program Files (x86)\Warcraft III\jassnewgenpack\jasshelper\executable

Double click the executable folder to go inside. Hold CTRL + A to select all of its contents. CTRL + X.

cutjasshelper.jpg


Hit backspace. Hit CTRL + V. If it prompts you about move and replace, hit move and replace ^_^.

Congratulations, you have just installed vJASS and updated it to the latest version ^_^.

cJASS
cJASS Manual

Download the Installer
downloadcjass.jpg


Run it.
runcjass.jpg


Hit next, and then hit next again. You will see a path. Paste in your Warcraft 3 JassNewGen directory

Default Paths:
32 Bit- C:\Program Files\Warcraft III\jassnewgenpack
64 Bit- C:\Program Files (x86)\Warcraft III\jassnewgenpack

cjassdirectory.jpg


Then hit install.

cJASS includes an auto updater so you should never have to download it again. The JassNewGen Pack (vJASS) and JassHelper will have to be downloaded again on new versions. JassNewGen pack isn't always updated to the latest JassHelper, so that is why both should be downloaded. Always be sure to check for new versions of those.

Getting to NewGen World Editor
To enable vJASS and cJASS, you will have to use the NewGen World Editor. It can be found in your Wacraft 3 directory.

Navigate to your Warcraft 3 Jass NewGen directory and find an exe named NewGen WE (or similar). Right click it and click Create Short Cut.

newgenweshortcut.jpg


Hit CTRL + X and then hit WINDOWS KEY + D.
Ctl_wndws_alt.jpg


You should now be at your desktop. Hit CTRL + V and you should see the shortcut you made appear on the desktop.

You should now have all the tools you need to proceed.

Everything after this assumes that you have NewGen World Editor open and that you are working on a new map from topic to topic. There is also required code that will be shown after Chapter 2. Sometimes it will ask you to save your map so that you can open it later on.

To make a new map-
newmap.jpg

Then just hit ok
newmap2.jpg


To run the map-
First CTRL + S or hit the save icon
savemap.jpg


Then CTRL + F9 or hit the Test Map Icon
testmap.jpg
Chapter 2- Exploring the Trigger Editor
Description
The Trigger Editor is used to write script for maps. Most aspects of Map Creation take place in the Trigger Editor.

How To Get To It
There are two ways to open up the trigger editor. The first way is by hitting F4.

The second way is by clicking the Trigger Editor icon (which looks like an a).
triggereditoricon.jpg


Trigger Editor Overview
When initially entering the trigger editor, you will see this-
triggereditoroverview.jpg


The area on the left is where the code areas, or more commonly referred to as triggers, go.
codeareas.jpg


Melee Initialization would be a trigger. When clicking on a trigger, the code area on the right displays what's inside of the trigger.
codearea.jpg


This trigger is in what is called GUI Format. GUI stands for Graphical User Interface.

Also, if you look above the trigger, you will see a comment area.
commentarea.jpg

The comment area is limited in its capacity, but is great for quick notes. Do not use these areas for documentation.

The folder called Initialization is a category, which can be used to organize the code. Categories can be expanded and contracted by double clicking them.

Teaching Map.w3m would be the custom map script, which is really pointless to use and has a few bugs. It was originally there for plain JASS. Click Teaching Map.w3m (or whatever your map name is) to see what the custom code area looks like.
customcodearea.jpg


Right clicking on Teaching Map.w3c will allow you to create new categories.
Right clicking on a category will allow you to create new categories and triggers.
Right clicking on a trigger will allow you to create new categories, triggers, or trigger comments.

To delete triggers, trigger comments, and categories, simply select them and hit the delete key.

GUI Variables can be accessed by hitting CTRL + G. You can also access them by clicking the GUI Variables Icon.
guivariables.jpg


Trigger Comments
Trigger comments are normally used for writing documentation. I suggest you never use these and instead use what are called comments. Comments will be taught at a later point, but trigger comments are really only for Vanilla Warcraft 3 (the default Blizzard Wc3). The reason is that they will automatically make the map that it's inside of a TFT Map (The Frozen Throne Expansion Pack), which lowers its accessibility. There are still many ROC (Reign of Chaos, or regular Warcraft 3) users out there.

Try making a new trigger comment
triggercomment.jpg


Trigger comments are pretty much like notepad (start -> run -> notepad), except that you can't use the tab key in them.

GUI In A Nutshell
GUI is like going through a series of menus. It's time consuming, it's slower than plain JASS, and reading it can be a serious chore.

There are three parts of a Trigger.

Events- what makes the trigger run. An event might be something like a unit casts a spell.

Conditions- what must be true for the event to fire. Let's say the spell has to be Life Drain.

Actions- what is done when the trigger is fired if all the conditions are true. Let's say that a spell was cast and it was indeed Life Drain.

To add new events, conditions, or actions, right click the trigger, events, conditions, actions, or any item.

Right clicking trigger
newguig.jpg


Right clicking an item
newguiitem.jpg


To copy text like this-
Trigger:
  • Melee Initialization
    • Events
      • Map initialization
    • Conditions
    • Actions
      • Melee Game - Use melee time of day (for all players)
      • Melee Game - Limit Heroes to 1 per Hero-type (for all players)
      • Melee Game - Give trained Heroes a Scroll of Town Portal (for all players)
      • Melee Game - Set starting resources (for all players)
      • Melee Game - Remove creeps and critters from used start locations (for all players)
      • Melee Game - Create starting units (for all players)
      • Melee Game - Run melee AI scripts (for computer players)
      • Melee Game - Enforce victory/defeat conditions (for all players)


right click and hit copy as text.

Trigger Copy As Text- Copies entire trigger like above
Event Copy As Text- Copies all events
Condition Copy As Text- Copies all conditions
Action Copy As Text- Copies all actions
Item Copy As Text- Copies Item

*item copy as text output*
Trigger:
  • Melee Game - Remove creeps and critters from used start locations (for all players)


To create and view GUI variables, open the Variable List. Any variable made there will be accessible by GUI.

Converting a Trigger to JASS
To convert a trigger to JASS, click the trigger, click on edit, and then click Convert to Custom Text

converttojass.jpg


The Melee Map trigger should now look like this

convertedtojass.jpg


From this point onwards, images will only be used to show in-game results. Everything from here on will be JASS, vJASS, and cJASS.
Chapter 3+ Requires vJASS and cJASS
Required code-
JASS:
//paste this into a jass trigger
include "cj_types.j"  
include "cj_typesEx.j" 
include "cj_types_priv.j"  
include "cj_typesEx_priv.j"
include "cj_order.j"  
include "cj_antibj_base.j"
include "cj_print.j"

Chapter 3- Comments and Semicolons
Comments
Comments
In essence, comments are like little notes.

Single Line Comment- [ljass]//[/ljass]
Delimited Comment (multiple lines)- [ljass]/*code*/[/ljass]

Exercises
Paste the code into the map and then comment it out to get rid of the syntax error.

Problem 1
Comment me to get rid of the syntax error

Problem 2
I am
your
syntax error
yes, you will

not stop
me at all

Semicolons
Semicolons represent a new line in programming. You can either split up lines with an enter like this-


or with a semicolon
;

You may only have one semicolon after or in between code though (unless it is a comment). Semicolons really allow you to write a bundle of code all on the same line. They are really only useful for what are called variable declarations as you will see in the next chapter. Any other use of them only results in convoluted code.

As you begin programming, the use of semicolons will become more apparent. In just about all cases you do not need one.

Chapter 4- Variables and Code Blocks
What is a Variable?

The Pieces of a Variable
Each variable has two parts: a type and a name

The type describes what the variable contains. The name is the name of the variable, or how it is identified.

Let's say that you get a new dog. The name of your new dog is Shilo
pineforest2.jpg


Now let's say you also get a new desktop. Your desktop is a Gamer Xtreme XT
01_400.jpg


You can't describe your new dog as a desktop. A dog just isn't a desktop. You can't turn it on and play games or program or whatever else that that you do with a desktop.
You can't describe your new desktop as a dog. A desktop just isn't a dog. If you try to play fetch with it, things will probably go badly.

These are what are known as types. Shilo is a dog and Gamer Xtreme XT is a desktop. Shilo is the name of the dog and Gamer Xtreme XT is the name of the desktop.

Variable Type
dog -> Shilo
desktop -> Gamer Xtreme XT

This would be pretty accurate

pet -> dog -> Shilo
computer -> desktop -> Gamer Xtreme XT

This would also be accurate. A dog can be described as a pet and the dog's name can be Shilo. A desktop can be described as a computer and the desktop could be the Gamer Xtreme XT

Let's say you also got a laptop-
computer -> laptop -> Xplorer X8-8800
02_400.jpg


That's a pretty sweet laptop huh? The laptop can be described as a computer and that laptop could be an Xplorer X8-8800. Luck you.

So what if we had this?
computer -> Gamer Xtreme XT
computer -> Xplorer X8-8800

Well, can Gamer Xtreme XT be described as a computer? What about an Xplorer X8-8800?

A desktop is a type of computer and so is a laptop, so both could be described as a computer. The problem is that a computer could be described as either a desktop or a laptop.

If you were just given that information, how would you be able to tell if a Gamer Xtreme XT was a laptop or a desktop? You couldn't.

What this means is that while something described as laptop or a desktop can be described as a computer, the computer cannot be described as either a destop or a laptop because there's no way to tell what the computer is. It could be either or.

The World of JASS Variables
In JASS, there are two main types of variables. There are variables that store things directly: numbers and words, and there are variables that point to complicated things: a dog tag pointing to a dog.

The two main types of variables are called primitives and handles.

Primitives are so named because they hold very simple values like the word "dog" or the number 6. Handles are named because they handle and point to very complicated values, like an actual dog or a whole hospital.

Variable Names
Let's say you now have another dog and you decided to name it Shilo as well.
dog1 -> Shilo
dog2 -> Shilo

You call out Shilo but both of them come. Why? They both have the same name. Things can't have the same name, otherwise there's
no way to get something unique out of it.

If you were to have a friend named Shilo that you had named your dog after-
friend -> Shilo
dog -> Shilo

And you called out, "hey Shilo, get over here." They'd still both come. Even if the type is different, the names have to be unique.

Primitive Types
JASS:
integer //stores whole numbers
real //stores decimal numbers
string //stores characters
boolean //stores only true or false


Counterparts (these mean the same thing as the above, they are just written differently)
JASS:
int //integer
float //real
string //still string
bool //boolean


So you can do-
integer or int
real or float
string
boolean or bool

They will do the exact same thing.

Declaring A Variable
The word declare is just a fancy way of saying, "I'm writing this variable out for the first time." It's sort of like when I said you have a new dog.

To declare a variable, you just write it out:
[ljass]variable[/ljass]

But wait! Remember variables have two parts: a type and a name. This variable only has one of those two parts. To fix it, why not give it a name from one of the primitive types?

[ljass]int variable[/ljass]

Much better.

Because I'm just so creative with names
JASS:
float number
string hi
bool has


Variables of the same type can also be declared on the same line in a comma separated list-
[ljass]int x, y, z[/ljass]

This would be the same code as-
JASS:
int x
int y
int z


If you want different types, a semicolon is used to split it up into different lines
[ljass]int x, y, z; float h, n; string i[/ljass]
JASS:
int x
int y
int z
float h
float n
string i


When declaring a variable in the map plainly, it is what is known as a global variable. A global variable is a variable that exists for the entire game. When you think global, think of a term like global warming. Global Warming exists for the entire planet.

A global variable can be accessed from anywhere.

[ljass]int x //a global declaration[/ljass]

Code Blocks
A block of code is just a set of code that's put into a container. All blocks of code have a start and a finish. Traditionally, the start and finish for a block of code is blockName { } (curly brackets). This is true for all code blocks. All blocks of code in programming have to have a start and a finish.

All blocks of code can have unlimited lines-
JASS:
blockName
{






}


You can have as many blocks of code as you like-
JASS:
blockName {}

blockName {}

blockName
{

}

blockName {
}


The most common way of writing a code block is-
JASS:
blockName {
}


Generalized notes on a block of code are generally written on the second curly bracket with a single line comment.

JASS:
blockName {
} //notes on the block


With plain JASS, the block of code is the blockName endBlockName. This is true for all plain JASS code.
JASS:
blockName
endBlockName


With the plain JASS code block, notes are generally written above the block-
JASS:
//notes
blockName
endBlockName
The Globals Block (deprecated)
A globals block is just a block of code used to declare globals. This is no longer required, but you should know what it is so that you can recognize it when reading someone else's code.

The globals block name is globals-
JASS:
globals {
}


JASS:
globals
endglobals


A globals block in action:
JASS:
globals
    int i
endglobals


Only variables can go into global blocks, so this isn't valid-
JASS:
globals {
	globals {
	}
}
Naming Convention
Variables are named lowercase first with camelcasing-
helloHello
Chapter 5- Variable Operations
The Order of Operations
Recognize these: + - * /
Those are all operators.

Recognize this: ()
This is used for grouping

3 + 4 * 5

Following the order of operations:
4 * 5 = 20
20 + 3 = 23

If you did this-
(3 + 4) * 5

Following the order of operations:
3 + 4 = 7
7 * 5 = 35

An operator is just something that is used to manipulate something else.
Code:
Adding 4 to 5 will change 5 to 9
Subtracting 1 from 9 will change 9 to 8
Multiplying 8 by 5 will change 8 to 40
Dividing 40 by 8 will change 40 to 5

In each case, the value being changed was manipulated by the operator.

The = operator sets the thing on the left to the thing on the right. The = operator isn't like it is in mathematics. Remember, all operators manipulate or retrieve a value. = does both (gets value from right) (sets value on left to the rerieved value on right)

So the above examples would now be-
JASS:
5 = 4 + 5 //The value on the right is 9, 9 is set to the value on the left, so 5 is now 9
9 = 9 - 1 //The value on the right is 8, 8 is set to the value on the left, so 9 is now 8
8 = 8 * 5 //The value on the right is 40, 40 is set to the value on the left, so 8 is now 40
40 = 40 / 8 //The value on the right is 5, 5 is set to the value on the left, so 40 is now 5


But this still isn't ready. You can't set a literal value (40 opposed to x).

JASS:
x = 5 //x is now 5
x = x + 4 //(9) //5+4
x = x - 1 //(8) //9-1
x = x * 5 //(40) //8*5
x = x / 8 //(5) //40/8


And that would work. In plain JASS, the deprecated set keyword is used (makes it easier to see)
JASS:
set x = 5
set x = x + 4 //(9)
set x = x - 1 //(8)
set x = x * 5 //(40)
set x = x / 8 //(5)


Remember, the left side is always being set to the right side so the set keyword works well.

Operations of Types
Integers-
Integers can only be whole numbers-
JASS:
int x = 15 //remember, you can use either the int or integer keyword


Integers work with these operators with other integers (+, -, *, /)
An integer may not be set to a real (=)

Reals-
Reals can be whole numbers or fractional numbers-
JASS:
float x = 15 //remember, you can use either the float or real keyword
real y = 16.111


Reals work with these operators with other integers and reals (+, -, *, /, =)

Booleans-
Booleans can only be boolean values-
JASS:
boolean b = true
bool c = false //remember, you can use either the boolean or bool keyword


Booleans only work with one generic operator (=)

Strings-
Strings can only be string values. String values start and end with double quotes (" ") or (` `) (top left of your keyboard under escape)
JASS:
string s = "hello"
string cheese = `hello`


The " " is a standard string. The ` ` takes the literal text in the string and wraps " " around it. It pretty much always does the same thing as a string. The times when it does not do the same thing are when you wrap up definitions, which will be covered later.

Strings may be added to other strings and may be set to other strings (+, =)

Initialization
Initialization is the first time a variable gets a value.

[ljass]x = 0[/ljass]

Variables may be initialized in their declaration

[ljass]int x = 16[/ljass]

A variable that isn't initialized cannot be used.

JASS:
int x
int y = x


While that may be syntactically correct (no syntax error), it will result in an immediate termination of the code. The map won't crash, but nothing past the usage of the variable will occur.

JASS:
int x
x = x + 1


That would not work either. The reason is x still does not have a value.

JASS:
int x = 0
int x = x + 1


That would work.

Shortcut Operations
++ and --
++ stands for +1 and -- stands for -1

After
Whenever ++ or -- are used after the variable, their operations are done after where they are used.

JASS:
int x = 0
x++


x++ would translate into
[ljass]x = x + 1[/ljass]

So x would now equal one.

JASS:
int x = 0
x--


x-- would translate into
[ljass]x = x - 1[/ljass]

So x would now equal -1.

JASS:
int x = 16
int b = x--


Because -- is after the x, the operation is done after it is used.
b would be 16, x would be 15.

JASS:
int x = 16
int b = x
x = x - 1 //after the operation


JASS:
int x = 16
int b = x++


Because ++ is after the x, the operation is done after it is used.
b would be 16, x would be 17

JASS:
int x = 16
int b = x
x = x + 1 //after the operation
Before
Whenever ++ or -- are used before the variable, their operations are done before where they are used.

JASS:
int x = 0
++x


++x would translate into
[ljass]x = x + 1[/ljass]

So x would now equal one.

JASS:
int x = 0
--x


--x would translate into
[ljass]x = x - 1[/ljass]

So x would now equal -1.

JASS:
int x = 16
int b = --x


Because -- is before the x, the operation is done before it is used.
b would be 15, x would be 15.

JASS:
int x = 16
int b
x = x - 1 //before the operation
b = x


JASS:
int x = 16
int b = ++x


Because ++ is before the x, it is done before it is used.
b would be 17, x would be 17

JASS:
int x = 16
int b
x = x + 1 //before the operation
b = x
+=, -=, /=, *=
[ljass]x += 3[/ljass]
[ljass]x = x + 3[/ljass]

[ljass]x -= 3[/ljass]
[ljass]x = x - 3[/ljass]

[ljass]x /= 3[/ljass]
[ljass]x = x / 3[/ljass]

[ljass]x *= 3[/ljass]
[ljass]x = x * 3[/ljass]
Chapter 6- Functions
What is a Function?

Basic Overview of a Function
A function can be thought of like a procedure with a number of steps, like the steps you have to take for turning on a computer.

The procedure would be the task of turning on the computer

The steps would be-
Step 1- Hit computer power button
Step 2- Hit monitor power button

or

Turn On The Computer {
Step 1. Hit computer power button
Step 2. Hit monitor power button
}

A procedure can have any amount of steps, even 0.

You can input things into a procedure, like maybe a laptop instead.

laptop -> Turn On The Computer {
Step 1. Hit the laptop power button
Step 2. Hit the laptop monitor button (if it has a monitor button)
}

And the procedure can ouput a state. Turning on the computer would output the state computer is on

computer -> Turn On The Computer {
Step 1. Hit the laptop power button
Step 2. Hit the laptop monitor button (if it has a monitor button)
} -> Computer Is On

What about an add procudure, like in a calculator?

Only has one step and takes two values-
value1, value2 -> Add {
Step 1. value1+value2
} -> Sum

And returning a specific value?

value1, value2 -> Add {
Step 1. value1+value2 ->
} -> Sum

Creating Functions in JASS
When looking at a function, they look almost like variables, except that they have 4 parts.

Part 1: The return type (the type of the output)
Part 2: The name (the name of the function)

So far it's looking just like a variable-
[ljass]int MyFunction //this would return an integer[/ljass]

Part 3: Arguments () (the input)
[ljass]int MyFunction()[/ljass]

Part 4: Code Block {} (the steps)
[ljass]int MyFunction() {}[/ljass]

That would be a totally empty function that returned an integer. Code in the block is just plain code-
JASS:
int x = 15
int y = 16

int MyFunction() {
	x += y //x is now 31, 15+16
}


A function that returns something (the ->) always has to return that something. MyFunction would have to return an integer. If a function that returns a type does not return something, it causes a syntax error (if you try to save it, the trigger editor will complain).

To return a value, the return keyword is used.
JASS:
int MyFunction() {
	return 0
}


And now MyFunction returns 0 : o.

The last line of a function that returns something always has to be a return. When a return is used, it returns to whatever called it with a special package: the value!

Functions cannot go into functions, that makes no sense... could you put the procudure of Baking Cookies into the procedure of Turning on a Computer? No. Steps go in and procedures call other procedures and that is it.
JASS:
int MyFunction() {
	int MyOtherFunction() //what the hell?? Syntax Error!!
	{
		return 0
	}
	return 0
}


Functions can also be treated like variables in a sense (except that they have the () for parameters), so if you wanted to set a variable to this-
[ljass]x = MyFunction() //when setting variables to variables, do you use the type? No. Do you use the internal stuff? No[/ljass]

So, let's go over this real fast again-
[ljass]int myVar //will always return an integer when it is used. Doesn't take any arguments because it is a variable[/ljass]
[ljass]int MyFunc() //will always return an integer when it is used. Can take arguments because it is a function, so requires ()[/ljass]

Functions are defined after globals, so a global variable cannot be initialized to a function.

JASS:
int MyFunction() {return 0}
int x = MyFunction() //syntax error!!


Also, because MyFunction in this case returns an integer, it can only be set to integers and reals. Could you set a string variable to an integer variable? No.

Can functions be set to something? No. You can set a set of steps to something.

Finally, you don't even have to set a function to a variable to use it, you can just do this-
[ljass]MyFunction() //runs the function[/ljass]

Yea, it still returns a value, but the value isn't used or set to anything, which is totally legit.

Each parameter, like a variable, needs a name and a type. Just like procedures, they are separated by commas. The parameters themselves look like little variable declarations. Parameters cannot be initialized.

[ljass]int MyFunction(int x) {return 0} //this takes an integer now[/ljass]
[ljass]int MyFunction(int x = 0) {return 0} //Parameters cannot be initialized!! They are plugged in! Error[/ljass]

And multiple parameters
[ljass]int MyFunction(int x, int y) {return 0} //comma separated list[/ljass]

And different types

[ljass]int MyFunction(int x, bool c, string helloHello, real hi) {return 0} //total freedom to declare whatever you want[/ljass]

You always have to have the type for each argument-
[ljass]int MyFunction(int x, y, z) {return 0} //Error![/ljass]

The parameters of the function can be used inside of the function just like regular variables. They can be set, returned, and whatever.

JASS:
int MyFunc(int x) {
	x = x + 5
	return x + 5 //x is now x + 10, if you plugged in 5, 15 would be returned
}


To input values into a function, plug them into the arguments list (). When a parameter variable is operated on in a function and changed, the actual variable outside of the function is not changed.

JASS:
int MyFunc(int x) {
	x = x + 5
	return x + 5 //x is now x + 10. 9 was plugged in, so 19 would be returned
}
int MyFunc2() {
	int x = 9
	MyFunc(x) //x is still 9
	return 0
}


It would be changed in this case though, but only because it is set to the result

JASS:
int MyFunc(int x) {
	x = x + 5
	return x + 5
}
int MyFunc2() {
	int y = 9
	y = MyFunc(y) //they don't have to be the same names
	MyFunc(6) //anything can be plugged in, even regular values
	return 0
}


Multiple Types and multiple parameters?
JASS:
int z = 0

int MyFunc(int x, int y, int z, string h) {
	return x + y + z
}
int MyFunc2() {
	z = MyFunc(z, 5, 16, "") //set z to z + 5 + 16, or 21
	z = MyFunc(16, 9, 20, "") //set z to  16+9+20, or 45
	return 0
}


Notice that all parameters have to be passed in even if they are empty. String h wasn't used because typecasting hasn't been covered yet ^_^.

You can do multiple returns but you can only return one type and one value. If you were to do mutiple returns, you could, but only the very first return would go.

JASS:
int MyFunc() {
	return 0
	return 16
}


This would return 0 and not 16. The use will become apparent later on, but for now this feature is pretty useless.

If you want to make a function that returns nothing, that is totally possible with the void keyword-
JASS:
void MyFunc() {}


Functions that return nothing can't be set to a variable because there isn't a variable that stores nothing =P.

[ljass]integer x = MyFunc() //Syntax Error[/ljass]

Only functions that return something can be set to variables.

You can still use the return keyword in a function that doesn't return anything. How does that work? You return nothing of course
JASS:
void MyFunc()
{
	return
}


Also, the last line of a function that returns a value must always be a return.

JASS:
int MyFunc(int x, int y, int z)
{
	z = x + y + z
	return x + y + z
}


JASS:
int MyFunc(int x, int y, int z)
{
	x = y
	z = x
	return z //syntax error, no return on the last line
	z = 16
}


JASS:
int MyFunc(int x, int y, int z)
{
	x = y
	z = x
	return z //this is what is returned
	z = 16
	return z
}//this is ok because it has a return on the last line


There is another way to write functions: the JASS way-
JASS:
function Hello takes nothing returns nothing
endfunction


The returns is the type, the takes are the parameters, and instead of {}, a function and endfunction are used because the blockName is function. Hello is the name. Nothing keyword is the same as the void keyword.

JASS:
function Hello takes integer x, integer y returns integer
	return x+y
endfunction


Quite a mouthful, but shown so that you know what you are reading when reading most JASS code. As you can see, multiple parameters are still separated by commas, but there is no () to group them. Parameters can be used the same way.

Single values are pretty much the same way too.
JASS:
function Hello takes integer x returns integer
	return 0
endfunction


The { } can't be used with the JASS function declaration-
JASS:
function Hello takes nothing returns nothing
{
}//Syntax Error


You may not have strange hybrids like these-
JASS:
nothing function Hello takes integer x
{
}


or

JASS:
nothing function Hello takes ()
end


Functions may also be called with the deprecated call keyword-
[ljass]call MyFunc()[/ljass]

The exact same thing as-
[ljass]MyFunc()[/ljass]

A lot of JASS uses the call keyword.
Naming Convention
Functions start with an uppercase letter and are camelcase-

HelloHello
Chapter 7- Local Variables
A local variable is a variable that is declared inside of a function. They can be declared just like regular variables-

JASS:
void MyFunc()
{
	int y = 42
}


They can also be declared anywhere inside of the function

JASS:
void MyFunc()
{
	int z
	return
	int h
	h = h + 1
	int y
}


You could even have this-
JASS:
void MyFunc()
{
	int z = h //don't do this unless you have a really good reason ><
	int h
	int x, y, o; string i
}


The reason you don't want to set a variable to a variable that isn't defined yet is because it translates from
JASS:
int z = h
int h


to

JASS:
int z
int h
z = h


Meaning slower code and more lines over all. Nifty if you really must have it, but you shouldn't do it.

You can also do some wacky things with variable declarations.

JASS:
int MyFunc()
{
	return h
	int h
}


What happens is all the declarations are automatically placed at the top of the function in the order that they are declared. That code is really-

JASS:
int MyFunc()
{
	int h
	return h
}


Which makes more sense. The fact is, you shouldn't write something like the first example-
[ljass]return h; int h //remember ; is a new line[/ljass]

The reason is because it makes the code really confusing to read. When you saw that first example, the first thought that went into your mind was probably: wtf?

If you wrote code like that and someone else was to read it, the first thing that would pop into their mind would also be: wtf?

They would have to stop and think for a second and go: wtf?

After a minute or two of analyzing your code and thinking, they'd then go, oh, ok. This is a total waste of time on their part ><. You should only write code that can be scanned quickly and is easy to read. If someone else has to pause for a minute and go: wtf, then you did something wrong =P.

Doing something like this-
JASS:
int MyFunc()
{
	return h
        int h
}


Is not acceptable ><. Always declare all your variables at the top... that is good practice. Declaring this here and that there is not good practice and makes it that much longer for someone to understand your code. Good code is easy to read. Bad code is hard to read. Maintainability is the #1 key in coding.

Local variables may also be declared with the local keyword-
JASS:
void MyFunc()
{
	local int h
}
Chapter 8- Scope
Scope is an important concept in programming languages – one cannot read or write large programs without properly understanding the concept of scope. The scope of a variable in a program is the lines of code in the program where the variable can be accessed.

To put it more simply, a scope is like a category. Scopes don't return anything or take anything, they are just blocks of code that are placed into a category like putting files into a folder.

[ljass]scope Boo {}[/ljass]

JASS:
scope Boo
{
	void hi() {}
}


JASS:
scope Boo
{
	int x
	void oh() {}
	scope Rawr
	{
	}
}


Scopes may also be written with the customary endtype keyword (JASS)
JASS:
scope Boo
endscope


Scopes may also have what is called an [ljass]initializer[/ljass] . Initializers run a function when the map starts up. The function is not allowed to have any parameters and cannot return a value. An initializer requires the function.

JASS:
scope Hello initializer Hi
{
	void Hi()
	{
	}
}


That would call Hi at the start of the map.

Nested scopes, or scopes that are inside of other scopes, may not have initializers.
JASS:
scope Hello
{
    scope UhOh initializer Hi //this scope is in another scope, so it can&#039;t have an initializer!!
        void Hi()
	{
	}
    endscope
}


Scopes may also go into global blocks
JASS:
globals
    scope Hi
        integer x
    endscope
endglobals


The above would be the same thing as this-
JASS:
scope Hi
{
	int x
}


Convention
Scopes start with an uppercase letter and are camelcase.

HelloHello
Chapter 9- Natives
JASS Natives are like JASS functions except that they are written in C++, which is the programming language that JASS is built on. Natives are all premade and are included with Warcraft 3 and they may be used at any point in the map. They are defined before anything else.

Natives don't use the function keyword when being declared because they aren't functions, they're natives. The native keyword is used.
[ljass]native ClearMapMusic takes nothing returns nothing //natives are plain JASS, so C syntax, which is what you are used to, isn't used in their declaration[/ljass]

You may notice that this looks exactly like a regular function declaration except for two primary differences. The native keyword and no endnative. Natives are fully written in wc3, so they are always one liners. They have 0 JASS inside of them. Functions on the other hand are purely JASS.

Natives come from two wc3 jass files, one called common.j and the other called common.ai. The first is used for making maps and the latter is used for making ai. Things in common.j may not be accessed from ai things and stuff from common.ai may not be accessed from maps.

While you may not declare your own natives, you may declare ones that already exist and use them. In map making, all natives and what not in common.j are already and automatically declared for you, so the natives you'd want to declare are from common.ai.

Not all natives in common.ai work. Here's a list of all the working ones.
JASS:
native GetPlayerUnitTypeCount takes player p, integer unitid returns integer
native GetUnitGoldCost takes integer unitid returns integer
native GetUnitWoodCost takes integer unitid returns integer
native GetUnitBuildTime takes integer unitid returns integer
native CreepsOnMap takes nothing returns boolean
native UnitAlive takes unit id returns boolean


You may declare these in your map and then use them. Again, the C syntax way of declaration will not work with natives.

common.j natives and functions can be found in the Function List located in the trigger editor.
JASS:
function ClearMapMusicBJ takes nothing returns nothing
    call ClearMapMusic()
endfunction


This is a function from the list. As you can tell, it looks exactly like a normal function, and it calls the ClearMapMusic native. You should rarely use these functions as it will almost always be faster to inline it, or write out the function's contents in your own function-
[ljass]ClearMapMusic() //fast[/ljass]
[ljass]ClearMapMusicBJ() //slow and moronic[/ljass]

The function list also holds all of the common.j variables. There are checkboxes for filtering out functions and there are radio buttons for viewing variables or functions/natives.

The biggest window with the actual code in it shows the function/native. The small text box on the top right can be used for search for functions/natives/variables.
Chapter 10- Includes
Includes allows you to include external JASS files. There is one directory where the tool searches for included files: [JNGP path]\AdicHelper\lib. Another option is to provide an absolute path: "d:\..."

In other words, it looks inside of your JassNewGenPack directory inside of the AdicHelper folder inside of the lib folder or it looks in a path you designate.

To include a file, the include keyword is used followed by the follow the file (string format).

[ljass]include ""[/ljass]

There are 7 jass files that come with cJASS so far that you should always include in your maps.

JASS:
include &quot;cj_types.j&quot;
include &quot;cj_typesEx.j&quot;
include &quot;cj_print.j&quot;
include &quot;cj_types_priv.j&quot;  
include &quot;cj_typesEx_priv.j&quot;
include &quot;cj_order.j&quot;  
include &quot;cj_antibj_base.j&quot;


These will be covered later in the guide. For now, just know that they are all there.

A JASS File is just a text file with .j extension. They can be created in notepad or you can use WE to write out some text, cnp it into a text file, and then change the extension after saving it.

There are also very good JASS Editors out there. The most widely known one is JassCraft

Try out jasscraft and write out some plain jass to see what a jass file is like. To get an idea for how includes works, try including the file using the direct path method. To get the path of the file, right click it and click on properties and then cnp the path. Try using a variable you declared in the file or a function.
Chapter 11- printf
This displays text to all players in the game.
[ljass]printf("string")[/ljass]

JASS:
scope Hello initializer Hi
{
    void Hi()
    {
	printf(&quot;hello&quot;)
    }
}


Now try out some of the stuff you've been learning.

ex:
JASS:
scope Hello initializer Start
{
	string Hi(string a, string b)
	{
		return a+&quot; &quot;+b+&quot;!&quot;
	}

	void Start()
	{
		printf(Hi(&quot;Hello&quot;, &quot;World&quot;))
	}
}


This will display Hello World!
Chapter 12- null
The null keyword undefines a pointer. To undefine something is to make it equal to nothing. The variable remains initialized, but it has no value. Because it can only be used on pointers, only handles and strings qualify.

Strings are a primitive type? Not quite... they are pointers as well. In Warcraft 3, there is a huge string table in the background. As a new string is made, it is added to the table and all uses of that string point to the value in the table. Once a string value is added, it can never be removed from the table. In this way, new strings can be quite slow, but uses of already made strings are quite fast. Also, because strings are never removed, they take up memory, meaning each new string increases the amount of memory Warcraft 3 (your map) uses. Strings are extremely small, so you shouldn't worry about this.

JASS:
string myString = &quot;hi&quot;
myString = null


null is primarily used to clean up memory. When nothing points to a piece of memory, that memory is removed, meaning Warcraft 3's (your map's) memory usage goes down. When a piece of memory is no longer used, it is called a memory leak. So, in essence, handles can be cleaned up in memory, but not strings. This means that setting a string to null serves no purpose if you aren't planning to use the string again. Setting a handle to null is a requirement if you aren't planning to use that handle again.
Chapter 13- Arrays
Arrays are variables with multiple slots. To make a variable into an array, the array keyword is used inside of the declaration
[ljass]int x[][/ljass]

In plain JASS
[ljass]int array x[/ljass]
Notice array is the second keyword. Array is sort of like a subtype.

Arrays cannot be initialized to a value.
[ljass]integer x[] = 0 //syntax error![/ljass]

But all slots on all arrays are automatically initialized to a default value-
JASS:
integers: 0
reals: 0.0
booleans: false
all pointers: null //(a string null is &quot;&quot;, so you can do string s; printf(s+&quot;hi&quot;))


JASS:
int x[] //every element in the array is initialized to 0 because it is an array


Arrays require an index whenever they are used. The index is accessed using brackets [ ]. Arrays may contain indexes from 0 to 8191. Keep in mind that the 8191 and 0 indexex are buggy as they will not work when loading a saved game. It is safest to use 1 thru 8190. If you don't plan on saved games, then use 0 and 8191 to your heart's content. Keep in mind that the 8192 number comes from an array size of 8kb.

JASS:
void Ha()
{
    int x[]
    x = 0 //bad, will result in a syntax error
}


JASS:
void Ha()
{
    int x[]
    x[0] = 0 //good
    x[5000] = 50 //good
}


Exercises
Create a global integer array with a variable called x. Make a function that
sets index 0 to 50, index 50 to 25, index 25 to 75, and index 75 to 100. After
the variables are set, get to index 100 without using it and set it to 95. Be
sure to display the output to test.
Chapter 14- Handles
Handles are pointers to complicated data structures in the background, like units and items.

Pointer------Data
1 -------> Unit
2 -------> Unit
3 -------> Item

The most basic handle is the primitive handle type. The second most basic is the agent handle (not a primitive).

When a handle is defined, the type keyword is used followed by the handle's name. Keep in mind that all Warcraft 3 handles are already defined for you. You cannot define your own handles unless you actually write C++ code to handle them.

[ljass]type agent[/ljass]

There are many different types of handle variables. They extend off of each other like branches on a tree. The handle type can be thought of as the base of the base of a tree while everything else can be thought of as branches. The agent handle is like a really really big branch =P.

When a handle extends another handle, the extends keyword is used followed by the handle to be extended-

[ljass]type agent extends handle[/ljass]

In this case, agent extends handle.

An extending handle may always be stored into the handle being extended (agent goes into handle), but an extended handle may not go into the handle extending it (handle does not go into agent). This rule applies to every handle down the line-
JASS:
type agent extends handle
type widget extends agent
type unit extends widget


Unit goes into widget, agent, or handle.
Widget goes into agent of handle
Agent goes into handle

Handle cannot go into agent, widget, or unit
Agent cannot go into widget or unit
Widget cannot go into unit

[ljass]type widget extends agent[/ljass]
------------------------------------------------
[ljass]local widget w[/ljass]
[ljass]local agent a = w //widget goes into agent, good[/ljass]

[ljass]local agent a[/ljass]
[ljass]local widget w = a //agent goes into widget, not good[/ljass]

[ljass]type unit extends widget[/ljass]
------------------------------------------------
[ljass]local unit u[/ljass]
[ljass]local widget w = u //unit goes into widget, good[/ljass]

[ljass]local widget w[/ljass]
[ljass]local unit u = w //widget goes into unit, not good[/ljass]

Most handles within warcraft 3 that are used in map making extend off of the agent handle.

List of Handles
JASS:
type agent			    extends     handle  // all reference counted objects
type event              extends     agent  // a reference to an event registration
type player             extends     agent  // a single player reference
type widget             extends     agent  // an interactive game object with life
type unit               extends     widget  // a single unit reference
type destructable       extends     widget
type item               extends     widget
type ability            extends     agent
type buff               extends     ability
type force              extends     agent
type group              extends     agent
type trigger            extends     agent
type triggercondition   extends     agent
type triggeraction      extends     handle
type timer              extends     agent
type location           extends     agent
type region             extends     agent
type rect               extends     agent
type boolexpr           extends     agent
type sound              extends     agent
type conditionfunc      extends     boolexpr
type filterfunc         extends     boolexpr
type unitpool           extends     handle
type itempool           extends     handle
type race               extends     handle
type alliancetype       extends     handle
type racepreference     extends     handle
type gamestate          extends     handle
type igamestate         extends     gamestate
type fgamestate         extends     gamestate
type playerstate        extends     handle
type playerscore        extends     handle
type playergameresult   extends     handle
type unitstate          extends     handle
type aidifficulty       extends     handle
type eventid            extends     handle
type gameevent          extends     eventid
type playerevent        extends     eventid
type playerunitevent    extends     eventid
type unitevent          extends     eventid
type limitop            extends     eventid
type widgetevent        extends     eventid
type dialogevent        extends     eventid
type unittype           extends     handle
type gamespeed          extends     handle
type gamedifficulty     extends     handle
type gametype           extends     handle
type mapflag            extends     handle
type mapvisibility      extends     handle
type mapsetting         extends     handle
type mapdensity         extends     handle
type mapcontrol         extends     handle
type playerslotstate    extends     handle
type volumegroup        extends     handle
type camerafield        extends     handle
type camerasetup        extends     handle
type playercolor        extends     handle
type placement          extends     handle
type startlocprio       extends     handle
type raritycontrol      extends     handle
type blendmode          extends     handle
type texmapflags        extends     handle
type effect             extends     agent
type effecttype         extends     handle
type weathereffect      extends     handle
type terraindeformation extends     handle
type fogstate           extends     handle
type fogmodifier        extends     agent
type dialog             extends     agent
type button             extends     agent
type quest              extends     agent
type questitem          extends     agent
type defeatcondition    extends     agent
type timerdialog        extends     agent
type leaderboard        extends     agent
type multiboard         extends     agent
type multiboarditem     extends     agent
type trackable          extends     agent
type gamecache          extends     agent
type version            extends     handle
type itemtype           extends     handle
type texttag            extends     handle
type attacktype         extends     handle
type damagetype         extends     handle
type weapontype         extends     handle
type soundtype          extends     handle
type lightning          extends     handle
type pathingtype        extends     handle
type image              extends     handle
type ubersplat          extends     handle
type hashtable          extends     agent
Chapter 15- code variables
A code variable is a variable that can store a function. Code variables may only be global, and as they are global, they can not be initialized to functions as variables are made before functions. The reason code variables cannot be local is because they refer to the actual machine code in the background. Machine code cannot be dynamically generated. Code variables cannot be arrays.

The type of the code variable is code.

[ljass]code codeVar[/ljass]

To pass functions in as values, treat them like a variable. The type would be function and the name would be the name the function has.

[ljass]function Hello[/ljass]
[ljass]code c = function Hello[/ljass]
JASS:
code d
code h

void Epp(code c)
{
	h = c
}

void Ha() {}

void Ohh()
{
    d = function Eep
    Eep(function Ha) //passes a function that isn&#039;t defined for eep!
}


You cannot call code variables.
 

Nestharus

o-o
Reaction score
84
Chapter 16- Boolean Expressions
A boolean expression is any expression that returns a boolean (true/false).

1. Apples are the same things as oranges (false)
2. Some apples are red (true)

Both would be boolean expressions because they both returned a boolean value.

In programming, a very simple example of a boolean expression would be the true and false values. true returns true and false returns false, or
[ljass]true[/ljass]
[ljass]false[/ljass]

If Statement
An if statement checks to see if a boolean expression is true.

1. If apples are the same things as oranges, then I will grow oranges and apples
2. If some apples are red, then I will eat apples

In case number one, apples and oranges are not the same thing, so I would not grow oranges and apples
In case number two, some apples are red, so I would eat apples

An if statement in JASS works the same way. It uses the if keyword followed by the statement and then the normal code block { }.

JASS:
if statement
{
//do stuff
}


JASS:
void Hi()
{
	if true
	{
		printf(&quot;This Statement is Def True&quot;}
	}
}


"This Statement is Def True" is only printed when true. If you were to change it to this-

JASS:
void Hi()
{
	if false
	{
		printf(&quot;This Statement is Def True&quot;}
	}
}


It would not print.

Nice Trick
JASS:
void Hello()
{
    if false
    {
        printf(&quot;This is so true&quot;)
        return //terminate the function
    }
    printf(&quot;This is so false&quot;)
}


What happens is if the statement is true, then "This is so true" is displayed and the function returns (terminates). If it's not true, it continues on and "This is so false" is displayed.

Exercises
Create a function that checks a boolean. If the boolean is true, set the boolean to false.

Else
If apples are the same as oranges, then I will grow apples and oranges, otherwise I will grow beans.

The else statement is used to say, that isn't true, then I am going to do this instead.

If apples are the same as oranges, otherwise I will grow beans, then I will grow apples and oranges.

That makes no sense right? The else statement is always used at the end of an if statement.

If apples are the same as oranges, then I will grow apples and oranges, otherwise I will grow beans, otherwise I will bake pies.

That too doesn't really make any sense. You can only have one else statement.

The else keyword is used
JASS:
void Hello()
{
	bool run = true
	if run
	{
		printf(&quot;Running!&quot;)
	}
	else
	{
		printf(&quot;Not runing <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite3" alt=":(" title="Frown    :(" loading="lazy" data-shortname=":(" />&quot;)
	}
}

Else If
If apples are the same as oranges, then I will grow apples and oranges, otherwise if apples are the same as pears, then I will grow apples and pears, otherwise if some apples are red, I will just grow apples, otherwise I don't know what I'm going to do ><.

Let's break this down-

Code:
If apples are the same as oranges
	I will grow apples and oranges
otherwise if apples are the same as pears
	I will grow apples and pears
otherwise if some apples are red
	I will just grow apples
otherwise 
	I don't know what I'm going to do ><

In essence, an else if is an else statement with a boolean expression. If nothing before was true, then check this. The elseif keywords are used.

JASS:
void Hello()
{
	bool run = false
	if run
	{
		printf(&quot;run is true&quot;)
	}
	elseif true
	{
		printf(&quot;this is true&quot;)
	}
	elseif false
	{
		printf(&quot;how did I get here??&quot;)
	}
	else
	{
		printf(&quot;what the hell?? not true or false? Fun times&quot;)
	}
}

Boolean Expression Operators
==
Will check to see if two values are equal. All values must be the same type except for reals and integers.

[ljass]1 == 3 //will return false[/ljass]
JASS:
void Hello()
{
	int x = 1
	int y = 3
	if x == y
	{
		printf(&quot;x is equal to y!&quot;)
	}
	else
	{
		prinft(&quot;x isn&#039;t equal to y!&quot;)
	}
}


!=
Will check to see if the two values are not equal. All values must be the same type except for reals and integers.

[ljass]1 != 3 //will return true[/ljass]
JASS:
void Hello()
{
	int x = 1
	int y = 3
	if x != y
	{
		printf(&quot;x is not equal to y!&quot;)
		return
	}
	printf(&quot;x is equal to y!&quot;)
}


>
Will check to see if one value is greater than another value. This will only work on integers and reals.

[ljass]3 > 3 //will return false[/ljass]
JASS:
void Hello()
{
	int x = 3
	int y = 3
	if x &gt; y
	{
		printf(&quot;x is greater than y!&quot;)
		return
	}
	printf(&quot;x is less than y!&quot;)
}


<
Will check to see if one value is less than another value. This will only work on integers and reals.

[ljass]1 < 3 //will return true[/ljass]
JASS:
void Hello()
{
	int x = 1
	int y = 3
	if x &lt; y
	{
		printf(&quot;x is less than y!&quot;)
		return
	}
	printf(&quot;x is greater than y!&quot;)
}


>=
Will check to see if one value is greater than or equal to another value. This will only work on integers and reals.

[ljass]3 >= 3 //will return false[/ljass]
JASS:
void Hello()
{
	int x = 3
	int y = 3
	if x &gt;= y
	{
		printf(&quot;x is greater than or equal to y!&quot;)
		return
	}
	printf(&quot;x is less than y!&quot;)
}


<=
Will check to see if one value is less than or equal to another value. This will only work on integers and reals.

[ljass]4 <= 3 //will return false[/ljass]
JASS:
void Hello()
{
	int x = 4
	int y = 3
	if x &gt; y
	{
		printf(&quot;x is less than or equal to y!&quot;)
		return
	}
	printf(&quot;x is greater than y!&quot;)
}

Functions as Boolean Expressions
Remember functions can return booleans!

JASS:
bool greaterThan(int x, int y)
{
	return x &gt; y //a boolean expression that equates to a boolean, this will work
}

void woo()
{
	if greaterThan(3, 6)
	{
		printf(&quot;Looks like it is greater than&quot;)
	}
}


JASS:
bool notTrue()
{
	return false //returns false, so nothing would run
}

void woo()
{
	if notTrue()
	{
		printf(&quot;This is false?&quot;)
	}
}


JASS:
int equation(x, y)
{
	return 3*x+y
}

int equation2(x, y)
{
	return x*(y+3)+1
}

void woo()
{
	int x = 5
	int y = 1
	if equation(x, y) == equation2(x, y)
	{
		printf(&quot;This is True!&quot;)
	}
}

The Boolean Expression Handle
There is a handle that actually stores boolean expressions. Keep in mind that boolean expressions return booleans, so a boolean expression can't be plugged in plainly. It must be plugged into in a function format. Also, keep in mind that functions as a type are not boolean expressions.

The variable is of type boolexpr-
[ljass]boolexpr hi[/ljass]

Because boolexpr variables cannot take parameters, a function cannot take any parameters if it is to be stored in a boolean expression.

JASS:
bool MyBooleanExpression()
{
    return (1 &gt; 2)
    //this does not take a parameter and returns a boolean, so this can be stored into a boolean expression variable
}


JASS:
bool MyBooleanExpression(int i)
{
    return i &gt; 5
}

//this takes a parameter, so this could not be stored into a boolean expression variable

This returns a boolean because all boolean expressions must return a boolean. This function is still not enough though. It must be converted into a boolean expression using the Condition native.

[ljass]native Condition takes code func returns conditionfunc[/ljass]
JASS:
bool MyBooleanExpression()
{
	return true
}
void Woah()
{
	boolexpr hi = Condition(function MyBooleanExpression)
}


Boolean Expression Keywords
!
flips a boolean (true is false and false is true)

JASS:
if !14 &lt;= 6 {}

//1. 14 &lt;= 6 is false
//2. not false is true (flipped)

//3 this would be true


The ! keyword can be used infinite times, but it is kinda pointless
JASS:
!!true

//1 true is true
//2 not true is false
//3 not false is true

//4 this would be true


JASS:
!!!true

//1 true is true
//2 not true is false
//3 not false is true
//4 not true is false

//5 this would be false


Tips
JASS:
local boolean b = true
local boolean c = !b //c is now false
set b = !b //b is flipped, now false
set c = !b //c is now true
set b = !!b //false to true back to false, b is still false


The not keyword can also be used-
[ljass]bool b = not true[/ljass]

&&
The && keyword states that both this and that must be true

[ljass](1 < 3) && (2 < 3) //will return true[/ljass]
JASS:
void Hi()
{
	if 1 &lt; 3 &amp;&amp; 2 &lt; 3
	{
		printf(&quot;1 is less than 3 and 2 is less than 3!&quot;)
		return
	}
	printf(&quot;Either 1 isn&#039;t less than 3 or 2 isn&#039;t less than 3!&quot;)
}


The and keyword can also be used
[ljass]1 < 3 and 2 < 3[/ljass]
||
The || keyword states that either one can be true. The if statement returns true for the very first expression that is true.
[ljass](1 < 3) || (5 < 4) //will return true, only 1 < 3 is checked[/ljass]
[ljass](5 < 4) || (1 < 3) //still returns true, but both checked[/ljass]
JASS:
void Hi()
{
	if 1 &lt; 3 || 5 &lt; 4
	{
		printf(&quot;1 is less than 3 or 5 is greater than 4! Either could be true : D&quot;)
		return
	}
	printf(&quot;Both 1 is less than 3 and 5 is greater than 4 must be false for this to happen!&quot;)
}


|| also has precedence over && much like multiplication has precedence over adding in the order of operations-
JASS:
if false &amp;&amp; true || true {
    printf(&quot;hi&quot;)
}


The above would look like this with para-
JASS:
 if false &amp;&amp; (true || true) {
    printf(&quot;hi&quot;)
}


The or keyword can also be used
[ljass](1 < 3) or (5 < 4)[/ljass]

Grouping
The ( ) can be used for grouping in boolean expressions-
[ljass]if 1 < 3 && (!1 > 3 && 3 < 5) //will return true[/ljass]

1 < 3: true

Part 2 is true-
Code:
{
	1 > 3 is false, but flipped is true
	3 < 5 is true
}

Tips
Remember, boolean expressions always return booleans, so these key words can be used to set boolean variables!

JASS:
bool b = 1 &lt; 3
bool c = 1 &gt; 3 || ((5 &lt; 16) &amp;&amp; !false)
b = !b || (b &amp;&amp; b)

Exercises
Determine whether these will return true or false

1. [ljass](1 < 3) || ((5 < 9) && (16 > 32))[/ljass]
2. [ljass]!(true) || (!false && ((6 < 9) && !(9 < 6)))[/ljass]

Boolean Expression Native Conversions
[ljass]native Condition takes code func returns conditionfunc[/ljass]
[ljass]boolexpr myExpression = Condition(function myBoolFunc)[/ljass]

These weren't:
[ljass]native Or takes boolexpr operandA, boolexpr operandB returns boolexpr[/ljass]
[ljass]boolexpr myExpression = Or(Condition(function Expr1), Condition(function Expr2))[/ljass]

[ljass]native And takes boolexpr operandA, boolexpr operandB returns boolexpr[/ljass]
[ljass]boolexpr myExpression = And(Condition(function Expr1), boolExpr)[/ljass]
Chapter 18- Conversion Natives
[ljass]native I2S takes integer i returns string[/ljass]
Converts an integer into a string
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		int x = 9
		printf(I2S(x))
		printf(I2S(10))
	}
}
[ljass]native R2S takes real r returns string[/ljass]
Converts a real (float) into a string. Automatically rounds the float to 3 decimal places for the string.
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		float f = 19.111
		printf(R2S(f))
		printf(R2S(11.1119))
	}
}
[ljass]native R2SW takes real r, integer width, integer precision returns string[/ljass]
Converts a real (float) into a string.

width: how far to the right the message should be
precision: how many decimal places.

precision can remain accurate at up to 7 digits. At 8 digits, it starts to lose accuracy.
JASS:
1.234567
12.34567
123.4567
1234.567
12345.67
123456.7
1234567.

JASS:
scope Demo initializer Initialization {
	void Initialization() {
		float f = 1.234567
		printf(R2SW(f, 0, 6))
		printf(R2SW(765.4321, 100, 4))
	}
}
[ljass]native I2R takes integer i returns real[/ljass]
Converts an integer into a real
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		int x = 9
		float r = I2R(x)
		printf(R2S(r))
	}
}


If you want to convert a direct value and not a variable, then using a decimal place is faster and gets the same results.
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		printf(R2S(9.))
	}
}
[ljass]native R2I takes real r returns integer[/ljass]
Converts a real into an integer
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		float r = 10.11
		int x = R2I(r)
		printf(I2S(x))
	}
}


Can be used in rounding-
Round Down:
[ljass]R2I(value)[/ljass]

Round Up:
[ljass]R2I(value+1)[/ljass]

Round:
[ljass]R2I(value+.5)[/ljass]
[ljass]native S2I takes string s returns integer[/ljass]
Converts a string to an integer
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		string s = &quot;123&quot;
		int i = S2I(s)
		printf(I2S(i))
	}
}
[ljass]native S2R takes string s returns real[/ljass]
Converts a string to a real
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		string s = &quot;123.123&quot;
		float r = S2R(s)
		printf(R2S(r))
	}
}
[ljass]native StringHash takes string s returns integer[/ljass]
Hashes a string into a unique integer. The hash is mostly unique to the given string and is always the same value from game to game. Larger strings have a chance of having the same value as smaller strings as the hash changes the large string value into a small integer value. This should only be used on small strings.

To hash something means to convert it into a smaller usable number.
JASS:
scope Demo initializer Initialization {
	void Initialization() {
		int x = StringHash(&quot;boo!&quot;)
		printf(I2S(x))
	}
}
Chapter 18- Loops
Overview
If you were told to set indexes 0 through 100 in an array all to 50 in JASS, what would you do? You could do-
JASS:
x[0] = 50
x[1] = 50
x[2] = 50
x[3] = 50
//etc


Or you could use what is called a loop. A loop does an action over and over again.

Standard Loop
The most basic type of loop is your standard JASS loop. A JASS loop uses the loop keyword and a regular code block-
JASS:
loop
{
}


From here, the exitwhen keyword is used to determine when to exit out of the loop. The exitwhen uses a boolexpr (like an if statement) and checks to see when it is true. When the boolean expression returns true, the loop is exited.

JASS:
loop
{
	exitwhen true
}


This loop would exit immediately. A loop that never exits is called an infinite loop.

The most basic type of loop is called an iterative loop, or a loop with a counter that's set +1 every iteration.

JASS:
void MyFunc()
{
	int i = 0
	loop
	{
		//do stuff
		exitwhen ++i &gt; 100
	}
}


This would keep iterating and incrementing i until it was greater than 100. There is a mistake though ><. In every case you can, you should go downwards and not upwards (--i instead of ++i, or i-- instead of i++). Comparing to a smaller number over and over again is a lot faster than comparing to a big number (i == 0 is faster than i == 100). So let's rewrite this to do the exact same thing but be more efficient ^_^.

JASS:
void MyFunc()
{
	int i = 100
	loop
	{
		//do stuff
		exitwhen --i &lt; 0
	}
}


And now this would be much faster and it would iterate backwards.
whilenot
The whilenot loop keeps doing something while a boolean expression is not true and is sort of like declaring the exitwhen in the loop declaration itself. The whilenot keyword is used followed by a boolean expression-

JASS:
whilenot expression 
{
	//do stuff
}


Because the whilenot has an expression in its declaration, an exitwhen statement is not needed. Translated into plain JASS, it'd be the same code as this-

JASS:
loop 
{
	exitwhen expression
	//do stuff
}


The exitwhen is placed at the top of the block.

So, now for a basic iterative whilenot loop

JASS:
void MyFunc()
{
	int i = 101
	whilenot --i &lt; 0
	{
		//do stuff
	}
}


This would end up entering the loop one extra time, and on that extra time it would just exit. A whilenot loop would not be a good solution to the problem o-o.

If there was a chance that i may be 0, then it would be a good solution because it could mean we'd avoid entering a loop altogether.
JASS:
void MyFunc(int i)
{
	i++
	whilenot --i &lt; 0
	{
		//do stuff
	}
}
do
The do loop is the exact opposite of the whilenot loop. Instead of placing the exitwhen statement at the top of the block, it places it at the bottom. The do loop requires a whilenot at the end of the block.

JASS:
do 
{
	//stuff
} whilenot statement


And a quick demonstration-

JASS:
void MyFunc()
{
	int i = 100
	do
	{
		//do stuff
	} whilenot --i &lt; 0
}


This would be a fantastic solution to our problem
The Problem Addressed
JASS:
int array x
void MyFunc()
{
	int i = 100
	do {
		x<i> = 50
	} whilenot --i &lt; 0
}
</i>

Exercises
For this exercise, you will be using the GetRandomInt native (random number)-
[ljass]native GetRandomInt takes integer lowBound, integer highBound returns integer[/ljass]

Create a function that sets the values of an array to the index * 10 from 1 to a random int that is anywhere from 1 to 100. So x[10] would be 100 and x[11] would be 110. After the array is filled up, set the variable storing your maximum to 0 (a requirement). Display the results of the array from the start to the random max. The max is 0, so you will need to be creative in determining when the array ends!

Chapter 19- Libraries
Libraries are exactly like scopes except that when the map is saved, all code inside of libraries is placed at the very top of the map's script.

For example, if there was code (represented by C) and a library (represented by L) in this order-
C1
C2
L1
C3
L2
L3

It'd be put in this order (where C is put into a random order and L is put into a random order)
L1
L3
L2
C3
C1
C2

To create a library, you use the library keyword and your regular { }

JASS:
library Hi
{
}


Libraries can also use the initializer keyword just like a scope-

[ljass]library Hi initializer Woo {void Woo() {}}[/ljass]

But libraries can also be placed into a specific order using 3 keywords!
[ljass]requires[/ljass]
[ljass]needs[/ljass]
[ljass]uses[/ljass]

All three of these keywords do the exact same thing, so it doesn't matter what you use. Most JASS programmers use the uses keyword because it is the smallest.

The keyword is placed after the library name followed by the required library-

A library that uses Hi
JASS:
library Who uses Hi { }


When Who uses Hi, it is automatically ordered to this-
lib Hi
lib Who

If Hi were to uses libraries, all of the libraries it was using would be ordered above Hi-
UsedByHiLib
UsedByHiLib
UsedByHiLib
lib Hi
lib Who

A library with an initializer that uses another library
JASS:
library Boo initializer Haha uses Gaga
{
	void Hah() { }
}


And libraries using libraries below and above them-
JASS:
library Hello uses Boo {}
library Ah uses Hello {}
library Boo {}


Libraries that use libraries that use other libraries will automatically use all necessary libraries. In the example, Ah uses both Hello and Boo because Hello uses Boo.

Libraries cannot go inside of anything, but everything can go into them. This means you may not nest libraries, but you may put scopes into libraries.

JASS:
library Growl
{
    scope Who
    {
        scope La {}
    }
    scope Oo {}
}


And as normal, nested scopes cannot have initializers.
Chapter 20- Constants
Constants are values that cannot change. The value that they initially have is the value that they have forever. When defining a constant, the constant keyword is used. Constants must be initialized in their declaration. Constants may only be global variables. Arrays may not be constants as they cannot be initialized in their declaration. Code variables may not be constants. The reason is because code variables cannot be initialized to a value: global variables are declared before functions.

Constant naming convention states that variables must be written in all caps with _ as spaces between the words.

Variables
[ljass]constant int MY_NUMBER = 15[/ljass]

In JASS, constant variables are inlined (replaced in code with their value) if they hold a value. If they hold a function that returns a value, they are not inlined. The only reason to use a constant variable is for the inlining.

So the translation looks like this
JASS:
constant int MY_NUMBER = 15

void Hi()
{
	int x = MY_NUMBER
}


JASS:
void Hi()
{
	int x = 15 //inlined! ^^
}
Functions
Constant functions may not call non-constant functions and they may not manipulate any element that cannot be a constant (arrays and code).

Both regular functions and constant functions are inlined if they follow these rules:
* The function is a one-liner

* If the function is called by call the function's contents must begin with a variable assignment (=) or a function call or be a return of a single function.

* If the inlined function is an assigment, it should not assign one of its arguments (input).

* Every argument must be evaluated once and only once by the function, in the same order as they appear in the arguments list.

* If the function contains function calls, they should all be evaluated after the arguments UNLESS the function is marked as non-state changing, at the moment some very few native functions and also return bug exploiters are considered as non-state changing.

So really, constant functions are pretty deprecated.
JASS:
constant string HelloWorld(string hi)
{
    return hi+&quot; woo&quot;
}
Constants that aren't inlined are exactly the same speed as their non-constant cousins-
constant void HelloWorld
void HelloWorld

both same speed : |.
Chapter 21- Access Modifiers
Access modifiers modify how data is accessed and are a key to what is called encapsullation, or making it so data cannot be accessed from the outside.

Access modifiers may be applied to functions, all data (variables, structs (will be covered later), definitions (later), etc) and scopes. Each thing may have a maximum of one access modifier. Things with access modifiers must be inside of a scope, a library, or a structure. Things within the same scope/library (nested or actual) may call each other (following normal rules of functions) without worrying about access modifiers.

Public
The public access modifier will put the name of the scope (whatever the data or function or w/e is inside of) in front of the data/function or w/e in a ScopeName_Name format.

JASS:
library Boo
{
	public void Hi()
	{
	}
}


The name of Hi is now Boo_Hi when accessed from outside of Boo.

JASS:
library Boo
{
	public void Hi()
	{
	}
}
library Eep uses Boo
{
	public void Hi()
	{
		Boo_Hi()
	}
}


You may be thinking wth, but the public changes the name remember?
This would have 2 functions: Boo_Hi and Eep_Hi.

JASS:
library Boo
{
	scope Hi
	{
		public void DeeDee() {}
		public void DaDa() {DeeDee()} //calls DeeDee without an access modifier since they are in the same scope
		scope Oh
		{
			public void Ahhh() {DaDa()} //Calls DaDa without an access modifier since it is in a nested scope of DaDa
		}
	}
	public void Hoo() {}
}

library Cheese uses Boo
{
	void Oi()
	{
		Boo_Hi_DeeDee() //library Boo, scope Hi, function DeeDee
		Boo_Hoo() //library Boo, function Hoo
	}
}
Private
The private access modifier will make things inaccessible from outside of its immediate scope (scope/library/structure).
JASS:
library Boo
{
	private void DooDoo() {}
	scope Hi
	{
		private void LaLa() {}
		private void DeeDee() {
			LaLa() //will work as it is in the same scope
		}
		private scope Oo {
			private void Cry() {
				DeeDee() //will work as it is in a nested scope
			}
		}
	}
	private void MakeMeWork() {LaLa()} //Will Fail
}

library Cheese uses Boo
{
	void Oi() {
		call Boo_Hi_DeeDee() //Will Fail
		call Boo_DooDoo() //Will Fail
	}
}

Chapter 22- Triggers (first draft)
Overview of a Trigger
A trigger is a group of functions. When the trigger is run, all functions in the group get run.

A trigger can be run three different ways-
Event (returns nothing)
Execution (returns nothing)
Evaluation (returns boolean)

Triggers are stored in the trigger handle-
[ljass]trigger myTrigger[/ljass]

They are created with the [ljass]CreateTrigger[/ljass] native-
[ljass]trigger myTrigger = CreateTrigger()[/ljass]

And they are destroyed with the [ljass]DestroyTrigger[/ljass] native-
[ljass]native DestroyTrigger (trigger whichTrigger) returns nothing[/ljass]

Destroyed triggers can cause handle stack corruptions and desyncs if not used properly. For example, if you have events running on the trigger and you destroy it, those events may still fire. Also, actions may leak if they are not removed from a trigger. It's generally a good idea to disable a trigger before destroying it (only when there are events on it).

Disabled triggers will not fire with events, but will still fire normally from evaluations and executions. Triggers are automatically enabled when they are created.

Triggers are disabled with [ljass]DisableTrigger[/ljass]
[ljass]native DisableTrigger (trigger whichTrigger) returns nothing[/ljass]

They are enabled with [ljass]EnableTrigger[/ljass]
[ljass]native EnableTrigger (trigger whichTrigger) returns nothing[/ljass]

You can also check whether or not a trigger is enabled with [ljass]IsTriggerEnabled[/ljass]
[ljass]native IsTriggerEnabled (trigger whichTrigger) returns boolean[/ljass]

Many people also use a native called [ljass]TriggerSleepAction[/ljass]
[ljass]native TriggerSleepAction (real timeout) returns nothing[/ljass]

This puts the thread to sleep for an amount of seconds. This is inaccurate in online games and is not as accurate as things called timers, but it's very easy to use. Triggers can be set up to either sleep on sleeps or ignore them via [ljass]TriggerWaitOnSleeps[/ljass], which doesn't actually work.
[ljass]native TriggerWaitOnSleeps (trigger whichTrigger, boolean flag) returns nothing[/ljass]

You can also check whether or not a trigger is set up to wait on sleeps with [ljass]IsTriggerWaitOnSleeps[/ljass]
[ljass]native IsTriggerWaitOnSleeps (trigger whichTrigger) returns boolean[/ljass]

Using [ljass]IsTriggerWaitOnSleeps[/ljass] in an if statement can use the trigger flags to check whether you should do a [ljass]TriggerSleepAction[/ljass] or not.

You can forcefully allow [ljass]TriggerSleepAction[/ljass]s whether they are enabled for a trigger or not by using [ljass]TriggerExecuteWait[/ljass]
[ljass]native TriggerExecuteWait (trigger whichTrigger) returns nothing[/ljass]

But as flags are not working for triggers in JASS right now, it's kind of pointless ;).

Triggers can also wait for sounds with [ljass]TriggerWaitForSound[/ljass]
[ljass]native TriggerWaitForSound takes sound s, real offset returns nothing[/ljass]

Also, if you would like to get the trigger handle of the current running trigger from your code, you can use [ljass]GetTriggeringTrigger[/ljass]
[ljass]constant native GetTriggeringTrigger () returns trigger[/ljass]

This works in evaluations, executions, and events and can be used in any function that is part of the trigger. From here you can destroy it or do whatever you like with it.
Adding Functions as Actions to Triggers
When adding a function as an action to a trigger the [ljass]TriggerAddAction[/ljass] native is used-
[ljass]native TriggerAddAction (trigger whichTrigger, code actionFunc) returns triggeraction[/ljass]

The triggeraction handle returned can be used to remove an action from the trigger with [ljass]TriggerRemoveAction[/ljass]
[ljass]native TriggerRemoveAction (trigger whichTrigger, triggeraction whichAction) returns nothing[/ljass]

To remove all actions from a trigger, [ljass]TriggerClearActions[/ljass] is used
[ljass]native TriggerClearActions (trigger whichTrigger) returns nothing[/ljass]

Functions added as triggers are run whenever the trigger is executed using [ljass]TriggerExecute[/ljass]
[ljass]native TriggerExecute (trigger whichTrigger) returns nothing[/ljass]

Whenever a trigger is executed, the eval count and exec count go up by 1.
[ljass]constant native GetTriggerExecCount (trigger whichTrigger) returns integer[/ljass]
[ljass]constant native GetTriggerEvalCount (trigger whichTrigger) returns integer[/ljass]

The count can be reset via [ljass]ResetTrigger[/ljass]
[ljass]native ResetTrigger (trigger whichTrigger) returns nothing[/ljass]

The count also goes up whenever an event is fired for the trigger, however it works differently. EvalCount only goes up whenever a condition is run on the trigger. ExecCount only goes up when an action is run. If conditions return false, ExecCount count will not go up.

JASS:
scope Hi initializer Test {
    trigger myTrigger = CreateTrigger()

    void Tester2() {
        printf(&quot;hi&quot;)
    }

    void Tester3() {
        printf(&quot;hi again&quot;)
    }

    void Test() {
        TriggerAddAction(myTrigger, function Tester2)
        TriggerAddAction(myTrigger, function Tester3)
        TriggerAddAction(myTrigger, function Tester2)
        TriggerExecute(myTrigger) //displays hi, hi again, hi
    }
}


TriggerExecute is slower than TriggerEvaluate. Events work the same way in that actions on a trigger are slower than conditions on a trigger.
Adding Functions as Conditions to Triggers
When adding a function as a condition to a trigger, it must first be converted into a boolean expression with the [ljass]Condition[/ljass] native. From there, [ljass]TriggerAddCondition[/ljass] is used
[ljass]native TriggerAddCondition (trigger whichTrigger, boolexpr condition) returns triggercondition[/ljass]

The triggercondition handle that is returned can be used to remove a specific condition from the trigger via [ljass]TriggerRemoveCondition[/ljass]
[ljass]native TriggerRemoveCondition (trigger whichTrigger, triggercondition whichCondition) returns nothing[/ljass]

All trigger conditions can also be cleared with [ljass]TriggerClearConditions[/ljass]
[ljass]native TriggerClearConditions (trigger whichTrigger) returns nothing[/ljass]

Remember, Trigger Evaluations also return a boolean, so you can use them in if statements.
JASS:
if TriggerEvaluate(myTrigger) {
}


The conditions added to Trigger Evaluations work the same way as standard boolean expressions. Look under boolean expression conversion natives.

JASS:
scope Hi initializer Test {
    trigger myTrigger = CreateTrigger()
    trigger myTrigger2 = CreateTrigger()

    bool Tester2() {
        printf(I2S(GetTriggerEvalCount(GetTriggeringTrigger()))
        printf(I2S(GetTriggerExecCount(GetTriggeringTrigger()))
        printf(&quot;------------------------------------------------&quot;)
        return false
    }

    bool Tester3() {
        printf(I2S(GetTriggerEvalCount(GetTriggeringTrigger()))
        printf(I2S(GetTriggerExecCount(GetTriggeringTrigger()))
        printf(&quot;------------------------------------------------&quot;)
        return true
    }

    void Test() {
        TriggerAddCondition(myTrigger, Condition(function Tester2))
        TriggerAddCondition(myTrigger2, Condition(function Tester3))
        TriggerEvaluate(myTrigger) //1, 0 //condition returns false, so doesn&#039;t make it to exec
        TriggerEvaluate(myTrigger) //2, 0 //still 0
        TriggerEvaluate(myTrigger2) //1, 0, exec is incremented after evaluate, so this becomes 1 after the conditions are done
        TriggerEvaluate(myTrigger2) //2, 1 this is 1 atm, but becomes 2 after conditions fired
    }
}
Register Events to Triggers
Events are in-game events that the trigger responds to. For example, you might make a trigger fire when a unit dies on the map. When using triggers, you can get the triggering handles involved as well, for example, you can retrieve the unit that caused the trigger to fire.

Trigger events are stored in an event handle. Once an event is registered on a trigger, it can never be removed, meaning that you have to destroy the trigger if you want to get rid of the event. Events also take up memory.

When adding an event to a trigger, the event handle is always returned. The only use for this is that you could set up a trigger's events in global declaration
JASS:
trigger t = CreateTrigger()
event e = TriggerRegisterEvent(t, event) //not an actual native


The event id that fired the trigger can be retrieved with [ljass]GetTriggerEventId[/ljass]
[ljass]constant native GetTriggerEventId takes nothing returns eventid[/ljass]

From here, you can use the event id to determine what type of event the trigger fired off of. The event id that is returned is an actual event id, for example the event id for unit even death. The event id can be converted into an event and from there used to registered events of the same type of w/e. The problem is that the actual event type is unknown, so you'd really have to know what to convert the event to.

Conversion Methods Are
JASS:
constant native ConvertDialogEvent takes integer i returns dialogevent
constant native ConvertGameEvent takes integer i returns gameevent
constant native ConvertPlayerEvent takes integer i returns playerevent
constant native ConvertPlayerUnitEvent takes integer i returns playerunitevent
constant native ConvertUnitEvent takes integer i returns unitevent
constant native ConvertWidgetEvent takes integer i returns widgetevent


Useful Trigger Event utility http://www.thehelper.net/forums/showpost.php?p=1029299&postcount=1

Events will be covered with their handles (for example, unit events will be covered in the unit handle).
Chapter 23- Players (not done)
Overview of Players
Players are the computer players, playing players, non playing players, and neutral players within the game. There are 16 players total in the game from 0 through 15. Players are stored in the [ljass]player[/ljass] handle.

Players 0 through 11 are the players that can be in the game (computer or player). Players 12 through 15 are neutral players.

The max players are defined in [ljass]bj_MAX_PLAYERS[/ljass]
[ljass]constant integer bj_MAX_PLAYERS=12[/ljass]

This value refers to in-game players.

[ljass]bj_MAX_PLAYER_SLOTS[/ljass] refers to the slot count (16)
[ljass]constant integer bj_MAX_PLAYER_SLOTS=16[/ljass]

The extra players are-
[ljass]PLAYER_NEUTRAL_AGGRESSIVE[/ljass]
[ljass]constant integer PLAYER_NEUTRAL_AGGRESSIVE=12[/ljass]

[ljass]bj_PLAYER_NEUTRAL_VICTIM[/ljass]
[ljass]constant integer bj_PLAYER_NEUTRAL_VICTIM=13[/ljass]

[ljass]bj_PLAYER_NEUTRAL_EXTRA[/ljass]
[ljass]constant integer bj_PLAYER_NEUTRAL_EXTRA=14[/ljass]

[ljass]PLAYER_NEUTRAL_PASSIVE[/ljass]
[ljass]constant integer PLAYER_NEUTRAL_PASSIVE=15[/ljass]

Some of these players don't have all player features enabled. bj_PLAYER_NEUTRAL_EXTRA works well though if you ever need to use a hidden player.

Common Player Natives and Utilities
Integers can be converted into players using [ljass]Player[/ljass]
[ljass]constant native Player (integer number) returns player[/ljass]

You can also retrieve a local player on a computer with [ljass]GetLocalPlayer[/ljass]
[ljass]constant native GetLocalPlayer () returns player[/ljass]

A local player is the player of the machine code is currently running on. When code runs in a map, the player sends packets to the host to let them know code is running (unless it is the host) and then the host disperses packets to the rest of the players to tell them to run the code. Each piece of code is run on each machine (stays synchronized). When you get disconnected due to the map, this is usually to do what is called a desync, meaning that the state of one machine (code being run) is different from the state of another machine. There are some cases where you can keep code local to a given machine. Things that must stay synchronized are the handle table.

GetLocalPlayer() is typically used in an if statement-
[ljass]if currentPlayer == GetLocalPlayer()[/ljass]

What this means is that code within that if statement will only run on the local player's machine. Be careful with this as a lot of the time this type of code can lead to desyncs.

Common uses of GetLocalPlayer are for camera and text. For example, printf uses GetLocalPlayer() to display text on each local machine-
[ljass]DisplayTextToPlayer(GetLocalPlayer(), ...)[/ljass]

A very useful Player Utility can be found at http://www.thehelper.net/forums/showthread.php?t=135783

A host tracking utility can be found at http://www.thehelper.net/forums/showpost.php?p=1124575&postcount=41

Player Natives
[ljass]constant native GetPlayerState takes player whichPlayer, playerstate whichPlayerState returns integer[/ljass]

Returns a player state

Convert with [ljass]ConvertPlayerState[/ljass]
[ljass]constant native ConvertPlayerState takes integer i returns playerstate[/ljass]

Player States
[ljass]PLAYER_STATE_ALLIED_VICTORY[/jass]

[ljass]PLAYER_STATE_FOOD_CAP_CEILING[/jass]
The food cap for a given player, or limit

[ljass]PLAYER_STATE_GAME_RESULT[/jass]
The player game result, used with events




[ljass]PLAYER_STATE_GIVES_BOUNTY[/ljass]
does player give bounty?

[ljass]PLAYER_STATE_GOLD_GATHERED[/ljass]
how much gold has been gathered

[ljass]PLAYER_STATE_GOLD_UPKEEP_RATE[/ljass]
gold tax

[ljass]PLAYER_STATE_LUMBER_GATHERED[/ljass]
lumber gathered

[ljass]PLAYER_STATE_LUMBER_UPKEEP_RATE[/ljass]
lumber tax

[ljass]PLAYER_STATE_NO_CREEP_SLEEP[/ljass]
do creeps sleep for player?

[ljass]PLAYER_STATE_OBSERVER[/ljass]
is the player an observer?

[ljass]PLAYER_STATE_OBSERVER_ON_DEATH[/ljass]
does the player turn into an observer when that player loses?

[ljass]PLAYER_STATE_PLACED[/ljass]
has a player's start location been placed?

[ljass]PLAYER_STATE_RESOURCE_FOOD_CAP[/ljass]
player's food cap? or limit?

[ljass]PLAYER_STATE_RESOURCE_FOOD_USED[/ljass]
how much player has food used

[ljass]PLAYER_STATE_RESOURCE_GOLD[/ljass]
current player gold

[ljass]PLAYER_STATE_RESOURCE_HERO_TOKENS[/ljass]
how many heroes can that player currently get

[ljass]PLAYER_STATE_RESOURCE_LUMBER[/ljass]
current player lumber

[ljass]PLAYER_STATE_UNFOLLOWABLE[/ljass]
can player be followed? No clue on this one atm

Players and Triggers
Player events can be registered on triggers with [ljass]TriggerReigsterPlayerEvent[/ljass]
[ljass]native TriggerRegisterPlayerEvent (trigger whichTrigger, player whichPlayer, playerevent whichPlayerEvent) returns event[/ljass]

The player events are-
JASS:

Event response natives include-
[ljass]constant native GetEventPlayerState takes nothing returns playerstate[/ljass]
 

Nestharus

o-o
Reaction score
84
Chapter Exercise Solutions
Chapter 13
x[0] is equal to 50
x[x[0]] is equal to 25
x[x[x[0]]] is equal to 75
x[x[x[x[0]]]] is equal to 100
x[x[x[x[x[0]]]]] is equal to 95
Chapter 16
1. false
[ljass]1 < 3 //false[/ljass]
[ljass]||[/ljass]
(
[ljass]5 < 9 //true[/ljass]
&&
[ljass]16 > 32 //false[/ljass]
) true && false = false
false || false = false

2. true
[ljass]!true //false[/ljass]
||
(
[ljass]!false //true[/ljass]
&&
(
[ljass]6 < 9 //true[/ljass]
&&
[ljass]!9 < 6 //true[/ljass]
) true && true = true
) true && true = true
false || true = true
Chapter 17
JASS:
scope MyScope initializer MyFirstLoop
{
    void MyFirstLoop() {
        int array myArray; int max = GetRandomInt(1, 100), iterator = max
        do {
            myArray[iterator] = iterator * 10
        } whilenot --iterator == 0
        max = 0; iterator = 1
        do {
            printf(I2S(myArray[iterator]))
        } whilenot myArray[++iterator] == 0
    }
}
 

Nestharus

o-o
Reaction score
84
Stuff to Be Covered At Some Point (Advanced)
Primitive numbers maintain 32 bit accuracy outside of a local scope. Within local scopes, they retain absolute accuracy to any degree by combining variables. They may be incremented or decremented up to 32 bits at a time within the local scope. Once out of the scope, they will auto conform to 32 bits, so be sure to return them to 32 bit form to retain data. One way around this is to use multiple primitive values to store something and to merge them all into a single value when entering the function (like a stack).

set x = x * 1000000000
set x = x + 2147483647
set x = x - 2147483647
set x = x / 1000000000

Reals
[ljass]real x[/ljass]
Range- -2147483647 to 2147483647

These can be in all the forms of integers and have the same range, but they can have decimal places. They are dropped down to 4 decimal places when they pass in between functions. They round to 3 decimal places when they are displayed. Globals are dropped down to 4 decimal places. Locals maintain absolute accuracy in increments/decrements of 2147483647 or 32 bits, meaning you could have an n bit real number.

[ljass]real x = .999999999[/ljass] displays 1.000
[ljass]real x = .999499999[/ljass] displays 1.000 (the 9 rounds 4 up to 5, which rounds up)
[ljass]real x = .999399999[/ljass] displays .999



Keep in mind that the range isn't from those small numbers to those huge numbers, but it's an absolute range. For example, your range might be this if you wanted 9 decimal accuracy-
-2.147483647 to 2.147483647

Reals can only go out to 9 decimals as there is always a 0 in front.
0.999999999

Reals maintain absolute accuracy while inside of a given function.

Integers
Range- -2147483647 to 2147483647.
Decimal Form
regular numbers
JASS:

integer x = 1500 //will be 1500
integer x = R2I(1500.3218) //will hold 1500, not the decimals

Octal Form
If it starts with 0, it holds octal values (base 8).
JASS:

integer x = 07 //will hold 7
integer x = 012 //will hold 10


May not contain any digits above 7
JASS:

integer x = 08 //syntax error
integer x = 018 //syntax error
integer x = 081 //still a syntax error

Hexadecimal Form
If it starts with 0x, it holds hex values (base 16)
JASS:

integer x = 0x2 //will hold 2
integer x = 0xA //will hold 10
nteger x = 0x10 //will hold 16
integer x = 0xFF //will hold 255

Hex Characters
0 = 0
1 = 1
2 = 2
3 = 3
4 = 4
5 = 5
6 = 6
7 = 7
8 = 8
9 = 9
A = 10
B = 11
C = 12
D = 13
E = 14
F = 15

F+1 = 10 = 16
FF+1 = 100 = 256

Ascii Form
4 ascii characters surrounded by ' '. This form is used for ids in the object editor.
JASS:

integer x = &#039;hpea&#039;
integer x = &#039;Aloc&#039;
integer x = &#039;0&#039; //also works


You may use 1 ascii char or 4. You cannot use 2 or 3
[ljass]integer x = '00' //does not work[/ljass]

useful ascii character software

Simply download that software and run the exe. It'll allow you to type in various characters to see their ascii related values. Also, if you hit info you will be able to see the entire ascii chart wc3 uses. This tool will be an invaluable resource for you later on.

Reals
[ljass]real x[/ljass]
Range: same as integers except that the numbers presented can be any derivation with a decimal point-
2.147483647
214748.3647

Reals can go out to a maximum of 9 decimal places, but it is safest to only use them out to 5 decimal places. Advanced users may use them out to any amount of decimal places, but these techniques will be discussed at a later time.
JASS:

real x = 3.333 //good
real x = 3.33333 //bad


Decimal Form- May have decimals in the actual name
JASS:

real x = 16.2 //good
real x = 16 + .2 //good


Octal Form- May have decimal in the actual number
JASS:

real x = 060.11 //good&lt;
real x = 060 + .11 //good


Hexadecimal Form- May not have decimals in the actual number
JASS:

real x = 0x1 + .11 //good
real x = 0x1.11 //bad&lt;


Ascii Form- May not have decimals in the actual number
JASS:

real x = &#039;0&#039; + .1 //good
real x = &#039;0&#039;.1 //bad

Booleans
[ljass]boolean x[/ljass]

Booleans may only contain true or false.

JASS:

boolean x = true
boolean x = false

Strings
[ljass]string x[/ljass]
Max Size: 2048 bytes

[ljass]string x = "Hello World"<[/ljass]

Special String Symbols
" refers to the start and end of a string
\ an escape character
| a format character

\
The \ character in a string refers to the escape character. This is used to escape from the string and put in things like special string symbols.
  • \" will result in a " inside of the string
  • \\ will result in a \ in the string
  • \| will result in the | in the string
  • \n will result in a new line
  • \r will result in a carriage return

|
|c
Hexadecimal Color Chart

Used for coloring strings in JASS. Colors in JASS are put in with hexadecimal numbers. Hexadecimal color formatting follows the RGB format (red, green, blue). Each value (red, green, blue) has a min value of 0 and a max value of 255. Each value gets 2 digits in the hexadecimal number, so the hexadecimal number is 6 digits long.

000000 - possible hexadecimal color.

The above would result in this- 00|00|00 or
red = 0
green = 0
blue = 0

which would do white.

FFFFFF would be
red = FF which is 255
green = FF which is 255
blue = FF which is 255

this would be black

0F0F10 would be 0F|0F|10 or F, F, and 10.
red = F which is 15
green = F which is 15
blue = 10 which is 16

To use it-
|c000000

[ljass]string hello = "|cFF0000Hello World"[/ljass]
This would display Hello World

|r Will reset the color of the text back to the default color.

|n is the exact same as \n. This shouldn't be used.

Exercises
Display these different outputs

If you swear there is nothing there, try highlighting the text by holding down left click and moving your mouse over. It'll show you the text. Invisible text is white ^_^.
1.
Hello World

2.
Hello World

3.
Hello
World

4.
Hello

World
-------------------------------------------------------------
Template
JASS:

scope MyVariable initializer Ini
    globals
        string myMessage = &quot;&quot;
    endglobals
    
    function Ini takes nothing returns nothing
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, 500, myMessage)
    endfunction
endscope
 

Azlier

Old World Ghost
Reaction score
461
You know, stuff labeled "complete" should be "complete" :p.

I actually like that you included cJass in there, for some reason.

Would anyone mind if I started a group that hunted people who abuse spoiler tags?
 

Azlier

Old World Ghost
Reaction score
461
>Would you rather the page stretched on for 20 miles? =P

20 miles is not enough.
 

Sevion

The DIY Ninja
Reaction score
413
o_O' Not enough? I rather like the setup. It keeps the sections organized and doesn't have a zillion mile long page.
 

Nestharus

o-o
Reaction score
84
All spoiler tags and quote tags removed



Before with my formatting, this was perfectly readable.

Now it's impossible to read.
 

Nestharus

o-o
Reaction score
84
Changing the format to work with a combination of a wiki and here =).

As the helper forums is the primary resource people use, this will contain a table of contents with an overview of each chapter. It will help lower the thread size.

Each chapter will refer to a wiki page.
 

Van Damm

New Member
Reaction score
7
I have some additions as for installing of the tools:
  1. You messed up the NewGen install - the provided pictures are for JassHelper
  2. It's not a good idea to install Newgen directly to warcraft folder, you'd better install it to jassnewgenpack subfolder of the warcraft folder - in this case it will cause less mess
  3. cJass installation doesn't point to warcraft 3 folder by default - it points to C:\ or to the NewGen folder if you've already installed cJass. And you should point to NewGen folder, not a game folder.
 

Nestharus

o-o
Reaction score
84
You messed up the NewGen install - the provided pictures are for JassHelper

Totally true ^_^, didn't notice until you pointed it out ; o

It's not a good idea to install Newgen directly to warcraft folder, you'd better install it to jassnewgenpack subfolder of the warcraft folder - in this case it will cause less mess

I just did it the exact way I installed newGen. My installations has 0 problems too ^_^.

cJass installation doesn't point to warcraft 3 folder by default - it points to C:\ or to the NewGen folder if you've already installed cJass. And you should point to NewGen folder, not a game folder.

As the newgen folder is in the main wc3 directory in this case, pointing it there is right.

Also, I was doing the guide after I had already installed cJASS (a few days ago), so I was just saying input.

I'll be sure to fix the mistakes on installation tho ok : ).

Also, as for my idea about the wiki... everything that has a picture will be in post form and everything that doesn't have pictures will be in wiki form =).
 

Romek

Super Moderator
Reaction score
963
> Hit extract and paste in the path to your Warcraft III directory-
It's recommended that you do not extract the files into your default directory.

Also, at first glance; this doesn't appear to be particularly user friendly, and it doesn't seem to be well explained.
 

Nestharus

o-o
Reaction score
84
I'll change chapter 1 then to extract into its own stuff and what not, but I seriously have had 0 problems extracting it to wc3 directory, lol. It works fine ^_^.


And chapter 1 is now updated ^_^.
 

Azlier

Old World Ghost
Reaction score
461
I will kill you for creating an exercise in commenting! :mad:
 

Romek

Super Moderator
Reaction score
963
You seem to link to external sites which explain things an awful lot, instead of clearly explaining it yourself.

Also, the
Code:
 abuse is horrible. I hate having to scroll to the side constantly.

u -> You
def -> Definitely
etc.

The way you explain things really is terrible. It's more like a description of JASS, not an explanation of what things do in JASS.
 

Nestharus

o-o
Reaction score
84
You seem to link to external sites which explain things an awful lot, instead of clearly explaining it yourself.

This guide is being written for people from knowing 0 about programming to experienced programmers =).

The descriptions the links link to are pretty good descriptions in my opinion =). In times when I couldn't find a very good description, I try to describe it myself as best I can. Those descriptions I linked to are just.. wonderful ^_^. Also, I figured doing a quote and a link would be silly, so that's why I just did the link =).

Also, the
Code:
 abuse is horrible. I hate having to scroll to the side constantly.
[/quote]

Originally, these were sep'd into quote tags, but it was a little chaotic because you'd see big chunks and little lines and so on. I can put them back into quote. Next, I had them with 0 tags, and it was almost unreadable ><. The boxes are a huge help (if I could just a do a div tag with a border it'd be better /cry). The code tag is there to take advantage of the scrolling so that the blocks can easily be seen in one window or w/e ^_^.

It's really up to what people have an easier time with. I personally think that the scroll bar is a small price to pay for better readability, but I'll see what people think =).

[quote]
The way you explain things really is terrible. It's more like a description of JASS, not an explanation of what things do in JASS.
[/quote]

I actually explain what something is, like a description of JASS, and then I explain what it does. Most JASS guides just explain what something is ; \, meaning if you've never programmed in your life before you are pretty screwed ^_^. Actually, most courses and guides on every language is like that ><. I'm trying to break that trend : O.

Another thing I'm trying to break is starting with Hello World. I know guides and courses do that so people can see their output and see the results of what they are doing, but.... they have no idea what they are writing if that happens. Originally, this guide had code in it that you'd change stuff in, code I wrote for the user to mess around with so they could see their output. Now, I'm trying to stay away from that as well so that there is 0 magic code.

The guide is written in an order so that you can see your output as quickly as possible. I believe that going from variables to functions is actually possible as well because once you learn about variables you can technically learn about functions =). When you learn about scope and then calling functions and various natives, you then literally have enough knowledge to run your own code. In essence, this guide tries to get people writing their own code as quickly as possible. It may not be the most elegant of code and they may not know how to do everything yet, but they do know how to write their own code and use variables in it to display their results. They also learn a few natives and about the Function List in JassNewGen =).

Now, I am looking for tips, but I am looking for them in the form of questions from beginners reading this guide.
 
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top