HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

custom script yields casual results only

01-28-2006, 02:10 PM#1
Doomhammer
I'm still on my way developing a neat system for mass movement. This is one of the most important parts for my mass battle map, which is pure slaughter and extremely fun.
Atm the movement system consists of 1 base function, 2 additional functions and several filters. Phyrex1an already helped me a big deal on the base function, which I slowly modified to adjust my needs, but it's still somewhat not perfect yet:
I'm just about to test the base function. sometimes it runs through all the loops perfectly, sometimes it cuts off the final 3 loops, sometimes, it only works off the first few loops. I'm displaying text messages to see how it runs.

Could I post it somewhere? Is it okay for the experts here to have a look on it?
credit will be given for every help getting the whole damn thing working nice and neat...
01-28-2006, 02:17 PM#2
Blade.dk
Post it here so we can see it. That is completely ok, and if you don't do it chances that we can help you are small.
01-28-2006, 03:03 PM#3
Doomhammer
ok then, let's see what we got:

the udg_zone arry is my 33 gen. zones, basically covering all the relevant part of the map. This here is just the small part (about 30%), as I said, the two functions following are yet to be proved/changed. As I said, the whole thing works sporadically well...

Code:
function All_filter takes nothing returns boolean
    return IsUnitType(GetFilterUnit(), UNIT_TYPE_STRUCTURE) == false  and IsUnitType(GetFilterUnit(), UNIT_TYPE_PEON) == false and GetWidgetLife(GetFilterUnit()) > 0.4
endfunction

function OneId_filter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) == bj_groupEnumTypeId and GetWidgetLife(GetFilterUnit()) > 0.4
endfunction

function TwoId_filter takes nothing returns boolean
    return GetUnitTypeId(GetFilterUnit()) ==  bj_groupEnumTypeId  or GetUnitTypeId(GetFilterUnit()) == bj_forceCountPlayers  and GetWidgetLife(GetFilterUnit()) > 0.4
endfunction

function Group_filter takes nothing returns boolean
    return IsUnitInGroup(GetFilterUnit(), bj_randomSubGroupGroup)
endfunction

function MassMoveType takes integer unitId1, integer unitId2, real x1, real y1, player forPlayer, real sleeps returns nothing
    local group array zonegroup
    local group g = CreateGroup()
    local boolexpr b
    local unit tmp
    local real x
    local real y 
    local real dy
    local real dx
    local integer j
    local integer n
    local rect r
 
    if unitId1 == 0 and unitId2 == 0 then
        set b = Filter(function All_filter)
    elseif unitId2 == 0 then
        set bj_groupEnumTypeId = unitId1
        set b = Filter(function OneId_filter)
    else
        set bj_groupEnumTypeId = unitId1
        set bj_forceCountPlayers = unitId2
        set b = Filter(function TwoId_filter)               
    endif 
    
    call GroupEnumUnitsOfPlayer(g, forPlayer, b)
    call DestroyBoolExpr(b)
    set n = CountUnitsInGroup(g)
    call DisplayTextToForce( GetPlayersAll(), "g " + I2S(n) )  //display what's going on
    
    if n == 0 then
        call DoNothing()
    elseif n > 0 and n <= 12 then
        call GroupPointOrder( g, "attack", x1, y1)
        call DestroyGroup( g )
    elseif n > 12 then
        set j = 1
        set b = Filter(function Group_filter)
        set bj_randomSubGroupGroup = g  
        loop
            exitwhen g == null
            set zonegroup[j] = CreateGroup()
            call GroupEnumUnitsInRect(zonegroup[j], udg_zone[j], b)    
            set n = CountUnitsInGroup( zonegroup[j] )
              call DisplayTextToForce( GetPlayersAll(), "zonegrp " + I2S(j)+ " units " + I2S(n) )  // display what#s going on
            if n == 0 then
                call DoNothing()
            elseif n > 0 and n <= 12 then
                set x = GetRectCenterX(udg_zone[j])
                set y = GetRectCenterY(udg_zone[j])
                set dx = x1 - x
                set dy = y1 - y
                set x = 200 / SquareRoot(dx*dy + dy*dy) * dx
                set y = 200 / SquareRoot(dx*dy + dy*dy) * dy
                call GroupPointOrder(zonegroup[j], "attack", x1-x, y1-y )
                set bj_groupRemoveGroupDest = g
                call ForGroup(zonegroup[j], function GroupRemoveGroupEnum)
            elseif n > 12 then
                set bj_groupRemoveGroupDest = g
                call ForGroup(zonegroup[j], function GroupRemoveGroupEnum)
                set x = GetRectCenterX(udg_zone[j])
                set y = GetRectCenterY(udg_zone[j])
                set dx = x1 - x
                set dy = y1 - y 
                //if RAbsBJ(dx) > RAbsBJ(dy) then //I disabled this part to see whether the main function alone would do its duty
                  //  call SubDivideX(zonegroup[j], x1, y1, GetRectMinX(udg_zone[j]), GetRectMinY(udg_zone[j]), GetRectMaxX(udg_zone[j]), GetRectMaxY(udg_zone[j]), sleeps )
                //elseif RAbsBJ(dx) < RAbsBJ(dy) then
                  //  call SubDivideY(zonegroup[j], x1, y1, GetRectMinX(udg_zone[j]), GetRectMinY(udg_zone[j]), GetRectMaxX(udg_zone[j]), GetRectMaxY(udg_zone[j]), sleeps )
                //endif
            endif
            exitwhen j == 33
            call DestroyGroup(zonegroup[j])
            set zonegroup[j] = null
            set j = j + 1
        endloop
    endif
    call DestroyBoolExpr(b)
    call DestroyGroup( g )
    set g = null
