[Log in / Register]
| News | Chat | Pastebin | Donations | Tutorials | Rules | Forums | Starcraft II |
| Maps | Skins | Icons | Models | Spells | Tools | Jass | Packs |
(Keeps Hive Alive)
Go Back   The Hive Workshop > Warcraft III Tutorials > JASS/AI Scripts Tutorials

JASS/AI Scripts Tutorials Contains tutorials regarding JASS scripting and the AI editor.
Read the Rules before posting.

Closed Thread
 
LinkBack (24) Thread Tools
Old 02-16-2007, 04:01 AM   24 links from elsewhere to this Post. Click to view. #1 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
Beginning JASS Tutorial Series

Contents
Overview
Introduction to JASS
Lesson 1: A Simple Function
Lesson 2: Variables
Lesson 3: Functions
Lesson 4: If/Then/Else and loop structures
Lesson 5: Triggers in JASS
Lesson 6: Memory Leaks
Lesson 7: Starting a Spell in JASS
Lesson 8: Continuing the Spell

This tutorial series is being made by:
-darkwulfv
-moyack
-wyrmlord

Overview

Have you wanted to learn JASS, but haven't really had enough tutorials to walk you through the basics and beyond? The aim of this series of tutorials is to provide many tutorials to help a new user start from scratch and after going through the tutorials (and practicing a bit after) to have a fairly good understanding of JASS. "Lessons" are meant to be fairly small, and have only a few topics explained at once in an attempt to not overwhelm people trying to learn.

If anything in any of the tutorials isn't explained clearly enough, please say so. We want the tutorials to be as informative as possible, and an unclear point could ruin an entire lesson.

This tutorial series was originally posted at wc3campaigns. We decided to submit the tutorial series here on The Hive because we just recently found out that Daelin was unable to continue his JASS Classroom, so we thought it would be a good idea to have somewhere else for people to look to learn more than what Daelin had taught.

If you are interested, the attachment at the bottom contains all the tutorials in either .doc or .html format.

Good luck, and happy JASSing!

Introduction to JASS

Tutorial 1: Welcome to the world of JASS.

What is JASS?
-JASS is the programming language used by the Wc3 engine.

What is GUI?
-GUI stands for Graphic User Interface. It is the default crap used by the trigger editor, made to make triggering easier. Unfortunatly, Blizzard made it harder. GUI is bad. It uses BJ's (which will be covered later on), inneficient code, and is overall messy and limiting.

Why use JASS? Can't I just use GUI?
-Sure, you can use GUI. It's not recomended anymore, but it's not dead or nothing.

Here are the Pros of JASS:
-Easier to write out
-Faster, more effecient, and no leaks (when done properly that is)
-Breaks many restraints created by GUI
-Doesn't use BJ's (which again is possible when done correctly)
-Neater, easier on the eyes for longer triggers
-Easier to copy/paste, and can be edited in a text editor or 3rd-party editors (such as JASScraft)
-Generally faster to do when you get the hang of it. Much less clicking around.

However, you must be careful with JASS. As great as it is, it must be used correctly. One single mis-type can screw up an entire trigger.

Will it be hard to use?
-If you've programmed anything before, JASS will be much easier. Even if you haven't, its still pretty easy. It'll take some getting used to, and can be frustrating. You may even feel like reverting back to GUI, but don't. This is worth it. Very complex things will obviously be harder, but we're gonna start you off easy.


How do I get JASS in my editor?
-Make a trigger and name it. Then go to Edit -> Convert to Custom Text. This cannot be reversed. Now edit away!

I'm having trouble typing JASS in the WE!
-Use a 3rd party program for some help. JASScraft and Silly JASS Utility are 2 I would suggest for anyone. Both can be found on the site. JASScraft is perfect for editing your new JASS, since it gives function names, native lists, and Take/Return values, plus a good syntax checker, and more. Definatly a must-have.

When I try to save or test, I get a ton of errors!!
-You probably have a typo or two somewhere, or an unexistant function. Check all your code and JASS is VERY case sensitive. If you type an "A" where an "a" should be, you will get an error. Also, check to make sure there aren't other errors. JASScraft can assist you here. That's why we recommend editing your codes in JASScraft. Much much much easier.

So what's the first step to learning JASS?
-Forget everything you know about GUI, except for globals. JASS is far different from GUI, and trying to compare them is a bad idea. However, a good first step is to make some triggers in GUI, then make them JASS. Throw them into JASScraft and have a ball converting BJ's to natives and cleaning leaks. You'll learn fast. It definatly helps the crossover from GUI to JASS.

Ok, I know the basics. Now what?
-If you want to learn more, read ahead to tutorial #2, by Wyrmlord. He'll teach you the basics of functions. Or, you can go ahead and take it alone from here. The choice is yours. Either way, I wish you good luck!

~Darkwulfv

Lesson 1: A Simple Function

Overview
In this lesson, I will go over with you a very simple function example. I will explain everything you will need to know about it and then at the end I will give you a 'challenge'. This challenge contains some content from the next section, so you will be able
to find out your answer in Lesson 2.

Now that you've looked at an introduction to the advantages of JASS, you're probably eager to get started with some code, right? Now, forget GUI (regular 'triggers'), JASS is different from GUI, so I'll be treating
it that way. Now, open up a text editor of some sort such as Notepad (windows) or some other program
depending on your operating system.

Now, I'm going to show some code. It will be a bit confusing at first, but I'll explain it throughout this lesson.
Jass:
function HelloWorld takes nothing returns nothing
    call BJDebugMsg("Hello World")
endfunction

Now, don't put this into the editor yet as it's not complete. First off, I'll start with the first line.
JASS, like many programming languages, is made up of a series of functions. I won't go into detail
on that yet, but for now just know that you are declaring/creating a function.

Now, the next line:
Jass:
call BJDebugMsg("Hello World")

This particular line 'calls' a function. Functions are like actions if you've used GUI before, they execute a command. This particular function puts the text "Hello World" (without the quotes) onto the screen.

Jass:
endfunction

Now, the final line is pretty simple, when you declare/create a function it needs to end somewhere, right? This line just tells you that the function ends here.

Now, I've gone over with you a very basic example of JASS, if you wish to test this function in the World Editor, simply:
-Create a new map
-Go to the trigger editor
-Click on the map icon at the top of the list of triggers
-Paste the code in the custom script section.

Now, create a trigger (sorry for the GUI reference), you can make the event whatever you want, I'd suggest that you make it go off whenever you press an arrow key. Now, for the action, just find custom script, and in the box
that it gives you, type:
Jass:
call HelloWorld()

And there you have it, you can now test the function in the game.

Notice how you call a function in that line. I'm now going to go over the function declarations a bit.
When you call a function, you type 'call <function_name>( <parameter1>, <parameter2>, <parameterN> )'
What this basically says is that you type call, while is followed by the name of the function and parenthesis '()'. If the function needs certain info (known as parameters) you put that specific info inside the parenthesis. Each set of 'info' is separated by a comma ','

This particular function only needed a string (message) to display on the screen. Here's some more info:

Jass:
function HelloWorld takes nothing returns nothing

When a function has the text 'takes nothing', that means you don't need anything in the parenthesis when calling it.
The return value is a value that the function returns. Like the CreateUnit function returns a unit. If you're confused, don't worry as this will be covered in a later lesson.

Now, feel free to mess around with the HelloWorld function, add more calls to the BJDebugMsg, show whatever text you want. Let me say that for now, the text should be inside quotation marks "like this"

Challenge #1: Modify the HelloWorld function to print out other info:

