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. The Lich King demands your service! We've reached the 19th edition of the Icon Contest. Come along and make some chilling servants for the one true king.
    Dismiss Notice
  4. The 4th SFX Contest has started. Be sure to participate and have a fun factor in it.
    Dismiss Notice
  5. The poll for the 21st Terraining Contest is LIVE. Be sure to check out the entries and vote for one.
    Dismiss Notice
  6. The results are out! Check them out.
    Dismiss Notice
  7. Don’t forget to sign up for the Hive Cup. There’s a 555 EUR prize pool. Sign up now!
    Dismiss Notice
  8. The Hive Workshop Cup contest results have been announced! See the maps that'll be featured in the Hive Workshop Cup tournament!
    Dismiss Notice
  9. 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: possible to call function a from within function b that is called from within function a?

Discussion in 'Triggers & Scripts' started by seasand3, Jul 9, 2019.

  1. seasand3

    seasand3

    Joined:
    Dec 17, 2017
    Messages:
    38
    Resources:
    0
    Resources:
    0
    Hey guys,
    there be two functions: function a and function b.
    if i call function b from within function a,
    is there a way i can call function a from within that function b again?

    since i declare b before a (blueprintish):
    Code (vJASS):

    function b
       
    endfunction

    function a
        call b()
    endfuction
     


    i cant call a from within b:

    Code (vJASS):

    function b
       call a() // this wont work
    endfunction

    function a
        call b()
    endfunction
     


    is there a workaround? the only thing that came to my mind was doing it with return values:
    Code (vJASS):

    function b
       return true
    endfunction

    function a
        bo = call b()
        if bo == true then
            call a() // parameters missing..
        endif
    endfunction
     

    but this probably wont work for me, not only cant i give parameters to a, but also can I only call a once, everytime I call b...

    Is it maybe possible with CreateTrigger() or CreateFunction() ?

    thanks in advance!
     
  2. Sabe

    Sabe

    Joined:
    Jul 30, 2018
    Messages:
    272
    Resources:
    1
    Spells:
    1
    Resources:
    1
    What is the exact purpose? Because that would generally create an infinite loop, which will lead to game crash.
     
  3. seasand3

    seasand3

    Joined:
    Dec 17, 2017
    Messages:
    38
    Resources:
    0
    Resources:
    0
    of course, i will only call a from within b under certain circumstances, e.g. something like:

    Code (vJASS):

    function b takes unit u, real x returns nothing
       SetUnitManaPercentBJ(u, GetUnitManaPercentBJ() - x)
       if GetUnitManaPercentBJ(u) > x then
           call a(u, x) // this wont work
       endif
    endfunction

    function a takes unit caster, real manacost returns nothing
        call b(caster, manacost)
    endfunction
     


    this is just an example and doesnt make sense the way it is. the actual functions will be more complex, i just cant post them, because i have not written them yet. still trying to figurre out the best way to do it!
     
  4. TriggerHappy

    TriggerHappy

    Code Moderator

    Joined:
    Jun 23, 2007
    Messages:
    3,668
    Resources:
    22
    Spells:
    11
    Tutorials:
    2
    JASS:
    9
    Resources:
    22
    You can with
    TriggerEvaluate
    on a wrapper function with globals as the paramaters.

    vjass handles it automatically with
    .evaluate
    .

    JassHelper 0.A.0.0
     
  5. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,046
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    In your example, what is the purpose of function "a" when you instead could just call the function "b" directly?

    Some context into what exactly you're trying to do would be preferred, and would avoid this logic dilemma you're facing.
     
  6. seasand3

    seasand3

    Joined:
    Dec 17, 2017
    Messages:
    38
    Resources:
    0
    Resources:
    0
    hey, thanks for your replies, Sabe, Triggerhappy and Bribe!
    :)

    hm i want to stay away from vJass^^
    but
    that could work without v,right?

    as i said, that function doesnt make sense the way it is:
    but to elaborate on the context: i want to make a fully coded projectile (function a). when it impacts on a unit (or an target area) it will do certain things (effects - aswell fully coded) to that unit or area (depending on the projectile). the effects would be function b. if the hero that fires the projectile has a certain ability or item, it has a chance on impact to create more projectiles. I dont want to make a function for every kind of projectile or effect, so i made an effect function (function a) that executes the specific effect depending on its parameters.
    The same thing i need to do now for projectiles, but here is the problem: Imagine for example an projectile that explodes when it hits a target. from every unit within the explosion-area there flies off another projectile that returns to the caster and.. heals him if you want. i cannot do this if i cant find a way to call function a (projectile) from within function b (effect)

    hope that makes sense:D
    Greetings;)
     
  7. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,046
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Sounds like you should move the projectile creation function into a trigger condition and evaluate the trigger instead of calling it as a function. This ties into what @TriggerHappy was saying about wrapping it like that. Triggers can be evaluated at any point in the script regardless of where their functions originated from (in terms of precedence).

    I strongly recommend learning and using Lua however as the functions are much easier, logical and flexible to work with there.
     
  8. Ceday

    Ceday

    Joined:
    Feb 22, 2010
    Messages:
    1,076
    Resources:
    0
    Resources:
    0
    Just to mention another option, you can use ExecuteFunc and pass any required parameters via globals if necessary.
     
    Last edited: Jul 9, 2019
  9. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,046
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    Yeah ExecuteFunc is very versatile, albeit a slower option than adding conditions to triggers and evaluating them. Both of which are MUCH slower than simply calling a function in Lua.
     
  10. seasand3

    seasand3

    Joined:
    Dec 17, 2017
    Messages:
    38
    Resources:
    0
    Resources:
    0
    wow nice:)

    as far as i understood, there are now two possibilities to do it (besides lua, which im not yet familiar with and i probably wont use, because idk, it isnt viable in older versions.)
    possibility 1:
    put the projectile-initiation/creation function in the condition of a dummy-trigger and then execute that function via TriggerEvaluate() from anywhere in the script, even from within a function that is declared before the condition.

    possibility 2:
    use ExecuteFunc(),
    like for example:
    Code (vJASS):

    function b
       ExecuteFunc(a) // this works now?
    endfunction

    function a
        call b()
    endfunction
     


    would that work?

    this is so cool, thank you very much:)
     
  11. Ceday

    Ceday

    Joined:
    Feb 22, 2010
    Messages:
    1,076
    Resources:
    0
    Resources:
    0
    Although I agree, and think TriggerHappy's suggestion is better way to go, since he wanted a pure jass solution I decided to mention it. Because it won't be fun everytime you perform the wrap-around stuff manually where you perform an eval/execute.
     
  12. Bribe

    Bribe

    Joined:
    Sep 26, 2009
    Messages:
    8,046
    Resources:
    25
    Maps:
    3
    Spells:
    10
    Tutorials:
    3
    JASS:
    9
    Resources:
    25
    ExecuteFunc takes a string, so it would be "a".

    Also, while older versions of WarCraft 3 have a place, 1.31+ are the versions of the future where the most impressive features exist - and there are loads more to come! Lastly, backwards compatibility is nice, but Lua is an opportunity for you to learn an actual programming language (since JASS is not used by any other games in existence).

    People using 1.26a are running either on Vista or are using an illegitimate copy of WC3 (or both). Just embrace the future.
     
  13. Dr Super Good

    Dr Super Good

    Spell Reviewer

    Joined:
    Jan 18, 2005
    Messages:
    25,587
    Resources:
    3
    Maps:
    1
    Spells:
    2
    Resources:
    3
    Most performant way is to bind the function to a trigger condition. The trigger condition can be evaluated and arguments can be passed via dedicated global variables for storage in local variables.

    Slower than that is executing the function via function name string. Parameter passing is done the same way as before, using global variables and saving the values into local variables.
     
  14. seasand3

    seasand3

    Joined:
    Dec 17, 2017
    Messages:
    38
    Resources:
    0
    Resources:
    0
    Alright:)

    so the more preformant way {via TriggerEvaluate()} would look like this (trigger to custom):
    Code (vJASS):


    function effect takes unit caster, unit target, real x, real y, integer effekt, returns nothing
        local real angle
        //...
        set udg_proj_x = x
        set udg_proj_y = y
        set udg_proj_a = angle // for example a random angle
        TriggerEvaluate(gg_trg_test)
    endfunction

    // some other code, triggers, etc..

    function Trig_test_Conditions takes nothing returns boolean
        local real x
        local real y
        local real angle
        set x = udg_proj_x
        set y = udg_proj_y
        set angle = udg_proj_a
        //...
    endfunction
    function Trig_test_Actions takes nothing returns nothing
    endfunction
    //===========================================================================
    function InitTrig_test takes nothing returns nothing
        set gg_trg_test = CreateTrigger(  )
        call TriggerAddCondition( gg_trg_test, Condition( function Trig_test_Conditions ) )
        call TriggerAddAction( gg_trg_test, function Trig_test_Actions )
    endfunction
     


    and the less performant one {via ExecuteFunc()} would just use the function directly as long as it takes nothing, since i cant pass parameters that way.
    Code (vJASS):

    function effect takes unit caster, unit target, real x, real y, integer effekt returns nothing
        local real angle
        //...
        set udg_proj_x = x
        set udg_proj_y = y
        set udg_proj_a = angle // for example a random angle
        set udg_proj_c = caster
        set udg_proj_t = target
        set udg_proj-e = effekt
        ExecuteFunc("projectile") // this works now!
    endfunction

    function impact takes unit caster, unit target, real x, real y, integer effekt, returns nothing
        call effect(caster, target, x, y, effekt)
    endfunction

    function projectile takes nothing returns nothing
        call impact(udg_proj_c, udg_proj_t, udg_proj_x, udg_proj_y, udg_proj_e)
    endfunction
     



    Thank you guys, now i can continue with my project:)
    well after the exams are done:D
    Greetings;)
     
    Last edited: Jul 10, 2019