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

Essentials Tutorial

Level 17
Joined
Mar 17, 2009
Messages
1,349
@ Eleandor:
Eleandor said:
Uh, sure, but he doesn't say how to detect bugs like that.
First of all I said generally what the problem is:
Deuterium said:
Thus, the information it might carry while looping could be changed due to any interception by other triggers which also contain Integer A. What happens then - once the looping of the original trigger resumes - is that the value of Integer A is different leading to faulty looping - i.e. bug.
PurplePoot said:
The actual reason is because (Integer A) is a global so two loops running it at once interfere with one another as they both access it and change it at the same time (more accurately, one changes it while the other is waiting for the first to finish).

And as you see, since I thought what I said wasn't clear enough, I quoted PP. I didn't go deep into details, 'cause I know that doing so would simply confuse the users.

And why would they need to detect it when I already told them to avoid those integers?

Eleandor said:
He just says to use different variables for each loop you have, and honestly that's just idiot.
Oh really?

Eleandor said:
Especially when bugs like this happen in maybe 2% of the triggers you have.
It's a bug nevertheless.

Eleandor said:
Those are local variables.
Well, once a global is indexed, it functions in a common manner to a local variable, except much less efficient. And also a trigger would intercept it's own actions, so even if the global isn't indexed and the spell is instant, as long as it's unique for that trigger, it's safe.

Eleandor said:
Creating a separate global variable for each iterator is just going to explode your variablelist when you don't have to. And the GUI variable list is already ugly.
One of the burden's of using GUI.


@ aznricepuff:
Thanks for the support :)
 
Level 12
Joined
Oct 16, 2008
Messages
512
About: "Avoiding the usage of Index A (or Index B)"

'Kay i've read all the posts dealing with that in this thread, and i was extremely surprised to learn that a trigger can pause the execution of another one and overwrite "Integer A" inside itself, before re-enabling the first trigger to go on o_O

At first i thought it was b*llshit to be honest. Fact is, i have a whole map with billions of executions of loops including integer A's and B's. They include absolutely no "waits" of any sort, so until now, i assumed they were completely safe.
I very rarely experience weird bugs with that map, such as the complete unability to build anything for a player, or things not happening for some weird obscure reason.

If that issue with those preset integers happens to be the reason, Man you deserve a medal. Actually, just for the sake of this fact being true, you already do. Wait, not only you, the people who found this out also do.
But that's one helluva stealth problem we got there, further decreasing my trust in GUI, and you were the one to get this tutorial in here, in such a neat and reader-friendly manner. +rep.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
First of all I said generally what the problem is:
Oh, sure but rather than getting into more specific details on how you know if your loop will cause trouble, you just tell people to use different variables anyway? I don't see much tutoring in this part of the tutorial.

And why would they need to detect it when I already told them to avoid those integers?
Here's why:
  • Test
  • Events
    • A player skips a cinematic
    • Unit - a unit enters playable map area
  • Conditions
    • SomeInt less than 100
  • Actions
    • for Integer C from 1 to 10 do
      • Unit - create a unit of type UnitArray[Integer C] at center of playable map area
      • set SomeInt = SomeInt + 1
They're avoiding Integer A and Integer B, yet I doubt that they expect this trigger to behave like it does.
What they probably wanted to do is something like waves of units with an equal spreading of the unit types, and a maximum unitcount of 100

It's a bug nevertheless.
But not a bug with Integer A or Integer B. It's a bug in their own code, and you're not telling them how they can write good code.

Well, once a global is indexed, it functions in a common manner to a local variable
No, see the example trigger I gave. If the looping variable would have been local there would be no problem at all.

One of the burden's of using GUI.
Fact is, i have a whole map with billions of executions of loops including integer A's and B's.
Hell, if you have lots of loops I really think using Integer A and Integer B is a lot better than creating a different variable.
 
Level 15
Joined
Aug 11, 2009
Messages
1,606
Why most of you guys dislike GUI?In every chance you are given you mention it isn't good/usefull and etc...Using jass i guess you can make everything but...the 95% of them can also be made in GUI +custom texts.
For me and many other users that don't want or don't have time to go through the process to learn jass,GUI has never let me down until now.(except 1 time when i was making a spell and i wanted to toss enemy untis in the air )
 
Last edited:
Level 17
Joined
Mar 17, 2009
Messages
1,349
@ Eleandor:
No offense - and I thank you for your opinions - but apparently it's only you who find a problem with that section, although I believe it's fine since it contains the explanation of what the problem is and how to fix it. And the explanation is just at the right dose for a beginner GUI user. I might have to add an example or two, but I'll do so once I'm in a "coding" mood :)P). Anyways, I'll ask some people to check it out, and if anyone finds it's lacking, I'll see how I could improve it.

