HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

test

01-20-2008, 04:34 AM#1
Zandose
This spell creates a area of ice and then after a set amount of time changes it back to the original terrain. It works fine but if you cast the ability on the buttom left of the map it doesn't work. The first jass code is what (i think) is giving me problems and the second is the whole thing. Download the map if you don't want to go though the trouble of setting it up.

Collapse JASS:
    loop //Changes the terrain back to normal depending on if ix/iy is 0 (no reset) or 1 (reset)
        loop
            if block[(i[2] * RADIUS) + i[1]] == 1 then //Just assume this is always true
                call SetTerrainType(x + I2R((i[1] * 128)), y - (I2R(i[2] * 128)), te[R2I(y / 128) - i[2]].t[R2I(x / 128) + i[1]], va[R2I(y / 128) - i[2]].v[R2I(x / 128) + i[1]], 1, 1)
            endif
            set i[1] = i[1] + 1 //Simply moves y to next place along its axis
            exitwhen i[1] == RADIUS * 2
        endloop
        set i[2] = i[2] + 1
        set i[1] = 0
        exitwhen i[2] == RADIUS * 2
    endloop

Collapse JASS:
scope Ice

globals //You can edit anything here
    private constant integer AID_ABILITY = 'A000' //The ability
    private constant integer TID_TERRAINTYPE = 'Iice' //Whatever type of terrain you want to use. I can change this to use a list of different terrains and variances, just ask.
    private constant integer TID_VARIANCE = -1 //Each terrain type should have 18 variances. Use -1 for random variances
    private constant integer RADIUS = 3 //size/area affected; one equals one block (128x128); just do some testing with it and use lowest numbers
    private constant integer SHAPE = 1 //0=circle; 1=square; Should I add different shapes?
    private constant real RESET = 5.00 //How long to wait before changing the area back to normal for a level 1 ability
    private constant real RESET_PRELEVEL = -1.00 //How much time to add/subtract per level
    private constant integer MAP_SIZE_X = 32 //Width: Left/Right
    private constant integer MAP_SIZE_Y = 32 //Height: Up/Down
endglobals

private struct data //For each instace of the ability
    real x //simple casting point aligned to the grid
    real y //simple casting point aligned to the grid
endstruct

private struct terrain
    integer array t[MAP_SIZE_X] //Terrain Types
endstruct

private struct variance
    integer array v[MAP_SIZE_X] //Terrain Variances
endstruct

globals //Used for struct globals
    terrain array te //Used for terrain type storage. NOT PRIVATE; can be used by other triggers.
    variance array va //Used for terrain type storage. NOT PRIVATE; can be used by other triggers.
    private data array index //Index for the struct "data"
endglobals

private function TerrainReset takes nothing returns nothing
    //Changes a select area back to normal terrain
    local data s = index[0]
    local data s2
    local integer array i //Loop array
    local real x = s.x - (RADIUS * 128) //Current struct instance
    local real y = s.y + (RADIUS * 128) //Changes the casting point to the top/left of the area effected (iced)
    local real x2 //Some other struct instance
    local real y2 //Some other struct instance
    local real array block //Used to keep track of which blocks should NOT be reset; 0=no reset, and 1=reset.
    set i[1] = 0
    loop //Presets the reset/no-reset terrain thing to 1, which can be altered/changed later.
        set block[i[1]] = 1
        set i[1] = i[1] + 1
        exitwhen i[1] == (RADIUS + RADIUS) * (RADIUS + RADIUS)
    endloop
    set i[6] = 0
    loop //Checks every struct to see if any will effect this one
        set i[6] = i[6] + 1
        exitwhen index[i[6]] == null
        set s2 = index[i[6]]
        //Checks the distance between every other instance. Can't have the ice disappearing if another ability is over it.
        if SquareRoot((s2.x + s.x) * (s2.x + s.x) + (s2.y - s.y) * (s2.y - s.y)) <= RADIUS * 2 * 128 and s != s2 then
            set x2 = s2.x + (RADIUS * 2 * 128) //Same as above but for the infringing instance
            set y2 = s2.y - (RADIUS * 2 * 128) //Same as above
            set i[1] = 0 //x
            set i[2] = 0 //y
            set i[3] = 0 //x2
            set i[4] = 0 //y2
            set i[5] = 0 //Counter for wait/sleep
            call BJDebugMsg("2.1")
            //I used if statements instead of extra loops; It was confusing to read with all those loops.
            //Some extra code can be added to decrease the number of checks; simply change where x/y starts and ends to decrease the area that needs to be checked.            
            loop
                loop
                    loop
                        loop
                            if x - (i[1] * 128) == x2 - (i[3] * 128) and y + (i[2] * 128) == y2 + (i[4] * 128) then //Checks if the x/y points are equal to any of the tx/ty points
                                set block[i[1] * RADIUS + i[2]] = 0 //Sets the terrain reset to no
                            endif
                            set i[3] = i[3] + 1
                            set i[5] = i[5] + 1
                            if i[5] == 2000 then
                                set i[5] = 0
                                call TriggerSleepAction(0.01)
                            endif
                            exitwhen i[3] == RADIUS * 2  
                        endloop
                        set i[3] = 0
                        set i[4] = i[4] + 1
                        exitwhen i[4] == RADIUS * 2  
                    endloop
                    set i[1] = i[1] + 1
                    exitwhen i[1] == RADIUS * 2    
                endloop
                set i[1] = 0
                set i[2] = i[2] + 1
                exitwhen i[2] == RADIUS * 2
            endloop
        endif
    endloop //This is the closing for the distance check loop and if statment
    set i[1] = 0 //X
    set i[2] = 0 //Y
    loop //Changes the terrain back to normal depending on if ix/iy is 0 (no reset) or 1 (reset)
        loop
            if block[(i[2] * RADIUS) + i[1]] == 1 then
                call SetTerrainType(x + I2R((i[1] * 128)), y - (I2R(i[2] * 128)), te[R2I(y / 128) - i[2]].t[R2I(x / 128) + i[1]], va[R2I(y / 128) - i[2]].v[R2I(x / 128) + i[1]], 1, 1)
            endif
            set i[1] = i[1] + 1 //Simply moves y to next place along its axis
            exitwhen i[1] == RADIUS * 2
        endloop
        set i[2] = i[2] + 1
        set i[1] = 0
        exitwhen i[2] == RADIUS * 2
    endloop
    call s.destroy()
    set i[1] = 0 //index number
    loop //Moves all the structs (integers) one index down on the array
        set i[1] = i[1] + 1
        if index[i[1]] == null or index[i[1]] == 0 then
            set index[i[1] - 1] = 0
            exitwhen true
        endif
        set index[i[1] - 1] = index[i[1]]
    endloop
    set index[0] = 0
    call BJDebugMsg("Terrain Reset")
