• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

[JASS] Destructible Creation Loop Issue

Status
Not open for further replies.
Level 23
Joined
Nov 29, 2006
Messages
2,482
Okay, so I have this code which is run at map initialization creating doodads all over the map. But the weird thing is that it doesn't fill the whole map; I stops somewhere of 25% on the x-direction, but creates trees on the y-direction. So any help would be appreciated

Please not that I am aware of that this is a custom texted trigger. However I use so many custom scripts since BJ fuctions are completely incompetent, so I think it should be considered to be posted here in the jass section ._.

Im also aware of not nullifying some variables, but I will, its not the main problem.

Also Im wondering, isnt it possible to create local variables on map init? I get a compiling error when I try that.
Edit: I found the problem with the locals (still this trigger is global though)

Anyway here is the code:
JASS:
globals
    real                    udg_rx                     = 0
    real                    udg_ry                     = 0
    rect                    udg_r                      = null
    integer                 udg_i1                     = 0
    location                udg_p1                     = null
    integer                 udg_i2                     = 0
    location                udg_p2                     = null
    trigger                 gg_trg_Tree_Creation       = null
endglobals

JASS:
function Trig_Tree_Creation_Actions takes nothing returns nothing
    call FogEnableOff(  )
    call FogMaskEnableOff(  )
    set udg_r = bj_mapInitialPlayableArea
    set udg_rx = (GetRectMaxX(udg_r) - GetRectMinX(udg_r))/128
    set udg_ry = (GetRectMaxY(udg_r) - GetRectMinY(udg_r))/128
    set udg_p1 = Location(GetRectMinX(udg_r), GetRectMinY(udg_r))
    set udg_i1 = 0
    loop
        exitwhen udg_i1 > R2I(udg_rx)
        set udg_i2 = 0
        loop
            exitwhen udg_i2 > R2I(udg_ry)
            set udg_p2 = Location(GetLocationX(udg_p1) + (I2R(udg_i1) * 128), GetLocationY(udg_p1) + (I2R(udg_i2) * 128))
            call CreateDestructableLoc( 'ATtr', udg_p2, GetRandomDirectionDeg(), GetRandomReal(0.80, 1.20), GetRandomInt(0, 4) )
            call RemoveLocation( udg_p2 )
            set udg_p2 = null
            set udg_i2 = udg_i2 + 1
        endloop
        set udg_i1 = udg_i1 + 1
    endloop
    call RemoveLocation( udg_p1 )
    set udg_p1 = null
endfunction

/regards
 
Last edited:
Level 11
Joined
Feb 18, 2004
Messages
394
#1: Use locals...
#2: Don't use locations...
#3: Use JASS NewGen. Your problem is likely a thread crash from hitting the op limit. (War3Err, part of NewGen, will tell you when that happens in-game.) Adding a call to TriggerSleepAction(0) in the outer loop should fix it. (or splitting the code in to two separate functions and using ExecuteFunc, but TSA() should do.)

JASS:
function Trig_Tree_Creation_Actions takes nothing returns nothing
    local real startx = GetRectMinX(bj_mapInitialPlayableArea)
    local real starty = GetRectMinY(bj_mapInitialPlayableArea)
    
    local real endx = (GetRectMaxX(bj_mapInitialPlayableArea) - startx) / 128
    local real endy = (GetRectMaxY(bj_mapInitialPlayableArea) - starty) / 128
    
    local integer ix = 0
    local integer iy = 0

    loop
        exitwhen ix > endx
        
        set iy = 0
        loop
            exitwhen iy > endy
            
            call CreateDestructable('ATtr', startx + ix * 128.0, starty + iy * 128.0, GetRandomReal(0, 360), GetRandomReal(0.80, 1.20), GetRandomInt(0, 4))

            set iy = iy + 1
        endloop
        call TriggerSleepAction(0)
        
        set ix = ix + 1
    endloop
    
    call FogEnableOff()
    call FogMaskEnableOff()
endfunction

Syntax checked but not tested. Also, as this code isn't creating and destroying a crapload of locations, it should run somewhere around twice as fast. (barring the sleep, of course.) If it runs excessively slow, use ExecuteFunc() to run the inner loop and loose the wait.
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
hm okay I see your way is way more effective than mine.

When it comes to JASSnewgen I cant figure out how to run war3err when testing.
Also, is this making the trigger completely unreadable by normal WE or do I have to stick to NewGen in the future?

Also, isnt it better/faster to create a local rect variable calling bj_mapInitialPlayableArea once, instead of calling it multiply times?

hm =)?
Thx for the solution, (but I still have these questions above left, so feel free to answer again)

/me adds rep.
 
Level 11
Joined
Feb 18, 2004
Messages
394
When it comes to JASSnewgen I cant figure out how to run war3err when testing.
Under the Grimoire menu in the main WE window, ensure "start WC3 with grimoire" is checked, as well as "Enable war3err"

