СКРИПТЫ ОТКЛЮЧЕНЫ

Дальнейшая работа данной страницы будет остановлена

[HD2][урок] Скриптинг в LS3d

Мануалы по моддингу в H&D2/SS/H&D3
Аватара пользователя
danilasar
Сообщения: 256
Зарегистрирован: 11 июл 2016, 17:13

[HD2][урок] Скриптинг в LS3d

Сообщение danilasar » 02 дек 2017, 19:30

Сценарии - одна из важнейших частей модификации или создания полной новой совместной миссии. Это похоже на язык программирования, но с аккуратным количеством команд и математических операторов. Вы решаете здесь, как должен действовать человеческий ИИ или когда появляться, вы устанавливаете цели, а многое другое обрабатывается использованием скриптов.
Для редактирования скриптов рекомендуется использовать Notepad++ или Notepad2.
Когда вы работаете со сценариями, вы всегда должны помнить следующее:
  • Каждый скрипт связан с объектом (человеческим актером, манекеном, ..), который должен существовать в .bin-файлах либо act.bin, либо scene2.bin.
  • Вы можете связать более одного объекта с тем же скриптом.
  • Какой объект связан с тем, какой скрипт хранится внутри MPscripts.dta в папке Missions.
    Если ваш скрипт, похоже, не влияет на него, потому что он неправильно связан или из-за синтаксической ошибки (например, вы забыли закрыть скобку)
  • Команды не чувствительны к регистру, но использование некоторых капиталов может сделать ваш скрипт более понятным. (сравнить getactorstate с GetActorState)
  • Команды, которые влияют только на то, чтобы включить или выключить что-либо, вы можете либо написать «true / false», либо «1/0». например «DisableSignals (1)»; равно «DisableSignals (True)»;
  • Сценарии читаются только сервером. Таким образом, только хостингу нужны файлы сценариев, а не клиентам.
Структура
Код
//Default Script for AI

Block
{
Frame me; FRM_GetMyFrame(me);
SetAlarmType(1,1);
SetAlarmType(2,1);
SetAlarmType(4,1);
SetAlarmType(8,1);
SetAlarmType(16,1);
SetAlarmType(32,1);
SetAlarmType(64,1);
SetAlarmType(128,1);
SetAlarmType(256,1);
SetAlarmType(512,1);
}

//------------------------------------------------------------------------------------------

OnDeath(){
EndScript();
}

OnAlarm(){
EndScript();
}

OnAlarmDone(){
HUMAN_SetAlarm(false);
goto END;
}

//------------------------------------------------------------------------------------------

goto END;

Label END:
Большинство скриптов управляют людьми (вражеские и союзные солдаты). Зачастую в них используются следующие директивы:
OnAlarm()
OnAlarmDone()
OnDeath()
OnHit()
Директива OnDeath() Также употребляется у любых разрушаемых объектов (техника, радио)
Комментарии
В большинстве языков Вы можете комментировать строки или даже куски кода. В LS3d Script существует комментарий строк - "//". Закомментированные строки не будут читаться игрой.
Связать frame с объектом
Если вы хотите взаимодействовать с другим объектом в вашем скрипте (он должен существовать в .bin-файлах), вы должны привязать его к желаемому объекту в качестве фрейма.
Обычно связанные фреймы записываются в начале скриптов и внутри элементов блока:
Код
Frame frame1; FRM_FindFrame(frame1, "object1");
SetActorState(frame1, 1);
Объяснение
Мы определяем объект (здесь: object1) как фрейм (здесь: frame1), который теперь может использоваться в следующем коде.
Использование имени объекта напрямую не работает. SetActorState (объект1, 1);
Чтобы получить объект вашего текущего скрипта, используйте: Обычно кадр называется «this» или «me», но это зависит от вас.
Код
Frame me; FRM_GetMyFrame(me);
frame me; FRM_GetMyFrame(me);
FRM_SwitchFaceTexture(me, "e_f024");
Элемент Block { ... }
Вы можете написать несколько команд внутри элемента Block {}, чтобы загрузить их одновременно. В качестве логического результата команды Delay () не считываются внутри элементов блока.
Однако вы должны это делать, только если это действительно имеет смысл. Загрузка нескольких команд одновременно в нескольких сценариях может вызвать проблемы.
Код
Block {
Frame Soldier1; FRM_FindFrame(Soldier1,"01_E01");
Frame Soldier1; FRM_FindFrame(Soldier1,"01_E12");
frame Soldier3; FRM_FindFrame(Soldier1,"01_E03");
Frame Obj1; FRM_FindFrame(Obj1,"Objective1");
Frame me; FRM_GetMyFrame(me);
Frame Documents;
}
Директива OnAlarm() { ... }
Используется для ИИ людей.
Значения (1 - параметр; Закрыть стрельбу - описание):
1 Закрыть стрельбу
2 Вражеские выстрелы
4 Слушайте шаги (не работая для клиентов)
8 Звук действия (не работает для клиентов)
16 Взрывы (не работает для клиентов)
32 зрячий
64 ранен
128 Из сценария - не знаю, как это работает
256 Дружественные снимки
512 Достопримечательности труп
1023 Все действия одновременно