Here's an example:
Jass:
function HelloWorld takes nothing returns nothing
    call BJDebugMsg("Hi, my name is Bob.")
    call BJDebugMsg("I am 2 years old!")
    //And so on, by the way you can add comments to your code like this
    //Basically if you have '//' somewhere on a line, the rest of the line (after the '//') counts as a comment
endfunction

This may seem like a waste of time, but the more you use JASS the more familiar it will become.

Good Luck -wyrmlord

Lesson 2: Variables
By: Darkwulfv

What is a variable?
-A variable is sort of like a place holder for a handle or other object. There are 2 types of variables. Local and Global.

What is the difference between Local and Global variables?
-Local variables are variables only usable by the function they’re declared in. These are used for cleaning Memory Leaks (which will be explained later), neatening code, and making script Multi-instanceable.
-Globals are variables which can be accessed by any function, but can also be changed by any function. This can be bad for multi-instanceability (which will now be referred to as MUI), depending. MUI will be discussed later on.

How do I create a local variable?
-There are two ways to creating/setting a variable.
Jass:
 function variable_test takes nothing returns nothing
  local unit u = CreateUnit()
endfunction
This method creates and sets it in one line, at the beginning of the function.

Jass:
 function variable_test takes nothing returns nothing
  local unit u
    set u = CreateUnit(&#8230;..) //Creates a unit and sets the variable to it
endfunction
And this method creates a blank variable, to be set later on in the function.

Hey wait! I want the value to change, does that mean I need a new variable?
-No, not necessarily. All you need to do is put “set your_variable = newvalue
Here’s an example.

Jass:
function variable takes nothing returns nothing
local unit u = CreateUnit(&#8230;)
//Other actions
set u = other_unit //other_unit would be some other unit, don't use this example literally!
endfunction

Remember though, that old value isn’t set to that variable, so if you want 2 different units, use 2 different variables.


Ok, so I have my local variable. Now what?
-Now, use it! Here’s an example.

Jass:
function KillUnit takes unit u returns nothing
-If you notice, KillUnit needs a unit. Now, you can fill this with many things, like GetTriggerUnit(), GetSpellAbilityUnit(), or any function which returns a unit. However, a variable can be a unit, so you can put that there instead. Here’s a side-by-side comparison.

Jass:
function variable_testA takes nothing returns nothing
  local unit u = GetTriggerUnit()
    call KillUnit(u)
endfunction

function variable_testB takes nothing returns nothing
    call KillUnit(GetTriggerUnit())
endfunction
They both work, it's up to you to choose which way you prefer.

Naming variables
When naming variables, you can't just use any name. First off, the only characters you can use are any letter in the alphabet, any number, and the underscore character (_). The first letter in a variable name must be a letter, after that you can use numbers, letters, and underscores all you want. Let me make it clear that you can not use spaces in a variable name.


What about global variables?
-Global variables are created through the Variable Editor, inside the Trigger Editor. These variables can be used in any function, unlike locals. Example:

Jass:
 function A takes nothing returns nothing
  call KillUnit(udg_u)
endfunction

function B takes nothing returns nothing
    call KillUnit(udg_u)
endfunction
This is basically what it means. A variable starting with “udg_” usually means it is global. You can do this sort of thing with locals, but it isn't advised. If you need to refer to the same unit in a different function, there are methods of doing so which will be discussed later. The names of the variables you create are udg_variable_name. Each space in the variable name you enter in should be referred to with an underscore '_'

You mentioned Memory Leaks, what are those?
-Although these will be discussed in full later, it is good that you know now.
Edit by wyrmlord
Whenever a variable, handle, or string is created, the game must set aside space for it to use. To get rid of that space, there are various methods you can use depending on the object. For example, if you had a special effect, you could destroy it and free up any space it was using. Memory leaks occur when an object isn't able to be destroyed, and it will stay in memory until the end of the game. Another example: suppose I create another special effect, and no variable is set to it. The special effect will use up memory (even if it can't be seen), and since it's unable to be destroyed, it will continue to use memory until the end of the game. Local variables that aren't integers, reals, or boolean are like this too. The fix to them is simply setting them equal to null at the end of a function. Strings use up memory as well, but you can't do anything to stop them from doing so.


So how do I fix Memory Leaks?
Edit by wyrmlord
Memory leaks will be gone over in a later tutorial. If you're eager to learn about them, by all means skip to the lesson on memory leaks. However, I wouldn't suggest doing any major amounts of coding until you know more about them


I saw an option to make the variable an array. What’s that mean?
-An array is a variable with more than one option, per say. It’s like an index of that variable type, sort of like a library. To access the variables, you must set them to an index number, then retrieve them as such.
Example:
Jass:
 function variable_test takes nothing returns nothing
  local unit array u
set u[1] = GetTriggerUnit()
set u[2] = GetSpellTargetUnit()
    call KillUnit(u[1])
    call KillUnit(u[2])
set u[1] = null
set u[2] = null
endfunction
There is an easier way to assign index numbers and null them. It involves integers and loops, and will be shown during the discussion of loops.
Functions can also be fit into those brackets [] to set it to a number; any function that returns an integer or real should cover it.

Edit by wyrmlord
This is just to have multiple explanations of the same thing, for possibly confused readers. Arrays are basically a lot of variables squeezed into one. To be exact, 8192 variables. To declare an array in JASS, you would do something like this:
Jass:
local integer array int_array
The difference is really just adding the word "array" before the variable name. You are unable to set the array to a value on the same line that you create it, keep in mind. Now, you'll need to know how to access each of the 8192 parts of the array. You do that like a normal variable, only you have brackets after the variable with an integer between them, which would be a number from 0 to 8191. If that's a bit confusing, here's an example:
Jass:
local integer array myIntegers //declaring the integer array
set myIntegers[0] = 5 //Setting the 0th slot in the array to 5
set myIntegers[1] = myIntegers[0] + 2  //Setting the 1st slot in the array to the value in the 0th slot in the array + 2
set myIntegers[myIntegers[1]] = 2 //This is just showing that you can use a variable inside the brackets as well, it doesn't have to be an array though
I would not recommend using arrays for a purpose as small as this. An array contains 8192 values, no more and no less. For something like this it's like killing a fly with a bazooka. (In other words, don't use arrays unless they are actually needed)


There you have it! Variables in a nutshell. If you want to see a list of all the variables, open up either common.j in the Patch.mpq file. Or if you're not sure how to do that, get a tool like JassCraft, and on the right side of the screen when you open it up is a search box and a long list. On the bottom of that list is "show options". Click that, and then uncheck everything in the "search for" box except types. You can now click "hide options" and search through the types of variables.

Edit by wyrmlord

There are a few main variable types: integer, real, string, boolean, and handle. I'm sure you know what an integer is, it's a whole number (including negatives) such as: 1, 145, -37. A real is a number with decimal places such as: 3.14, -15.78, 11.1134. A string, as you might already know can be thought of as a message or text: "Hello", "This is a string". A boolean has two values: true or false. A handle, you could say, is a reference to an object such as a unit. You don't direct use the handle type usually, but you use types that extend the handle type. This basically means that they are a specific type of handle. A handle is pretty much anything that isn't an integer, real, string, boolean. Handles include: units, special effects, timers, groups, players, and so on.


CHALLENGE:
Can you fill in this code with the correct variables? (this does not involve arrays)
The “_”’s represent where something needs to be filled in.

Jass:
 function variable_challenge takes nothing returns nothing
  local ____ _ = GetTriggerUnit()
    call KillUnit(_)
set _ = ____
endfunction

Good luck, and happy JASSing!
~Darkwulfv

Lesson 3: Functions
Overview