Again, thanks!

@ TBD:
TheBlooddancer said:
Oh, and in 'How not to use wait, a-example' aren't you making it wait 1 second, instead of 0.1?
Well the wait is in a loop which runs ten times. It waits 0.1 sec. every instance, summing up to 1 seconds. I think it's right unless I missed your point. Did I?

@ Dj0z:
Glad you learnt that!

@ reason 3:
GUI does suck, but it's not forbidden :p
 
Level 15
Joined
Aug 11, 2009
Messages
1,606
Don't turn this tutorial into a jass vs gui thread please, you'll lose anyway. Check out the warcraft 3 forum for such a topic.

Sry about it Eleandor i wasn't going to turn this into a GUI vs Jass thread,and yes i know with jass there are more possibilities and the code is also faster...i know all these.My point was just to prove you that GUI isn't "sucking"!
 
Level 7
Joined
Mar 8, 2009
Messages
360
Nice tutorial, although i'll stay to vJASS :p.

I have another reason why to save GetBlaUnit in variable. They bug when they are used in a function that is not called by the "event trigger", even when there are no waits and it happens with GetTriggerUnit too. Because of that you can't use GetBlaUnit in loops because GUI loops are run in another function.

Here is the thread in which i found out this problem.
 
Level 17
Joined
Mar 17, 2009
Messages
1,349
Vulcano said:
I have another reason why to save GetBlaUnit in variable. They bug when they are used in a function that is not called by the "event trigger", even when there are no waits and it happens with GetTriggerUnit too. Because of that you can't use GetBlaUnit in loops because GUI loops are run in another function.
True indeed, but this tutorial focuses on GUI (by now, maybe I'll make a Jass section someday), and in GUI that is no problem - unless you're sharing information between two different triggers (I might have to mention that instead).

Thanks for checking :)
 
Level 7
Joined
Mar 8, 2009
Messages
360
I had the problem in a gui trigger. That one wasn't working.

But this one works (stored TriggeringUnit and Target unit... in a variable):
  • Forked Banish
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chain Banish (|cffdc143cUltimate|r)
    • Actions
      • Set tempUnit = (Triggering unit)
      • Set tempUnit2 = (Target unit of ability being cast)
      • Set tempPoint = (Position of tempUnit)
      • Set point1 = (Position of tempUnit2)
      • Set tempInt = 0
      • -------- - --------
      • -------- Cast Banish on target --------
      • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
      • Unit - Add Chain Banish (dummy) to (Last created unit)
      • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning tempUnit2
      • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
      • If ((Last created unit) Equal to No unit) then do (Game - Display to (All players) the text: BeforeLoop) else do (Do nothing)
      • Unit - Add Banish to (Last created unit)
      • Unit - Order (Last created unit) to Human Blood Mage - Banish tempUnit2
      • -------- - --------
      • -------- Cast Banish on random targets around target --------
      • Set tempGroup = (Units within 400.00 of point1 matching (((Matching unit) belongs to an enemy of (Owner of tempUnit)) Equal to True))
      • Unit Group - Remove (Target unit of ability being cast) from tempGroup
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Set tempInt = (tempInt + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • 7 Greater than tempInt
            • Then - Actions
              • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
              • If ((Last created unit) Equal to No unit) then do (Game - Display to (All players) the text: bla) else do (Do nothing)
              • Unit - Add Chain Banish (dummy) to (Last created unit)
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Picked unit)
              • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
              • Unit - Add Banish to (Last created unit)
              • Unit - Order (Last created unit) to Human Blood Mage - Banish (Picked unit)
            • Else - Actions
      • Custom script: call DestroyGroup(udg_tempGroup)
      • Custom script: call RemoveLocation( udg_tempPoint )
      • Custom script: call RemoveLocation( udg_point1 )
Thx for giving me 3 orbs :)
 
Level 15
Joined
Jul 19, 2007
Messages
618
I had the problem in a gui trigger. That one wasn't working.

