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

Материал из АвиаВики
Перейти к: навигация, поиск
(Загрузка подмиссий (автор FG28_Kodiak))
 
(не показаны 3 промежуточные версии ещё одного участника)
Строка 1: Строка 1:
 
:'''Автор:''' FG28_Kodiak
 
:'''Автор:''' FG28_Kodiak
 
:'''Ссылка:''' [http://translate.googleusercontent.com/translate_c?hl=en&rurl=translate.google.com&sl=de&tl=en&twu=1&u=http://forum.sturmovik.de/index.php/topic,721.0.html%3FPHPSESSID%3Dac198c6ea43133020cb39e5f138fa85a&usg=ALkJrhiUPU7IvyTBPlLaOn7JmUlwfZx2pw Перейти (перевод Google)]
 
:'''Ссылка:''' [http://translate.googleusercontent.com/translate_c?hl=en&rurl=translate.google.com&sl=de&tl=en&twu=1&u=http://forum.sturmovik.de/index.php/topic,721.0.html%3FPHPSESSID%3Dac198c6ea43133020cb39e5f138fa85a&usg=ALkJrhiUPU7IvyTBPlLaOn7JmUlwfZx2pw Перейти (перевод Google)]
 +
 +
Скачать оригиналы миссий:
 
:[http://forum.sturmovik.de/index.php?action=dlattach;topic=721.0;attach=218 Samples.zip]
 
:[http://forum.sturmovik.de/index.php?action=dlattach;topic=721.0;attach=218 Samples.zip]
 +
Скачать примеры с Sukhoi.ru:
 +
:[http://www.sukhoi.ru/forum/attachment.php?attachmentid=142554&d=1318334365 Samples.zip]
 +
  
 
В предыдущих двух миссиях мы загружали под-миссии после начала миссии-хоста. В этой части мы научимся контролировать загрузку миссиий при помощи метода '''public virtual void OnTickGame ()'''
 
В предыдущих двух миссиях мы загружали под-миссии после начала миссии-хоста. В этой части мы научимся контролировать загрузку миссиий при помощи метода '''public virtual void OnTickGame ()'''
Строка 86: Строка 91:
  
 
Условие '''Time.tickCounter() % 334 == 0''' всегда выполняется когда значение'''tickCounter()''' равно 334 тика (то есть остаток  от деления 334%334 равен нулю и отправляет сообщения в чат через каждые 10 секунд.
 
Условие '''Time.tickCounter() % 334 == 0''' всегда выполняется когда значение'''tickCounter()''' равно 334 тика (то есть остаток  от деления 334%334 равен нулю и отправляет сообщения в чат через каждые 10 секунд.
 +
 
Условие '''Time.tickCounter() % 509 == 0''' всегда выполняется когда значение'''tickCounter()''' равно 509 тиков (то есть остаток  от деления 509%509 равен нулю и отправляет сообщения в чат через каждые 15 секунд.  
 
Условие '''Time.tickCounter() % 509 == 0''' всегда выполняется когда значение'''tickCounter()''' равно 509 тиков (то есть остаток  от деления 509%509 равен нулю и отправляет сообщения в чат через каждые 15 секунд.  
  
Строка 133: Строка 139:
  
  
Далее нам необходима подмиссия. В ней будет один автомобиль, который проедет от одного конца ВПП до другого и остановится.
+
Далее нам необходима подмиссия. В ней будет один автомобиль, который проедет от одного конца ВПП до другого.
 
   
 
   
  
Строка 207: Строка 213:
 
Разберем код нашего скрипта. Во-первых мы используем новый метод:
 
Разберем код нашего скрипта. Во-первых мы используем новый метод:
 
  '''using System.Collections.Generic;'''
 
  '''using System.Collections.Generic;'''
this we need the code to access the class list of C # to get the List class provides methods to insert and read this (and much more) make a list of objects. To be given more time.
 
  
This time we need the following variables have in the entire context of validity:  
+
В скрипте нам понадобятся следующие переменные:
'''AiAircraft PlayerPlane;''' The game engine provides us with the class AiAircraft available, all aircraft in the game, except the members of this group are static, so to speak.  
+
 
'''const int MaxAnzahlWellen = 10;''' This constant specifies the number of submissions runs.
+
'''AiAircraft PlayerPlane;''' - '''AiAircraft''' класс, в котором содержатся все доступные самолеты в игре, все самолеты за пределами этой группы являются статическими.
'''int AnzahlWellen = 0;''' waves, wave number is used as a counter in the course of the current number of runs saved.
+
 
'''int ZerstoerteZiele;''' This variable contains the number of targets already destroyed.
+
'''const int MaxAnzahlWellen = 10;''' - количество запусков под-миссий, в нашем случае равно кол-ву грузовиков (целей)
 +
'''int AnzahlWellen = 0;''' - кол-во уже запущенных под-миссий
 +
'''int ZerstoerteZiele;''' - количество уничтоженных целей
  
 
  public override void OnBattleStarted()
 
  public override void OnBattleStarted()
Строка 222: Строка 229:
 
  }
 
  }
  
In '''OnBattleStarted ''' we establish with MissionNumberListener = -1, that all events are taken from the missions. And with the help of:
+
В методе '''OnBattleStarted ''' установим '''MissionNumberListener = -1''', чтобы иметь доступ к объектам под-миссий.
'''PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();'''  we have to plan the player of the variables from the player occupied aircraft. As happens in this mission, only one aircraft by sitting the player can an assignment is sufficient to start the mission, several aircraft to be in the game, it makes sense to check before important the players relevant events whether it is sitting still in the early airplane and if not reassign . But certainly something we need in a later lesson. For us, the assignment IGamePlay class method gpPlayer () to disposition by the '''(AiAircraft)''' we share the game with what we mean in this case, the class '''AiAircraft''', there are several derived classes it is necessary to inform the system that we because my (eg, the player is a member of the class '''AiActor, AiCart, AiAircraft..)'''. Place () belongs to the class and tells players where the player is currently located. Note also that you can only use gpPlayer in single missions, multiplayer games coming gpRemotePlayers used.
+
 
Important is currently the only one with the help of '''(AiAircraft)GamePlay.gpPlayer().Place()''' in a single player game the player gets the plane as a return.  
+
'''PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();'''  - определяем самолет игрока.  
 +
Используем для этого класс IGamePlay, в котором есть метод '''gpPlayer()'''. Указываем нужный нам класс '''(AiAircraft)''' куда входит игрок (так же он присутствует в классах '''AiActor, AiCart, AiAircraft..)'''. '''Place()''' определяет текущее положение игрока. Метод '''gpPlayer''' используется только в одиночных миссиях, для мультиплеера нужно использовать метод '''gpRemotePlayers'''.
 +
 
  
 
  public override void OnTickGame()
 
  public override void OnTickGame()
Строка 246: Строка 255:
 
'''OnTickGame ()'''
 
'''OnTickGame ()'''
  
'''if (Time.tickCounter() % 1000 == 0 && (AnzahlWellen < MaxAnzahlWellen))''' - The query load the map every 30 seconds. and that is the number of waves <MaxAnzahlWellen long as, in our case just 10th without this "& & (count waves <MaxAnzahlWellen)" The submission would be charged indefinitely, or just until the player has no more desire. Where, if I'm considering the name and number of waves in a vehicle MaxAnzahlWellen were somewhat exaggerated  . If the condition is true our SubMission charged and thereby caused the vehicle on the road. Then increases the number of waves around an issue and issued a check in the chat bar so you can adjust the times may still, as I said the number of ticks per second can vary depending on usage. Should of course be removed from the final version.  
+
'''if (Time.tickCounter() % 1000 == 0 && (AnzahlWellen < MaxAnzahlWellen))''' - условие, которое загружает под-миссию, если прошло 30 секунд ''И'' (оператор '''''&&''''') и номер текущей подмиссии меньше переменной ''const int MaxAnzahlWellen''.
  
'''if (Time.tickCounter() == 11500)''' - is our Abruchbedingung the 11 500 ticks should of course be chosen so that the last vehicle can also complete the route. This condition makes the use of a time trigger unnecessary. So the time is expired, a control message is output which outputs the number of waves and the time required to remove this message also in the final.
+
'''if (Time.tickCounter() == 11500)''' - если прошло 11500 тиков (то есть время, выделенное на выполнение задания - выводится итоговый результат по количеству уничтоженных целей)
There is still a message on the screen:
+
  
 
[[Файл:Sfdp3-6.jpg|800px]]
 
[[Файл:Sfdp3-6.jpg|800px]]
Строка 270: Строка 278:
  
  
The method '''OnActorCreated(int missionNumber, string shortName, AiActor actor)''' is called each time a new Actor  is created, an Actor in Cliffs of Dover is anything to either move or function (eg artillery), has something that only stupid in the area is not part of it (ie buildings, trucks static, static aircraft, etc.).
+
'''OnActorCreated(int missionNumber, string shortName, AiActor actor)''' - метод вызывается каждый раз, когда создается новый '''Actor'''.
Also here is the first base call to make sure everything is initialized properly.  
+
  
'''if (actor is AiGroundActor)''' -  here is checked whether the current actor is among the AiGroundActor class in this class are all items that are traveling on the ground, thus moving trucks, artillery, ships, etc. If the query is TRUE is next
+
'''if (actor is AiGroundActor)''' -  проверяем, принадлежит ли '''Actor''' к классу '''AiGroundActor'''
 +
в котором содержатся все "живые" наземные объекты: автомобили, танки, корабли, артиллерия. Если условие равно TRUE выполняется соответствующий код.
  
'''Timeout(75, () => { Anweisungen });''' executed. When the timeout is specified first time, after something is to be executed, in this case 75 seconds. in the curly brackets are the instructions to be executed then why is the spelling with () => a little strange, beyond the scope of this lesson, we say stop is just so  . The timeout after 75 seconds then executes instructions If the query in this query is whether the actor is also currently available (it may already have been removed elsewhere), if nothing happens, but if (actor as '''AiGroundActor''') we put hereby determine that the actor should be treated as '''AiGroundActor''' (if we do not do this, we get an error message because the system does not know what we mean Actor) with.
 
  
'''.Destroy()''' then this is completely removed from the mission, then simply disappears. This makes you an "overpopulation" of the card to avoid running so essentially multiplayer maps (as is the despawn time course much larger) the number of times. But here it fits quite well purely  .  
+
'''Timeout(75, () => { Anweisungen });''' - "отсчитываем" 75 секунд после создания '''Actor''', далее проверяем существует ли он еще - '''if (actor != null)'''. Если условия выполняются - указываем, что объект должен рассматриваться как '''AiGroundActor''' и уничтожаем объект командой '''.Destroy();'''.
 +
 
 +
 
 +
'''.Destroy()''' - удаляет объект из мисии (с карты он исчезает).
  
 
  public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
 
  public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
Строка 292: Строка 302:
  
  
To register if we have destroyed a target, we overloaded the method OnActorDead(..)
+
Чтобы зарегистрировать уничтоженный объект в статистике переопределим метод '''OnActorDead(..)'''.
'''public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)'''
+
  
This method is used by system called each time when an actor is destroyed (or better Incapacitate is) and that this happens twice, once for the vehicle and then for the imaginary occupant, here you realize it is in the game also provided the ground vehicles and by human players can be controlled. Since we do not want our ''' "DeadCounter" ''' is incremented twice, we introduce the variable name of type String killed. Killed name then sets up the name to be observed, because here you have to decide actor.Name () (ie the name of the destroyed target) once the value of "1:0_Chief0" and the second call "1:0_Chief" (one that varies depending on mission number), according to the number after the occupants of the Chief is all spent. The base name can be found in the Mis-file in our example SubMission here:  
+
'''public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)'''
 +
 
 +
Этот метод вызывается при нанесении объекту повреждений, причем два раза - первый раз для техники, второй - для экипажа. Так как мы будем считать только уничтоженные грузовики введем переменную '''KilledName'''. Переменная будет состоять из номера миссии и имени уничтоженного объекта. Имя объекта можно найти в файле мисиии '''.mis''':
  
 
  [Chiefs]
 
  [Chiefs]
 
  0_Chief Vehicle.Austin_10_Tilly gb
 
  0_Chief Vehicle.Austin_10_Tilly gb
  
One can of course use the Mis-file and edit there own.
 
I signed up for "Missionnummer:0_Chief" decided, that the vehicle itself
 
  
 
  '''if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))'''  
 
  '''if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))'''  
  
Thus the explanation for the If statement is again somewhat larger
+
- условие в котором определяется, что игрок уничтожил объект. Если выполняется - прибавляем к счетчику уничтоженных грузовиков еще один и выводим сообщение сервреа об этом.
 
+
'''damages.Count != 0''' - '''System.Collections.Generic.List<DamagerScore>''' damages of the type, well actually not a type but a list, this list is by us from C #; provided ('''using System.Collections.Generic;'''). This list contains elements of type DamagerScore be on this list from the game all the actuators were placed in the destruction of this object (Actor) involved. The more players than can be had even AIs. With the help of '''.Count''' one can count the number of items in the list, this value is zero, no one was involved, the query is needed because the method '''.Destroy()''' method throws the '''OnActorDead''' because we were only on the Players interested destroyed vehicles, we ignore the system simply eliminated.
+
 
+
'''&& (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name()))''' - this is to ensure that even the player is the one who destroyed the vehicle has '''PlayerPlane.Name()''' contains the name of the pilot ( has fired in my case, therefore, Kodiak) and ''''damages[0].initiator.Actor.Name()''' returns the name of the person as the last of the car (or plane).
+
'''damages[0]''' - sufficient because only one aircraft and a player were on the road. Both will be compared and if consensus is part of this perception. With & & KilledName.Equals (actor.Name () is then queried even if the target is consistent with our desired. Thus, if the entire if statement is true, the ZerstoerteZiele counter incremented by one and spent a brief test message on the screen.  
+
  
But do not worry in the next lessons will deepen the whole still.
 
As always, I am grateful for criticism and suggestions.
 
  
The attachment contains the current instance missions.  
+
: ''Для установки миссий-примеров скопируйте их в папку:
 +
..\Documents\1C SoftClub\il-2 sturmovik cliffs of dover\missions\Single
  
 +
----
 +
=== Загрузка подмиссий (автор FG28_Kodiak) ===
 +
Оригинальные темы см. на форуме [http://translate.google.com/translate?hl=en&sl=de&tl=en&u=http%3A%2F%2Fforum.sturmovik.de%2Findex.php%2Fboard%2C17.0.html sturmovik.de](перевод от Google):
  
 +
*[[Ил-2 Штурмовик: Битва за Британию. Скрипты. Скрипты для чайников. Часть 1 - Загрузка подмиссий|Часть 1 - Загрузка подмиссий]]
 +
*[[Ил-2 Штурмовик: Битва за Британию. Скрипты. Скрипты для чайников. Часть 2 - Загрузка подмиссий|Часть 2 - Загрузка подмиссий]]
 +
*[[Ил-2 Штурмовик: Битва за Британию. Скрипты. Скрипты для чайников. Часть 4 - Загрузка подмиссий|Часть 4 - Загрузка подмиссий]]
  
 +
[[Ил-2 Штурмовик: Битва за Британию. Скрипты|Вернуться на страницу "Скрипты"]]
  
 
[[Категория:Ил-2 Штурмовик: Битва за Британию. Скрипты]]
 
[[Категория:Ил-2 Штурмовик: Битва за Британию. Скрипты]]

Текущая версия на 18:30, 6 ноября 2011

Автор: FG28_Kodiak
Ссылка: Перейти (перевод Google)

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

Samples.zip

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

Samples.zip


В предыдущих двух миссиях мы загружали под-миссии после начала миссии-хоста. В этой части мы научимся контролировать загрузку миссиий при помощи метода public virtual void OnTickGame ()

public override void OnTickGame()

Метод OnTickGame() направляет вызовы с частотой 34 тика в секунду, в зависимости от компьютера может быть больше или меньше времени.

Например:

using System;
using maddox.game;
using maddox.game.world;
public class Mission : AMission
{
   public override void OnTickGame()
   {
       double WievielSekunden = 0;
       
       if (Time.tickCounter() == 334) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Meldung nach: {0} Ticks das sind {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
       if (Time.tickCounter() == 667) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Meldung nach: {0} Ticks das sind {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
       if (Time.tickCounter() == 1000) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Meldung nach: {0} Ticks das sind {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
  }
} 

Данный пример ничего не делает, кроме как отправляет сообщение в чат сервера каждые 10, 20, 30 секунд.

Time.tickCounter() - содержит количество тиков, прошедших с момента начала мисиии Time.TicksToSecs - переводит такты в секунды

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

GamePlay.gpLogServer (null, "Meldung nach: {0} Ticks das sind {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});

В игре это будет выглядеть так:


Sfdp3-1.jpg


Также вы можете использовать OnTickGame() для задания циклов, зависящих от времени, например:


using System;
using maddox.game;
using maddox.game.world;
public class Mission : AMission
{
   public override void OnTickGame()
   {
       double WievielSekunden = 0;
       
       if (Time.tickCounter() % 334 == 0) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Erste Meldung: {0} Ticks = {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
       if (Time.tickCounter() % 509 == 0) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Zweite Meldung: {0} Ticks = {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
   }
}

Для вычисления остатка при целочисленном делении в языке С# используется оператор деления по модулю %. Он применяется таким же образом, что и оператор деления, но в результате вычисляется не частное, а остаток.

3%3   результат: 0
3%2   результат: 1
5%3   результат: 2
Подробнее можно прочитать здесь: Деление с остатком )

Условие Time.tickCounter() % 334 == 0 всегда выполняется когда значениеtickCounter() равно 334 тика (то есть остаток от деления 334%334 равен нулю и отправляет сообщения в чат через каждые 10 секунд.

Условие Time.tickCounter() % 509 == 0 всегда выполняется когда значениеtickCounter() равно 509 тиков (то есть остаток от деления 509%509 равен нулю и отправляет сообщения в чат через каждые 15 секунд.


Sfdp3-2.jpg


Если вы не хотите выводить сообщение в начале миссии, можете использовать задержку изменив ноль в предыдущем примере на значение меньше, чем делитель. Вот примеры неправильных условий:

if (Time.tickCounter() % 334 == 334)
if (Time.tickCounter() % 334 == 335)
Эти условия никогда не будут выполнены и сообщение не появится на экране.

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

using System;
using maddox.game;
using maddox.game.world;
public class Mission : AMission
{
   public override void OnTickGame()
   {
       double WievielSekunden = 0;
       
       if (Time.tickCounter() % 334 == 333) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Erste Meldung: {0} Ticks = {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
       if (Time.tickCounter() % 509 == 508) 
       {
           WievielSekunden = Time.TicksToSecs(Time.tickCounter());
           GamePlay.gpLogServer (null, "Zweite Meldung: {0} Ticks = {1} sek.\n", new object [] {Time.tickCounter(), WievielSekunden});
       }
   }
} 

Результат:

Sfdp3-3.jpg


В основную миссию два добавим камуфляжную палатку, она появится перед исчезновением и скроет технику.


Sfdp3-4.jpg


Далее нам необходима подмиссия. В ней будет один автомобиль, который проедет от одного конца ВПП до другого.


Sfdp3-5.jpg


Подмиссия будет загружаться скажем каждые 30 секунд, так мы создадим колонну грузовиков, которые будут курсировать по ВПП и станут для нас отличной мишенью. Транспортные средства будут двигаться на некотором расстоянии друг от друга. В нашей миссии автомобили буду исчезать через 75 секунд - это время, которое понадобится им, чтобы достичь конечной точки пути. Игрок должен уничтожить как можно больше автомобилей. Количество машин (точнее под-миссий) будет равно 10. В этот раз мы не будем использовать триггеры, зачет результатов атаки и сведения о поврежденной технике будут содержаться в коде скрипта.

Код с тестовыми сообщениями:


using System;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;
public class Mission : AMission
{    
   AiAircraft PlayerPlane;
   const int MaxAnzahlWellen = 10;
   int AnzahlWellen = 0;
   int ZerstoerteZiele = 0;    
   public override void OnBattleStarted()
   {
       base.OnBattleStarted();
       MissionNumberListener = -1;
       PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();
   }	
   private void serverMessage(string msg)
   {
       GamePlay.gpLogServer (null, msg, new object [] {msg});
   }    
   public override void OnTickGame()
   {
       if (Time.tickCounter() % 1000 == 0 && (AnzahlWellen < MaxAnzahlWellen))  //ca. alle 30sek die Karte laden
       {
           GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen5Sub1.mis");
           AnzahlWellen++;
           GamePlay.gpLogServer (null, "{0} nach {1} sek.\n", new object [] {AnzahlWellen, Time.TicksToSecs(Time.tickCounter())});//Testmeldung
       }        
       if (Time.tickCounter() % 11500 == 0)     
       {
                   GamePlay.gpLogServer (null, "{0} nach {1} sek.\n", new object [] {AnzahlWellen, Time.TicksToSecs(Time.tickCounter())});//Testmeldung
                   GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlWellen.ToString() + " Fahrzeugen zerstört" );
       }
   }    
   public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
   {
       base.OnActorCreated(missionNumber, shortName, actor);
       if (actor is AiGroundActor)
       {
           Timeout(75, () => {
               if (actor != null)
               { 
                   (actor as AiGroundActor).Destroy(); 
               }
           });
       }
   }    
   public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
   {
   		base.OnActorDead(missionNumber, shortName, actor, damages);        
       string KilledName;     		
    		KilledName = missionNumber.ToString()+ ":0_Chief";     		
    		if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))
    		{
    		    ZerstoerteZiele++;
    		    serverMessage(ZerstoerteZiele.ToString());
    	  }
   }
}


Разберем код нашего скрипта. Во-первых мы используем новый метод:

using System.Collections.Generic;

В скрипте нам понадобятся следующие переменные:

AiAircraft PlayerPlane; - AiAircraft класс, в котором содержатся все доступные самолеты в игре, все самолеты за пределами этой группы являются статическими.

const int MaxAnzahlWellen = 10; - количество запусков под-миссий, в нашем случае равно кол-ву грузовиков (целей) int AnzahlWellen = 0; - кол-во уже запущенных под-миссий int ZerstoerteZiele; - количество уничтоженных целей

public override void OnBattleStarted()
{
   base.OnBattleStarted();
   MissionNumberListener = -1;
   PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();
}

В методе OnBattleStarted установим MissionNumberListener = -1, чтобы иметь доступ к объектам под-миссий.

PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place(); - определяем самолет игрока. Используем для этого класс IGamePlay, в котором есть метод gpPlayer(). Указываем нужный нам класс (AiAircraft) куда входит игрок (так же он присутствует в классах AiActor, AiCart, AiAircraft..). Place() определяет текущее положение игрока. Метод gpPlayer используется только в одиночных миссиях, для мультиплеера нужно использовать метод gpRemotePlayers.


public override void OnTickGame()
{
   if (Time.tickCounter() % 1000 == 0 && (AnzahlWellen < MaxAnzahlWellen))  //ca. alle 30sek die Karte laden
   {
       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen5Sub1.mis");
       AnzahlWellen++;
       GamePlay.gpLogServer (null, "{0} nach {1} sek.\n", new object [] {AnzahlWellen, Time.TicksToSecs(Time.tickCounter())});//Testmeldung
   }
       
   if (Time.tickCounter() == 11500)     
   {
       GamePlay.gpLogServer (null, "{0} nach {1} sek.\n", new object [] {AnzahlWellen, Time.TicksToSecs(Time.tickCounter())});//Testmeldung
       GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlWellen.ToString() + " Fahrzeugen zerstört" );
       MissionAbgeschlossen = true;
   }
}


OnTickGame ()

if (Time.tickCounter() % 1000 == 0 && (AnzahlWellen < MaxAnzahlWellen)) - условие, которое загружает под-миссию, если прошло 30 секунд И (оператор &&) и номер текущей подмиссии меньше переменной const int MaxAnzahlWellen.

if (Time.tickCounter() == 11500) - если прошло 11500 тиков (то есть время, выделенное на выполнение задания - выводится итоговый результат по количеству уничтоженных целей)

Sfdp3-6.jpg


public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
   base.OnActorCreated(missionNumber, shortName, actor);
   if (actor is AiGroundActor)
   {
       Timeout(75, () => {
           if (actor != null)
           { 
               (actor as AiGroundActor).Destroy(); 
           }
       });
   }
}


OnActorCreated(int missionNumber, string shortName, AiActor actor) - метод вызывается каждый раз, когда создается новый Actor.

if (actor is AiGroundActor) - проверяем, принадлежит ли Actor к классу AiGroundActor в котором содержатся все "живые" наземные объекты: автомобили, танки, корабли, артиллерия. Если условие равно TRUE выполняется соответствующий код.


Timeout(75, () => { Anweisungen }); - "отсчитываем" 75 секунд после создания Actor, далее проверяем существует ли он еще - if (actor != null). Если условия выполняются - указываем, что объект должен рассматриваться как AiGroundActor и уничтожаем объект командой .Destroy();.


.Destroy() - удаляет объект из мисии (с карты он исчезает).

public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
{
   base.OnActorDead(missionNumber, shortName, actor, damages);        
   string KilledName;           
   KilledName = missionNumber.ToString()+ ":0_Chief";           
   if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))
   {
       ZerstoerteZiele++;
       serverMessage(ZerstoerteZiele.ToString()); //Testmeldung
   }
}


Чтобы зарегистрировать уничтоженный объект в статистике переопределим метод OnActorDead(..).

public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)

Этот метод вызывается при нанесении объекту повреждений, причем два раза - первый раз для техники, второй - для экипажа. Так как мы будем считать только уничтоженные грузовики введем переменную KilledName. Переменная будет состоять из номера миссии и имени уничтоженного объекта. Имя объекта можно найти в файле мисиии .mis:

[Chiefs]
0_Chief Vehicle.Austin_10_Tilly gb


if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name())) 

- условие в котором определяется, что игрок уничтожил объект. Если выполняется - прибавляем к счетчику уничтоженных грузовиков еще один и выводим сообщение сервреа об этом.


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

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

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

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