HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

question about locals

06-16-2006, 10:55 AM#1
StRoNgFoE_2000
I've read up on local variables and I think I finally understand their usage. If I read correctly, using a local can prevent using huge arrarys and also prevent multiple triggers from affecting the variable you are using. I put together this trigger and I wonder, will this correctly work and not affect other heroes that resurrect?

Trigger:
AutoRessurection
Collapse Events
Unit - A unit Dies
Collapse Conditions
((Dying unit) is A Hero) Equal to True
Collapse Actions
Custom script: local unit udg_HeroRevivable
Set HeroRevivable = (Dying unit)
Wait (3.00 x (Real((Hero level of HeroRevivable)))) seconds
Set TempPoint = ((Owner of HeroRevivable) start location)
Hero - Instantly revive HeroRevivable at TempPoint, Show revival graphics
Point - Remove TempPoint

The only thing I am not sure is if you can use the Set HeroRevivable = (Dying unit) after declaring it local.
06-16-2006, 11:05 AM#2
iNfraNe
Yep this should work, why dont you just test it ? :)

Only thing you need to still do (at least i think so..) is set the variable to "No Unit" (null) at the end else it will leak a bit of memory.
06-16-2006, 11:12 AM#3
StRoNgFoE_2000
Quote:
Originally Posted by iNfraNe
Yep this should work, why dont you just test it ? :)

Only thing you need to still do (at least i think so..) is set the variable to "No Unit" (null) at the end else it will leak a bit of memory.

Sorry, I did test it and it worked but I just wanted to double check with the pros if I did it correctly. Local variable are the greatest thing ever, and the only last question I have is suppose I use a local for a loop. Can it be used multiple times in the trigger? I'll whip up a quick example...

Trigger:
Untitled Trigger 001
Events
Conditions
Collapse Actions
Custom script: local integer udg_localinteger
For each (Integer localinteger) from 1 to 4, do (-------- Actions --------)
For each (Integer localinteger) from 1 to 2, do (-------- Actions --------)
Collapse For each (Integer localinteger) from 1 to 23, do (Actions)
Collapse Loop - Actions
-------- Actions --------
-------- Actions --------
For each (Integer localinteger) from 1 to 5, do (-------- Actions --------)
06-16-2006, 12:28 PM#4
blu_da_noob
Yes. Just remember you can't use it any conditional stuff (the if part of if/then/else's) in GUI.
06-16-2006, 12:36 PM#5
StRoNgFoE_2000
Quote:
Originally Posted by blu_da_noob
Yes. Just remember you can't use it any conditional stuff (the if part of if/then/else's) in GUI.

Thank you. It's good to know it can still be used in the actions part.
06-16-2006, 12:56 PM#6
blu_da_noob
Oh yes, and they also can't be used in 'Pick everyunit in group and do XXX' actions (in this case, JASS or GUI, unless you use the firstofgroup loop method).
06-16-2006, 01:14 PM#7
iNfraNe
Just to tell you why that is the case: the gui code will create a new function for unit group / player group loops & conditions, in this new function the new local variable doesnt exist.

The solution for the if is easy. Just write it in custom text: "if true then" and to close it "endif". To view what the condition should look like just convert the trigger to jass, find the function holding your condition and paste the conditional part without not between the if and then in your custom script. Done :) for player/unitgroups its more difficult with using FirstOfGroup as blu suggested.
06-16-2006, 02:07 PM#8
StRoNgFoE_2000
Quote:
Originally Posted by iNfraNe
Just to tell you why that is the case: the gui code will create a new function for unit group / player group loops & conditions, in this new function the new local variable doesnt exist.

The solution for the if is easy. Just write it in custom text: "if true then" and to close it "endif". To view what the condition should look like just convert the trigger to jass, find the function holding your condition and paste the conditional part without not between the if and then in your custom script. Done :) for player/unitgroups its more difficult with using FirstOfGroup as blu suggested.

Cool, so if I do the below example trigger to kill the unit all should be good?
Trigger:
AutoRessurection
Collapse Events
Unit - A unit Dies
Collapse Conditions
((Dying unit) is A Hero) Equal to True
Collapse Actions
Custom script: local unit udg_HeroRevivable
Set HeroRevivable = (Dying unit)
Wait (3.00 x (Real((Hero level of HeroRevivable)))) seconds
Set TempPoint = ((Owner of HeroRevivable) start location)
Hero - Instantly revive HeroRevivable at TempPoint, Show revival graphics
Point - Remove TempPoint
Custom script: if ( IsUnitAliveBJ(udg_HeroRevivable) == true ) then
Unit - Kill HeroRevivable
Custom script: endif
Set HeroRevivable = No unit

