HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

Changing Terrain: Strings, Integers, SubString, etc.

02-29-2008, 03:34 AM#1
Zandose
This is a example of using a string which has terrain information (type and variance), then SubString to split it up into what is needed. The problem is each time you use string it creates a new one, thus leaking. I'm wondering if there are any others methods or ways in which I could do this with less leaks.
Collapse JASS:
scope test

public struct Terrain_Preset
    static integer     array    terrain_type //Should be changed from 2 integers to WC3's Terrain Type integer system.
    static integer     array    terrain_variance //This only uses 2 integers (18 variances pre terrain type).
    static integer              limit //Simply when to stop (size of the map).
    
    //Simply changes all the terrain on a map. It starts at the top/left of the map, moving to the next left terrain block
    //(128.00 real), repeating until it reachs the end (32), then moves one block down and repeats again, changing the 
    //whole map.
    static method Create takes nothing returns nothing
        local integer i1=0 //X
        local integer i2=0 //Y
        local integer i3=0 //counter
        local rect r=GetWorldBounds()
        local real x=GetRectMinX(r) //top/left
        local real y=GetRectMaxY(r) //^^
        local real w=(GetRectMaxX(r)-GetRectMinX(r))/128 //Size of map and when to stop
        local real h=(GetRectMaxY(r)-GetRectMinY(r))/128 //^^
        call RemoveRect(r)
        loop
            loop
                call SetTerrainType(x+(i1*128),y-(i2*128),.terrain_type[i3],.terrain_variance[i3],1,1)
                set i1=i1+1
                exitwhen i1==w+1
            endloop
            set i1=0
            set i2=i2+1
            exitwhen i2==h+1
        endloop
        set i1=0
        set i2=0
        set i3=0
        set x=0
        set y=0
        set w=0
        set h=0
    endmethod
    
endstruct


function start takes nothing returns nothing
    local Terrain_Preset STP=Terrain_Preset.create()
    local integer i=0
    //One big string/integer with all terrain information; 2 integers for the Terrain Type, and 2 integer for the Terrain 
    //Variance. This should be 4096 integers long, but I made it small for the example.
    local string s="7142893757385789574381578947584375894173957485743857894357934758478634832948329403248329432403294823"
    set STP.limit=1024 //1024 equals the number of terrain blocks (128x128) in a 32x32 game.
    loop
        set STP.terrain_type[i]=S2I(SubString(s,(i*4),(i*4)+1)) //Gets the first 2 integers in a 4 block. Ex: 71
        set STP.terrain_variance[i]=S2I(SubString(s,(i*4)+2,(i*4)+3)) //Gets the second two integers in a 4 block. Ex: 42
        set i=i+1
        exitwhen i==STP.limit
    endloop
endfunction

endscope


I looked into using one long integer but you can't SubString an integer (doesn't exist). I should make a integer array and manually split the integers into seperate array variables, but doing it 2048 times for a 32x32 map doesn't really sound fun, plus larger maps would be worse. Now that I think about it, would anyone make me a program that given a string of integers will automaticlly seperate it into their own code (see example below).
Collapse JASS:
//7142893757385789574381578947584375894173957485743857894357934758478634832948329403248329432403294823
//Would become (see function at buttom)...

scope test

public struct Terrain_Preset
    static integer     array    terrain_type //Should be changed from 2 integers to WC3's Terrain Type integer system.
    static integer     array    terrain_variance //This only uses 2 integers (18 variances pre terrain type).
    static integer              limit //Simply when to stop (size of the map).
    
    //Simply changes all the terrain on a map. It starts at the top/left of the map, moving to the next left terrain block
    //(128.00 real), repeating until it reachs the end (32), then moves one block down and repeats again, changing the 
    //whole map.
    static method Create takes nothing returns nothing
        local integer i1=0 //X
        local integer i2=0 //Y
        local integer i3=0 //counter
        local rect r=GetWorldBounds()
        local real x=GetRectMinX(r) //top/left
        local real y=GetRectMaxY(r) //^^
        local real w=(GetRectMaxX(r)-GetRectMinX(r))/128 //Size of map and when to stop
        local real h=(GetRectMaxY(r)-GetRectMinY(r))/128 //^^
        call RemoveRect(r)
        loop
            loop
                call SetTerrainType(x+(i1*128),y-(i2*128),.terrain_type[i3],.terrain_variance[i3],1,1)
                set i1=i1+1
                exitwhen i1==w+1
            endloop
            set i1=0
            set i2=i2+1
            exitwhen i2==h+1
        endloop
        set i1=0
        set i2=0
        set i3=0
        set x=0
        set y=0
        set w=0
        set h=0
    endmethod
    
endstruct

function blah takes nothing returns nothing
    local Terrain_Preset STP=Terrain_Preset.create()
    set STP.terrain_type=71
    set STP.terrain_variance=42
    set STP.terrain_type=89
    set STP.terrain_variance=37
    set STP.terrain_type=57
    set STP.terrain_variance=38
    set STP.terrain_type=57
    set STP.terrain_variance=89
    //etc...
endfunction

endscope

Edit: I'm going to sleep now. So take your time. I won't reply or see this for almost 24 hours.
02-29-2008, 07:15 AM#2
Ammorth
You could use a bignum library and then push numbers into the decimal (divide by 10^x) and then convert the decimal back to the number (multiply by 10^x). The problem you will run into with normal integers is that with long numbers, you will over-flow.
02-29-2008, 07:34 AM#3
PipeDream
there's no leak, you're good to go as is. you'll probably run into other problems using strings, but cross that bridge when you come to it.
02-29-2008, 11:58 AM#4
Toadcop
Quote:
there's no leak, you're good to go as is. you'll probably run into other problems using strings, but cross that bridge when you come to it.
+1
own experience is the best experience.

Quote:
would anyone make me a program that given a string of integers will automaticlly seperate it into their own code
i theoreticaly =) (it's not so hard) PM me if something.
02-29-2008, 12:52 PM#5
Zandose
Quote:
Originally Posted by Ammorth
You could use a bignum library and then push numbers into the decimal (divide by 10^x) and then convert the decimal back to the number (multiply by 10^x). The problem you will run into with normal integers is that with long numbers, you will over-flow.
I don't really understand this, but I'm in a rush so I'll take a better look later today. Is there a name or wiki for this?

Quote:
Originally Posted by PipeDream
there's no leak, you're good to go as is. you'll probably run into other problems using strings, but cross that bridge when you come to it.
I thought each time you used a native which required a string (Ex: SubString) you'd create a new string (leak), and you can't remove it.
02-29-2008, 01:44 PM#6
Vexorian
To add, you are generating very few strings, besides of the huge one that is totally necessary for your idea, you cannot generate more than 10 different new strings. So, string-wise your code is a non-issue.
03-01-2008, 12:43 AM#7
Pyrogasm
Isn't there a limit to the length of strings? I thought over 800 characters or something and you have to use contenation (however it is you spell that).
03-01-2008, 01:29 AM#8
Zandose
@vex
I'm not doing only 10 SubStrings. For a 32x32 map I'd be doing 2048 SubString's (I think). The short integer string in the example was only a example. The real thing will have 4096 integers, divided into an array of string variables depending on the string limit.
03-01-2008, 03:09 PM#9
Toadcop
1023... is the limit.
1013 (or 1015,1016 and you map will crash on save loading.)

preproccesor TT.