In this lesson, I will be going over how to:
1.Create functions
2.Call functions
3.Anything else I can think of

Part 1: Creating a function

Now, you're probably wanting to know how to create functions, right? Well, to create functions, you first need to tell the program that you're creating a function, so you do that by delcaring a function. This is basically telling the program the function's name, what values it needs to get when called, and what it returns. Take a look at this function:

Jass:
function DisplayAMessage takes string message returns nothing
    call BJDebugMsg(message)
endfunction

Now, the word 'function' tells the program that you will be declaring a function. The next part of the function is the name of the function. You need to make sure your function has a unique name that no other function has, otherwise you'll get errors when saving a map. Next, you tell the program what the function 'takes' or needs pretty much. This function 'takes' a string, which is basically a message of some sort. After you put the type the function needs, you then have to put a name for it (so you can refer to it inside of your function). Lastly, you tell the program the type the function will return. You could make this a string, integer, real, and so on. However for this example, no value will be returned so we put 'nothing'.
After declaring a function, inside the function you need to put what the function does, otherwise it would be pretty useless. This function simply calls another function using the string value that is needed to call it. Lastly, you need to tell the program when the function ends, you do this by putting 'endfunction' at the end of the function.

Part 2: Calling functions

Now, that may not all make sense, so I'll now explain how you call functions, which should hopefully clear things up a bit. First off, you can call a function in a few different ways, but I'll start by the easiest way, which is using the word 'call'.

Jass:
call DisplayAMessage("hello")

This line would call the function I just showed you. When calling a function this way, you need to have the word 'call' followed by the function name which is then followed by parenthesis with the values the function takes inside of them. If a function takes multiple values, they are each separated by a comma ','. It works that same way when declaring functions too (whoops forgot to mention that earlier =P)
Now, I will go over what the return values in functions are. They're pretty simple really, though I don't want anyone to be confused about anything. When a function has a return value, you can set variables that are the same type as the return value to that function. Here's an example:

Jass:
local string player_name = GetPlayerName(Player(0))

Now, see that when you set a variable to the return value of a function, you don't need the word 'call'. Also, if you want to pass the return value of a function into another function call, you don't need to put the word 'call' either, as seen with the Player function that was the needed parameter in the GetPlayerName function.

If when and when not to use call are confusing you, let me just say you can only have 1 call in a line, and call can't be used if you have another word before that such as 'set' or you're declaring a local variable.

Also, and this is important when declaring a function, if the function declaration states that the function returns a value, somewhere in the function if must have a line that 'returns' the value, like so:

Jass:
function TestReturn takes nothing returns integer
    return 5
endfunction

When a function reaches the line with return on it, it returns the specified value and ends (no code below that line is looked at by Wc3)

There is one last thing you need to know when calling functions, you can only call a function that is above another, since that may not make complete sense, here's an example:

Jass:
function SomeFunction takes nothing returns nothing
endfunction

function SomeOtherFunction takes nothing returns nothing
endfunction

Now, this is only used as a visual example so I can more easily describe what I was saying. You can only call a function that is above the function you are currently in. So, 'SomeOtherFunction' would be able to call 'SomeFunction'. However, 'SomeFunction' wouldn't be able to call 'SomeOtherFunction'.

Challenge Time!

Now, I figure you're wondering why the challenges so far aren't very hard (I'm just assuming that), and that's because we haven't taught you enough for us to really stump you on something. I hope this challenge will make you think more than normal. The following code has a few errors in it, find each error in it. There are 5 errors in the following code, can you find them all?

Jass:
function Function2 takes nothing returns string
 local string message = SomeFunction("Hello World")
endfunction

function SomeFunction takes string returns nothing
 local string a message
    a message = 'Something is wrong'
    call DisplayTextToPlayer(Player(0), 0, 0, a message)
endfunction



Good Luck -wyrmlord

Lesson 4: if/then/else and loop structures
Tutorial No 4. if/then/else and loop structures. By Moyack.

These kind of structures are the most important in any programming language. In JASS, these structures are quite versatile and useful.

Let's see the first structure: IF/THEN/ELSE

To work with it, we can write it in this way.

if/then/else structure
Jass:
if <condition 1 function or variable> then
    <Condition 1 script>
elseif <condition 2 function or variable> then
    <Condition 2 script>
...
else
    <Else condition script>
endif

Now you understand why I said versatile :)

As you can see, the conditions must be a function which has to return a boolean variable type (true/false) or a boolean variable. Other interesting feature with the if/then/else structure in JASS, is that it can be used as a multiselection structure too, something very useful in many cases.

In order to ensure the understanding of this structure, This is a small example showing the IF/THEN/ELSE in action

IF/THEN/ELSE example
Jass:
function Set_Damage_To_Unit takes integer level returns real
    // this example will set the damage amount in a spell, according to a level
    // (unit level, ability level, etc)
    local real dam
    if level < 2 then
        set dam = 0
    elseif level == 1 then
        set dam = 50. 
        // probably you noticed the point after the number. this is used to indicate the number is a real one.
        // Is a good programming practice to do that in order to avoid annoying debugging mistakes.
    elseif level == 2 then
        set dam = 63.
    elseif level == 3 then
        set dam = 125.
    else
        set dam = 125. + 50. * (level - 1)
    return dam
endfunction

Here we are using a local variable which will have a value according to the input argument in the function, and then that variable will be returned by the function.

Important note
If any IF or ELSEIF clauses apply, then the ELSE clause will be avoided. This example function has a bug by purpose, in order to show an IF/THEN/ELSE characteristic. if level = 1, then the first clause will be executed (set dam = 0). Then the second condition will be executed and will be true too (elseif level == 1), then it will execute the second clause (set dam = 50). With that we can see that the IFTHENELSE structure can be used to make data filtering, for instance.


Another Important Note
The '=' character is used when setting a value, the '==' operator is used when comparing values. In other words, don't do: if x = 5 then... because Wc3 can't read your mind as to what you want it to really do. This line is saying to the computer "if (set x = 5) then..." and I don't think that makes much sense, how about you?


Now let's see the LOOP structure.

Loops in programming are used to make a set of instructions to be executed several times, loops can be classified by finite and infinite. The finite loops are which have a defined a fixed number of repetitive executions, controlled by an exit control. The Infinite loops in the other hand, will execute the script contained in it indefinitely.

The loop structure is as following:

Jass:
loop
    //Here you can put code too :)
    exitwhen <condition function or variable>
    //your iterative script
endloop

This structure is quite flexible as you can see, because you can put the exitwhen condition in ANY place inside the loop. Let's see an example.

Loop Example
Jass:
function Heal_Unit_Group takes group g returns nothing
    // this example will heal all units in a unit group.
    local unit u // a local unit variable
    loop
        set u = FirstOfGroup(g) //Selects the first unit in the group.
        exitwhen u == null // the loop will finish when the group will be empty,
        // in tother words, when the FirstOfGroup() function returns null
        call SetUnitState(u, UNIT_STATE_LIFE, GetUnitState(u, UNIT_STATE_MAX_LIFE))
        //sets the life of the selected unit at its maximum.
        call GroupRemoveUnit(g, u) // removes the unit from the group
    endloop
    call DestroyGroup(g) // to avoid group leaks, we must destroy the group variable.
endfunction

The usage of FirstOfGroup and group functions inside a loop is very common in AOE spells, with them we can do several things to a unit group.


Some tips with loops


Sometimes, we want to use the loops as a way to do a mass effect spell. If you want to add special effects inside a loop, there is a big chance the code will lag, in order to avoid that, you should use a TriggerSleepAction() function, which will give to the WC3 engine a small break to process other tasks.

