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

Crash Course

Status
Not open for further replies.
full

<Download voice guide>

1. Information

The crash course tests your basic knowledge about coding and the WorldEditor. You should ensure everything, or most parts of this knowledge is already known to you before you start doing the missions.

Each mission is devided into (possibly) a preparation + mission parts + (possibly) a conclusion. The preparation defines the required tequnique or method that has to be applied in the mission, mission parts define the content that has to be done or solved, and the conclusion ends the mission with a last word.

Please, when making threads about your mission submission or discussions do always care of making a short but fitting thread title.
We don't need 20 threads named "Need Feedback Plz", but more descriptive thread titles like "[Crash Course] Variables - Issue", etc. Also ensure you have read the Help Me information before asking or helping. Also always use preferable one thread for one submission, so the discussions don't get complex and mixed.​

2. Template Map

You can use following template map for making the missions. It has some allowed default settings that can be used. Such settings are, default gold/lumber, vision on the whole map, zoom and clear commands. <Download here>
3. Basics

Submitter: IcemanBo

Variable

A variable is like a pointer, so it does only point on something. It's always and only a reference for the actual content.
That means if I assign my variable with "Unit A", it will point to "Unit A", and when I assign it with "Unit B", then it will point to "Unit B" from then on.
So when you work with variables, you actually always work with the thing where the variable points to at this moment.
Preparation

Following global variables must be declared and used (<type> , <name>):
  1. integer Counter
Following local variables must be declared and used (<type> , <name>):
  1. unit u
  2. string text
  3. real x
  4. real y
Part 1

Create a (JASS) trigger that runs when a player types "-" as exact string.
The trigger's goal is to create a footman on the map at a random position.
The unit must be created within the map's playable area.
Increase the "Counter" variable by 1 each time the trigger runs.
Part 2

Create a new trigger (in the same trigger sheet) that runs when a unit dies.
When the trigger runs, the "Counter" must be decreased by 1, furthermore
the "Counter" 's value must be displayed on screen to get to know how many footmen are alive.
Conclusion

Always remember that variables are your friends and are very powerful. Global variables are not limited to one trigger, and may be accessed from any code function. Use them to store gameplay important data, or to simplifly your work.
Very often we only need temporary variables inside a function, so then local variables come very handy.


Submitter: IcemanBo

Variable Array

Array is a simple data structure that you can have of (almost) any type of variable. You can imagine it similar like a straight list of normal/scalar (non-array) variables.

The conclusion is that you may use an array[] variable as you would have multiple normal/scalar variables of one type, and for distinguishing them you use a unique number in the brackets[], which is called "index".

So:
MyVariable[0] is one variable for itself of the array "MyVariable[]" with the index "0".
MyVariable[1] is one variable for itself of the array "MyVariable[]" with the index "1".
.. so they both are part of the same array, but they both also can hold different values, as they have a different index.

The range of valid array indices in JASS starts with [0] and ends up with [8191], so you never can work with more than 8192 indices in one array. For example using "8500" as array index is not allowed, as it's beyond the maximum limit "8191".
Preparation

Following global variables must be declared and used (<type> , <name>):
  1. integer Counter[array]
Local variables can be used.
Part 1

