HomeUser Control Panel (unavailable in archive)ForumsTutorialsArt GalleryResourcesMaps

NOVAH's Unit Swap Question

12-13-2002, 08:56 AM#1
Guest
This post is for Novah, who I ran into on the irc channel. I hope you are out there. I figured I would post to the forum, as this may benefit someone else.

You were trying to figure out a way to swap all units of one player to another player. Shortly after you left the channel, I figured out a way that works in my test case.

I have a timer set up in the initialization function which fires a mere 0.1 seconds later and starts my unit swap trigger. Inside the unit swap trigger, I add all player 1 units to a unit group variable (RedUnits). Then I change ownership of all player 2 units to player 1, retaining color. Then I change ownership of all units in the RedUnits group to be owned by player 2, retaining color. Then I just swap the player colors. This seems to do the trick nicely.

I have spent the last hour or so trying to figure out a way to write a more generalized JASS function which could be used by everyone, but I am annoyed that the group API does not seem to support a way to iterate through the group elements without using ForGroup(). I dislike this function because you are required to create another function as the callback. If JASS had anonymous/lambda functions or something, this problem would go away, but it doesn't and for the time being I'm not happy requiring 4 functions where one should seemingly suffice.

anyway, hope that helps.. see you on IRC (or Bnet).

BB-jerji
12-13-2002, 02:24 PM#2
Aiursrage2k
Heres what I came up with... In this instance it switches player 1 units with player 2, then player 3 with player 4.

function ChrPlyrY takes nothing returns nothing
call SetUnitOwner( GetEnumUnit(), ConvertedPlayer(udg_Plyr1), udg_conDen1)
endfunction
function ChrPlyrX takes nothing returns nothing
call SetUnitOwner( GetEnumUnit(), ConvertedPlayer(udg_Plyr2), udg_conDen2)
endfunction

function swp takes integer count1, integer count2, boolean tf1, boolean tf2 returns nothing
call GroupClear( udg_X )
call GroupClear( udg_Y )
call GroupAddGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), ConvertedPlayer(count1)), udg_X )
call GroupAddGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), ConvertedPlayer(count2)), udg_Y )
set udg_Plyr1 = count1
set udg_Plyr2 = count2
set udg_conDen1 = tf1
set udg_conDen2 = tf2
call ForGroup( udg_Y, function ChrPlyrY )
call ForGroup( udg_X, function ChrPlyrX )
endfunction

function Trig_Pck_Actions takes nothing returns nothing
call swp(1,2, true, true)
call swp(3,4, true, true)
endfunction

//===========================================================================
function InitTrig_Pck takes nothing returns nothing
set gg_trg_Pck = CreateTrigger( )
call TriggerAddAction( gg_trg_Pck, function Trig_Pck_Actions )
endfunction

Where: udg_X, udg_Y are unit groups and udg_Plyr1, udg_Plyr2 are integers, udg_conDen1, udg_conDen1 are booleans. The idea was based on the algortithm given by BB-jerji. BTW it seems that Unit Group arrays do not work, anyone else experience this?

swp(a,b,c,d).
a=1st Player to be swapped.
b=2nd Player to be swapped.
c = 1st player retain color (True) / change color (False)
d = 2nd player retain color (True) / change color (False)
a & b, x > 0 && x <= 12
12-13-2002, 06:41 PM#3
Guest
Define "do not work." From reading these forums, I would guess that perhaps your problem is that the array was not initialized. Apparently you have to set up all the fields in the initialization or you end up with a zero-length array.

btw, thanks for your feedback. I had written something very similar, actually. I was just hoping to avoid having to use global variables to pass the player indexes to my callbacks. ahh, the woes of Jass. :)

I haven't given up hope though! I still think there exists a better way. :)

BB-jerji
12-13-2002, 06:54 PM#4
Aiursrage2k
It seems in the function ForGroup has two parameters, the second parameter which happens to be a function wont let you pass a parameter, which is a pain the ***... If you find a better way I would be glad to here of it.
12-13-2002, 07:00 PM#5
Guest
Yeah, this is what I was referring to. You can't pass an argument in places where jass expects a callback. This is super easy to do in Lisp. :)

I'll reply here if I figure anything out.

BB-jerji
12-13-2002, 09:59 PM#6
Aiursrage2k
Been working on this for quite a while, it works with my test trials. Just make sure not to pass invalid data, no udg variables are required, does not use ForGroup function.

function ForG2 takes group whichGroup, integer count1, boolean tf1 returns nothing
local unit xy = null
local integer n = CountUnitsInGroup(whichGroup)
set bj_forLoopAIndex = 1
set bj_forLoopAIndexEnd = n
loop
set xy = null
exitwhen bj_forLoopAIndex > bj_forLoopAIndexEnd
set xy = FirstOfGroup(whichGroup)
call SetUnitOwner( xy , ConvertedPlayer(count1), tf1)
call GroupRemoveUnitSimple( xy, whichGroup )
set bj_forLoopAIndex = bj_forLoopAIndex + 1
endloop
endfunction

function swp takes integer count1, integer count2, boolean tf1, boolean tf2 returns nothing
local group x = CreateGroup()
local group y = CreateGroup()
call GroupAddGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), ConvertedPlayer(count2)), x )
call GroupAddGroup( GetUnitsInRectOfPlayer(GetPlayableMapRect(), ConvertedPlayer(count1)), y )
call ForG2( x, count1, tf1)
call ForG2( y, count2, tf2)
endfunction

function Trig_Pck_Actions takes nothing returns nothing
call swp(1,2, true, true)
call swp(4,3, true, true)
endfunction

function InitTrig_Pck takes nothing returns nothing
set gg_trg_Pck = CreateTrigger( )
call TriggerAddAction( gg_trg_Pck, function Trig_Pck_Actions )
endfunction