HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Dang JASS, help me plz.

02-23-2004, 02:18 AM#1
Narwanza
Okay, I'm an idiot today. The only question I have left is: Are there really only 26 or so elseifs allowed per if-then block?
02-23-2004, 03:22 AM#2
Oinkerwinkle
I have no idea about your question, but if you are running into that then you should just be able to nest a new if block in the final else of your first one.
02-23-2004, 03:30 AM#3
weaaddar
I've never tested it but I believe that the Elseif problem was more of a call limit issue and not a limitation of jass.
02-23-2004, 05:23 AM#4
Narwanza
I ask the question because of this at the jass sourceforge page.

Quote:
- Noted that there is a max of 26 elseif clauses per if-then-else block.

I will test it for myself though

Okay, now I have really run into a problem. See if you can help me figure this out. It seems that the spawn functions won't execute the other spawn functions unit the entire funciton is done running wich makes no sense. Right now all of the enemytypes are set to 'hkni' because I wanted to c if it was a problem with my if-then block, but it wasn't I got the same delay. Help me if you can.

Code:
function Spawn_Monsters_Left takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Left_Spawn)
[color=red]    call Spawn_Monsters_FLeft()[/color]
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Spawn_Monsters_Right takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Right_Spawn)
[color=red]    call Spawn_Monsters_Left()[/color]
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Trig_Timer_Destroy_Actions takes nothing returns nothing
    call DestroyTimerDialogBJ( udg_TimerWindow )
[color=red]    call Spawn_Monsters_Right()[/color]
//    call TriggerSleepAction( 0.25 )
    call DisplayTextToForce( udg_Players, ( ( "|c00FF8E00Level " + ( I2S(udg_Level) + " of 40" ) ) + ( ": " + ( ( I2S(( udg_EnemyNumber[udg_Level] + 1 )) + ( " " + ( GetUnitName(GetLastCreatedUnit()) + "s" ) ) ) + "|r" ) ) ) )
//    call Spawn_Monsters_Left()
//    call TriggerSleepAction( 0.25 )
//    call Spawn_Monsters_FRight()
//    call TriggerSleepAction( 0.25 )
//    call Spawn_Monsters_FLeft()
//    call TriggerSleepAction( 0.25 )
    call TriggerSleepAction( 2 )
    if ( udg_Level == 0 ) then
        call ExplodeUnitBJ( gg_unit_hmpr_0035 )
    else
        call DoNothing(  )
    endif
endfunction

I didn't copy the whole trigger because it is huge, but see if you can help.
02-23-2004, 09:22 AM#5
Cubasis
Yes

There is a ifelse limit, however, you should not need to get close to it if you code properly, I reccomend you to rethink your function if you're having so many ifelse's. Like f.ex. use Arrays and Loops to do everything you need.

Btw, why in hell are you using integer arrays x and y? :/, it seems you only need 1 element. However, I do not see imediately what the problem is.
I can not see call Spawn_Monsters_FLeft().
And i don't understand your explenation of the problem, please explain better.

Oh, and why isn't this in AI/JASS forums?

Cubasis
02-23-2004, 01:59 PM#6
Narwanza
I dunno why it is here. I said I didn't post the entire trigger because it is huge, and I use arrays in case I end up using multiple loops in one function. When I don't need multiple loops and I complete the function I will delete the array part and just leave them as integers. For some strange reason it just won't run the next function until it is through spawning its side. If you want the whole trigger then here it is. It will answer your elseif question. Keep in mind that I am not finished with this trigger yet so there may be a whole bunch of extra sutff that I will delete later.
Code:
function Trig_Timer_Destroy_Conditions takes nothing returns boolean
    if ( not ( udg_isGameOver == false ) ) then
        return false
    endif
    return true
endfunction

