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

Things You Should Know When Using Triggers / GUI

Level 20
Joined
Apr 14, 2012
Messages
2,901
Congrats on the approval Mate!!

Oh yeah, about do nothing, note that Do Nothing is for filler in this trigger :
  • Action
  • If Condition then do Action else do Action
Since if you use that trigger u need to fill the other empty one. Anyway, nice tutorial, useful for me making a minor system :)

+2 Rep From Daffa the Mage

You don't need to add Do Nothing to fill the other empty one. It will work regardless.
 
Level 16
Joined
Jul 31, 2012
Messages
2,217
  • (Triggering unit) Equal to bossUnit1
  • (Triggering unit) Equal to bossUnit2
  • (Triggering unit) Equal to bossUnit3
Change those to:
  • Or - Any (Conditions) are true
    • (Triggering unit) Equal to bossUnit1
    • (Triggering unit) Equal to bossUnit2
    • (Triggering unit) Equal to bossUnit3
Just a little mistake, :p
Good tutorial btw, very...., big :p
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
Weird, i copied and pasted the same things of ch 22, and when i call the function, it causes errors :/
This might be because the way the triggers are organized.
The trigger with the function in ("Test") needs to be created before the other trigger ("RunTest") is created.
If it is the other way around, then it cannot find the function.

So be sure you create that one first :).
And if not: simply copy the second trigger ("RunTest"), delete it and then paste it again.
 