You can create an infinite and unstoppable loop using only the loop and endloop instructions without an exitwhen command.


Exercise.


Create a function which displays all the numbers which can divide perfectly a given number. The function should be in that way:
Jass:
function DivideNumbers takes integer n returns nothing
    // your code here
endfunction

For exaple, if we make
Jass:
DivideNumbers(12)
we should see on the game screen something like this:

1, 2, 3, 4, 6, 12


Good luck :

Lesson 5: Triggers in JASS
Overview

Now, if all you've ever known is GUI, you're used to everything being a trigger. GUI is just a system of triggers, but you're probably wondering what exactly is a trigger. This lesson will cover triggers in JASS and how to use them. First, I'd like to tell you exactly what a trigger is.

What is a Trigger?

I'm sure that you know what a trigger is if you've used GUI before, but GUI hides some important things from you. A trigger is really just another object, like a unit or a special effect. What makes triggers useful is that they are able to detect events. Without triggers, you couldn't do too much in the editor without a lot of trouble. Now, here's an example of making a trigger in JASS:\

Jass:
function InitTrig_JASSTrigger takes nothing returns nothing
 local trigger myTrigger = CreateTrigger()
    call TriggerRegisterPlayerEvent(myTrigger, Player(0), EVENT_PLAYER_END_CINEMATIC)
    call TriggerAddAction(myTrigger, function MyFunction)
 set myTrigger = null
endfunction

Now, this may be a bit overwhelming at first, but I'll explain everything well enough so that you should understand. First off, you're going to create a local variable for the trigger. This is fine if you don't need other triggers to run TriggerExecute on this trigger (TriggerExecute is a function that runs a trigger). Now, whenever you create a new trigger, you must use the function CreateTrigger(). It's like using the CreateUnit function to create a unit. Now that you have created a trigger, you'll need to add some things to it so it would be useful. The next line adds an event to the trigger. TriggerRegisterPlayerEvent takes 3 values, which are the trigger you want to add the event to, the player this event applies to, and the specific event. There are many other TriggerRegister... functions which you can experiment with later, but for now this will be fine. The next line adds an action which is basically telling the trigger to call that function when the event happens. Now, I didn't show you the function MyFunction, but you need to know that it must take nothing and return nothing. Now, the final line sets the local variable to null, which is necessary for local variables which are handles so that memory leaks can be prevented. If you don't know what a memory leak is, don't worry about it, they will be covered in a later tutorial.

Okay, now you're probably still using that GUI trigger to run your test functions in the custom script. This JASS trigger does pretty much the exact same thing as the GUI trigger, so you can replace it. Just create a new trigger, and then go to Edit -> Convert to Custom Text. What you will see is something similar to the function shown above, only it's setting a global variable automatically generated by the editor to a trigger and just adding an action. Delete all the code and make a new function that has the name: InitTrig_[insert trigger name here]. So if the name of your trigger was JASSTrigger, you would have your function be: function InitTrig_JASSTrigger takes nothing returns nothing It's important that you name it this way so that it gets called while the map is loading.

Now, if you've noticed, I've left out how to add a condition, oh my! Well, I'll show you how adding conditions work in triggers. Don't convert a GUI trigger to JASS to see how to do conditions, that way is inefficient. There's more code than you really need to use. Let me show you an example:

Jass:
function Condition_Function takes nothing returns boolean
 return GetTriggerPlayer() == Player(0)
endfunction

function InitTrig_JASSTrigger takes nothing returns nothing
 local trigger myTrigger = CreateTrigger()
    call TriggerRegisterPlayerEvent(myTrigger, Player(0), EVENT_PLAYER_END_CINEMATIC)
    call TriggerAddCondition(myTrigger, Condition(function Condition_Function))
    call TriggerAddAction(myTrigger, function MyFunction)
 set myTrigger = null
endfunction

This might look confusing, it might not. Either way I'm going to review what everything does. First off, I'll review how to set up a function so it can be used as a condition in a trigger. First off, you can name the function whatever you want, but it has to take nothing and return boolean. A boolean value, as you should know, is true/false. This function returns GetTriggerPlayer() == Player(0). You might look at that and be clueless, others might understand it already. The first part gets the player who triggered the event (the player pressing escape). And finally, the == Player(0) part checks if the player is Player(0) (Player 1 (Red)). Since this is a boolean statement, meaning it is either true or false, it can be used as a return value.

Finally, we have the added line in the InitTrig_JASSTrigger function. The function TriggerAddCondition takes a trigger and a boolexpr (boolean expression) . You don't need to know what a boolexpr is yet, all you need to know is that you put Condition(function [insert trigger name here]) and it returns a boolexpr which is used for conditions in triggers.

Challenge

This challenge will require a bit of researching JASS functions, so I recommend you get a tool such as JassCraft. Well, I'll give you three possible challenges. The first challenge will to be to create a trigger in JASS that will run a function that you create (any). After you've messed with that a bit, open up JassCraft or a similar program where you can search JASS functions. You're next challenge will be to create a trigger that will go off whenever you type in "-run" or whatever kind of text message in-game. I'll give you some help in telling you that the function you're looking for to add the event is TriggerRegisterPlayerChatEvent, however it's up to you to figure out how to use it. If you've solved that challenge, then make a trigger that goes off when the message a player types contains the character "-" or whatever letter you choose. In the actions, you will then display the value the message the player typed in. Hints for this challenge are keep using the same function to add the event, only you need to change a value or two. And I suppose it would also be helpful to tell you that the GetEventPlayerChatString can be used to get the string that the player types in.

Good Luck -wyrmlord

Lesson 6: Memory Leaks
Lesson 6: Memory Leaks
By: Darkwulfv, edited by wyrmlord

What is a memory leak?
-A memory leak is caused by bad coding, where a handle that was stored in memory is lost from refrence. Basically, it’s something that got placed in wc3’s memory usage and never got removed, and is unable to be removed.

What does a memory leak do?
-A memory leak adds a little tiny bit of memory usage to Wc3 when it’s running. If enough memory leaks, your map is going to cause some serious lag.

What causes memory leaks?
-When a handle is created, it's stored it in Wc3’s memory. If it is not destroyed or removed when you are done with it, then it stays there, taking up memory.

Well how am I supposed to fix them?
-Well, there are a few ways to do so, depending.