По умолчанию активируются все типы сигналов тревоги. Команда SetAlarmType (x, y) включает или выключает будильник.
например SetAlarmType (4, True);

Если вам нужно включить более одного типа сигналов одновременно, вы можете просто подсчитать числа вместе. например SetAlarmType ( 12 , True);
Тревожные типы 4 и 8 установлены верно. (4 + 8 = 12)

Типы сигналов тревоги обычно определяются в начале сценария.

Чтобы включить / отключить все аварийные сигналы, вы можете либо написать
SetAlarmType (1023, True); / SetAlarmType (1023, False);
(1 + 2 + 4 + 8 + 16 + 32 + 64 + 128 + 256 + 512 = 1023)
или
DisableAlarms (False); / DisableAlarms (True);
GetAlarmType () считывает новый тип тревоги и может быть сохранен как любая целочисленная переменная.
Код
Integer AIEvent = 0;
Integer counter = 0;

OnAlarm() {
AIEvent =_GetAlarmType();

If((AIEvent == 1) OR (AIEvent == 64))
{
HUMAN_SETMODE_Lie();
}
If(AIEvent == 512)
{
counter = counter + 1;
If(counter==2)
{
EndScript();
}
goto End;
}
EndScript();
}

Label End:
Объяснение
Если наш солдат получит предупреждение, скрипт сначала получит тип Тревога и сохранит его в переменной «AIEvent», которую мы ранее определяли как Integer.
Далее идет запрос If. Если солдат был близко расстрелян (Тревожный тип 1) или получил травму (Тип сигнала тревоги 64), он будет лежать и переходит к следующей свободной строке в коде, здесь: first EndScript ();
Но если он обнаружит труп (возможно, на патрулирование), переменная «counter» станет 0 + 1 = 1. Теперь указатель переходит к метке End, где он ждет другого ввода.
Если солдат обнаружит другой труп, счетчик добавит +1: 1 + 1 = 2. Теперь аргумент If равен true (счетчик == 2), и солдаты обращаются к ближайшему игроку, и скрипт заканчивается. (второй EndScript ();)

ПРИМЕЧАНИЕ. Не добавляйте коды движения в этот раздел, поскольку человеческий ИИ не попадет в режим съемки до EndScript (); есть загрузка.

Директива OnDeath () { ... }
Используется для человеческого ИИ и разрушаемых объектов. Отвечает за действия при уничтожении объекта.
Директива OnHit () { ... }
Рассказывает, что делать, если ударит человеческий ИИ / объект.
Цикл Whenever
Аналогичен while в C-подобных и .NET языках программирования и скриптинговом Pawn.
Команды в фигурных скобках загружаются, если выполняется условие / s.
Если вам нужно больше одного условия, просто привяжите их к «и» или если требуется только одно из многих условий, используйте «OR».
Код
Whenever name ((_PlayerIsNear(20)) AND (_FrameIsNear(tank, 50)))
{
...
}
Функция SetWhenever ()
Активирует/деактивирует Whenewer'ы:
SetWhenever (name, True / False)
Функция SetWheneverTime ()
Определяет время a Всякий раз, когда событие проверяется. например SetWheneverTime («имя», 5000) проверяет каждые 5 секунд, если условие выполнено. Поместите кавычки вперед и позади тех, где имена, иначе это не сработает!
Код
SetWheneverTime("PIAR", 5000);

