| 04-25-2003, 02:17 PM | #1 |
I found a way to sync any integers, so you can for example get camera target information in multiplayer. It uses the selection of the player of whom you want the information to send the bits of the integer. It creates some flying sheeps for this but this can be done with any selectable unit. The wait can probably be reduced and optimized to reduce the time the information transfer takes. For an example of how this can be used look at the newest version of AMAI, that now includes a dialog version of the Commander ( http://home.no/amai ). The attack Current Screen command uses this. Here is the function. You pass the unsynced integer and the player of whom you want the information and get the synced integer returned: Code:
//===========================================================================
// Sync integer
//===========================================================================
function SyncInteger takes player sync_p, integer unsynced returns integer
local integer array source_int // the bits of the unsynced integer are stored in there
local integer array target_int // the bits of the synced integer are stored in there
local unit array sel_unit // the units used for the selection
local integer i = 1
local integer j = 0
local integer sum = unsynced
local group old_selection = CreateGroup()
local unit u = null
local integer bits_per_selection = 8 // that many bits are sent per selection
local integer selection_num = 4 // that many times a selection is done
local integer bits_number = selection_num * bits_per_selection // number of bits of integer used
local timer t = CreateTimer()
// separate integer in bits
if sum < 0 then
set source_int[0] = 1
set sum = -sum
else
set source_int[0] = 0
endif
loop
exitwhen i >= bits_number
set source_int[i] = ModuloInteger(sum, 2)
set sum = sum / 2
set i = i + 1
endloop
// create units to select
set i = 0
loop
exitwhen i >= bits_per_selection
set sel_unit[i] = CreateUnitAtLoc( sync_p, 'nshf', GetPlayerStartLocationLoc(sync_p), bj_UNIT_FACING )
set i = i + 1
endloop
// save old selection
call SyncSelections()
call GroupEnumUnitsSelected(old_selection, sync_p, null)
// send the bits by selection
set i = 0
loop
exitwhen i >= selection_num
// write information
if GetLocalPlayer() == sync_p then
set j = 0
call ClearSelection()
loop
exitwhen j >= bits_per_selection
if source_int[i*bits_per_selection + j] == 0 then
call SelectUnit(sel_unit[j], false)
else
call SelectUnit(sel_unit[j], true)
endif
set j = j + 1
endloop
endif
// read information
call TimerStart(t, 1, false, null) // prevent wait bug
loop
exitwhen TimerGetRemaining(t) <= 0
call TriggerSleepAction(0.5)
endloop
call SyncSelections()
set j = 0
loop
exitwhen j >= bits_per_selection
if IsUnitSelected(sel_unit[j], sync_p) then
set target_int[i*bits_per_selection + j] = 1
else
set target_int[i*bits_per_selection + j] = 0
endif
set j = j + 1
endloop
set i = i + 1
endloop
// restore selection
if GetLocalPlayer() == sync_p then
call ClearSelection()
loop
set u = FirstOfGroup(old_selection)
exitwhen u == null
call SelectUnit(u, true)
call GroupRemoveUnit(old_selection, u)
endloop
endif
call SyncSelections()
// remove units to select
set i = 0
loop
exitwhen i >= bits_per_selection
call RemoveUnit(sel_unit[i])
set i = i + 1
endloop
// rebuild integer
set i = bits_number - 1
set sum = 0
loop
exitwhen i < 1
set sum = 2 * sum + target_int[i]
set i = i - 1
endloop
if target_int[0] != 0 then
set sum = -sum
endif
return sum
endfunctionIf you only have small numbers you can reduce the number of bits that are sent. |
