Данная библиотека предназначена для быстрой синхронизации данных между игроками. Передача происходит через вызовы локального события клика по юниту.
Установка
Для установки скопируйте папку UnitSync, скопируйте dummy из РО, убедитесь что равкод dummy совпадает со значением UNIT_ID в триггере USync. Пользуйтесь. В карте также есть два примера периодической синхронизации данных, передача integer и real.
Для установки скопируйте папку UnitSync, скопируйте dummy из РО, убедитесь что равкод dummy совпадает со значением UNIT_ID в триггере USync. Пользуйтесь. В карте также есть два примера периодической синхронизации данных, передача integer и real.
Передача integer
function event_kill_count takes nothing returns nothing
local integer data = USync.integer
local integer player_id = USync.player_id
call BJDebugMsg("sync kill_count"+I2S(data))
call BJDebugMsg("sync player_id"+R2S(player_id))
endfunction
function send_my_value takes nothing returns nothing
if GetLocalPlayer() == Player(0) then
call USync.send("kill_count", 37)
endif
endfunction
function trigger_init takes nothing returns nothing
call USync.register_integer("kill_count", 0, 1000, true, function event_kill_count)
endfunction
В данном примере мы сначала регистрируем сообщение с помощью USync.register_integer() куда передаем callback - функцию, которая будет вызвана после получения данных.
Передача real
function event_damage_multiplier takes nothing returns nothing
local real data = USync.real
call BJDebugMsg("sync damage_multiplier"+R2S(data))
endfunction
function send_my_value takes nothing returns nothing
if GetLocalPlayer() == Player(0) then
call USync.send("damage_multiplier", 15.)
endif
endfunction
function trigger_init takes nothing returns nothing
call USync.register_real("damage_multiplier", -50, 50, 0.1, true, function event_damage_multiplier)
endfunction
Числа типа real всегда приходят с погрешностью потому что мы не передаем все 32 бита. В данном примере 0.1 это максимально допустимая погрешность. Например если вы отправите 15.0, то ожидайте, что прийти может число от 14.9 до 15.1
Передача координат
function send_position takes nothing returns nothing
local real x = GetCameraTargetPositionX()
local real y = GetCameraTargetPositionY()
if GetLocalPlayer() == Player(0) then
call USync.send_coordinate("unit_position", x, y)
endif
endfunction
function event_get_position takes nothing returns nothing
local real x = USync.x
local real y = USync.y
call SetUnitX(UNIT, x)
call SetUnitY(UNIT, y)
call send_position()
endfunction
function trigger_init takes nothing returns nothing
call USync.register_coordinate("unit_position", 1, true, function event_get_position )
endfunction
Функция USync.register_coordinate() предназначена для регистрации событий отправки данных тип которых это координаты плоскости игровой карты. В примере мы синхронизируем координаты камеры локального игрока и перемещаем туда юнита.
Описание функций
register_real() - зарегистрировать сообщение. Возвращает количество кликов, которые необходимы для отправки данных.
method register_real takes string name, real min, real max, real maximum_error, boolean buffering, code callback returns integer
name - название, используется для создания/отправки сообщения. Повторная регистрация выведет сообщение об ошибке.
min - минимально возможное передаваемое значение. Передача значения меньше min выдаст сообщение об ошибке.
max - максимально возможное передаваемое значение. Передача значения больше max выдаст сообщение об ошибке.
maximum_error - максимально возможная погрешность при передачи. Обычно принимает значения [1, 0.1, 0.01]. Передача больших диапазонов значений с большой точностью может быть затруднительно.
buffering - буферизация событий, по-умолчанию true, более подробно ниже.
callback - функция которая будет вызвана после синхронизации данных.
register_integer() - зарегистрировать сообщение. Возвращает количество кликов, которые необходимы для отправки данных.
method register_integer takes string name, integer min, integer max, boolean buffering, code callback returns integer
name - название, используется для создания/отправки сообщения. Повторная регистрация выведет сообщение об ошибке.
min - минимально возможное передаваемое значение. Передача значения меньше min выдаст сообщение об ошибке.
max - максимально возможное передаваемое значение. Передача значения больше max выдаст сообщение об ошибке.
buffering - буферизация событий, по-умолчанию true, более подробно ниже.
callback - функция которая будет вызвана после синхронизации данных.
PS Значение maximum_error выставляется автоматически, для integer == 1.
register_coordinate() - зарегистрировать сообщение. Возвращает количество кликов, которые необходимы для отправки данных.
method register_coordinate takes string name, real maximum_error, boolean buffering, code callback returns integer
name - название, используется для создания/отправки сообщения. Повторная регистрация выведет сообщение об ошибке.
maximum_error - максимально возможная погрешность при передачи. Обычно принимает значения [1, 0.1]
buffering - буферизация событий, по-умолчанию true, более подробно ниже.
callback - функция которая будет вызвана после синхронизации данных.
PS Значения min и max автоматически устанавливаются равными границам карты.
send() - отправить данные по сохраненному сообщению. Возвращает логическое значение успеха.
method send takes string name, real value returns boolean
name - название сообщения, которое было указано при регистрации.
value - само передаваемое значение, полезная нагрузка.
send_coordinate() - отправить данные по сохраненному сообщению. Возвращает логическое значение успеха.
method send_coordinate takes string name, real x, real y returns boolean
name - название сообщения, которое было указано при регистрации.
x - значение по оси x.
y - значение по оси y.
Buffering
Для того чтобы понять как работает буферизация рассмотрим следующий код
Для того чтобы понять как работает буферизация рассмотрим следующий код
function test_buffering takes boolean buffering returns nothing
call USync.register_integer("data", 0, 10, buffering , function event_callback)
if GetLocalPlayer() == Player(0) then
call USync.send("data", 1)
call USync.send("data", 2)
call USync.send("data", 3)
call USync.send("data", 4)
call USync.send("data", 5)
endif
endfunction
Если buffering == true, то через время будет вызвано пять событий с данными 1, 2, 3, 4, 5
Если buffering == false, то через время будет вызвано два события со значениями 1, 5 поскольку попытки отправить и 2 и 3 и 4 и 5 были в тот момент времени, когда 1 еще не синхронизировалось, а после синхронизации было отправлено последнее востребованное обновление.
Если buffering == false, то через время будет вызвано два события со значениями 1, 5 поскольку попытки отправить и 2 и 3 и 4 и 5 были в тот момент времени, когда 1 еще не синхронизировалось, а после синхронизации было отправлено последнее востребованное обновление.
Где это нужно? Например если вы решите слать сообщения быстрее, чем они будут доходить - каждые 0.15с - то сообщения будут скапливаться в очередь, которая будет бесконечно расти, и из за этого время от момента отправки события до момента его синхронизации тоже начнет бесконечно расти. Возможно вы синхронизируете координату мыши или около того, и вам важно как можно быстрее получить как можно более актуальные данные, и совершенно без разницы в каких координатах находилась мышь до этого. Один из способов разрешить проблему накапливания очереди событий получения данных это установить buffering == false. В таком случае все новые попытки отправить данные будут лишь обновлять "следующую отправку", которая произойдет только после того как последние отправленные данные синхронизируются.
Второй способ избавится от накапливания очереди событий получения данных это не создавать такие очереди. Вы можете обновлять данные не только с помощью периодического таймера, а, например, отправлять данные только после получения предыдущих. В этом случае вы будете поддерживать максимально возможную скорость передачи данных.
Ред. host_pi