Create a (JASS) trigger that runs when a player presses the 'Esc' button (Skip Cinematic).
The trigger's goal is to count how often a player has hit the 'Esc' button, and to print the correct value on screen.
The trigger must be MPI (tip: always search for things you don't know Elemental Coder Guide).
Part 2

If you don't already have done so, do now the "Part 2" without using any "if statement".
Tip: Each player has a unique player number.
Conclusion

When we have same data to work with with multiple instances, then array[] variables should be used to ensure efficient and clean code.
However, we must always ensure we have some kind of unique index that we can use to ensure that we can properly use the array.


Submitter: IcemanBo

There exist primitive (or "native") data types. Primitive means it's not a set or combination of other data types, and that you can not break it down anymore:
JASS:
integer
boolean
real
string
code
handle
The handle type is a bit special. Handles work as pointer for complex data types,
which means a handle can point to different data types in the end, instead of defining one constant and static data type.
So a handle is just a complex data type's reference.

Complex data types are something like "Effects" or "Groups" and are just different combinations of primitive/ native data types.
In theory you can break Complex Data Types down to multiple primtive-only data types.
handle type is used to point to Complex Data Types and complex types are also often called "Objects".

Here is a list of all handle types: JASS Manual: API Browser - Type handle.
When you click on "agent" there comes a new list, because agents are a bit special type of handles, but this does not bother us for now.


Submitter: IcemanBo

HandleId

Each object that exists also has it's own handleid. The handleid is just a unique number assigned to the object.
For two objects that exist the handleid will be never the same, unless the objects are the very same.

To get the handleid we just use:
GetHandleId( <handle>)
Part 1

Create 5 footmen units and print their handleid to screen.
Part 2

Declare 2 local variables and let them point to the same unit, then print both of their handleids.
Conclusion

The handleids seem to be very big numbers, far beyond the JASS array limit 8192, hmmm...


Submitter: IcemanBo

Hashtable

A hashtable is data structure, similar like array is - but instead of using one index[], it uses two indices [] [], which makes it pretty powerful.
That means that we can, and always have to define 2 indices for being able to work with a hashtable.

These two indices we define are called ParentKey and ChildKey. (you also can think of rows and columns if you do easier, like ParentKey = Column, ChildKey = Row)

Similar like normal variables you can store/load anything you want into a hashatble, for example units/integers/reals... in one hashtable entry.

So:
Hashtable[0][1] is one entry in hashtable on it's own
Hashtable[1][0] is one entry in hashtable on it's own
... so both are entries / possible placeholders in our hashtable, and both can hold different values.

Hashtable index for ParentKey and Childkey is not restricted to the number 8192 like array is. It can have indices up to 2147483647 (2^31 - 1), positive and even negative ones. (it's the max values an integer can hold)

The maximum amount of hashtables JASS can manage is 256, so you can't have more hashtables at same time.
Preparation

Following global variables must be declared and used (<type> , <name>):
  1. hashtable Hash
Part 1

Create a unit and save it into hashatble. ParentKey = 123456789 ; ChildKey = 0
Part 2

Print the name of the saved unit using the loaded value from hashtable. (you can do it in same function)


Submitter: IcemanBo

You already can use array of your data, and also know that you can use hashtables to store data... but what is the difference?

The major difference is the size/amount of data that we can store, and so said the allowed maximun/minimum index.
Arrays are able to work with 8192 entries of max, while hashtables allow much higher indices, up to "2^31 - 1".

Now remember the "Variable Array" mission, where you binded your data to a specific player using the unique "PlayerId" as index.
But what if you want to bind data to any object, like to units/items -- then the PlayerId becomes useless. But maybe an other unique number might be used as handle specific index...


Submitter: IcemanBo

Prepration

Following global variables must be declared and used (<type> , <name>):
  1. hashtable Hash
  2. unit Hero
Extra global variables are not allowed.
Part 1

Create a (JASS) trigger that runs (only) when Hero makes a point order.
Create a (JASS) trigger that runs (only) when Hero makes a target order.
Create a (JASS) trigger that runs (only) when Hero makes an order without target.

Create a (JASS) trigger that runs when you select the Hero.
The trigger's goal is to print following values on screen:
  1. PointOrders: X
  2. TargetOrders: Y
  3. NontargetOrders: Z
... where, X, Y, Z are the correct values respectivly how much orders the Hero did (like counters).

Tip: You must use the first three triggers to count the different orders, and use hashtable to bind the values to the unit.
Part 2

Create a (JASS) trigger that runs when a player presses the 'Esc' button.
The trigger's goal is to clean the hashtable of all it's entries.


Submitter: IcemanBo

Loop

A loop is a sequence of operations that is continually repeated until a certain condition is reached.
Loops are used to improve efficiency and readability, and they can shorten your code extremly once you found a good pattern.
Prepatation

Create one global integer variable "Footman Amount", and give it the value "5".
Part 1

Create a function, that runs on map initialiaztion.
The function's goal is to create <Footman Amount> footmen for Player_1 using a loop.
Part 2

Insert a new condition to exit the loop from Part 1 -- now the loop should (also) exit if Player_1's currently used food level is above "3".
Part 3

Create a new function, that also runs on map initialization.
The function's goal is to loop through all players, and to create <Footman Amount> footmen units for all of the players with using a loop, as well.
Conclusion

Loops help to structure your code; they can be nested, and also can have multiple exit conditions.


Submitter: IcemanBo

Timer

A timer is an object that is used for time references and purposes.
In GUI the timer usage is very limited, but in JASS it can become very important.
Preparation

Following local variables must be declared and used (<type> , <name>):
  1. timer clock
Part 1

Create a timer that fires a function "foo" after 2 seconds expired after map initialization.
In function "foo" the expired time must be printed on screen and the expired timer destroyed.
Part 2

Following global variables must be declared and used (<type> , <name>):
  1. hashtable Hash
Create a unit on map initialization.
Create a timer on map initialiaztion.

The unit must be saved into hashtable, using the timer as ParentKey, which means that the used index must be directly related to the timer object itself.

The timer should periodicly (each second) call a function "DamageUnit", which goal is to retrieve the saved unit from hashatble, and to decrease it's life by "10".

In case the unit is dead, the timer must be destroyed.​
Conclusion

A timer can do one-time runs, but can also serve as periodical call of operations.


Submitter: IcemanBo

Group

A unit group, or actually just "group", is a set of units combined in a data structure.
It comes useful to find certain units under certain conditions, or to categorisize units that belong together.
Preparation

Following global variables must be declared and used (<type> , <name>):
  1. group Group
Part 1

Create 200 footmen on the map at random locations. (but within playable map area)
Loop through all units on map, and kill them if they are in range of 1000 towards the center of the map.
Part 2

Create a trigger that runs when a player presses the 'Esc' button (Skip Cinematic).
When the trigger runs, the amount of alive footmen should be printed on screen.
For solving this part, the "FoG Enumeration" tequnique must be used.
3. Last Word

Congratulations! In case you could solve all the basics you can try yourself in the Missions!​
 

Attachments

  • JASS Class.w3m
    22.9 KB · Views: 272
  • Crash Course.mp3
    553.9 KB · Views: 154
Last edited:
Status
Not open for further replies.
Top