Method #1:
=============================
Jass:
function MemoryLeak takes nothing returns nothing
  call AddSpecialEffect(&#8230;) //Creates a special effect
endfunction
=============================
The native AddSpecialEffect(…) creates an effect. If you do not destroy this effect with the proper function, it will stay embedded in the memory, and thus take up memory. Now, one leak is terribly insignificant. But if your map made a lot of leaks very often, you would notice a big change.

Here’s a way to fix that leak:

Jass:
 function MemoryLeak takes nothing returns nothing
 local effect my_effect = AddSpecialEffect(...) //Create a special effect
   call DestroyEffect(my_effect) //Destroys the effect, removing it from memory
 set my_effect = null //You have to null local handles at the end of a function, or they leak too
endfunction

//Alternatively, this can be used

function MemoryLeak2 takes nothing
   call DestroyEffect(AddSpecialEffect(...))
   //Adds a special effect and destroys it all at once. This will still show the animation once for most (not necessarily all) effects, and doesn't require the use of a variable
   //However, if you want to see the entire animation, you should wait for the duration of the effect's 'stand' animation
endfunction

This method goes for anytime you are using a handle(any variable that isn’t a real, integer, boolean, boolexpr, code, or string)
However, the destroying/removing function changes for each type of handle. A list of variable types and how to remove them will be given later for you to refer to.

NOTE: When destroying/removing an object, you are removing/destroying a specific object and not the variable itself. The variable just points to the location in memory where the object is stored.


NOTE: A leak can be defined as an object that is created, not removed, unable to be removed during the game (assuming not removing it is undesired). If it’s only used once (like dummy units, rects, groups, etc.) then remove it. If not, you should leave it. (Like for spells, don’t remove the caster!)
NOTE: All non-handle variables except strings do not leak. String leaks cannot be fixed, but you usually don't need to worry about them.

So memory leaks only apply when you create things?
-WRONG!
A memory leak not only happens when you create things. It also happens when you make a handle-variable, set it to a value, and don’t null it.
Example:
Jass:
function MemoryLeak takes nothing returns nothing
  local unit u
    //actions
endfunction
This example wouldn't leak, as the handle variable wasn't set to a value. However, if it had been set to a value, like:
Jass:
local unit u = GetTriggerUnit()
It would leak. To fix this, set your variable to null. (Reals, integers, and booleans cannot be nulled, and don't need to be as the memory they use is automatically removed)
To null a variable, simply put

set yourvariable = null

You don't need to set a variable to null after removing each object. You only need to null it once; this is usually done at the end of a function.
Jass:
 function MemoryLeak takes nothing returns nothing
 local group g = CreateGroup()

//Some code

 set g = null
endfunction

NOTE: To satisfy those wanting to know why handle variables leak (not referring to the object, I'm referring to the variable). When you set a handle equal to a value, the handle points to where that value is stored in memory. It will remain pointing to where that value is stored unless it is set to null (meaning 0, not pointing to a specific place in memory.)

What about globals?
-Since these are always in the memory to begin with, and are always available, they don't count as leaks (and don't need to be nulled).

So uh… What do I do about non-handle variables?
-They don’t leak though, so worry not.

Conclusion:
-Always clean leaks. If you don’t, and there’s enough leaks, you will notice the effects.

Challenge!
-Clean this function of all memory leaks:

Jass:
function ChallengeTrigger takes nothing returns nothing
  local unit u = GetTriggerUnit() //This unit is in the game, it needs to be kept (hint)
  local effect SFX = AddSpecialEffect(&#8230;)
  local group g = CreateGroup()
  local unit u2  //this is going to be a dummy unit and should be removed (hint)
  local real r = 4
    //actions
    //(hint) only one of these variables isn’t nulled.
endfunction

Good luck!
Attached Files
File Type: zip JASS Tutorials.zip (31.8 KB, 487 views)
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.

Last edited by wyrmlord; 10-05-2007 at 01:54 AM.
wyrmlord is offline  
Old 02-17-2007, 04:58 PM   #2 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
Update

Lesson 7: Starting a Spell in JASS
Overview

Welcome to the next lesson. The basics have pretty much been covered, and now you'll probably want to use JASS to create spells or something. In this lesson, we'll go through the process of making a spell similar to the Omnislash spell found in DotA. (I've never actually seen the spell, but I know somewhat of how it works) This will show you some basic things used in JASS and room will be left for you to be able to modify the spell later on.

Starting Off

Before making a spell, you'll have to consider how it will work, what is happening step by step. First off, we need the trigger to go off when a unit casts a certain spell, right? And then we can begin thinking of the actions. In the spell I'm thinking off, the hero moves around in an area hitting a certain amount of units, but never the same unit twice. If you're looking at the spell being cast in-game, it might seem confusing, it might not. You have to break things down little by little. Here's some code for now that will start us off and I'll add to it as the lesson progresses:

Jass:
function Slash_Condition takes nothing returns boolean

    return GetSpellAbilityId() == 'A000' //Compares the ability id of the ability being cast to the ability id of our Slash spell.

endfunction

function Slash_Actions takes nothing returns nothing
endfunction

function InitTrig_Slash takes nothing returns nothing
 set gg_trg_Slash = CreateTrigger() //Set the global variable that is created for our trigger to a new trigger

    call TriggerRegisterAnyUnitEventBJ(gg_trg_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT) //This BJ function registers an event for whenever a unit starts the effect
                                                                                     //of an ability for our trigger

    call TriggerAddCondition(gg_trg_Slash, Condition(function Slash_Condition))
    call TriggerAddAction(gg_trg_Slash, function Slash_Actions)
endfunction

So far all we have is the basic trigger set up that will go off whenever the right ability is cast. You need to make sure you've created an ability (preferably based off channel with the values set correctly, if you need to know more about channel, please ask). Now we will create the actual effects of the spell. Now you'll need to think "what happens in the spell". Here's what happens: the hero is moved around within a certain area, he will only be moved to enemies, for each unit he is moved to, he will deal damage, and at the end he will return to the spot that he started at. The first thing to do now is to create a local variable to everything we'll need to keep track of. Here's what I thought of: a unit variable for the hero, a location for where the hero starts at, a group to hold all the enemies the hero will hit, and another unit variable to temporarily hold picked units in. You might not get the point of the last variable, but I'll show you how it's used soon. Here's what we should have now:

Jass:
function Slash_Actions takes nothing returns nothing

 local unit caster                       //Will hold our caster
 local location start_position        //Holds the starting position of the hero
 local group enemies                  //Will hold the unit group of enemies our hero will hit
 local unit temp                        //Used for when going through the group (explained later)

endfunction

Now, if you've used GUI before, you'll probably be wanting to do something like "Pick Every Unit in (group) and do actions", but there's a problem with that. In order to use that function (it's know as ForGroup in JASS), you'll need a separate function that you'll be unable to pass any values to. Now you could use global variables to transfer information, but then the spell wouldn't be able to be used by more than 1 unit at a time. You could possibly think of other ways around this, but they'd take more time than it would be worth. I'll give you a hint on how I do it, I use a loop. "Loop?" you might be thinking, "how can I use a loop?" because if you've used GUI before, the loops would run for a fixed length (for integer # through #, do actions), unlike in JASS where a loop will only end when a certain condition is met. And that condition will be that all enemies in the enemy group have been hit. Here's some more code to hopefully explain a little bit more of what I mean:

Jass:
function Slash_Actions takes nothing returns nothing

 local unit caster = GetSpellAbilityUnit()          //Create a local variable and set it to the unit that's casting the spell
 local location start_position = GetUnitLoc(caster) //Create the local and set it to the caster's position
 local group enemies = CreateGroup()                //When you create a group in JASS, it's like a trigger. First you need it empty, and then you add stuff to it
 local unit temp                                    //Used when looping through the group
 local integer count = 5                            //This will be the maximum amount of enemies that can be hit

    call GroupEnumUnitsInRangeOfLoc(enemies, start_position, 500.0, null)

// GroupEnumUnitsInRangeOfLoc takes a group, a location, a radius, and a boolexpr (a condition, kind of) and then gets units within that radius and adds them to our group

    loop
        set temp = FirstOfGroup(enemies)    //FirstOfGroup returns a unit from a group in no particular order that I know of
        exitwhen temp == null or count == 0

                                            //The loop will stop when temp is null (meaning that there are no more units left in the group) or when we've hit 5 enemies

        call GroupRemoveUnit(enemies, temp) //Removes the unit from the group so that it can't be picked again
    endloop

                                            //Cleaning up memory leaks will be put here

endfunction

In this section of code, we've set up some more basic parts to our code. We've initialized the variables and then filled the group with units within 500 range of the caster. Next, we start a loop and for each cycle in the loop, the temporary unit variable will be set to a unit from the group. Then we'll tell the loop to exit when the group has no units left in it or the caster has hit 5 enemies (count would be decreased for each enemy hit). At the end of each loop, the unit being used will be removed from the group so that it can't be picked again (and so prevents an infinite loop as well). Then we end the code executed by the loop and end the function.
The next step will now be to add in what the function will do for each unit picked. The first thing that you will have to notice is that the GroupEnumUnitsInRangeOfLoc grouped all units in 500 range of the hero's location, including allies and the hero. That means we'll have to add a simple condition to check whether or not the unit is an ally before performing additional actions. After that's done, what next? The unit will have to move to each enemy hit and damage them, right? Don't forget setting the count variable to count – 1 as well, or more enemies could be hit than desired. Before going on to the next bit of code, declare another location variable to hold the picked enemy's position, I'll go by the name of temp_loc. Here's what we'll have next for the loop:

Jass:
loop
    set temp = FirstOfGroup(enemies)
    exitwhen temp == null or count == 0
    
    if IsUnitEnemy(temp, GetOwningPlayer(caster)) then //If the enemy unit is an enemy of the owner of the caster

        set temp_loc = GetUnitLoc(temp)                //Set a temporary location variable to the enemy position
        
        call SetUnitPositionLoc(caster, temp_loc)      //Move our unit instantly to the enemy's location

        call UnitDamageTarget(caster, temp, 50, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)

                                                       //The caster will instantly damage the enemy for 50 damage with an attack type of chaos
                                                       //You can ignore the damage type, and the last parameter (weapontype) is just for sound, but we will
                                                       //have none for right now

        set count = count - 1                          //A unit has been hit, so now the units left to hit is reduced by 1

    endif

    call GroupRemoveUnit(enemies, temp)
endloop

Okay, this loop will now allow our unit to move to every unit within range and damage them. You might think we're done, right? Our hero will move to each unit in range and damage them, but you now have to ask yourself if we're missing anything. Are we?

Challenge

I bet you've already guessed the challenge, finish the spell! Don't worry about special effects (unless you want to), you just need to finish up on the basics that will happen and clean memory leaks. In the next lesson, the spell will be finished up and enhanced with special effects and more! Don't hesitate to post code on the forums if you're having trouble.

Good Luck! -wyrmlord

Lesson 8: Continuing the Spell

Overview

First off, I'd like to say sorry for taking so long, but here's finally the next tutorial in the series. In this tutorial, we'll continue off the spell from last time. Just to refresh your minds (in case you haven't looked at these tutorials in awhile like me) we were working on a slash spell where the hero would blink throughout an area and damage enemy units. He would hit up to a specified number of units, or until he had hit every nearby unit. Now to add the finishing touches, first we will rid the spell of memory leaks and add some special effects to make the spell more appealing. After that, we will work on ways to improve the spell further. To improve the spell further, we will look into timers and gamecache usage. However, this lesson will only cover the effects portion as I think you've waited long enough with no response from me and I also want to prevent the lesson from being too large.

Starting Off

Make sure you have the spell being worked on from last time. I'll post the code so you can take a look at it if you've misplaced the code from last time:

Jass:
function Slash_Condition takes nothing returns boolean
    return GetSpellAbilityId() == 'A000' 
endfunction

function Slash_Actions takes nothing returns nothing
 local unit caster = GetSpellAbilityUnit()
 local location start_position = GetUnitLoc(caster)
 local group enemies = CreateGroup()
 local unit temp
 local integer count = 5
    call GroupEnumUnitsInRangeOfLoc(enemies, start_position, 500.0, null)
    loop
        set temp = FirstOfGroup(enemies)
        exitwhen temp == null or count == 0
        if IsUnitEnemy(temp, GetOwningPlayer(caster)) then 
            set temp_loc = GetUnitLoc(temp)
            call SetUnitPositionLoc(caster, temp_loc)
            call UnitDamageTarget(caster, temp, 50, true, false, ATTACK_TYPE_CHAOS, DAMAGE_TYPE_NORMAL, null)
            set count = count - 1
        endif
        call GroupRemoveUnit(enemies, temp)
    endloop
endfunction
function InitTrig_Slash takes nothing returns nothing
 set gg_trg_Slash = CreateTrigger() 
    call TriggerRegisterAnyUnitEventBJ(gg_trg_Slash, EVENT_PLAYER_UNIT_SPELL_EFFECT)
    call TriggerAddCondition(gg_trg_Slash, Condition(function Slash_Condition))
    call TriggerAddAction(gg_trg_Slash, function Slash_Actions)
endfunction


I haven't commented the code because there's nothing new, and you should already know what it all does from last time. When making a spell, I always like to first get it working and then fine-tune it afterwards. It should already be working, but it still has errors in it because of memory leaks. I expected you to be able to fix these up yourself, but if you need to double-check your answers, here's what I would have done:

Jass:
        set count = count &#8211; 1
        call RemoveLocation(temp_loc)   // This line has been added
        endif
        call GroupRemoveUnit(enemies, temp)
    endloop

    // Everything below has been added

    call RemoveLocation(start_position)
    call DestroyGroup(enemies)
set caster = null
set start_position = null
set enemies = null
set temp = null


Now, if you thought the only errors were memory leaks, you've overlooked something else that needs to be changed with the code. The start_position variable is never used! We needed to return the hero to the location where the spell started being cast. I won't post the code for this, because I'm assuming you should know 100% how to do this. Just remember that you can't move the hero to a location that's been removed, and that the function you're looking for is already used for something else in the code.

Effects

This now brings us to the next point, making the spell more interesting. A spell where the hero just moves around an area looks rather boring don't you think? Also, you need to take into consideration how the hero moves from point to point and portray that with special effects of some sort. Since the hero is "blinking" we will use the blink model for a special effect. The model path for the blink model happens to be: Abilities\Spells\NightElf\Blink\BlinkTarget.mdl. I got this path from using the object editor. First, I found a random ability (doesn't matter) and then went to the Art – Special Field. After that, I added a new model that was the blink effect. After adding the model, I went to Edit Model and looked at the bottom text area next to the word "Custom:". The path for the model I had just picked was there.

Now, we will go over adding an effect. The function we will be using to create an effect is the "AddSpecialEffectLoc" function. Here's the function declaration for it:

Jass:
native AddSpecialEffectLoc takes string modelName, location where returns effect


This function is pretty strait-forward. You simply give it the path to the model you want to use and the location the effect is to be created at. However, there is one detail I need to go over about the model path. The above path I showed you needs a few minor modifications in order to be used properly. Here's how we would go about calling this function:

Jass:
set blinkEffect = AddSpecialEffectLoc("Abilities\\Spells\\NightElf\Blink\\BlinkTarget.mdl", effectLoc)


Notice how I replaced each "\" in the model path to "\\". This is required in JASS to properly represent the "\" character because the "\" character has other uses that I will not go into. Also, noticed how I set the effect to a variable. A very common mistake is creating the effect, not setting it to a variable, and then trying to use the GetLastCreatedEffectBJ function to refer to the effect. This function only works with the function AddSpecialEffectLocBJ which I do not ever recommend using as it has no point other than for allowing a "Get Last Created Effect" action in GUI. Since we are using JASS, we can ignore this function and use the native.

Challenge

Okay, so now we know how to add a special effect, but now we need to take advantage of this newly learned function and add it into our spell. First, we'll need to decide when and where we want the effect to be placed. I think now will be an appropriate time for a challenge. Your challenge will be to add special effects to the spell as you find appropriate. Feel free to experiment with various models and where you place them in the code. Now, I thought I'd give you one last tip before sending you on your way. Effects, like all other handles, leak. Even though the model of the effect may disappear after a few seconds, you'll still need to remove the effect. There are various ways to do so and I'll go over them now.
First, and most obvious, you create the effect and set it to a variable. Later in the function, you call the DestroyEffect function on the effect to destroy the model and get rid of the memory the model was using. Here's an example of that:

Jass:
local effect specialEffect = AddSpecialEffectLoc("model\\path", someLocation)
// Clean up
call DestroyEffect(specialEffect)
set specialEffect = null


This creates an effect and sets it to the local variable specialEffect. Later in the function, it is destroyed with the DestroyEffect function and set to null. Another thing that should be noted about special effects is that until it's destroyed, an effect will play its "stand" animation if it has one. When you destroy an effect, it plays its "death" animation if it has one. Here's where the second method comes into play. Some functions only have a single animation, or perhaps you only want to play an effect's death animation. You can both create and destroy an effect on the same line. Most effects will play either their death animation or sometimes their regular animation the whole way through before being removed. However, this may not work on all effects so be sure to test it out. Here's basically how the code would look to demonstrate this:

Jass:
call DestroyEffect( AddSpecialEffectLoc("model\\path", someLocation) )


Once again, some models may respond differently than expected with this function so make sure to look things over when using this method. This method is nice due to squeezing many things onto a single line. No other variable for the effect is needed and no memory leak is created from the effect. However, remember that you need to remove the location used in this function as it is not cleaned like the effect is.

Now, I think this is sufficient information for you to add special effects to the spell. Go ahead and give it a shot, the next tutorial will contain how I added the effects. If you have trouble with adding the effects, make sure to ask as questions help you learn.

Good Luck - wyrmlord



This tutorial is still in progress and I would greatly appreciate suggestions.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.

Last edited by wyrmlord; 10-05-2007 at 01:52 AM.
wyrmlord is offline  
Old 02-19-2007, 07:02 PM   #3 (permalink)
Wolverabid
 
Wolverabid's Avatar
Overall Site Manager
 
Join Date: Oct 2006
Posts: 8,408
Wolverabid has a brilliant future (1316)Wolverabid has a brilliant future (1316)Wolverabid has a brilliant future (1316)Wolverabid has a brilliant future (1316)Wolverabid has a brilliant future (1316)
Super Donor: This user has donated at least $100 to The Hive. Former Staff Member: This user used to be on the Hive Workshop staff. Respected User: This user has been given the respected user award. User of the Year: 2007 
IMPORTANT:
  • Posts in this thread should relate only to the tutorials themselves.
__________________
SuperSecretSearchSystem .......Netiquette....... Posting And You..........Read Me.......Vote

Antivirus Chat Dictionary Games Hoaxes Links Music News Quotations Reference Software

[timquote]blah[/timquote]

Last edited by Wolverabid; 04-30-2007 at 06:09 PM.
Wolverabid is offline  
Old 04-13-2007, 02:10 AM   #4 (permalink)
Registered User Deep Sea Kraken
Animator
 
Deep Sea Kraken's Avatar
 
Join Date: Dec 2006
Posts: 1,037
Deep Sea Kraken is on a distinguished road (68)Deep Sea Kraken is on a distinguished road (68)
Hmm, I have a suggestion: I completely SUCK at reading tutorials, so maybe you could put the tutorial into a downloadable map and create comments on what each function does; for me this would help alot, and im probably not the only person out there (looking at everything like they do in tutorials rly confuses me) i got JASS craft, but i have to have something (or someone) explaining what it does and how it work, and these tutorials just dont do that for me. Sorry if I'm bugging you or being over pretentious (whatever that means ^.^), but you did ask for suggestions, so this is mine.

Although i do probably have a slight edge over other people; i write codes in a program called: Ready to Program, which uses Java language, and its pretty close to this, but far less complex
__________________

Deep Sea Kraken is offline  
Old 04-14-2007, 01:13 AM   #5 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
For some reason, I am unable to upload files to this topic. The tutorials should pretty much be self-explanatory, but not everyone learns everything the same way. You'll probably have to stick with copying and pasting the code into a map (there's instructions for running JASS code) and later in the tutorial it goes into triggers in JASS so you'll lose the need for GUI. You should easily be able to put code into a map and just run it. As for commenting, I pretty heavily commented the source code for anything above self-explanatory things (and even some simple things as well).

EDIT: It seems the site allows me to upload files now, but creating a map showing this stuff off wouldn't really take much, so you should be able to do it as I said before.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.
wyrmlord is offline  
Old 04-14-2007, 03:41 AM   #6 (permalink)
Registered User Deep Sea Kraken
Animator
 
Deep Sea Kraken's Avatar
 
Join Date: Dec 2006
Posts: 1,037
Deep Sea Kraken is on a distinguished road (68)Deep Sea Kraken is on a distinguished road (68)
I still cant figure out how to make it create a specific unit.

How do you find out what the JASS term for each unit is (footman is: 'hf00') how would you find that for custom units? or would you just have to create it in GuI then convert the trigger?
__________________

Deep Sea Kraken is offline  
Old 04-14-2007, 01:32 PM   #7 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
While the object editor is open, press ctrl+d. That will show the rawcodes for all objects.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.
wyrmlord is offline  
Old 04-15-2007, 08:28 AM   #8 (permalink)
Registered User Deep Sea Kraken
Animator
 
Deep Sea Kraken's Avatar
 
Join Date: Dec 2006
Posts: 1,037
Deep Sea Kraken is on a distinguished road (68)Deep Sea Kraken is on a distinguished road (68)
Ah, thank you, also you used this code: local location start_position = GetUnitLoc(caster) to get the postiton of the casting unit whould you do:
local location start_position = GetUnitLoc(attacker) if you want it to be the position of an attacking unit?
__________________

Deep Sea Kraken is offline  
Old 04-15-2007, 04:07 PM   #9 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
Find the function that returns the attacking unit. Get a program such as JassCraft or open up common.j and search for it. I'm not going to do all the work for you. By the way, I'd like this thread to only be about the tutorials; if you have trouble go ask in the Jass Forum.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.
wyrmlord is offline  
Old 04-18-2007, 04:35 AM   #10 (permalink)
Forum Moderator PurgeandFire111
User Title
 
PurgeandFire111's Avatar
Tutorial Moderator
 
Join Date: Nov 2006
Posts: 1,812
PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)
This is a great and descriptive tutorial. I hope more is to be added, or is it finished? Either way, it is an outstanding tutorial (IMO), +rep... Thanx :emote_grin:
__________________
Vote For The Hive Workshop!
PurgeandFire111 is offline  
Old 04-18-2007, 10:54 PM   #11 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
Quote:
Originally Posted by PurgeandFire111 View Post
I hope more is to be added
More will be added, as I'm currently working on the next tutorial. I would probably have it finished by now, but I've had a lot of homework this week.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.
wyrmlord is offline  
Old 05-21-2007, 01:30 AM   #12 (permalink)
Registered User Armentia
of Clan BoM
 