function Set_up_wave takes integer i returns integer
    local integer enemies
    if (i == 0) then
        set enemies = 'hfoo'
    elseif (i == 1) then
        set enemies = 'hkni'
    elseif (i == 2) then
        set enemies = 'hrif'
    elseif (i == 3) then
        set enemies = 'hgry'
    elseif (i == 4) then
        set enemies = 'hspt'
    elseif (1 == 5) then
        set enemies = 'hmtt'
    elseif (i == 6) then
        set enemies = 'nmyr'
    elseif (i == 7) then
        set enemies = 'nnsw'
    elseif (i == 8) then
        set enemies = 'ospw'
    elseif (i == 9) then
        set enemies = 'hphx'
    elseif (1 == 10) then
        set enemies = 'otau'
    elseif (i == 11) then
        set enemies = 'nano'
    elseif (i == 12) then
        set enemies = 'nndr'
    elseif (i == 13) then
        set enemies = 'ucry'
    elseif (i == 14) then
        set enemies = 'nvde'
    elseif (1 == 15) then
        set enemies = 'hblm'
    elseif (i == 16) then
        set enemies = 'ndqs'
    elseif (i == 17) then
        set enemies = 'nina'
    elseif (1 == 18) then
        set enemies = 'npfm'
    elseif (i == 19) then
        set enemies = 'uskm'
    elseif (i == 20) then
        set enemies = 'nwgs'
    elseif (i == 21) then
        set enemies = 'edcm'
    elseif (i == 22) then
        set enemies = 'njgb'
    elseif (1 == 23) then
        set enemies = 'nsko'
    elseif (i == 24) then
        set enemies = 'nmgd'
    elseif (i == 25) then
        set enemies = 'h000'
    elseif (1 == 26) then
        set enemies = 'ndmu'
    endif
    if (i == 27) then
        set enemies = 'ntrd'
    elseif (i == 28) then
        set enemies = 'nubw'
    elseif (i == 29) then
        set enemies = 'nsgg'
    elseif (i == 30) then
        set enemies = 'nhrq'
    elseif (i == 31) then
        set enemies = 'esen'
    elseif (1 == 32) then
        set enemies = 'nnrg'
    elseif (i == 33) then
        set enemies = 'nsnp'
    elseif (i == 34) then
        set enemies = 'zhyd'
    elseif (i == 35) then
        set enemies = 'uktg'
    elseif (i == 36) then
        set enemies = 'nchr'
    elseif (1 == 37) then
        set enemies = 'nthr'
    elseif (i == 38) then
        set enemies = 'nhym'
    elseif (i == 39) then
        set enemies = 'nvl2'
    elseif (i == 40) then
        set enemies = 'zsco'
    endif
    return enemies
endfunction

function Spawn_Monsters_FRight takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Far_Right_Spawn)
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Spawn_Monsters_FLeft takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Far_Left_Spawn)
[color=red]    call Spawn_Monsters_FRight()[/color]
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Spawn_Monsters_Left takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Left_Spawn)
[color=red]    call Spawn_Monsters_FLeft()[/color]
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Spawn_Monsters_Right takes nothing returns nothing
    local integer enemytype = 'hkni'
    local location RectCenter
    local integer array x
    local integer array y
    set x[1] = 1
    set y[1] = udg_EnemyNumber[udg_Level]
    set RectCenter = GetRectCenter(gg_rct_Right_Spawn)
[color=red]    call Spawn_Monsters_Left()[/color]
    loop
        exitwhen x[1] >= y[1]
        call CreateNUnitsAtLocFacingLocBJ( 1, enemytype, Player(11), RectCenter, RectCenter )
        call SetUnitExplodedBJ( GetLastCreatedUnit(), true )
        call TriggerSleepAction(.5)
        set x[1] = x[1] + 1
    endloop
    call RemoveLocation(RectCenter)
    set RectCenter = null
endfunction

function Trig_Timer_Destroy_Actions takes nothing returns nothing
    call DestroyTimerDialogBJ( udg_TimerWindow )
[color=red]    call Spawn_Monsters_Right()[/color]
//    call TriggerSleepAction( 0.25 )
    call DisplayTextToForce( udg_Players, ( ( "|c00FF8E00Level " + ( I2S(udg_Level) + " of 40" ) ) + ( ": " + ( ( I2S(( udg_EnemyNumber[udg_Level] + 1 )) + ( " " + ( GetUnitName(GetLastCreatedUnit()) + "s" ) ) ) + "|r" ) ) ) )
//    call Spawn_Monsters_Left()
//    call TriggerSleepAction( 0.25 )
//    call Spawn_Monsters_FRight()
//    call TriggerSleepAction( 0.25 )
//    call Spawn_Monsters_FLeft()
//    call TriggerSleepAction( 0.25 )
    call TriggerSleepAction( 2 )
    if ( udg_Level == 0 ) then
        call ExplodeUnitBJ( gg_unit_hmpr_0035 )
    else
        call DoNothing(  )
    endif
endfunction

//===========================================================================
function InitTrig_Spawn takes nothing returns nothing
//    local trigger array spawntrigs
//    set spawntrigs[1] = CreateTrigger()
//    set spawntrigs[2] = CreateTrigger()
//    set spawntrigs[3] = CreateTrigger()
//    set spawntrigs[4] = CreateTrigger()
//    set spawntrigs[5] = CreateTrigger()
//    set gg_trg_Spawn = CreateTrigger(  )
    call TriggerRegisterTimerExpireEventBJ( gg_trg_Spawn, udg_NextLvlTimer )
    call TriggerAddCondition( gg_trg_Spawn, Condition( function Trig_Timer_Destroy_Conditions ) )
    call TriggerAddAction( gg_trg_Spawn, function Trig_Timer_Destroy_Actions )
    call TriggerAddAction( spawntrigs[1], function Spawn_Monsters_FLeft )
    call TriggerAddAction( spawntrigs[5], function Set_up_wave )