Whenever "PIAR" (_PlayerIsNear(20))
{
...
}
После этого можно отрицать. Для этого вам нужно добавить восклицательный знак перед этим условием.
например, _EnemyInRange (frame, x) становится отрицательным ! _EnemyInRange (frame, x)
Теперь условие выполняется, если противник находится не в радиусе действия.
_PlayerIsNear (х) х = диапазон (Int)
_EnemyInRange (frame, x) х = диапазон (Int)
_MP_IsTeamMemberInRange (1, x) х = диапазон (Int)
_SignalReceived (х) x = номер сигнала
_ACTOR_GetState (фрейм) == x x = статус актера (объекта) (Int)
_MP_IsTeamMemberInRange (1, x) х = диапазон (Int)
_FrameInRange (кадр) <х x = range (Int), разрешенные операторы: <,>, <=,> =, ==,! =
_MP_IsItemInTeamInventory (1, x, frame) x = номер списка товаров (Int)
_MP_IsTeamMemberInRange (1, x) х = диапазон (Int)
_PlayerInBox (кадр) В качестве коробки вы можете использовать масштабированный манекен
Аргументы If / Else
Еще один замечательный инструмент, позволяющий сделать это, - это аргументы If / Else. Давайте рассмотрим пример.
Код
Integer a = 0;

a=_RandomInt(5); //Creates a random integer number of the first 5 integers either 0,1,2,3 or 4.

If(a==0)
{ ... }
If(a==1)
{ ... }
If(a==2)
{ ... }
Else { ... }
Если вы сравниваете значение с другими, используйте двойные знаки равенства («==»).
И если вы просто хотите присвоить значение, используйте «=».
Не добавляйте аннотации непосредственно за аргументы. (If (a == 0) {...}) Вместо этого используйте новую строку до или после.

Если / Else аргументы могут использоваться в любом месте скрипта.
Часть Else может быть пропущена. В этом случае в качестве «Else» используется следующая строка.
Пример:
Код
...
if (a == 4)
{...}
EndScript ();
...
Если a != 4 (не равна), сценарий переходит к следующей свободной строке кода. Здесь: EndScript ()
Команды GoTo и Label
Чтобы перейти к определенной части кода в вашем скрипте, вы можете использовать команды GoTo / Label.
Каждому ярлыку должно быть присвоено имя (даже простое число работает), за которым следует двоеточие.
например, «Метка 1:»

GoTo
GoTo используются для перехода к определенной метке.

Например, если вы хотите перейти к Label 1, напишите «GoTo 1;»
Конечно, этот ярлык должен существовать, иначе скрипт будет сломан и не будет работать prober.

Если вы хотите , чтобы петли определенной части кода, просто добавьте «GoTo 1;» в конце «Ярлык 1:»,
например, он будет повторять реализованный код до тех пор, пока скрипты не получат другой вход, например, из сигналов, сигналов тревоги, когда события ...
Label 1:
[код]
GoTo 1;

GoSub
как «GoTo», но ярлык заканчивается на «Return»; который возвращает указатель скрипта на следующую строку после GoSub.
Теперь это трудно объяснить словами, но очень легко с примером:
Код
GoSub 1;
HUMAN_SetAnim("%%turnright", 300, 300, false);
GoTo End;


Label 1:
Delay(5000);
HUMAN_SetAnim("%%turnleft", 300, 300, false);
Return;


Label End:
Объяснение
Первая строка говорит сценарию, чтобы перейти к ярлыку 1, где он ждет 5 секунд (5000 miliseconds), тогда AI выполняет анимацию (здесь: поворот влево).
Команда Return сообщает сценариям вернуться к строке GoSub, что означает, что она будет читать следующая строка: здесь ИИ снова выполняет анимацию (поворачивает направо)
и переходит в конец метки, где сценарий ждет дальнейших инструкций.
В конце многих скриптов есть метка, называемая End или TheEnd, без какого-либо кода, и прыгайте туда, если ваш скрипт будет ждать другого ввода.
Еще один более сложный пример с if / else:
Код
OnSignal(3) {
goto L4_a;
}


