• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

from zero to hero - the ultimate GUI Tutorial

Welcome to the ultimate GUI Tutorial!!!
by Palaslayer




What you should know before reading this tutorial:
-what are variables
-what are arrays
-basic knowledge of the words used in GUI in what they mean
-a brain



I recomment reading some other tutorials before starting with this for better understandin. For example:
Starting with GUI
Beginners Guide to GUI
Array tutorial
GUI triggering
GUI list of actions/conditions/events

Frequently asked questions - do not ask us ^^



Who are we?
Ok, first off I will start to introduce ourself. All of you should know Paladon, right? If not, I can tell you that he is propably the best GUI user at the hive workshop.
Some of you might even know me. I am registered at the hive since spring 2008 and active since last autumn. I can proudly say that I learned a lot in the past year concerning the usage of GUI and even of JASS.



What is this Tutorial for?
After reading and practicing with this Tutorial, you should be able to do nearly everything possible with GUI. I includes a lot of experience and knowledge from both me and Paladon, who already won a Spells and Systems Mini Contest with his work, where the best scripters of the hive gather.
We want to give you a deeper view into GUI and answer a lot of questions which are frequently asked in the Triggers and Scripts Forum, which should be unnessecary after we submitted this Tutorial ;)

The Tutorial features a lot of Basics of GUI, you will learn about leaks, loops and much more, as well as some more difficult things, which even some of the better users do not know. In addition we will give you an explanation of MUI methods, which may be the most difficult thing to do in GUI especially when working with more complex systems and spells.



What is GUI?
GUI means General User Interface and is a mask for the true programming language implemented in Wc3: JASS. Truely, the WE converts all lines of GUI into Jass before executing the orders. GUI allows you to manipulate Warcraft 3 maps, make custom spells, create quests and a lot more and for beginners who don't have that much free time it is really easy to learn while for JASS you would have to spend a lot more time learing it.
Though JASS features many more aspects than GUI, with GUI you should be able to realize nearly everything your heart desires - if you are good enough.



What are variables and why do we use them?
Variables are like USB-sticks. You can save something in them. Namely units, special effects, strings and booleans or whatever. And they even work like USB-sticks. If you want to save new things in them, the old data is deleted and that is why we will do every spell MUI. (See MUIness) Variables are used for example after waits or if you want to carry on the unit into another trigger. You will learn how to use them later by triggering.



What is MUI/MPI?
Good question. MUI means Multi-Unit-Instanceable and MPI means Mulit-Players-Instanceable if I am correct. MUIness means that GUI spells, which have a longer duration can be cast by as many units as you want at the same time while non MUI spells cannot, because they will get interrupted by the next spell cast. This should be no problem if there is only one unit in the map with the same spell (e.g. in AOS-maps). MPIness features the same things for one unit per player.
To accomplish that we use variable arrays, to have the variables not being overwritten.

Ok, now this is it for now. Here is a list of the things we will work with in this Tutorial. To get to one point (if you use Firefox) simple press STRG + F and then type in the key like 1.y or 2.x.
To make you understand GUI and the Tutorial you should start reading it as a whole.



The system:
1 means easy
2 means advanced
3 means expert




category 1
a efective creep spawning via loops
b neutral creep respawn
c tree respawn
d setting alliances via chat (-ally and -unally)
e triggering a blink strike
f clearing leaks
g damaging an area with unit group
h damage via attributes (2x int aso.)
i making spells deal random damage
j special effects


category 2
a working with lightnings
b triggering a nova spell (most effective way)
c making a self-target spell target an area; e.g. war stomp
d damaging for percentage life/mana
e triggering a channeled self-target aoe spell (creating thunderclaps at random positions around the caster)


category 3
a triggering an efficient jump
b triggering dummy missiles
-following
-straight
-circled movement around a point
c triggering an omnislash
d triggering an efficient GUI Knockback
-making the knockback as a passive KB on attack
e triggering a Dot
f triggering a chain spell
g triggering evasion
h triggering a reincarnation aura