Edit: also, is there a good place where i can read up on this "FirstOfGroup loop method"? And, is it possible to put in multiple conditions as opposed to just one?
06-16-2006, 02:19 PM#9
blu_da_noob
Yes, that would work fine. You can remove the '== true' part if you wish, it serves no purpose.

About the group loop thing: http://www.wc3jass.com/viewtopic.php...de4c1f65573885 .
06-16-2006, 04:38 PM#10
Anitarf
Also, event responses (except some exceptions, like the buggy cast event responses) work similar to local variables (same except that they also work in functions you call from your main action function, so they work in conditions and pick every ... loops), so you don't need a local variable to do something with the dying unit after a wait.
06-17-2006, 01:15 AM#11
StRoNgFoE_2000
Quote:
Originally Posted by Anitarf
Also, event responses (except some exceptions, like the buggy cast event responses) work similar to local variables (same except that they also work in functions you call from your main action function, so they work in conditions and pick every ... loops), so you don't need a local variable to do something with the dying unit after a wait.

So what you are saying is that I can just use "Dying Unit" instead of "HeroRevivable" itself like so?

Trigger:
AutoRessurection
Collapse Events
Unit - A unit Dies
Collapse Conditions
((Dying unit) is A Hero) Equal to True
Collapse Actions
Custom script: local unit udg_HeroRevivable
Set HeroRevivable = (Dying unit)
Wait (3.00 x (Real((Hero level of (Dying unit)))) seconds
Set TempPoint = ((Owner of (Dying unit)) start location)
Hero - Instantly revive (Dying unit) at TempPoint, Show revival graphics
Point - Remove TempPoint
Custom script: if ( IsUnitAliveBJ(udg_HeroRevivable) then
Unit - Kill (Dying unit)
Custom script: endif
Set HeroRevivable = No unit
06-17-2006, 03:02 AM#12
PipeDream
Yes. Keep the caveat in mind, GetSpell____() must be stored before other code is allowed to execute.
BTW your if condition is still using the variable. "Dying Unit" translates to GetDyingUnit() if you want to forget the var.
FWIW, if your heroes are permanent, you don't need to set the variables containing the reference to them to null. For consistencies sake you might as well do it anyway.

You need to use Wait - Game time (PolledWait()) to avoid time hopping ahead during pauses. This'll probably be sufficient, if you don't mind a half second of slop. Otherwise you'll need to use timers.
06-17-2006, 02:03 PM#13
StRoNgFoE_2000
I never knew there was an actual significant difference between game time and real time, so I guess game time is definitely the better choice for accuracy.. should have thought of using that before.

I tried using GetDyingUnit() instead of the variable name and it wouldn't compile the map. I'm not 100% on the proper way of typing it out, but I can look into it. I'm slowly reading up and learning more and more JASS functions to reap from its benefits.. the GUI is too limited. Anyway, thank you all for your help!
06-17-2006, 02:50 PM#14
blu_da_noob
Game time and real time actually go at the same speed, it's just that 'real time' ignore's stuff like the game being paused, while game-time does not.
06-17-2006, 04:49 PM#15
The)TideHunter(
Polled wait also skips time if its too long, which i think is stupid.
This is how it goes:

Collapse JASS:
function PolledWait takes real duration returns nothing
    local timer t
    local real  timeRemaining

    if (duration > 0) then
        set t = CreateTimer()
        call TimerStart(t, duration, false, null)
        loop
            set timeRemaining = TimerGetRemaining(t)
            exitwhen timeRemaining <= 0

            // If we have a bit of time left, skip past 10% of the remaining
            // duration instead of checking every interval, to minimize the
            // polling on long waits.
            if (timeRemaining > 2.00) then
                call TriggerSleepAction(0.1 * timeRemaining)
            else
                call TriggerSleepAction(0.10)
            endif
        endloop
        call DestroyTimer(t)
    endif
endfunction

And TriggerSleepAction is just a native, so i dont surpose the should be much wrong about that