label L4_a:
If (_PlayerInRange(9) )
{
HUMAN_Move("AlBert_2");
goto L4_b;
} else {
HUMAN_TurnAtNearestPlayer();
delay(150);
goto L4_a;
}


label L4_b:
If (_PlayerInRange(9) )
{
HUMAN_Move("AlBert_3");
goto L4_c;
} else {
HUMAN_TurnAtNearestPlayer();
delay(150);
goto L4_b;
}


label L4_c:
If (_PlayerInRange(9) )
{
HUMAN_Move("AlBert_4");
goto end;
} else {
HUMAN_TurnAtNearestPlayer();
delay(150);
goto L4_c;
}


Label end:
Значения сигнала / игры
Сигнал
Для взаимодействия между скриптами могут использоваться сигналы. Вы можете отправлять сигналы на другой скрипт со следующей командной строкой: «SendSignal (frame, x)»;
x обозначает номер сигнала.

Для сценария приема вы можете использовать событие Whenever или команду OnSignal (x).
Код
SendSignal(frame, x);
Whenever name (_SignalReceived(x)) { ... }
OnSignal(1) { ... }
Значение игры
Тык
SaveGameValue(1, 200);
LoadGameValue
unsuspend_range = _LoadGameValue(1);
Задания
Статус выполнения задания устанавливается функцией "SetObjectiveStatus(id, status);", где id = ID задания, status = новый статус задания
Статусы задания (0 - ID статуса; Задание не выполнено - описание статуса):
0 Задание не выполнено
1 Задание выполнено
2 Задание провалено
3 Задание и миссия провалена
4 Дополнительное задание (скрыть из списка)
Субтитры
Код
SUBTITLES_SetOn(true);
SUBTITLES_SetText(07991406); //"ЗАДАЧА ВЫПОЛНЕНА: ВРАЖЕСКИЙ ГАРНИЗОН ЛИКВИДИРОВАН."
Delay(3500);
SUBTITLES_SetOn(false);
Речь и звуки
Код
FRAME get_player;
SUBTITLES_SetOn(true);
FRM_GetNearestPlayer(vysilacka, get_player);
FRM_MorphSpeechDelayed(get_player, 07991610, 3, 10); //"Докладывает подразделение САС, мы захватили оазис недалеко от Абн-Син-Оан"
FRM_MorphSpeechDelayed(faker, 07991611, 3, 10); //"Понял, поздравляю!"
SUBTITLES_SetText(07991405); //"ЗАДАЧА ВЫПОЛНЕНА: КОМАНДОВАНИЕ ПРОИНФОРМИРОВАНО"
Delay(2100);
SUBTITLES_SetOn(false);
Код
frame sound1; frm_findframe(sound1,"S_poryv1");
frame sound2; frm_findframe(sound2,"S_poryv");
frame sound3; frm_findframe(sound3,"S_palmy_poryv01");
frame sound4; frm_findframe(sound4,"S_palmy_poryv02");
frame sound5; frm_findframe(sound5,"S_palmy_poryv03");
frame sound6; frm_findframe(sound6,"S_palmy_poryv04");
integer rnd;
integer rnd_pause;
label loop:
rnd= _randomint(2) +1;
rnd_pause= _randomint(13900) +18000;
if (rnd==1) {FRM_SetOn(sound1,true);}
if (rnd==2) {FRM_SetOn(sound2,true);}
delay (2000);
FRM_SetOn(sound3, true);
FRM_SetOn(sound4, true);
FRM_SetOn(sound5, true);
FRM_SetOn(sound6, true);
delay(rnd_pause);
goto loop;
*Использовался контент HD2 Wiki
Помог? Не стоит благодарности.

Префиксы:

Вернуться в «Мануалы»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость

  • Имя пользователя:


    Пароль:


    Remember me

    Register now!



  •  Top Posters

  •  Newest members

  •  Ссылка на нас
  • Please feel free to link to Pawn Forum. Use the following HTML:




cron