Ил-2 Штурмовик: Битва за Британию. Скрипты. Скрипты для чайников. Часть 2 - Загрузка подмиссий

Материал из АвиаВики
Перейти к: навигация, поиск
Автор: FG28_Kodiak
Ссылка: Перейти (перевод Google)

Скачать оригиналы миссий:

Samples.zip

Скачать примеры с Sukhoi.ru:

Samples.zip


Как мы узнали из предыдущего урока загруженные из под-миссий объекты игнорируются триггерами миссии-хоста (триггеры основной миссии не знают о под-миссиях и их объектах). Этого можно избежать используя триггеры в самих под-миссиях. Создадим по одному триггеру в каждой из наших трех под-миссий:

Sfdp2-1.jpg


Sfdp2-2.jpg


Sfdp2-3.jpg

Используйте разные имена триггеров, чтобы избежать ошибок в дальнейшем. Вы можете обращаться к триггеру без указания номера миссии при помощи gpGetTrigger("Triggername").

Теперь у нас есть три под-миссии, в каждой из которых стоит триггер на уничтожение создаваемых этой под-миссией объектов. Далее объединим эти триггеры в одно условие, чтобы иметь возможность оценить результаты атаки. Можно задать несколько условий используя логические И/ИЛИ, однако мы сделаем более удобный вариант. За успешную атаку будет засчитывать очки и по их количеству потом подводится общий итог. Пусть количество необходимых выполненных заданий будет равно 2, третью миссиию можно провалить. Также введем переменную, которая будет определять выполнили ли мы все задание (если 2 из 3-х - задание выполнено).


using System; 
using maddox.game; 
using maddox.game.world; 
public class Mission : maddox.game.AMission 
{ 
enum MissionCondition {Neutral, Success, Failure}
MissionCondition AktuelleMissionCondition = MissionCondition.Neutral; 
const int NeededForMissionSuccess = 2; 
int WinConditionCounter = 0;
private void serverMessage (string msg) 
{ 
GamePlay.gpLogServer (null, msg, new object [] {msg}); 
}
public override void OnBattleStarted() 
{ 
base.OnBattleStarted(); 
MissionNumberListener = -1; 
serverMessage ("\nZerstören sie jeweils mindestens 3 Fahrzeuge aus zwei Gruppen\n\n");
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub1.mis"); 
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub2.mis"); 
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub3.mis"); 
}
public override void OnTrigger(int missionNumber, string shortName, bool active) 	 	 { 
base.OnTrigger(missionNumber, shortName, active); 	 	 
GamePlay.gpLogServer (null, "OnTrigger({0} | {1} | {2}) wurde ausgelöst", new object [] {missionNumber, shortName, active}); //Nur für Testzwecke, löschen oder auskommentieren wenn Endfassung 	 	 
if (AktuelleMissionCondition == MissionCondition.Neutral) 
{ 
if ("WinCondition1".Equals(shortName) && active) 
{ 
WinConditionCounter++; 
GamePlay.gpGetTrigger(shortName).Enable = false; 
} 
if ("WinCondition2".Equals(shortName) && active) 
{ 
WinConditionCounter++; 
GamePlay.gpGetTrigger(shortName).Enable = false; 
} 
if ("WinCondition3".Equals(shortName) && active) 
{ 
WinConditionCounter++; 
GamePlay.gpGetTrigger(shortName).Enable = false; 
} 
serverMessage ("Anzahl erledigter Teilziele: " + WinConditionCounter.ToString()); // Für Testzwecke. 	 
if (WinConditionCounter >= NeededForMissionSuccess) 
{ 
AktuelleMissionCondition = MissionCondition.Success; 
GamePlay.gpHUDLogCenter("Ziel erreicht"); 
serverMessage ("Endanzahl: " + WinConditionCounter.ToString()); // Für Testzwecke. 
GamePlay.gpGetTrigger("FailCondition1").Enable = false; 
} 
if ("FailCondition1".Equals(shortName) && active) 
{ 
AktuelleMissionCondition = MissionCondition.Failure; 
GamePlay.gpHUDLogCenter("Sie haben die Zeit überschritten"); 	 	 
serverMessage ("Endanzahl: " + WinConditionCounter.ToString()); // Für Testzwecke. 	 
GamePlay.gpGetTrigger(shortName).Enable = false; 	 
} 
} 
} 
} 


enum MissionCondition {Neutral, Success, Failure} -перечисление состояний статуса выполнения миссии (Нейтрально, Успех, Провал). Точка с запятой в конце не ставится.

MissionCondition AktuelleMissionCondition = MissionCondition.Neutral; - инициализация переменной состояния текщей миссии со значением Нейтрально.

const int NeededForMissionSuccess = 2; - константа, в которой мы задаем кол-во успешно завершенных миссий, для выполнения задания по штурмовке.

int WinConditionCounter = 0; - задаем начальное значение (ноль) счетчика успешно выполненных миссий. Увеличивается на единицу с каждым выполнением под-миссий.

private void serverMessage (string msg)
{
   GamePlay.gpLogServer (null, msg, new object [] {msg});
}