endfunction
02-23-2004, 02:11 PM#7
LegolasArcher
Just a tip. Set all your monsters types to an array in GUI at initialization, that call them with

Code:
udg_MonsterArray[udg_level]

Everytime a level ends set:

Code:
set udg_level = udg_level + 1

Thats how I coded the spawn system for the TD im triggering and terrianing for, and it works flawlessly.:D
02-23-2004, 02:33 PM#8
Cubasis
Ahhh

I think i see your problem.... you're misunderstanding how threads work in JASS, don't worry, I didn't figure it at start.

Basicly, your whole code is in "1" thread (a Trigger). When you call other functions, it exectutes the statements there while still being in the same original thread.

Now, when you do a TriggerSleepAction... it goes to do "other" threads. But since all your spawn functions are using the same thread, the runtime goes all the way to Spawn_Monsters_FRight, where it slowly spawns its units, when it has finished spawning, it continues up the function-call ladder you created to do the Spawn_Monsters_FRight statements etc.

So what you need to do, is to use this function, passing it the spawn function. And then it will create a thread for it. You can also loop all the spawns in one loop, but that's your choice.

Hope that helps.

And yes, what i was talking about in the earlyer thread is what .......LegolasArcher.... explained, to use Arrays (and loops if needed) instead of extended elseif's.

Cubasis

Edit.... *thinks about entering the Vex's-Avatar trend*
02-23-2004, 02:35 PM#9
LegolasArcher
Uh, Im not Lord Vexorian, although some days I wish I was (being more of a trigger expert and such). Its amazing what an avatar can do ;)
02-23-2004, 04:35 PM#10
Cubasis
erhm

Esotric: We (LegolasArcher) already mentioned that...

:D

Cubasis
02-23-2004, 10:40 PM#11
Narwanza
There is a very good reason as to why I am getting rid of my GUI array set up. There are 40 levels for the TD, and so that would be 40 different arrays called. Each array has an 8 byte index stacked on top of the actual stuff stored in the array. This would be stupid to have and causes unnecessary memory use. This function will get rid of global variables completely, plus it will get rid of the array pointers. So it is much more optimized than a normal GUI TD monster array. It is also contained in 1 trigger so that the game doesn't have to go through as many triggers thus reducing lag. I will look into your previous answer cubasis.
02-23-2004, 10:48 PM#12
Oinkerwinkle
I'm otherwise unhelpful, but I noticed that you had some typos involving replacing i's with 1's. I saw it on 5, 10, 15, 18, 23, 26, 32, and 37.
02-23-2004, 11:16 PM#13
Narwanza
Thanks for mentioning that oinkerwinkle. I just noticed it actually, I was testing and lvl 5 wouldn't work so I had to go back and change all of the 1's to i's. They look so much alike that I completly didn't see it and then I did CnP.
02-23-2004, 11:21 PM#14
Cubasis
Erhm

There are few things more efficient as working with arrays. You don't leak anything, and it is the (generally) same speed as accessing a normal variable (which happens instantly).

Quote:
There are 40 levels for the TD, and so that would be 40 different arrays called.


Do you mean 40 array elements? that is, slots in the array? Or... 40 arrays?, if the latter...why would you need 40 different arrays?

Quote:
would be stupid to have and causes unnecessary memory use.


Unit-Types are just integer values.... integer values take up 4 bytes in memory... 4x40 = 160 kb's .... is that really a concern where spawning a single unit uses up even more than that?

Quote:
plus it will get rid of the array pointers.


If you mean the index to the current level... isn't that just teh same as "takes integer i" this integer your function takes?


So generally, either i'm misunderstanding your post completely, or you're misunderstanding arrays and memory leaks completely.



Quote:
It is also contained in 1 trigger so that the game doesn't have to go through as many triggers thus reducing lag.


So you got to either cut it up in 4 threads, or combine all 4 spawn locations into a single loop.

I generally think you're overly paranoid against leaks and lag. Using that function to create different threads for you won't leak any memory. And .... Triggers don't cause lag, extensive visual statements do, or extensive memory leaking (or if you have a 0.001 periodic trigger doing something crazy).

However, NOTE: I just noticed one thing myself in that function, to be able to use it, you HAVE to remove the "DestroyTrigger" call in it, and add it to the end of each of your threads/functions (doing "call DestroyTrigger( GetTriggeringTrigger() )).

Good luck
02-24-2004, 12:13 AM#15
Narwanza
This way is more efficient, just trust me. Also, I don't need to remove the destroy trigger because I played it all the way through and it was just fine. I didn't say leak, I said get rid of unnecessary memory use. Anywayz now it works just fine, so thanks for your help earlier cubasis, can someone delete this thread now?