Armentia's Avatar
 
Join Date: May 2007
Posts: 14
Armentia has little to show at this moment (1)
One suggestion, which may or may not be avoidable. Fix the scrolling requirement. -.- When 'powerreading' tutorials as I do, I lose concentration when having to horizontally scroll for every line of text. I'm only guessing that this is do to the long comments in your code boxes. Maybe edit these and turn some of the longer ones into multiple lines. Thanks -Arm
Armentia is offline  
Old 05-30-2007, 12:35 PM   #13 (permalink)
Registered User HermanTheGibbon
Got moobs? O_o
 
HermanTheGibbon's Avatar
 
Join Date: May 2007
Posts: 174
HermanTheGibbon is on a distinguished road (69)HermanTheGibbon is on a distinguished road (69)
This a "most outstounding" tutorial Rufus! It's awesome for people like me who know precisely nil about technical computery witchcraft, it's thorough and in layman's terms, which is what a tutorial should be. All the other JASS tutorials I tried to read were obviously made by computer boffins/nerds (lol) who usually just outline a bit of code and expect all the 'begginers' who the tutorial is aimed at to know how to fill it in and what everything means. This is not the case here however, all the jazzy jassy terms explained nicely, most excellent tutorial dudes! +rep WHOOT!
HermanTheGibbon is offline  
Old 06-05-2007, 12:05 AM   #14 (permalink)
Forum Moderator PurgeandFire111
User Title
 