Level 28
Joined
Jan 26, 2007
Messages
4,789
So, what is the difference between your indexing and dynamic indexing which was made by a respected user.
His indexing is dynamic.
Maker explained this quite nicely in this thread (it isn't the main point of the thread, but his explanation is very clear).

Neither deathismyfriend's nor Hanky's indexing are anything 'special'.
I actually think they're the same, except that Hanky's combined Hashtables with it (I don't think that's worth it, though).
 
  • Like
Reactions: Rui
Level 14
Joined
Jan 15, 2007
Messages
349
His indexing is dynamic.
Maker explained this quite nicely in this thread (it isn't the main point of the thread, but his explanation is very clear).

Neither deathismyfriend's nor Hanky's indexing are anything 'special'.
I actually think they're the same, except that Hanky's combined Hashtables with it (I don't think that's worth it, though).

You got something wrong there. The dynamic indexing part of my template is without hashtables. The unit indexing part is with hashtables since I dislike saving the index with the custom value function for units.

You have to understand that the template I made got more than just one indexing method.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
You got something wrong there. The dynamic indexing part of my template is without hashtables. The unit indexing part is with hashtables since I dislike saving the index with the custom value function for units.

You have to understand that the template I made got more than just one indexing method.

i never saw ur template b4 so i cant comment on it. if u would tho could u give me link to ur template as i believe everyone should have a choice of what they like the indexed array format i use or the way u do it.
they are both efficient since u dont use hashtables and i would gladly put any links to tutorials that are covered under anything i cover in my tutorial.
 
Level 14
Joined
Jan 15, 2007
Messages
349
i never saw ur template b4 so i cant comment on it. if u would tho could u give me link to ur template as i believe everyone should have a choice of what they like the indexed array format i use or the way u do it.
they are both efficient since u dont use hashtables and i would gladly put any links to tutorials that are covered under anything i cover in my tutorial.

No need to link the template. I just wanted to point out that the given information by ap0calypse was wrong.
 
Level 20
Joined
Aug 13, 2013
Messages
1,696
I do disagree, you don't NEED those. You can code, anything with normal GUI therefor you don't NEED it. If you like GUI you want GUI not jass

Why you disagree in GUI with a LITTLE JASS line. When making a spell you must know the basics of JASS line because they are MORE efficient to create a spell eg. from removing leaks and making the user comfortable in spell making.
 
There are tons of factual problems with this huge tutorial.
I tried to list them all and correct them but I got overwhelmed ~.~

Couple of things:
- A handle does not need to be destroyed, the JASS Pseudo-VM cleans a lot of shit for you, and yes, that means most temporaries. There are special cases where you have heap-allocated objects that are not cleaned up like locations, groups or special effects.
- Using the word "object" to describe a widget is not good enough. They are interactable. Widgets also have life and position. (GetWidgetLife, GetWidgetX, GetWidgetY)
- A handle is not a pointer to an internal data structure, a handle is an internal chunk of data and in JASS, when you actually use them, you are using a pointer to a handle.
 
Level 29
Joined
Oct 24, 2012
Messages
6,543
There are tons of factual problems with this huge tutorial.
I tried to list them all and correct them but I got overwhelmed ~.~

Couple of things:
- A handle does not need to be destroyed, the JASS Pseudo-VM cleans a lot of shit for you, and yes, that means most temporaries. There are special cases where you have heap-allocated objects that are not cleaned up like locations, groups or special effects.
- Using the word "object" to describe a widget is not good enough. They are interactable. Widgets also have life and position. (GetWidgetLife, GetWidgetX, GetWidgetY)
- A handle is not a pointer to an internal data structure, a handle is an internal chunk of data and in JASS, when you actually use them, you are using a pointer to a handle.

It helps if you tell me what section these mistakes were made in.
I know that a handle is not a pointer a variable is a pointer to a handle i must've typed that in wrong when i was typing it up.
 
Level 18
Joined
Sep 14, 2012
Messages
3,413
  • Preload abilities
  • Events
    • Time - Elapsed game time is 0.00 seconds
  • Conditions
  • Actions
    • -------- Here we set the variables. --------
    • Set abilities[1] = Acid Bomb
    • Set abilities[2] = Animate Dead
    • Set abilities[3] = Attribute Bonus
    • Set abilities[4] = Avatar
    • Set abilities[5] = Avatar (Neutral)
    • -------- Now we will do the actions to preload --------
    • Set tempPoint = (Center of (Playable map area))
    • Unit - Create 1 Footman for Player 1 (Red) at tempPoint facing Default building facing degrees
    • Set tempUnit = (Last created unit)
    • For each (Integer tempInt) from 1 to 5, do (Actions)
    • Loop - Actions
      • Unit - Add abilities[tempInt] to tempUnit
      • Unit - Remove abilities[tempInt] from tempUnit
    • Unit - Remove tempUnit from the game
    • Custom script: call RemoveLocation( udg_tempPoint)
    • Custom script: set udg_tempPoint = null
    • Custom script: set udg_tempUnit = null
    • -------- Here is were we destroy the trigger since it isn't needed anymore. --------
    • Custom script: call DestroyTrigger( GetTriggeringTrigger())
In the part you destroy the trigger it will leak since you don't remove actions of the trigger or am I wrong ?
 
  • Preload abilities
  • Events
    • Time - Elapsed game time is 0.00 seconds
  • Conditions
  • Actions
    • -------- Here we set the variables. --------
    • Set abilities[1] = Acid Bomb
    • Set abilities[2] = Animate Dead
    • Set abilities[3] = Attribute Bonus
    • Set abilities[4] = Avatar
    • Set abilities[5] = Avatar (Neutral)
    • -------- Now we will do the actions to preload --------
    • Set tempPoint = (Center of (Playable map area))
    • Unit - Create 1 Footman for Player 1 (Red) at tempPoint facing Default building facing degrees
    • Set tempUnit = (Last created unit)
    • For each (Integer tempInt) from 1 to 5, do (Actions)
    • Loop - Actions
      • Unit - Add abilities[tempInt] to tempUnit
      • Unit - Remove abilities[tempInt] from tempUnit
    • Unit - Remove tempUnit from the game
    • Custom script: call RemoveLocation( udg_tempPoint)
    • Custom script: set udg_tempPoint = null
    • Custom script: set udg_tempUnit = null
    • -------- Here is were we destroy the trigger since it isn't needed anymore. --------
    • Custom script: call DestroyTrigger( GetTriggeringTrigger())
In the part you destroy the trigger it will leak since you don't remove actions of the trigger or am I wrong ?
Yeah it will.
Also you don't need to null global variables.

But at the other point you don't need to bother too much about memory leaks in triggers like this one. You can have 100 or even 1000 such like triggers in your map and it will still run perfectly fine.

Problems start to become serious when you use loops and/or times.
In situations like this one:
JASS:
loop
    exitwhen i == 1000

        //
        //bla bla bla leaks leaks leaks
        //

    set i = i + 1 
endloop

//
// where we call this code each 0.03 seconds using timer
//
Cleaning leaks should become something really important.

EDIT:

Also
  • Actions
    • Set p = (Point(0.00, 0.00))
    • -------- over --------
    • Set p = (Center of (Playable map area))
    • -------- when --------
    • Unit - Create 1 Footman for Player 1 (Red) at p facing Default building facing degrees
Because
JASS:
function Trig_Melee_Initialization_Actions takes nothing returns nothing
    set udg_p = Location(0, 0)
    // over
    set udg_p = GetRectCenter(GetPlayableMapRect())
    // when
    call CreateNUnitsAtLoc( 1, 'hfoo', Player(0), udg_p, bj_UNIT_FACING )
endfunction

//===========================================================================
function InitTrig_Melee_Initialization takes nothing returns nothing
    set gg_trg_Melee_Initialization = CreateTrigger(  )
    call TriggerAddAction( gg_trg_Melee_Initialization, function Trig_Melee_Initialization_Actions )
endfunction

//-----------------------------------------------------
//-------------- Here how they look like --------------
//-----------------------------------------------------
function GetPlayableMapRect takes nothing returns rect
    return bj_mapInitialPlayableArea
endfunction

function GetRectCenter takes rect whichRect returns location
    return Location(GetRectCenterX(whichRect), GetRectCenterY(whichRect))
endfunction
//-----------------------------------------------------
 
Level 17
Joined
Apr 27, 2008
Messages
2,455
It leaks if you don't null globals before changing the value.
Maker told it on a thread on the spell Gui Rupture

Not really, the conclusion is :

Not allowing a handle id to be recycled immediately after destruction causes a memory leak.
And well, it is still a really minor memory leak and sometimes you just can't avoid it. (even in vJass)
Sure it's still lame, but if a GUI user care about that, he should consider to use (v)jass instead, GUI have much more revelant leaks within GUI functions themselves.
PolledWait, some stuff with GroupEnum and probably more stuff like that.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,182
Just bumping the thread by suggestion that you add some sort of level indicator to the sections. Either a scale from 1-10 or something like Basic, Medium, Advanced

because if you come here to pick up some tricks as a rather new GUI user I doubt you "need" to learn from some of the sections unless you really want to "master" GUI if I may call it that.
 
Level 21
Joined
Mar 27, 2012
Messages
3,232
Still it means that you can do stuff as map init as the event.

It's effectively a "Time elapsed" event then, not map init anymore. Map init events are exclusively handled during loading. Waits can not be handled like this, because the game time is considered unchanging during loading, so they are queued and will be handled once the map finishes loading.
 
Top