endfunction
01-28-2006, 03:10 PM#4
Vexorian
Quote:
exitwhen g == null

in that loop you are never setting g to null, in fact the whole thing doesn't make any sense, when exactly do you want that loop to stop?
01-28-2006, 03:19 PM#5
qwertyui
Please use [jass] tags instead of [code] tags. Makes things easier to read.
Also don't really unnderstand the code too :/
01-28-2006, 03:39 PM#6
Doomhammer
g is the group of all groups so to speak. after the first sort all units of a certain unitID are sorted into g, regardless of their placement on the map. g contains all filtered units in all regions/zones. g becomes null after all units of g are spread on the zonegroups and removed from g. This is one exit condition, the other is when all my 33 zones are counted through, i.e. j == 33
hope it's clear
01-28-2006, 03:40 PM#7
Vexorian
did you really think g will become null when empty? g is a variable that points to a group . And the group itself isn't even destroyed. g will not become null unless you do g=null , I guess you would want to use (FirstOfGroup(g)==null) instead of (g==null)
01-28-2006, 03:45 PM#8
Doomhammer
I could go with IsUnitGroupEmptyBJ(g)
the exitwhen g == null is part of phyrex's script. there was nothing to criticize about that, it worked from the beginning, except that I often had a high overcount in the subgroups that would empty g far too soon.
01-28-2006, 03:49 PM#9
Vexorian
Of course "it worked" the loop never ended and eventually the thread crashed. IsGroupEmpty counts the units in the group so it is slower than FirstOfGroup(g)==null .

It also has some weird things like calling DoNothing() that is a dummy function that is not necessary in JASS you can just have
Code:
if n == 0 then
elseif n > 0 and n <= 12 then
01-28-2006, 03:57 PM#10
Doomhammer
didn't know about that. that'll definitely make it more efficient
having these changes done, it still not working as it should. I just had 20 units altogether, 11 in zone 30, 9 in zone 31. It just left the loop before zone 31.
01-28-2006, 04:06 PM#11
Vexorian
hmnn I just noted that there is another exitwhen condition , it also exits when j==33
01-28-2006, 04:10 PM#12
Doomhammer
jep, I haven't got more than 33 zones
for some reason I'm gettin different results whether a group would stand directly in a zone, or on the border between two zones.

hm, I reckon it's too much of a biggie to have it examinated by others...