PurgeandFire111's Avatar
Tutorial Moderator
 
Join Date: Nov 2006
Posts: 1,812
PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)PurgeandFire111 is a glorious beacon of light (447)
>wyrmlord:
Jass:
local unit caster = GetSpellAbilityUnit()

It is good to say that GetTriggerUnit() proves to be more efficient:
Jass:
local unit caster = GetSpellTargetUnit()

> When a function has the text 'takes nothing', that means you don't need anything in the parenthesis when calling it.

I think you could put something like this:

--=======--------------------------=======--

When a function has the text 'takes nothing', that means that there is no variables to substitute parameters of a call.

The format is like so:
Jass:
function JASS takes var Vname returns nothing

To have multiple parameters to what the function takes, you seperate them with commas:
Jass:
function JASS takes var1 Vname1, var 2 Vname2 returns nothing

An example of a function with parameters would be this:
Jass:
function Killunit takes unit whichUnit returns nothing
    call KillUnit(whichUnit)
endfunction

Parameters from functions can also be used to create your own functions:
Jass:
function Killunit takes unit whichUnit returns nothing
    call KillUnit(whichUnit)
endfunction

function test takes nothing returns nothing
    call Killunit(GetTriggerUnit)
endfunction

--=======--------------------------=======--

I may reply more, but that's it for now.
__________________
Vote For The Hive Workshop!
PurgeandFire111 is offline  
Old 06-05-2007, 12:08 AM   #15 (permalink)
Registered User wyrmlord
User
 
