Warcraft III resources & community, 2003–2006 · archived

SyncInteger

not rated
Submitted by AIAndyVariable Change0 downloads
This function syncs any unsynced integer. Pass the unsynced integer and the player from whom you want to sync it and it will return the same integer but synced. It uses the selection of the player from whom you sync but restores the old selection afterwards.
This can be used to retrieve unsynced information like camera information.

The function works by creating a number of flying sheeps. The sheeps are then selected a series of times to represent bits. If only one player selects something, it doesn't cause a desync, but it does sync that the player has selected the unit. This is why selections can be used to carry unsynced information.

Note: This function is not very fast.

Source

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

endfunction

Comments

0

No comments.