Ниже команда, которая позволяет выводить на экран сообщения сервера, в том числе и в лог сервера (если это разрашено):

serverMessage ("Пример текста. Я сервер. Баню читеров и таранщиков"); 

Пример вывода на экран сообщения сервера:

Simple example: 
using System; 
using maddox.game; 
using maddox.game.world;
public class Mission : maddox.game.AMission 
{ 
private void serverMessage (string msg) 
{ 
GamePlay.gpLogServer (null, msg, new object [] {msg}); 
}
public override void OnBattleStarted() 
{ 
base.OnBattleStarted(); 
serverMessage("Этот текст выводится после начала миссии."); 
} 
} 


Вот как это выглядит:

Sfdp2-4.jpg

Формат команды serverMessage(string msg), строка передается в метод gpLogserver класса IGamePlay (перевод неточен!). Рассмотрим этот метод подробней:

void gpLogServer(maddox.game.Player[] to, string msg, object[] args) имеет три передаваемых параметра:

  • maddox.game.Player[] to - массив игроков, которым отправляется сообщение. Если равно null - отправляется всем.
  • string msg - текстовое сообщение формата string.
  • object[] parms - с помощью этого параметра вы можете передавать в строку различные параметры. Они помещаются в строку в фигурные скобки {n} с указанием индекса массива n: {0}, {1}, {2}.

Пример 1:

GamePlay.gpLogServer (null, "OnTrigger({0} | {1} | {2})  wurde ausgelost", new object [] {missionNumber, shortName, active});

На экран выводится:

OnTrigger (2 | WinCondition2 | True) wurde ausgelöst

Пример 2:

GamePlay.gpLogServer (null, "OnTrigger({0} | {1} | {2})  wurde ausgelöst", new object [] {missionNumber, shortName, active});


Ниже пример при срабатывании триггера WinCondition2 из второй подмиссии:

Sfdp2-5.jpg


Теперь нам нужно после начала основной миссии отправить пилоту задание в виде сообщения сервера, для этого понадобиться поместить следующую команду в рассмотренный нами ранее метод OnBattleStarted():

serverMessage ("\nZerstören sie jeweils mindestens 3 Fahrzeuge aus zwei Gruppen\n\n");

,где символ \n является символом переноса строки. Мы его используем здесь, чтобы наше сообщение было более заметно в списке команд сервера:

Sfdp2-6.jpg

Наиболее значительные изменения произошли в методе OnTrigger:

public override void OnTrigger(int missionNumber, string shortName, bool active) 
{
   base.OnTrigger(missionNumber, shortName, active);          
   GamePlay.gpLogServer (null, "OnTrigger({0} | {1} | {2})  wurde ausgelöst", new object []  {missionNumber, shortName, active}); //Nur für Testzwecke, löschen oder auskommentieren wenn Endfassung    
   if (AktuelleMissionCondition == MissionCondition.Neutral)
   {
       if ("WinCondition1".Equals(shortName) && active) 
       { 
           WinConditionCounter++; 
           GamePlay.gpGetTrigger(shortName).Enable = false; 
         }
         if ("WinCondition2".Equals(shortName) && active) 
       { 
           WinConditionCounter++;
           GamePlay.gpGetTrigger(shortName).Enable = false;
         }
         if ("WinCondition3".Equals(shortName) && active) 
       { 
           WinConditionCounter++;
           GamePlay.gpGetTrigger(shortName).Enable = false;
         }
         serverMessage ("Anzahl erledigter Teilziele: " + WinConditionCounter.ToString()); // Für Testzwecke.              
       if (WinConditionCounter >= NeededForMissionSuccess)
       {
           AktuelleMissionCondition = MissionCondition.Success;
           GamePlay.gpHUDLogCenter("Ziel erreicht");
           serverMessage ("Endanzahl: " + WinConditionCounter.ToString()); // Für Testzwecke.
           GamePlay.gpGetTrigger("FailCondition1").Enable = false;
         }
         if ("FailCondition1".Equals(shortName) && active) 
       { 
           AktuelleMissionCondition = MissionCondition.Failure;
           GamePlay.gpHUDLogCenter("Sie haben die Zeit überschritten");      
           serverMessage ("Endanzahl: " + WinConditionCounter.ToString()); // Für Testzwecke.   
           GamePlay.gpGetTrigger(shortName).Enable = false;   
         }
   }
} 

if (AktuelleMissionCondition == MissionCondition.Neutral) - условие, проверяющее статус миссии после вызова триггера. Если "Нейтрально", то выполняется следующий за ним код.

Примечание:
== - в условии означает "равно"
|| - "или"
&& - "и"

Вы можете использовать их для создания нужных вам условий.
if ("WinCondition1".Equals(shortName) && active) 
{ 
   WinConditionCounter++; 
   GamePlay.gpGetTrigger(shortName).Enable = false; 
}

WinConditionCounter++; - упрощение формулы, означает прибавить к переменной WinConditionCounter единицу, тоесть мы получили счетчик при помощи которого будем определять сколько успешных атак провел пилот. Можно записать по другому, на результат это не повлияет, только сделает код более громоздким:

if ("WinCondition1".Equals(shortName) && active) 
{ 
   WinConditionCounter = WinConditionCounter + 1; 
   GamePlay.gpGetTrigger(shortName).Enable = false; 
}

Чтобы не копировать постоянно названия и не прописывать имена триггеров в скрипте миссии-хоста при добавлении новых ("WinCondition1", "WinCondition2", "WinCondition3" ... "WinConditionn"), мы можем использовать такой код:

if (shortName.Substring(0, 12).Equals("WinCondition") && active)
{
   WinConditionCounter++;
   GamePlay.gpGetTrigger(shortName).Enable = false;   
}

shortName.Substring(0, 12).Equals("WinCondition"). позволяет учитывать только первые 12 символов названия триггеров. Т.е. мы можем добавлять сколь угодно подмиссий с именами типа "WinConditionn" и не портить при этом код главного скрипта.

serverMessage ("Количество выполненных заданий: " + WinConditionCounter.ToString()); // Für Testzwecke. - служит для отладки скрипта, можно записать и так (чтобы сообщения отправлялись в лог сервера:

GamePlay.gpLogServer (null, "Количество выполненных заданий: {0}", new object [] {WinConditionCounter});

Так как serverMessage ("...") является строкой типа string, а WinConditionCounter целое число типа int мы должны преобразовать WinConditionCounter в тип string. Для этого воспользуемся методом ToString(), который для этого предназначен:

if (WinConditionCounter >= NeededForMissionSuccess)
{
   AktuelleMissionCondition = MissionCondition.Success;
   GamePlay.gpHUDLogCenter("Вы выполнили задание и уничтожили все цели");
   serverMessage ("Счет: " + WinConditionCounter.ToString()); // для отладки скрипта
   GamePlay.gpGetTrigger("FailCondition1").Enable = false;
}

Если счетчик WinConditionCounter имеет значение равно или больше необходимого кол-ва успешно выполненных заданий, которое задается переменной "NeededForMissionSuccess" статус миссии меняется на "Выполнено" и на экран выводится итоговый счет. Также отключается триггер FailCondition1/

if ("FailCondition1." Equals (shortname) & & active) 
{ 
current mission condition = MissionCondition.Failure; 
GamePlay.gpHUDLogCenter ("Вы не уложились в норматив, задание не выполнено"); 
server message ("final number:" + WinConditionCounter.ToString ()) // для отладки скрипта 
GamePlay.gpGetTrigger (ShortName) Enable = false.; 
} 

Если вы не уложились в заданное время, появляется сообщение о неудаче и статус миссии меняет на "Провал".

Как создателю миссий, чтобы использовать этот скрипт вам нужно проставить свои пути к файлам, кол-во заданий, которые нужно выполнить для успеха, текстовые сообщения и время выполнения задания.

Итоговый код:

using System;
using maddox.game;
using maddox.game.world;
public class Mission : maddox.game.AMission
{
   enum MissionCondition {Neutral, Success, Failure}
   MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
   const int NeededForMissionSuccess = 2;
   int WinConditionCounter = 0;
   private void serverMessage (string msg)
   {
       GamePlay.gpLogServer (null, msg, new object [] {msg});
   }
   public override void OnBattleStarted()
   {
       base.OnBattleStarted();
       MissionNumberListener = -1;
       serverMessage ("\nZerstören sie jeweils mindestens 3 Fahrzeuge aus zwei Gruppen\n\n");
       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub1.mis");
       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub2.mis");
       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen3Sub3.mis");
   }
   public override void OnTrigger(int missionNumber, string shortName, bool active)
           {
   		base.OnTrigger(missionNumber, shortName, active);     		
   		if (AktuelleMissionCondition == MissionCondition.Neutral)
   		{
   		    if (shortName.Substring(0, 12).Equals("WinCondition") && active) 
           { 
               WinConditionCounter++; 
               GamePlay.gpGetTrigger(shortName).Enable = false;
               }    		    
   		    if (WinConditionCounter >= NeededForMissionSuccess)
   		    {
   		        AktuelleMissionCondition = MissionCondition.Success;
   		        GamePlay.gpHUDLogCenter("Ziel erreicht");
   		        GamePlay.gpGetTrigger("FailCondition1").Enable = false;
   		    }
                   if ("FailCondition1".Equals(shortName) && active)
                   { 
       		    AktuelleMissionCondition = MissionCondition.Failure;
       		    GamePlay.gpHUDLogCenter("Sie haben die Zeit überschritten");		
       		    GamePlay.gpGetTrigger(shortName).Enable = false;
                   }
                  }
              }
}   


Для установки миссий-примеров скопируйте их в папку:
..\Documents\1C SoftClub\il-2 sturmovik cliffs of dover\missions\Single

Загрузка подмиссий (автор FG28_Kodiak)

Оригинальные темы см. на форуме sturmovik.de(перевод от Google):

Вернуться на страницу "Скрипты"