Join Date: Oct 2005
Posts: 293
wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)wyrmlord is a jewel in the rough (252)
Former Staff Member: This user used to be on the Hive Workshop staff. Zephyr Challenge #2 - Winner: Redemption Aura 
Quote:
Originally Posted by PurgeandFire111 View Post
>wyrmlord:
Jass:
local unit caster = GetSpellAbilityUnit()

It is good to say that GetTriggerUnit() proves to be more efficient:
Jass:
local unit caster = GetSpellTargetUnit()

> When a function has the text 'takes nothing', that means you don't need anything in the parenthesis when calling it.

I think you could put something like this:

--=======--------------------------=======--

When a function has the text 'takes nothing', that means that there is no variables to substitute parameters of a call.

The format is like so:
Jass:
function JASS takes var Vname returns nothing

To have multiple parameters to what the function takes, you seperate them with commas:
Jass:
function JASS takes var1 Vname1, var 2 Vname2 returns nothing

An example of a function with parameters would be this:
Jass:
function Killunit takes unit whichUnit returns nothing
    call KillUnit(whichUnit)
endfunction

Parameters from functions can also be used to create your own functions:
Jass:
function Killunit takes unit whichUnit returns nothing
    call KillUnit(whichUnit)
endfunction

function test takes nothing returns nothing
    call Killunit(GetTriggerUnit)
endfunction

--=======--------------------------=======--

I may reply more, but that's it for now.
The use of GetSpellAbilityUnit() is just for clarity. Thanks for your second suggestion, though unless I'm mistaken the tutorial already covers that.
__________________
A member of Clan TDG - Quality mapmaking and playtesting.

Tired of boring old GUI? Want to learn JASS? Take a look at these tutorials.
wyrmlord is offline  
Closed Thread

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


LinkBacks (?)
LinkBack to this Thread: http://www.hiveworkshop.com/forums/jass-ai-scripts-tutorials-280/beginning-jass-tutorial-series-30765/
Posted By For Type Date
Are These Jass/vjass tutorial Legit and reasonible? This thread Refback 02-11-2010 11:11 PM
Are These Jass tutorial Legit and reasonible? This thread Refback 02-11-2010 11:06 PM
What should I do right now? - The Helper Forums This thread Refback 11-16-2009 08:09 PM
Night of the Dead : Special Ops :: View topic - [Skill] Engineer - Improve Vision This thread Refback 11-08-2009 01:34 PM
More interactive JASS tutorial? - The Helper Forums This thread Refback 11-06-2009 01:26 AM
war3.co.za • View topic - JASS Editing This thread Refback 07-31-2009 09:56 PM
WECraft • Ba?l?k görüntüleniyor - Jass This thread Refback 05-07-2009 08:18 PM
WECraft • Ba?l?k görüntüleniyor - Jass This thread Refback 05-07-2009 07:12 PM
WECraft • Ba?l?k görüntüleniyor - Jass This thread Refback 05-05-2009 08:03 PM
survival.mybb3.org • Save codes This thread Refback 05-04-2009 01:40 PM
polar projection for my td (newbie needs help) - Page 2 - The Helper Forums This thread Refback 04-21-2009 06:58 PM
war3.co.za • View topic - JASS Editing This thread Refback 02-26-2009 06:20 PM
Tutorials (from hiveworkshop) This thread Refback 02-05-2009 12:14 AM
war3.co.za • View topic - JASS Editing This thread Refback 12-28-2008 10:02 AM
JASS : A New Beginning - Clan Mapz Forums This thread Refback 12-19-2008 11:57 PM
JASS : A New Beginning - Clan Mapz Forums This thread Refback 12-19-2008 11:07 PM
JASS : A New Beginning - Clan Mapz Forums This thread Refback 12-19-2008 10:24 PM
Useful Links for Aspiring Mapmakers - Page 2 - Salazaria This thread Refback 11-09-2008 06:10 PM
DotA Allstars 6.54b AI+ 1.52 - DotA Allstars Discussion This thread Refback 10-16-2008 06:40 AM
DotA Allstars 6.54b AI+ 1.52 - DotA Allstars Discussion This thread Refback 10-16-2008 04:01 AM
GAMER :: òøåõ àñèøèâéä :: ôåøåí Warcraft & Starcraft :: ãéåï äWorld edit - åäôòí: Warcraft & Startcraft! This thread Refback 10-08-2008 06:46 AM
Useful Links for Aspiring Mapmakers - Page 2 - Gwydia This thread Refback 09-11-2008 08:35 AM
war3.co.za • View topic - JASS Editing This thread Refback 07-24-2008 09:56 AM
inWarcraft.de Foren by ingame. - Jass This thread Refback 07-10-2008 03:37 PM

Similar Threads
Thread Thread Starter Forum Replies Last Post
JASS Scripting - AI Tutorial Modo Requests 0 10-17-2007 06:22 AM
[JASS] Tutorial JASS - PORTUGUÊS Marcelo Hossomi Triggers & Scripts 0 12-01-2006 12:30 AM
JASS Tutorial Daelin JASS/AI Scripts Tutorials 24 11-04-2006 06:55 AM
[JASS] Can Somone Point me to a JASS tutorial? Yu_Yevon Triggers & Scripts 0 02-06-2005 09:31 PM
[AI] Advice for beginning JASS AI scripters Tommi Triggers & Scripts 0 11-19-2004 08:37 PM

All times are GMT. The time now is 07:38 PM.





Powered by vBulletin®
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.3.1
Copyright©Ralle