1.a spawning creep waves
Ok, I think everybody knows those AOS maps like DotA, where creeps spawn frequently after a certain amount of time? Wanna know how to do it? Then read on.

Ok, first, we have an initialization trigger that makes units beginning to spawn after some time:

  • creep spawn init
    • Events
      • Time - Elapsed game time is 60.00 seconds
    • Conditions
    • Actions
      • Trigger - Turn on creep spawn timer <gen>
Now, that should be clear, eh? The spawning will start at the 60 seconds mark.

  • creep spawn timer
    • Events
      • Time - Every <desired inerval> seconds of game time
    • Conditions
    • Actions
      • -------- we will set the locations for each team, like in an aos, where two teams with 5 players take place --------
      • -------- this is for team 1, they have the same spawn loc, and the same target loc, right? --------
      • For each (Integer A) from 1 to <players in team 1>, do (Actions)
        • Loop - Actions
          • Set SPAWN_LOC[(Integer A)] = (<desired location>)
          • Set SPAWN_LOC[(Integer A)] = (<desired location>)
      • -------- this is for team 2, they have the same spawn loc, and the same target loc, right? --------
      • For each (Integer A) from <players in team 1 + 1> to <players in team 2>, do (Actions)
        • Loop - Actions
          • Set SPAWN_LOC[(Integer A)] = (<desired location>)
          • Set SPAWN_LOC[(Integer A)] = (<desired location>)
      • -------- this trigger is completely leakfree! ok, now we spawn the units and order them to execute an action --------
      • Custom Script: set bj_wantDestroyForce = true
      • Playergroup - Pick every player in (All players) and do (Actions)
        • Loop - Actions
          • For each (Integer A) from 1 to <desired number of units>, do (Actions)
            • Loop - Actions
              • Unit - Create 1 <desired unit> for (Picked player) at SPAWN_LOC[(Player number of (Picked player))] facing <desired angle> degrees
              • Unit - Order (Last created unit) to <desired order> to TARGET_LOC[(Player number of (Picked player))]
      • -------- and we clear all the locations at the end of the trigger, or it will leak and as a result: lagg --------
      • For each (Integer A) from 1 to <team 1 + team 2 players>, do (Actions)
        • Loop - Actions
          • Custom Script: call RemoveLocation(udg_SPAWN_LOC[bj_forLoopAIndex])
          • Custom Script: call RemoveLocation(udg_TARGET_LOC[bj_forLoopAIndex])
ok now, this is the spawning for one 'lane' or what you call it
do the same thing for the other ones and you are done
this will be included in test map!

(@ Paladon and Berz, plz tell me how to further improve that trigger, i think it is the most efficient way)


1.b neutral creep respawn


Ok, that is simple, too. We need two triggers again.
One that runs at the start of the game, and one that runs everytime a neutral unit dies.

First off, the init trigger.

  • respawn init
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Conditions
    • Actions
      • Custom script: set bj_wantDestroyGroup=true
      • Unitgroup - Pick every unit in (Units in (Playable map area) owned by Neutral enemy) and do (Actions)
        • Loop - Actions
          • Set CREEP_INTEGER = (CREEP_INTEGER + 1)
          • Unit - Set the custom value of (Picked unit) to CREEP_INTEGER
          • Set CREEP_LOC[(Custom value of (Picked unit))] = (Position of (Picked unit))
ok, we pick every neutral enemy creep on the map and set his position. there the units will spawn, when a neutral unit dies, allright?

now, lets go over to the second trigger:

  • respawn
    • Events
      • Unit - A unit owned by Neutral enemy dies
    • Conditions
      • (Custom value of (Triggering unit)) greater than 0
    • Actions
      • Wait <desired respawn time> seconds
      • Unit - Create 1 (Unit-type of (Triggering unit)) for Neutral enemy at CREEP_LOC[(Custom value of (Triggering unit))] facing (Facing of (Triggering unit)) degrees
      • Unit - Set the custom value of (Last created unit) to (Custom value of (Triggering unit))
