HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Help with //!textmacros

08-18-2009, 02:22 PM#1
Cheezeman
Hello mates!
So I'm making a spell once again, and I require assistance (due to the fact that I'm a newb).
The spell is quite complex, and because I'm new to textmacros I want to start off at a simple level.
What I want (at the current moment) spell to do is:
  • The user configures the path for a special effect in a string array (called SpecialEffectPath[n])
  • The user configures the interval he'd like the special effects to be created in a real array (called SpecialEffectInterval[n])
  • The user configures as many paths and intervals as he'd like to have
  • When the user casts the spell both (or more if the user would like) of the special effects are create at (0., 0.) every Interval[n] seconds
Right now, I'm not gonna use the timers just to keep it simple, but that should explain why I want to use textmacros (the intervals may differ so they have to call different functions)

So, to start off I made this textmacro:
Expand JASS:

Problem is I get an error:
Expand JASS:

This error is caused because I declare a function inside a function.
So... how do I avoid this? I'll need to have it inside MainActions because I'm gonna loop everything from 1 to [number of special effects]
I saw that it was possible in the online readme like this:
Expand JASS:
08-18-2009, 02:25 PM#2
Themerion
Collapse JASS:
    //! textmacro SFX takes NUMBER
        function SFX$NUMBER$ takes nothing returns nothing
            call AddSpecialEffect( SpecialEffect[$NUMBER$], 0., 0. )
        endfunction
    //! endtextmacro

  //! runtextmacro SFX("1")
  //! runtextmacro SFX("2")
  // etc...

    function MainActions takes nothing returns nothing
        call SFX1()
        call SFX2()
        // etc...
    endfunction
08-18-2009, 02:41 PM#3
Cheezeman
But... if I have to "call SFX1", this won't be very flexible?
I mean, after you set the path you still have to do "call SFXn" in the MainActions...
Isn't there some sort of "call SFX$number_of_instances_calculated_in_loop$" where number_of_instances_calculated_in_loop is how many arrays are used in SpecialEffectPath[]

something like
Collapse JASS:
function MainActions //blablabla
    local string str = SpecialEffectPath[1]
    local integer i = 0
    local integer i2 = 0
    loop
        exitwhen str == null
        set i = i + 1
        set str = SpecialEffectPath[i]
    endloop
    loop
        exitwhen i2 > i
        set i2 = i2 + 1
        //! runtextmacro SFX("i")
    endloop
endfunction     
08-18-2009, 02:53 PM#4
Themerion
Nope.

And your last code example is wrong. There's no function within a function:

Collapse JASS:
    //! textmacro bye
    call BJDebugMsg("1")
    call BJDebugMsg("2")
    call BJDebugMsg("3")
    //! endtextmacro

    function test takes nothing returns nothing
        //! runtextmacro bye()
        //! runtextmacro bye()
    endfunction
Collapse JASS:
// This is what it would look like when "compiled"
    function test takes nothing returns nothing
// Text-macro bye
        call BJDebugMsg("1")
        call BJDebugMsg("2")
        call BJDebugMsg("3")
// Text-macro bye
        call BJDebugMsg("1")
        call BJDebugMsg("2")
        call BJDebugMsg("3")
    endfunction

I don't really see why you're using TEXT macros when dealing with numbers... Just use a normal function!?

Collapse JASS:
function SFX takes integer i returns nothing
    call AddSpecialEffect( SpecialEffect[i], 0., 0. )
endfunction

//....

    loop
        exitwhen i2 > i
        set i2 = i2 + 1
        call SFX(i)
    endloop
08-18-2009, 03:04 PM#5
Cheezeman
I'll give it another shot of what I want then

Collapse JASS:
    //! textmacro SFX takes N
    function SFX$N$ takes nothing returns nothing
        call AddSpecialEffect( SpecialEffectPath[n], x, y ) //x and y are not declared yet
    endfunction
    //! endtextmacro

    private function MainActions takes nothing returns nothing
        local timer array t
        local string str = null
        local integer i = 1
        local integer n = 0
        
        loop
            set str = SpecialEffectPath[i]
            if str != null then
                set i = i + 1
            endif    
            exitwhen str == null
        endloop
        
        loop
            exitwhen n > i            
            set n = n + 1
            set t[n] = NewTimer()
            call TimerStart( t[n], SpecialEffectInterval[n], true, function SFX$n$ )
            //Somehow I want that $n$ but I don't know how I'm supposed to get it in there
        endloop
    endfunction

As I said, I'm new to textmacros so I'm not even sure this is possible.
Quote:
I don't really see why you're using TEXT macros when dealing with numbers... Just use a normal function!?
Because this includes timers with different intervals, and I want them to be automatically generated and not made by hand.
08-18-2009, 03:31 PM#6
Themerion
What about attaching the number 'n' to the timer? Since you're using NewTimer() I assume you are already using TimerUtils?

Collapse JASS:
// NO textmacros

function SFX takes nothing returns nothing
    local integer n = GetTimerData(GetExpiredTimer())
    call AddSpecialEffect( SpecialEffectPath[n], x, y )
endfunction

//.....

loop
  exitwhen n > i            
  set n = n + 1
  set t[n] = NewTimer()

  // Set n as data for the timer
  call SetTimerData(t[n],n)

  call TimerStart( t[n], SpecialEffectInterval[n], true, function SFX )
endloop

PS. Set/GetTimerData is in fact meant for structs, but since structs are integers, we can use it for integers too (in the cases where we only need 1 integer value per timer).
08-18-2009, 03:41 PM#7
Cheezeman
That is a terrific solution, I'll try it out right away.
+Rep aswell.
Edit: Second time I can't give you rep... ahve to spread around first...