1. Updated Resource Submission Rules: All model & skin resource submissions must now include an in-game screenshot. This is to help speed up the moderation process and to show how the model and/or texture looks like from the in-game camera.
    Dismiss Notice
  2. DID YOU KNOW - That you can unlock new rank icons by posting on the forums or winning contests? Click here to customize your rank or read our User Rank Policy to see a list of ranks that you can unlock. Have you won a contest and still havn't received your rank award? Then please contact the administration.
    Dismiss Notice
  3. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  4. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  5. Units have been turned into heroes in our latest Icon Contest! Vote for the best icon set at the Icon Contest #18 Poll!
    Dismiss Notice
  6. The poll for Hive's 12th Concept Art Contest is up! Go cast your vote for your favourite genie!
    Dismiss Notice
  7. The raddest synthwave tracks were chosen - Check out our Music Contest #12 - Results and congratulate the winners!
    Dismiss Notice
  8. Check out the Staff job openings thread.
    Dismiss Notice
Dismiss Notice
60,000 passwords have been reset on July 8, 2019. If you cannot login, read this.

[JASS] Natives and Local variables ...

Discussion in 'Triggers & Scripts' started by mckill2009, Feb 26, 2011.

  1. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    Hello Hivers!...I'm learning JASS and experimented on local variables...
    The trigger below works...but is there something better?...


    Code (vJASS):

    function Trig_Test_Flying_Height_Conditions takes nothing returns boolean
        if ( not ( GetSpellAbilityId() == 'ACbl' ) ) then
        endif
        return true
    endfunction
    function Trig_Test_Flying_Height_Actions takes nothing returns nothing
        local unit target = GetSpellTargetUnit()
        call TriggerSleepAction (10)
        call SetUnitFlyHeightBJ(target, 0.00, 500 )
    endfunction
    //===========================================================================
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        set gg_trg_Test_Flying_Height = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Test_Flying_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Test_Flying_Height, Condition( function Trig_Test_Flying_Height_Conditions ) )
        call TriggerAddAction( gg_trg_Test_Flying_Height, function Trig_Test_Flying_Height_Actions )
    endfunction
     


    • Test Kill Unit
      • Events
        • Unit - A unit Is attacked
      • Conditions
      • Actions
        • Custom script: local unit target = GetTriggerUnit()
        • Custom script: local unit caster = GetAttacker()
        • Custom script: call TriggerSleepAction(10)
        • Custom script: call KillUnit(target)
        • Custom script: set target = null


    An expert (forgot his name) said that GUI is limited and cant access all
    natives, so my question is this...can you provide an example of native(s) except local that GUI doesnt have?...
     
    Last edited: Feb 26, 2011
  2. Raven0

    Raven0

    Joined:
    Oct 16, 2010
    Messages:
    878
    Resources:
    2
    Maps:
    2
    Resources:
    2
    As far as natives goes theres:

    GetUnitZ(unit WhichUnit?)

    and the set lightning Z height

    struct capabilities

    and alot more

    ________________

    As far as the code goes:

    Take away the double negative in the condition, see how it says "if not then return false", that could just be "if then return true"

    You should null the local unit variable when you are done with it to free up the memory (set target = null)

    Sleeps/waits are very innacurate in jass, making them practically useless. Most jassers use timers instead.

    The BJ for SetUnitFlyHeight doesn't do anything different than the native, it just calls the native. So basically you'r going through two functions unnecessarily. Use the native instead (just take the "BJ" off the function name).

    ________________

    As far as your attempt to learn jass goes:

    Good luck!
     
  3. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    oh yeah the 'null' thing, it clears leaks :)...

    so on every function do we really have to remove BJ's?...

    why GUI doesnt have just "return true?"...

    anyway this is just a test...
     
  4. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    Do you have Jass NewGen? There's a built in function list in it.
     
  5. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    Code (vJASS):


    function Trig_Test_Flying_Height_Conditions takes nothing returns boolean
        if ( not ( GetSpellAbilityId() == 'ACbl' ) ) then
        endif
        return true
    endfunction

    //this could be just this

    function Trig_Test_Flying_Height_Conditions takes nothing returns boolean
        return  GetSpellAbilityId() == 'ACbl'
    endfunction

    /*And they say that its better to combine the conditions and actions into the conditions part, for better performance
    not sure if you could do the wait part inside the condition though, but its always better to avoid waits anyway

    something like this without the wait
    */


    function Trig_Test_Flying_Height_Conditions takes nothing returns boolean
        local unit target = GetSpellTargetUnit()
        if GetSpellAbilityId() == 'ACbl'  then
           call SetUnitFlyHeightBJ(target, 0.00, 500 )
        endif
        return true
    endfunction

    //===========================================================================
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        set gg_trg_Test_Flying_Height = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Test_Flying_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Test_Flying_Height, Condition( function Trig_Test_Flying_Height_Conditions ) )
    endfunction
     
     
  6. Raven0

    Raven0

    Joined:
    Oct 16, 2010
    Messages:
    878
    Resources:
    2
    Maps:
    2
    Resources:
    2
    If you DL JNGP and look through the function list you'll understand. BJ's are just functions that refer to natives in some way. Sometimes they do nothing and just call the native (making them useless), sometimes they just re-arrange the parameters and call the native (making them useless), and sometimes they call multiple natives to make it so you can get what you need done in just 1 function call (making them good in SOME cases). Not all BJ's are bad, just most are inefficient, useless, and impractical.
     
  7. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    Using waits inside boolexpr functions will cause the function to stop executing.

    Because actions start a new thread and conditions don't. I don't like it personally, since I like segregating my code to make em readable.

    Oh, some newbie tips, stop using BJ's (Blizzard jass), because:
    Code (vJASS):

    function SetUnitFlyHeightBJ takes unit whichUnit, real newHeight, real rate returns nothing
        call SetUnitFlyHeight(whichUnit, newHeight, rate)
    endfunction
     

    It just calls a native function call, and that's pointless, it would also slow down the execution since executing jass non-native functions are slow.
    Also, not all BJ's are bad, take ModuloInteger for example.
    Try opening the blizzard.j found on the jasshelper folder(if you have one), which contains the jass script written by blizzard.

    You also can't do recursions in jass, there's a thread execution limit.

    That's all I could add right now.
     
  8. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    so this is suppose to be the true JASS?...

    Code (vJASS):

    function Trig_Test_Flying_Height_Conditions takes nothing returns boolean
        return  GetSpellAbilityId() == 'ACbl'
    endfunction
     


    I have JNGP but I dont use it coz it makes hashtables nearly or completely useless...

    I now understand how things work, but what I dont understand is this...

    Code (vJASS):

    //===========================================================================
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        set gg_trg_Test_Flying_Height = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Test_Flying_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Test_Flying_Height, Condition( function Trig_Test_Flying_Height_Conditions ) )
        call TriggerAddAction( gg_trg_Test_Flying_Height, function Trig_Test_Flying_Height_Actions )
    endfunction
     


    What I do know it's a MUST to have since it initializes triggers, but I dont know how it works...can it be simplified?
     
  9. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    That's not true jass, rather its a better way of scripting jass, with regards to the previous script. Don't dislike if's, they are useful if used properly.

    It does not. The hashtable is used to attach things to things without using custom attachment systems.

    It's important to initialize triggers because, initializers basically tell the engine:
    If you don't initialize triggers, how would it know that you wanted to detect some event.

    Code (vJASS):
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        set gg_trg_Test_Flying_Height = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Test_Flying_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Test_Flying_Height, Condition( function Trig_Test_Flying_Height_Conditions ) )
        call TriggerAddAction( gg_trg_Test_Flying_Height, function Trig_Test_Flying_Height_Actions )
    endfunction

    Aside from the global variable's horrible name, this trigger is already simple. You could replace the global trigger variable with a local one but you will not be able to reference that trigger outside the initialization function, aside from the trigger's action and condition's thread.
     
  10. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    Like what I said, "it's a MUST to have since it initializes triggers"...

    But this is what I mean about simplifying coz this is really UGLY >>> "gg_trg_" <<<

    And this is repeated...

    function Trig_Test_Flying_Height_Conditions
    function Trig_Test_Flying_Height_Actions
     
  11. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    Code (vJASS):

    //Since this is pure JASS, you must stick with the name of the init trigger

    function Filterer takes nothing returns boolean
        local unit target = GetSpellTargetUnit()
        if GetSpellAbilityId() == 'ACbl'  then
           call SetUnitFlyHeight(target, 500, 0.00)
        endif
        return true
    endfunction

    //===========================================================================
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Condition( function Filterer ) )
    endfunction

    /*
    if you will use JNGP, you can do this... and oh, JNGP allows JASS hashtable, only the GUI one is not fully supported
    */


    scope Test initializer init

     private function Filterer takes nothing returns boolean
        local unit target = GetSpellTargetUnit()
        if GetSpellAbilityId() == 'ACbl'  then
           call SetUnitFlyHeight(target, 500, 0.00)
           //you can actually set the rate to a higher number so that the height change isn't instant
        endif
        return true
     endfunction


     private function init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Condition( function Filterer ) )
     endfunction

    endscope
     
     
  12. Raven0

    Raven0

    Joined:
    Oct 16, 2010
    Messages:
    878
    Resources:
    2
    Maps:
    2
    Resources:
    2
    It only does that to hashtables used via GUI, if you use straight native hashtables then they work fine. So long as your coding in jass, JNGP won't screw up hashtables.
     
  13. Raven0

    Raven0

    Joined:
    Oct 16, 2010
    Messages:
    878
    Resources:
    2
    Maps:
    2
    Resources:
    2
    Code (vJASS):
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        set gg_trg_Test_Flying_Height = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( gg_trg_Test_Flying_Height, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( gg_trg_Test_Flying_Height, Condition( function Trig_Test_Flying_Height_Conditions ) )
        call TriggerAddAction( gg_trg_Test_Flying_Height, function Trig_Test_Flying_Height_Actions )
    endfunction


    Does the same thing as:

    Code (vJASS):
    function InitTestFlyingHeight takes nothing returns nothing
        local trigger t = CreateTrigger()
        call TriggerRegisterAnyUnitEventBJ(t, EVENT_PLAYER_UNIT_SPELL_EFFECT)
        call TriggerAddCondition(t, Condition(function Trig_Test_Flying_Height_Conditions))
        call TriggerAddAction(t, function Trig_Test_Flying_Height_Actions)
        set t = null
    endfunction
     
  14. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    Code (vJASS):

    /*
      I merged the actions into the conditions part, coz they say its better  

      Since this is pure JASS, you must stick with the name of the init trigger
    */

    function Filterer takes nothing returns boolean
        local unit target = GetSpellTargetUnit()
        if GetSpellAbilityId() == 'ACbl'  then
           call SetUnitFlyHeight(target, 500, 0.00)
        endif
        return true
    endfunction

    //===========================================================================
    function InitTrig_Test_Flying_Height takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Condition( function Filterer ) )
    endfunction

    /*
    if you will use JNGP, you can do this... and oh, JNGP allows JASS hashtable, only the GUI one is not fully supported
    */


    scope Test initializer init

     private function Filterer takes nothing returns boolean
        local unit target = GetSpellTargetUnit()
        if GetSpellAbilityId() == 'ACbl'  then
           call SetUnitFlyHeight(target, 500, 0.00)
           //you can actually set the rate to a higher number so that the height change isn't instant
        endif
        return true
     endfunction


     private function init takes nothing returns nothing
        local trigger t = CreateTrigger(  )
        call TriggerRegisterAnyUnitEventBJ( t, EVENT_PLAYER_UNIT_SPELL_EFFECT )
        call TriggerAddCondition( t, Condition( function Filterer ) )
     endfunction

    endscope
     
     
  15. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    You could change the name/identifier of those Trig_ things, to anything you like, those are custom/user functions.

    Look at Adiktuz's script, it's optimized.

    On longer actions however, I don't advise to combine the triggeraction with the triggercondition, as it adds code complexity, but that's just my preference.
     
  16. mckill2009

    mckill2009

    Joined:
    Mar 10, 2009
    Messages:
    4,696
    Resources:
    34
    Maps:
    5
    Spells:
    27
    JASS:
    2
    Resources:
    34
    Now that's better...blizzard's convertion of GUI to JASS a 'crap' one lol!...and yeah Im talking about GUI hashtables in JNGP that is completely useless...

    the problem with..."local trigger t = CreateTrigger()" is that you cant use it outside like chobibo said...oh well nevermind...

    Thanks for your answers guys, but 2 last things before I focus to JASS tutorial section...

    1. Is this the same in any cases?
    InitTrig_Test_Flying_Height "OR" InitTestFlyingHeight

    2. Can a local trigger/variable call a global one outside or inside the trigger?


    Thanks!...+rep to all except Raven coz I already given him on the other thread :)...
     
  17. Adiktuz

    Adiktuz

    Joined:
    Oct 16, 2008
    Messages:
    9,674
    Resources:
    23
    Models:
    2
    Packs:
    1
    Maps:
    1
    Spells:
    16
    Tutorials:
    1
    JASS:
    2
    Resources:
    23
    @1 - I think not... at least on the normal WE...

    @2 - a global if not private (a vJASS add-on), can be used in ANY trigger, (as long as its declared above the line which calls it, if ur using the variable editor, you shouldn't have any problems)
     
  18. Raven0

    Raven0

    Joined:
    Oct 16, 2010
    Messages:
    878
    Resources:
    2
    Maps:
    2
    Resources:
    2
    I myself have never referneced a trigger since i've moved to jass (except in damage detection triggers). You always reference functions not triggers, so I always declare my triggers local and then null them.
     
  19. chobibo

    chobibo

    Joined:
    Sep 24, 2005
    Messages:
    2,692
    Resources:
    0
    Resources:
    0
    1. Yes, because you're using newgen.
    2. Yes, as long as you have a reference/pointer to it.
    Code (vJASS):

    function sample1 takes nothing returns nothing
        local trigger local_trigger=CreateTrigger()
        set global_trigger=local_trigger
    endfunction

    function sample2 takes nothing returns nothing
        local trigger t=global_trigger
    endfunction


    Always remember that handles are not copied when assigned to another variable, the variable is just a pointer to the handle.

    Code (vJASS):

    function sample1 takes nothing returns nothing
        local trigger local_trigger=CreateTrigger()
        set global_trigger=local_trigger
        call DestroyTrigger(local_trigger)
    endfunction

    function sample2 takes nothing returns nothing
        local trigger t=global_trigger // returns null because you already destroyed the trigger.
    endfunction
     


    This does not apply to primitive data types (boolean, integer, real and string) though.
     
  20. baassee

    baassee

    Joined:
    Nov 14, 2008
    Messages:
    3,220
    Resources:
    17
    Spells:
    14
    Tutorials:
    3
    Resources:
    17
    That's probably because in NewGen you aren't supposed to use the standard variable editor. Everything you need can you create within a globals block.

    Learn vJASS, it's easier and you learn it faster. And when you learned vJASS, you also automatically learns JASS with a few cons since you have to create a few variables in the variable editor like Hashtables.