We revive the unit after some time and reset the custom value. Hope it is clear.

Ok, lets do another respawn system. We only need to make another respawn trigger. And we have to implement another few lines into the init trigger.
Do as following:

  • respawn init
    • Events
      • Time - Elapsed game time is 0.00 seconds
    • Condition
    • Actions
      • Custom script: set bj_wantDestroyGroup=true
      • Unitgroup - Pick every unit in (Units in (Playable map area) owned by Neutral enemy) and do (Actions)
        • Loop - Actions
          • Set CREEP_INTEGER = (CREEP_INTEGER + 1)
          • Unit - Set the custom value of (Picked unit) to CREEP_INTEGER
          • Set CREEP[CREEP_INTEGER] = (Picked unit)
          • Set ANGLE[CREEP_INTEGER] = (Facing of (Picked unit))
          • Set CREEP_LOC[(Custom value of (Picked unit))] = (Position of (Picked unit))

ok, what did we change? We now save the unit into a variable and the facing angle as well because we will need it later. And we do not work with custom value anymore, which is good because we will not interfer into another spell, system or else, that uses custom value.

Let's take a look at the second trigger then:

  • respawn
    • Events
      • Time - Every <desired interval> seconds of game time
    • Conditions
    • Actions
      • For each (Integer A) from 1 to CREEP_INTEGER, do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Conditions
              • (CREEP[(Integer A)] is alive) unequal to True
            • 'THEN'-Actions
              • Unit - Create 1 (Unit-type of CREEP[(Integer A)]) for Neutral enemy at CREEP_LOC[(Integer A)] facing ANGLE[(Integer A)] degrees
              • Unit - Set the custom value of (Last created unit) to (Integer A)
              • Set CREEP[(Integer A)] = (Last created unit)
            • 'ELSE'-Actions
This trigger has changed a lot in my opinion. Every interval we check whether a neutral unit has died and if we revive it. There are as many units as CREEP_INTEGER and we can check all of them with a loop.
Later we use Integer A as the array. It indicates the figure of the loop. For example when the loop runs first time it is 1, second time 2 and so on.

Those are two ways of respawning creeps, which you can use both in an AOS. I personally prefer the second way, because it doesnt work with custom value and there is no wait inside the trigger.



1.c destructible respawn

This is a system how you can simply resurrect destructibles in your map. For a more advanced resurrection you should implement conditions so that all used treetypes can be revived.


We can make two different types of tree reviving systems. First one frequently revives trees after a periodic event and the second revives them shortly after their death.

Let's start with the first:

  • tree respawn intervalled
    • Events
      • Time - Every <desired interval> seconds of game time
    • Conditions
    • Actions
      • Destructible - Pick every destructible in (Entire map) and do (Actions)
        • Loop - Actions
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • 'IF'-Conditions
              • ((Picked destructible) is dead) equal to True
              • (Destructible-type of (Picked destructible)) equal to Summertreewall
            • 'THEN'-Actions
              • Destructible - Resurrect (Picked destructible) with (Max life of (Picked destructible)) life and showing birth animation
            • 'ELSE'-Actions

The trigger picks every destructable of type on the map each <desired interval> seconds (you can set whatever number you want in there from 99 to 0.75) and resurrects it.

Now Paladon's tree respawn system:

  • tree respawn
    • Events
      • Destructible - A destructible within (Entire map) dies
    • Conditions
      • Or - Any (Conditions) are true
        • Conditions
          • (Destructible-type of (Picked destructible)) equal to Summertreewall
    • Actions
      • Wait <desired number> game-time seconds
      • Destructible - Resurrect (Dying destructible) with (Max life of (Dying destructible)) life and showing birth animation

This system is more simple and easy to use. Chose between both you will not be disappointed neither when using mine nor when using paladon's.


1.d allying system (-ally and -unally)


The allying system allows players to build alliances easily ingame by just typing -ally <player number> or -ally <player color> and so on.
Let's see whether we can do that, too.
 
Last edited:
Top