Also, is this making the trigger completely unreadable by normal WE or do I have to stick to NewGen in the future?
The JASS I posted is not vJASS and does not require NewGen.
However, if you're using NewGen, then you shouldn't use ExecuteFunc() if you choose to go that route. You should use vJASS's .execute() syntax. (Not .evaluate()!) Read more in the vJASS manual. (Latest version is in the jasshelper folder of the latest newgen, but a commonly outdated version is available online)

Also, isnt it better/faster to create a local rect variable calling bj_mapInitialPlayableArea once, instead of calling it multiply times?
bj_mapInitialPlayableArea is a global variable. You'd gain microseconds at best by putting its value in to a local, especially considering you don't use it within the loops.
 
Level 23
Joined
Nov 29, 2006
Messages
2,482
(or splitting the code in to two separate functions and using ExecuteFunc, but TSA() should do.)

Well hi again, but TSA was definitely slow, since it uses ~0.3 seconds delay between the laps.
And, could you help me with the ExecuteFunc? I tried that, founding it creating only 1 row multiply times instead of 1. How should it be coded so that it can remember the x and y reals in both functions? (I suppose with globals, but you said I shouldnt)...

Hm, I might even got it all wrong. Alittle help again would be great :p
 
Level 11
Joined
Feb 18, 2004
Messages
394
If you're gonna use normal JASS, you should probably use a trigger with TriggerExecute anyway, but I'm too lazy to manually code that... so:
JASS:
globals
    real udg_treeCreateX
    real udg_treeCreateStartX
    real udg_treeCreateStartY
    real udg_treeCreateEndX
    real udg_treeCreateEndY
endglobals

function Trig_Tree_Creation_Actions_Child takes nothing returns nothing
    local integer i = 0
    loop
        exitwhen i > udg_treeCreateEndY

        call CreateDestructable('ATtr', udg_treeCreateStartX + udg_treeCreateX * 128.0, udg_treeCreateStartY + i * 128.0, GetRandomReal(0, 360), GetRandomReal(0.80, 1.20), GetRandomInt(0, 4))

        set i = i + 1
    endloop
endfunction

function Trig_Tree_Creation_Actions takes nothing returns nothing
    set udg_treeCreateStartX = GetRectMinX(bj_mapInitialPlayableArea)
    set udg_treeCreateStartY = GetRectMinY(bj_mapInitialPlayableArea)

    set udg_treeCreateEndX = (GetRectMaxX(bj_mapInitialPlayableArea) - udg_treeCreateStartX) / 128
    set udg_treeCreateEndY = (GetRectMaxY(bj_mapInitialPlayableArea) - udg_treeCreateStartY) / 128

    set udg_treeCreateX = 0
    loop
        exitwhen udg_treeCreateX > udg_treeCreateEndX

        call ExecuteFunc("Trig_Tree_Creation_Actions_Child")

        set udg_treeCreateX = udg_treeCreateX + 1
    endloop

    call FogEnableOff()
    call FogMaskEnableOff()
endfunction

And If you're gonna use vJASS:
JASS:
scope TreeCreate initializer Initialize
globals
    private real StartX
    private real StartY
    private real EndY
endglobals

private function Child takes real ix returns nothing
    local integer iy = 0
    loop
        exitwhen iy > EndY

        call CreateDestructable('ATtr', StartX + ix * 128.0, StartY + iy * 128.0, GetRandomReal(0, 360), GetRandomReal(0.80, 1.20), GetRandomInt(0, 4))

        set iy = iy + 1
    endloop
endfunction

private function Actions takes nothing returns nothing
    local integer ix = 0
    
    local real endx = (GetRectMaxX(bj_mapInitialPlayableArea) - GetRectMinX(bj_mapInitialPlayableArea)) / 128
    set EndY = (GetRectMaxY(bj_mapInitialPlayableArea) - GetRectMinY(bj_mapInitialPlayableArea)) / 128
    
    set StartX = GetRectMinX(bj_mapInitialPlayableArea)
    set StartY = GetRectMinY(bj_mapInitialPlayableArea)
    
    loop
        exitwhen ix > endx

        call Child.execute(ix)

        set ix = ix + 1
    endloop

    call FogEnableOff()
    call FogMaskEnableOff()
endfunction

// Have to create a trigger to fire on an event and all...
private function Initialize takes nothing returns nothing
    local trigger t = CreateTrigger()
    call TriggerAddAction(t, function Actions)
    //call TriggerRegisterWhateverEvent()
    // Or if you just want it to run on map initialization, remove this function
    // and rename "Actions" to "Initialize".
endfunction
endscope

Note that the vJASS version will be somewhat faster. (At least in theory.)
 
Status
Not open for further replies.
Top