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

jass: possible to call function a from within function b that is called from within function a?

Status
Not open for further replies.
Level 3
Joined
Dec 17, 2017
Messages
39
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):
JASS:
function b
    
endfunction

function a
    call b()
endfuction

i cant call a from within b:

JASS:
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:
JASS:
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!
 
Level 3
Joined
Dec 17, 2017
Messages
39
What is the exact purpose? Because that would generally create an infinite loop, which will lead to game crash.

of course, i will only call a from within b under certain circumstances, e.g. something like:

JASS:
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!
 
Level 3
Joined
Dec 17, 2017
Messages
39
hey, thanks for your replies, Sabe, Triggerhappy and Bribe!
:)

vjass handles it automatically with
.[COLOR=color: #666666]evaluate[/COLOR]
.
hm i want to stay away from vJass^^
but
You can with
TriggerEvaluate
on a wrapper function with globals as the paramaters.
that could work without v,right?

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.

as i said, that function doesnt make sense the way it is:
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!

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;)
 
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.
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
Just to mention another option, you can use ExecuteFunc and pass any required parameters via globals if necessary.
 
Last edited:
Level 3
Joined
Dec 17, 2017
Messages
39
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:
JASS:
function b
   ExecuteFunc(a) // this works now?
endfunction

function a
    call b()
endfunction

would that work?

this is so cool, thank you very much:)
 
Level 12
Joined
Feb 22, 2010
Messages
1,115
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.
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.
 
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:
JASS:
function b
   ExecuteFunc(a) // this works now?
endfunction

function a
    call b()
endfunction

would that work?

this is so cool, thank you very much:)

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.
 

Dr Super Good

Spell Reviewer
Level 64
Joined
Jan 18, 2005
Messages
27,201
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.
 
Level 3
Joined
Dec 17, 2017
Messages
39
Alright:)

so the more preformant way {via TriggerEvaluate()} would look like this (trigger to custom):
JASS:
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.
JASS:
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:
Status
Not open for further replies.
Top