endfunction

private function Queue takes nothing returns nothing //A never stopping loop
    loop
        call TriggerSleepAction(0.50)
        if index[0] != 0 then
            call TerrainReset.execute()
        endif
    endloop
endfunction

private function TerrainChange takes nothing returns nothing
    //Changes a select area into ice terrain
    local integer i = 0
    local real x = I2R(R2I(GetLocationX(GetSpellTargetLoc()) / 128) * 128) //Aligns the X point to the closest grid point of a multiple of 128
    local real y = I2R(R2I(GetLocationY(GetSpellTargetLoc()) / 128) * 128) //Aligns the Y point to the closest grid point of a multiple of 128
    call BJDebugMsg("First:" + R2S(x) + "/" + R2S(y))
    call SetTerrainType(x, y, TID_TERRAINTYPE, TID_VARIANCE, RADIUS, SHAPE) //Change to use selective shapes and such    
    call TriggerSleepAction(RESET + (RESET_PRELEVEL * GetUnitAbilityLevel(GetTriggerUnit(), GetSpellAbilityId())))
    loop //Finds a empty index for the struct
        if index[i] == null or index[i] == 0 then
            set index[i] = data.create()
            set index[i].x = x
            set index[i].y = y
            exitwhen true
        endif
        set i = i + 1
    endloop  
    call BJDebugMsg("Terrain Changed")
endfunction

private function Conditions takes nothing returns boolean
    return GetSpellAbilityId() == AID_ABILITY
endfunction

public function InitTrig takes nothing returns nothing
    local trigger t1 = CreateTrigger()
    local integer array i
    local rect r = GetWorldBounds()
    local real x = GetRectMinX(r)
    local real y = GetRectMaxY(r)
    //------------------------------------------------
    set i[1] = 0
    loop
        call TriggerRegisterPlayerUnitEvent(t1, Player(i[1]), EVENT_PLAYER_UNIT_SPELL_CAST, null)
        set i[1] = i[1] + 1
        exitwhen i[1] == 12
    endloop
    call TriggerAddCondition(t1, Condition(function Conditions))
    call TriggerAddAction(t1, function TerrainChange)
    //------------------------------------------------
    call RemoveRect(r)
    set i[1] = 0 //X
    set i[2] = 0 //Y
    loop
        set te[i[2]] = terrain.create()
        set va[i[2]] = variance.create()
        loop
            set te[i[2]].t[i[1]] = GetTerrainType(x + (128 * i[1]), y - (128 * i[2]))
            set va[i[2]].v[i[1]] = GetTerrainVariance(x + (128 * i[1]), y - (128 * i[2]))
            set i[1] = i[1] + 1
            exitwhen i[1] == MAP_SIZE_X + 1
        endloop
        set i[1] = 0
        set i[2] = i[2] + 1
        exitwhen i[2] == MAP_SIZE_Y + 1
    endloop
    set index[0] = 0
    call Queue.execute()
endfunction

endscope
Attached Files
File type: w3xIce2.w3x (19.9 KB)
01-20-2008, 10:25 AM#2
Vexorian
Your function is totally obfuscated by the fact you are using a friging array instead of correctly named variables.
01-20-2008, 10:32 AM#3
zen87
Quote:
Originally Posted by Zandose
Collapse JASS:
private struct terrain
    integer array t[MAP_SIZE_X] //Terrain Types
endstruct

private struct variance
    integer array v[MAP_SIZE_X] //Terrain Variances
endstruct

something is really really wrong here...
01-20-2008, 07:36 PM#4
Zandose
@Vex - I don't understand. Do you know it's so messed up you can't read/understand it? Please clarify.

@zen87 - Doesn't seem wrong to me. The map size can be anything from 32-256 (I think WE Unlimted can do larger?). Anyways, in a map of 32x32 (2944x2944 ingame) you have 1024 "blocks" which you need to save their information. Each block being 128x128 (that's the size each block of terrain is). Two arrays of 1024 would work for a 32x32 game, one to hold the terrain type, and the other the variance of the terrain. But, if you have a game of 256x256 you'd need an array of 65536, the games arrays stop at around 8100. To deal with the problem I could create a set of array in a box type (sorry I don't know the proper term). 256 arrays with a size of 256 each, but this would be troublesome, plus if the game was smaller you'd want the user to delect all those extra arrays. The solution is simple (I hope), use structs and create variable arrays as needed. I could be mistaken but aren't structs like variable arrays?