Главная |
Главная » Файлы » Платформа для создания 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 Хотите еще больше новостей? Подпишитесь на рассылку | |
Категория: Полезная справочная информация | Добавил: PIONEER | |
Просмотров: 2872 |
Загрузок: 163
| Всего Комментариев: 0 |