Главная » Файлы » Платформа для создания SP миссий » Полезная справочная информация

Основы выполнения скриптов в МП



Основы выполнения скриптов в МП

Введение.

 

Думаю все замечали что частенько те скрипты что работали в сингле, отказываются работать, или работают криво в мультиплеере. Чаще всего это происходит с маркерами, звуками, эффектами, действиями и т.д. В чём же здесь причина?

Причина в том, что в сети у части команд результат выполнения локален (далее я буду писать что команда локальна или выполняется локально) т.е. результат выполнения появляется только на том компьютере, на котором эта команда была запущена. А у другой части команд результат выполнения глобален (далее я буду писать что команда глобальна или выполняется глобально) т.е. после выполнения команды на одном компьютере, результат её выполнения передаётся по сети остальным компьютерам. Под компьютерами я имею ввиду сервер и компьютеры всех игроков играющих в сети.

Чтобы было понятней, приведу два простых примера:

Пример 1.

Создаём снеговика (да да, снеговик есть в аа2, можете проверить... там ещё много чего смешного есть) рядом с юнитом man. Для этого в ините юнита man пишем следующее:

Код:

 

snegovik = "snowman" createVehicle (position this);

 

В сингле всё отлично, но стоит нам позвать другого игрока чтобы показать это, и запустить на на выделенном сервере, как вместо одного снеговика мы получаем сразу трёх... Почему? А потому что команда createVehicle глобальна, и запущена была на всех трёх компьютерах (сервер, ваш клиент, клиент другого игрока). Т.е. она сначала выполнилась на сервере, и у всех создался первый снеговик, потом у вас, и второй снеговик появился у всех, и наконец у другого игрока - вот и третий снеговик.

 

Пример 2.

Делаем экшен по которому вам будет вылетать хинт. В инит своему юниту пишем:

Код:

 

hintAct = this addAction ["Хинт!", "hint.sqf"]

 

А в скрипте hint.sqf пишем простейшее:

Код:

 

hint "abugaga";

 

В сингле всё опять отлично, жамкаем на действие, выскакивает хинт с абугага. Зовём друга проверить это дело в сети, жамкаем на действие, у нас хинт выскочил, а другой игрок говорит что у него ничего нет. Просим его нажать на действие, он говорит что нажал и у него всё выскочило, но у нас ничего не выскакивает... Почему? Команда hint локальна. А скрипт запускаемый по нажатию на экшен запускается только на компьютере того кто нажал на действие.

Различить локальные и глобальные команды очень просто:

У глобальных команд на бис вики стоит значок

А у локальных команд стоит значок

 

 

 

 

Запрет на выполнение на части компьютеров

 

Начнём с решения проблемы первого примера. Очевидно что нам нужно ограничиться выполнением скрипта только на одном компьютере. Для этого существует три команды, но одна из них почти не используется. Вот они:

isServer - проверяет является ли компьютер сервером, и если да, то возвращает true. В сингле она также возвращает true.

isDedicated - проверяет является ли компьютер выделенным сервером. В отличие от изСервер в сингле возвращает false.

local - проверяет является ли объект локальным. Т.е. игрок будет локален для компьютера игрока, а бот будет локален для сервера (подробнее о том что кому локально можно прочитать тут).

Соответственно для решения проблемы с созданием снеговиков достаточно написать следующее:

Код:

 

if (isServer) then {snegovik = "snowman" createVehicle (position this);}

 

Отправка команд на остальные компьютеры

 

С тем чтобы ограничить выполнение команды запущенной на всех компьютерах как видите всё довольно просто. Но как решать проблему из примера 2, когда команда локальна и запущена только на одной машине, т.е. результат её выполнения не передастся на другие компьютеры?

Я знаю четыре способа. Хотя нет, благодаря ofpwarior их уже пять.

 

Способ первый: Пабликвар и триггер или while

Это самый простой способ, но при использовании триггеров применимый к сожалению только для миссий. В аддонах его использовать выйдет только если использовать while, но там встаёт вопрос о том как связать пабликвар и конкретную машину, поэтому для аддонов зачастую удобней способ №2.

Идея такая: по нажатию на экшен мы создаём publicVariable а в миссию добавляем триггер (или пускаем скрипт с бесконечным циклом из инита), условием в котором стоит этот пабликвар, а в эффекте то что нам было нужно сделать на всех компьютерах.

