| 01-28-2006, 02:10 PM | #1 |
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 |
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 |
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 | |
Quote:
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 |
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 |
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 |
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 |
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 |
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 |
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 |
hmnn I just noted that there is another exitwhen condition , it also exits when j==33 |
| 01-28-2006, 04:10 PM | #12 |
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... |