But this one works (stored TriggeringUnit and Target unit... in a variable):
  • Forked Banish
    • Events
      • Unit - A unit Starts the effect of an ability
    • Conditions
      • (Ability being cast) Equal to Chain Banish (|cffdc143cUltimate|r)
    • Actions
      • Set tempUnit = (Triggering unit)
      • Set tempUnit2 = (Target unit of ability being cast)
      • Set tempPoint = (Position of tempUnit)
      • Set point1 = (Position of tempUnit2)
      • Set tempInt = 0
      • -------- - --------
      • -------- Cast Banish on target --------
      • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
      • Unit - Add Chain Banish (dummy) to (Last created unit)
      • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning tempUnit2
      • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
      • If ((Last created unit) Equal to No unit) then do (Game - Display to (All players) the text: BeforeLoop) else do (Do nothing)
      • Unit - Add Banish to (Last created unit)
      • Unit - Order (Last created unit) to Human Blood Mage - Banish tempUnit2
      • -------- - --------
      • -------- Cast Banish on random targets around target --------
      • Set tempGroup = (Units within 400.00 of point1 matching (((Matching unit) belongs to an enemy of (Owner of tempUnit)) Equal to True))
      • Unit Group - Remove (Target unit of ability being cast) from tempGroup
      • Unit Group - Pick every unit in tempGroup and do (Actions)
        • Loop - Actions
          • Set tempInt = (tempInt + 1)
          • If (All Conditions are True) then do (Then Actions) else do (Else Actions)
            • If - Conditions
              • 7 Greater than tempInt
            • Then - Actions
              • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
              • If ((Last created unit) Equal to No unit) then do (Game - Display to (All players) the text: bla) else do (Do nothing)
              • Unit - Add Chain Banish (dummy) to (Last created unit)
              • Unit - Order (Last created unit) to Orc Far Seer - Chain Lightning (Picked unit)
              • Unit - Create 1 caster 5 sec for (Owner of tempUnit) at tempPoint facing Default building facing degrees
              • Unit - Add Banish to (Last created unit)
              • Unit - Order (Last created unit) to Human Blood Mage - Banish (Picked unit)
            • Else - Actions
      • Custom script: call DestroyGroup(udg_tempGroup)
      • Custom script: call RemoveLocation( udg_tempPoint )
      • Custom script: call RemoveLocation( udg_point1 )
Thx for giving me 3 orbs :)

the target unit "function" returns that unit when called, once it is called it clears that unit and thats why second time using it will return null or smth...

thous storing it to variable is a must if you will use that function multiple times, it might not clear it after first call but most likely it will...
 
Level 15
Joined
Jul 19, 2007
Messages
618
Triggering unit was also bugging....

In case you are interested, this is the thread on wc3c on which someone helped me with this.

no GetTriggerUnit() always works! it was your bug coz "GetTriggerUnit()" returns an "event" unit and in your case event unit was null. why? coz there was no event, only response was a timer which executed that function, this is same bug that Deuterium made in his spells. all this GetTriggerUnit, GetExpiredTimer, GetEventDamage()... they work only for events and well GetExpiredTimer is not responding fully to event but its logical that it returns timer which just expired...

however GetSpellTargetUnit() is different and well maybe blizzard did not want to clear it but maybe they did... anyway you must store it in variable same as GetSpellTargetLoc(), well X and Y where added through...
 
Level 11
Joined
Feb 22, 2006
Messages
752
Channel is a dummy spell. Most people use it for completely triggered spells. For example, they give an ability based off channel to a unit or a hero then when that ability is cast, a trigger is run that actually runs all the spell effects (special effects, damage, buffs, w/e). Channel is an ideal base ability for dummy abilities because it allows you to change a lot of stuff that other spells don't:

  • BaseOrderID
  • Visibility in the UI
  • Target Type (Instant, Unit, Point)
  • Show/Don't show AOE art (the graphic that appears over the AOE circle for spells like blizzard and flamestrike)
  • Treat as Physical/Universal spell (i.e. bypass spell immunity)
  • Unique Cast (if multiple units are selected all with the spell, does ordering the spell to be cast cause all selected units to cast it simultaneously? e.g. Defend is not a unique cast while Roar is)
 
Level 4
Joined
Aug 13, 2009
Messages
57
Channel is a dummy spell. Most people use it for completely triggered spells. For example, they give an ability based off channel to a unit or a hero then when that ability is cast, a trigger is run that actually runs all the spell effects (special effects, damage, buffs, w/e). Channel is an ideal base ability for dummy abilities because it allows you to change a lot of stuff that other spells don't:

But i Have a Problem I can't See the Skill At the Hero Abilities In-game:nemor:
 
Level 2
Joined
Feb 8, 2009
Messages
16
Great post. This helped me with at least 90% of the issues I was having. I'm new to triggering and I found this easy to follow. Nicely done.
 
Level 4
Joined
Mar 1, 2014
Messages
68
Some explanation please :vw_wtf: The periodic time is .01 seconds

Problems:
1.) The angle sometimes not accurate :(
2.) The spell isn't running unless i have 2 units casting at the same time .. TY
 

Attachments

  • Run.png
    Run.png
    29.1 KB · Views: 89
  • Setup.png
    Setup.png
    15.2 KB · Views: 62
Top