Т.е. на рассматриваемом примере с хинтом это будет так:

В скрипте hint.sqf мы пишем:

Код:

 

my_pv_hint = true;

publicVariable "my_pv_hint";

 

В условии триггера вместо this пишем my_pv_hint

А в активации пишем:

Код:

 

hint "abugaga";

 

Способ второй: сетвар и триггер или while

Отлично подходит для аддонов, или для вещей связанных с объектами. Идея в том чтобы для определённого объекта добавить некоторое свойство. В отличие от пабликвар переменная установленная для объекта командой setVariable может быть любого типа. Соответственно мы устанавливаем нужное нам значение, а в триггере или запущенном везде скрипте с бесконечным циклом проверяем изменилось значение на то которое нам нужно, или нет. Для этого используем команду getVariable. Как я уже говорил, для миссий данный способ не шибко удобен, но для создания контрольной панели к какому нибудь объекту - то что нужно.

 

 

Способ третий: инит

Сам не использовал, только видел примеры использования. Возможно плохо дружит с JIP (join in progress) т.е. возможно не будет срабатывать у игроков присоединившихся после старта, в отличии от первых двух вариантов. Повторяю, возможно т.к. сам я этот способ ни разу не использовал.

Идея простая. Мы изменяем на ходу строчку инита у некоего объекта, и заставляем её выполниться. Пример выполнения:

Код:

 

//Передаем анимацию на все компьютеры

_unit setVehicleInit "this switchMove 'AcrgPknlMstpSnonWnonDnon_AmovPercMstpSrasWrflDnon_getOutMedium'";

processInitCommands;

clearVehicleInit _unit;

 

Думаю всё понятно, т.к. идея действительно очень простая.

В нашем случае примера с хинтом это будет так, пишем в hint.sqf

Код:

 

player setVehicleInit "hint 'abugaga'";

processInitCommands;

clearVehicleInit player

 

Способ четвёртый: пабликВар ЕХ

Универсально, на как всё универсальное не самое удобное. Идея заключается в использовании команды addPublicVariableEventHandler. Работает как часы, но надо помнить что срабатывает только на других машинах, т.е. не на той на которой изменён сам пабликВар. Чтобы было хоть чуточку понятней, вернёмся к нашему экшену с хинтом...

В инит своему юниту пишем слудующее:

Код:

 

"my_pv_hint" addPublicVariableEventHandler {hint "abugaga"};

hintAct = this addAction ["Хинт!", "hint.sqf"];

 

А в самом скрипте hint.sqf: (обратите внимание что тут мы тоже вызываем хинт, если этого не сделать, то хинт вылете у всех, кроме того кто нажал на действие)

Код:

 

my_pv_hint = true;

publicVariable "my_pv_hint";

hint "abugaga";

 

Способ пятый: используем CBA

Кто не знает, СВА (Community Base addons) это набор аддонов включающих в себя кучу всяких полезностей для картоделов и скриптёров. В частности он включён в АСЕ. Так что если вы всё равно используете CBA, то почему бы не использовать его мощь?

Итак функция CBA_fnc_globalExecute из аддона CBA

Код:

 

[_channel, {player globalChat _this}, _parameter] call CBA_fnc_globalExecute;

 

_channel Всем: -2, Только клиентам: -1, Только серверу: 0 [Целое число] (именно с минусом)

_code Code to execute [Code]

_parameter Опционально. Передается в код в переменных _this [Любое значение]

 

 

Заключение

Надеюсь я смог хоть немного помочь разобраться в этом деле. Первоначально кажется что это всё очень сложно, но при ближайшем рассмотрении всё становится довольно простым и понятным. Если разобраться с этим, то создание любых МП миссий становится лишь вопросом свободного времени.





Размер файла на сервере: 46.0 Kb



Хотите еще больше новостей? Подпишитесь на рассылку

Введите e-mail адресс:

Похожие материалы
Дата добавления: 27.11.2010, 14:00
Категория: Полезная справочная информация | Добавил: PIONEER
Просмотров: 2872 | Загрузок: 163 | Всего Комментариев: 0
Добавлять комментарии могут только зарегистрированные пользователи.
[ Регистрация | Вход ]
Верстка by ArmA-2