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

Материал из АвиаВики
Перейти к: навигация, поиск
(Загрузка подмиссий (автор FG28_Kodiak))
 
(не показано 5 промежуточных версии ещё одного участника)
Строка 2: Строка 2:
 
:'''Ссылка:''' [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,727.0.html%3FPHPSESSID%3Dac198c6ea43133020cb39e5f138fa85a&usg=ALkJrhhbK_cwK9rxUTG45GzS5T3g0YVzBQ Перейти (перевод 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,727.0.html%3FPHPSESSID%3Dac198c6ea43133020cb39e5f138fa85a&usg=ALkJrhhbK_cwK9rxUTG45GzS5T3g0YVzBQ Перейти (перевод Google)]
  
In the last lesson we have so busy trying to load a single SubMission to 30sec and monitors all the vehicles destroyed using the method OnActorDestroyed () to count.  
+
Скачать оригиналы миссий:
With this lesson we will randomly select and load each one of multiple submissions and. We are also building a small trap for the player, namely friendly vehicles. Is one of those destroyed by the player, the mission is a failure. The player will learn to look more closely and we will learn how the Army finds a membership Actors, then both of them what  . In addition, we no longer count the total number of vehicles but only those of the Enemy.  
+
:[http://forum.sturmovik.de/index.php?action=dlattach;topic=721.0;attach=21823 Samples.zip]
 +
Скачать примеры с Sukhoi.ru:
 +
:[http://www.sukhoi.ru/forum/attachment.php?attachmentid=142554&d=131833436523 Samples.zip]
  
So prepare for the first submissions, the primary mission remains unchanged. We open the SubMission from last time, change the vehicle and then saves the mission under another name. Here as an example once befriended our vehicle:
+
В последнем уроке мы научились загружать подмиссии с заданным интервалом времени и учитывать уничтоженные объекты с помощью метода '''OnActorDestroyed()'''.  
  
[[Файл:Sfdp4-1.jpg|800px]]
+
В этом уроке мы научимся случайным образом выбирать и загружать подмиссии, а также подготовим небольшую ловушку для игрока в виде дружественной техники при уничтожении которой засчитывается поражение. Игроку предстоит быть более внимательным, а мы узнаем как задать принадлежность к армии для '''Actor '''. Кроме того в зачет уничтоженных целей будет идти только вражеская техника, в отличие от предыдущего урока.
  
 +
Основную миссию оставляем без изменений, возьмем под-миссию из прошлого урока, поменяем в ней технику и сохраним под другим именем. Сделайте несколько таких подмиссий:
  
Overall, I've created the next from last time, three other submissions, including one friend with a vehicle.
+
[[Файл:Sfdp4-1.jpg|800px]]
The code for this example mission
+
  
using System;
 
using maddox.game;
 
using maddox.game.world;
 
using System.Collections.Generic;
 
  
 +
Одну из подмиссий сделаем с дружественным транспортным средством (та самая ловушка).
  
public class Mission : AMission
+
Код скрипта:
{
+
enum MissionCondition {Neutral, Success, Failure}
+
  
MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;  
+
using System;
AiAircraft PlayerPlane;  
+
using maddox.game;
const int MaxAnzahlFeindlicheFahrzeuge = 10;  
+
using maddox.game.world;
int Zeitspanne = 4000;  
+
using System.Collections.Generic;
int AnzahlFeindlicheFahrzeuge = 0;  
+
public class Mission : AMission
int ZerstoerteZiele = 0;  
+
{
 +
    enum MissionCondition {Neutral, Success, Failure}   
 +
    MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
 +
    AiAircraft PlayerPlane;
 +
    const int MaxAnzahlFeindlicheFahrzeuge = 10;
 +
    int Zeitspanne = 4000;  
 +
    int AnzahlFeindlicheFahrzeuge = 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 (AktuelleMissionCondition == MissionCondition.Neutral)
 +
        {   
 +
            if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge))  //ca. alle 30sek die Karte laden
 +
            {
 +
                Zeitspanne += 1000;  // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
 +
                Random ZufaelligesFahrzeug = new Random();           
 +
                switch (ZufaelligesFahrzeug.Next(1,5))
 +
                {
 +
                    case 1:
 +
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
 +
                    break;
 +
                    case 2:
 +
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
 +
                    break;
 +
                    case 3:
 +
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
 +
                    break;
 +
                    case 4:
 +
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
 +
                    break;
 +
                    default:
 +
                        serverMessage("Mission nicht gefunden");
 +
                    break;
 +
                }
 +
            }           
 +
            if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)   
 +
            {
 +
                GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
 +
                AktuelleMissionCondition = MissionCondition.Success;
 +
            }
 +
        }
 +
    }   
 +
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
 +
    {
 +
        base.OnActorCreated(missionNumber, shortName, actor);       
 +
        if (actor is AiGroundActor)
 +
        {
 +
            GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung           
 +
            if (actor != null && actor.Army() == 1)  // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
 +
            {
 +
                AnzahlFeindlicheFahrzeuge++;  // Wird nur gezählt wenn gegnerische Seite
 +
            }         
 +
            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()))
 +
        {           
 +
            if (actor != null && actor.Army() == 2)  // 2 steht für Rote Seite 1 würde für Blaue Seite stehen
 +
            {
 +
                GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
 +
                AktuelleMissionCondition = MissionCondition.Failure;
 +
            }
 +
            ZerstoerteZiele++;
 +
        }
 +
    }
 +
}
  
public override void OnBattleStarted()
 
{
 
base.OnBattleStarted();
 
MissionNumberListener = -1;
 
PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();
 
}
 
  
 +
В нашей миссии будет несколько глобальных переменных:
  
private void serverMessage(string msg)
+
enum MissionCondition {Neutral, Success, Failure}
{  
+
MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
GamePlay.gpLogServer (null, msg, new object [] {msg});  
+
}
+
  
 +
Здесь мы задаем статус миссии, подробней можно посмотреть в одном из предыдцщих уроков.
  
public override void OnTickGame()
+
'''const int MaxAnzahlFeindlicheFahrzeuge = 10;''' - общее количество вражеской техники.
{
+
if (AktuelleMissionCondition == MissionCondition.Neutral)
+
{
+
if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge)) //ca. alle 30sek die Karte laden
+
{
+
Zeitspanne += 1000; // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
+
Random ZufaelligesFahrzeug = new Random();  
+
  
switch (ZufaelligesFahrzeug.Next(1,5))
+
'''int Zeitspanne = 4000;''' - эта переменная нужна для задания интервалов между появлением техники (загрузкой подмиссий).
{
+
case 1:
+
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");  
+
break;
+
case 2:
+
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
+
break;
+
case 3:
+
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
+
break;
+
case 4:
+
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
+
break;
+
default:
+
serverMessage("Mission nicht gefunden");
+
break;
+
}
+
}
+
  
if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)
+
'''int AnzahlFeindlicheFahrzeuge = 0;''' - переменная для хранения текущего количества вражеской техники.  
{
+
GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );  
+
AktuelleMissionCondition = MissionCondition.Success;
+
}
+
}
+
}
+
  
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)  
+
'''OnBattleStarted()''' и '''serverMessage(string msg)'''  также претерпели изменения.
{
+
base.OnActorCreated(missionNumber, shortName, actor);
+
  
if (actor is AiGroundActor)
 
{
 
GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung
 
  
if (actor != null && actor.Army() == 1) // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
+
public override void OnTickGame()
{  
+
{
AnzahlFeindlicheFahrzeuge++; // Wird nur gezählt wenn gegnerische Seite
+
    if (AktuelleMissionCondition == MissionCondition.Neutral)
}  
+
    {   
 +
        if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge)) //ca. alle 30sek die Karte laden
 +
        {
 +
            Zeitspanne += 1000;  // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
 +
            Random ZufaelligesFahrzeug = new Random();       
 +
            switch (ZufaelligesFahrzeug.Next(1,5))
 +
            {
 +
                case 1:
 +
                    GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
 +
                break;
 +
                case 2:
 +
                    GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
 +
                break;
 +
                case 3:
 +
                    GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
 +
                break;
 +
                case 4:
 +
                    GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
 +
                break;
 +
                default:
 +
                    serverMessage("Mission nicht gefunden");
 +
                break;
 +
            }
 +
        }       
 +
        if (Time.tickCounter() > Zeitspanne)   
 +
        {
 +
            GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
 +
            AktuelleMissionCondition = MissionCondition.Success;
 +
        }
 +
    }
 +
}
  
Timeout(75, () => {
+
Метод '''OnTickGame()'''.  
if (actor != null)
+
{
+
(actor as AiGroundActor).Destroy();
+
}
+
});
+
}
+
}
+
  
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)  
+
'''if (AktuelleMissionCondition == MissionCondition.Neutral)''' - проверяем статус миссии.
{
+
base.OnActorDead(missionNumber, shortName, actor, damages);
+
  
string KilledName;
+
'''if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge))''' - проверяем, прошло ли заданное время и не исчерпан ли лимит загружаемых подмиссий (целей).
  
KilledName = missionNumber.ToString()+ ":0_Chief";
+
Если эти два условия выполняются выбираем случайным образом одну из подмиссий при помощи класса '''Random''' ([http://msdn.microsoft.com/en-us/library/system.random.aspx подробнее здесь]):
  
if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))  
+
switch (ZufaelligesFahrzeug.Next(1,5))
{
+
{
 +
    case 1:
 +
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
 +
    break;
 +
    case 2:
 +
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
 +
    break;
 +
    case 3:
 +
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
 +
    break;
 +
    case 4:
 +
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
 +
    break;
 +
    default:
 +
        serverMessage("Mission nicht gefunden");
 +
    break;
 +
}
  
if (actor != null && actor.Army() == 2) // 2 steht für Rote Seite 1 würde für Blaue Seite stehen
+
'''ZufaelligesFahrzeug.Next(1,5)''' - где 1 - минимальное значение, 5 - максимальное, которое никогда не выбирается генератором случ. чисел. '''default''' - все остальные варианты.
{
+
GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
+
AktuelleMissionCondition = MissionCondition.Failure;
+
}
+
  
ZerstoerteZiele++;  
+
'''if (Time.tickCounter() > Zeitspanne)''' - проверяем, истекло ли время. Если да - выводим сообщение о победе и устанавливаем статус миссии "Выполнено" - '''AktuelleMissionCondition = MissionCondition.Success;'''.
}
+
}
+
}
+
  
 +
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
 +
{
 +
    base.OnActorCreated(missionNumber, shortName, actor);   
 +
    if (actor is AiGroundActor)
 +
    {
 +
        GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung       
 +
        if (actor != null && actor.Army() == 1)  // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
 +
        {
 +
            AnzahlFeindlicheFahrzeuge++;  // Wird nur gezählt wenn gegnerische Seite
 +
        }     
 +
        Timeout(75, () => {
 +
            if (actor != null)
 +
            {
 +
                (actor as AiGroundActor).Destroy();
 +
            }
 +
        });
 +
    }
 +
}
  
First, back in the mission globally valid between variables:  
+
В метод '''OnActorCreated''' добавляем следующее:  
mission condition enum {neutral, Success, Failure}  
+
GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});
mission condition condition = MissionCondition.Neutral current mission;  
+
As we once again have a termination condition, we use a lesson from the past already known enumeration
+
  
const int MaxAnzahlFeindlicheFahrzeuge = 10; Since this time we want to consider only the total number of enemy vehicles, a more meaningful variable name was chosen.  
+
Используя метод '''.InternalTypeName()''' мы можем вывести на экран имена объектов '''AiGroundActors'''из игры:  
int period = 4000; With this variable we consider that the last vehicle still needs some time to find their way back down. This variable is later raised in the code for each newly added SubMission to 1000 because we can not know how many vehicles have made friends at the end of the road.
+
int count = 0 enemy vehicles; Here is the current number of enemy vehicles stored.
+
The rest does not change the previous lesson.
+
 
+
OnBattleStarted () and server message (string msg) also remain unchanged.
+
 
+
 
+
public override void OnTickGame ()
+
{
+
if (condition == current mission MissionCondition.Neutral)
+
{
+
if (Time.tickCounter ()% 1000 == 0 & & (number of enemy vehicles <MaxAnzahlFeindlicheFahrzeuge)) / / about 30sec load all the map
+
{
+
Time + = 1000; / / For each new vehicle 30 seconds added to the total time
+
ZufaelligesFahrzeug random = new Random ();
+
 
+
switch (ZufaelligesFahrzeug.Next (1,5))
+
{
+
case 1:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub1.mis");
+
break;
+
case 2:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub2.mis");
+
break;
+
case 3:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub3.mis");
+
break;
+
case 4:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub4.mis");
+
break;
+
default:
+
server message ("Mission not found");
+
break;
+
}
+
}
+
 
+
if (Time.tickCounter ()> interval)
+
{
+
GamePlay.gpHUDLogCenter ("You" + "destroyed vehicles" ZerstoerteZiele.ToString () + "from" + AnzahlFeindlicheFahrzeuge.ToString () +);
+
current mission condition = MissionCondition.Success;
+
}
+
}
+
}
+
 
+
In contrast, if the method was OnTickGame ().
+
 
+
if (condition == MissionCondition.Neutral current mission) is first queried first whether the mission is still neutral status. So the mission was already a failure by a friendly target to be destroyed, no new submissions are more loaded.
+
 
+
if (Time.tickCounter ()% 1000 == 0 & & (number of enemy vehicles <MaxAnzahlFeindlicheFahrzeuge)) The query is executed when are passed about 30sec and has already spawned the number of enemy vehicles have not reached the maximum number.
+
If the query is so true
+
can be the first time around 1000 increased the amount of time + = 1000 as a one time = time + 1000 to write. The + = (just as there are -=, *= and / =) is shorthand for lazy writing (Ok not quite  ).
+
ZufaelligesFahrzeug random = new Random () we hereby create a new object with the name ZufaelligesFahrzeug from the Random class, this class will put us through. Net is available and provides us with pseudo-random numbers. Pseudo-states under the same conditions will always produce the same numbers. But for our purposes, ranging from this type of random numbers (where there is more information about this.).
+
 
+
switch (ZufaelligesFahrzeug.Next (1,5))
+
{
+
case 1:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub1.mis");
+
break;
+
case 2:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub2.mis");
+
break;
+
case 3:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub3.mis");
+
break;
+
case 4:
+
GamePlay.gpPostMissionLoad ("missions \ \ music \ \ samples \ \ test submissions \ \ MissionNachladen6Sub4.mis");
+
break;
+
default:
+
server message ("Mission not found");
+
break;
+
}
+
 
+
To determine what is loaded SubMission we use a switch .. case statement. It is checked whether the listed behind switch expression, either an integer or a string must be consistent with the stated case behind constants. This will in turn proceed therefore first checks whether the first case is true, then if the second, etc. You can in C # does not specify the area behind the case, things like first case .5: are not possible in C #. Makes a case for, all instructions are to break; executed. By default, you can define a branch which is executed in any case, if no case is true. But as we look at the switch -. Statement of our script to switch closer (ZufaelligesFahrzeug.Next (1,5)) With ZufaelligesFahrzeug.Next (..,..) we produce with the help of the Random object is an integer random number. The first value in parentheses indicates the minimum value, this is including the second value indicates the maximum value, this is exclusive, which means the maximum value is not generated by the random number generator, the minimum value on the other hand already. If you want to, for example, random numbers 1 to 10 would have. Next specify (1.11). In our example, we currently have 4 missions so we need the numbers from 1 to 4, so we need to define. Next (1.5). The random number was generated, compares the switch statement case all cases were found to the right and then loads the specified there SubMission. Had we accidentally. Next (1,6) as specified random number range, would be produced also from time to time the number 5, but there is no case scenario, so there would be the default active area and this gives us a brief message in the chat bar.
+
 
+
With if (Time.tickCounter ()> time), we check whether the time has already expired, if yes, we give a "winning message" and to evaluate current condition = MissionCondition.Success mission and the mission a success.
+
 
+
public override void OnActorCreated (int mission number, string ShortName, AiActor actor)
+
{
+
base.OnActorCreated (mission number, short name, actor);
+
 
+
if (actor is AiGroundActor)
+
{
+
GamePlay.gpLogServer (null, "Car: {0} n \.", New object [] {(actor as AiGroundActor) InternalTypeName ()});// test message
+
 
+
if (actor! = null & & actor.Army () == 1) / / 1 stands for Red to Blue page 2 would stand side
+
{
+
number of enemy vehicles + + / / If only counted when opposing side
+
}
+
 
+
Timeout (75, () => {
+
if (actor! = null)
+
{
+
(As actor AiGroundActor) Destroy ().;
+
}
+
});
+
}
+
}
+
 
+
OnActorCreated were added to the method following instructions:
+
GamePlay.gpLogServer (null, "Car: {0} s \", new object [] {(actor as AiGroundActor) InternalTypeName ()});.
+
With the help of. InternalTypeName () can retrieve the output internal name of a game or AiGroundActors. The output looks like this:  
+
  
 
[[Файл:Sfdp4-2.jpg|800px]]
 
[[Файл:Sfdp4-2.jpg|800px]]
  
  
if (actor! = null & & actor.Army () == 1) is queried with the If statement whether the actor is present and whether it belongs to the opposing army. Army () returns an integer value for the Army, this one stands in the Red Cliffs of Dover on page 2 and blue for the page. So the actor belongs to the Red side of enemy vehicles will be increased by one.
+
'''if (actor != null && actor.Army() == 1)''' - проверяем дружественный ли объект был уничтожен. Если условие верно статус миссии меняется "Провал". Если уничтожен враг - к счету уничтоженных целей прибавляется 1.
 
+
public override void OnActorDead (int mission number, string ShortName, AiActor actor, System.Collections.Generic.List <DamagerScore> damages)
+
{
+
base.OnActorDead (mission number, short name, actor, damages);
+
 
+
Killed string name;
+
 
+
Killed missionNumber.ToString name = () + ": 0_Chief";
+
 
+
if ((damages.Count! = 0) & & (PlayerPlane.Name (). Equals (damages [0]. initiator.Actor.Name ())) & & KilledName.Equals (actor.Name ()))
+
{
+
 
+
if (actor! = null & & actor.Army () == 2) / / 2 stands for Blue side
+
{
+
GamePlay.gpHUDLogCenter ("You have destroyed one of their own vehicles - <<<Mission failed>>>");
+
current mission condition = MissionCondition.Failure;
+
}
+
 
+
ZerstoerteZiele + +;
+
}
+
}
+
 
+
  
Compared to the mission from the last lesson, this If statement was inserted:  
+
public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
if (actor! = null & & actor.Army () == 2) / / 2 stands for Blue side
+
{
{  
+
    base.OnActorDead(missionNumber, shortName, actor, damages);   
GamePlay.gpHUDLogCenter ("You have destroyed one of their own vehicles - <<<Mission failed>>>");  
+
    string KilledName;   
current mission condition = MissionCondition.Failure;  
+
    KilledName = missionNumber.ToString()+ ":0_Chief";   
}  
+
    if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))
You from asking whether the actor is present and by actor.Army () == 2 if it belongs to the blue (ie our) side, this is the case, a message is displayed and updated mission set to failure condition, so the mission was a failure.
+
    {       
 +
        if (actor != null && actor.Army() == 2)   // 2 steht für Blaue Seite
 +
        {
 +
            GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
 +
            AktuelleMissionCondition = MissionCondition.Failure;
 +
        }
 +
        ZerstoerteZiele++;
 +
    }
 +
}
  
 
[[Файл:Sfdp4-3.jpg|800px]]
 
[[Файл:Sfdp4-3.jpg|800px]]
  
  
When testing the above mission, is a relatively quick notice that some vehicles do not come to the second camouflage netting, before they disappear. These vehicles are too slow and therefore need more time until they reach their destination. One could, of course, now simply increase the time after which the vehicles Destroy () will be removed. But then there would be any traffic jams at the destination, which would be an easy target for the player.  
+
Тестируя миссию вы могли заметить, что некоторые машины едут медленнее и неукладываются в установленное время (то есть либо исчезнут по пути, либо будут скапливаться у тента). Чтобы избежать этого мы заставим их уничтожать по достижении определенной точки:
  
To avoid this, you can also write a method that checks where an actor is straight and when this reaches a certain point, it is simply removed from the game. Such a method might look like this:  
+
private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)
 +
{
 +
    Point3d DestroyPos;
 +
    DestroyPos.x = x;
 +
    DestroyPos.y = y;
 +
    DestroyPos.z = 1;
 +
    for (int i = 0; i < MissionsCount; i++)
 +
    {
 +
        AiGroundActor curActor;
 +
        for (int j = 0; j < 10; j++)
 +
        {
 +
            string nameActor = i.ToString() + ":0_Chief" + j.ToString();
 +
            curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
 +
            if (curActor != null)
 +
            {
 +
                if (curActor.Pos().distance(ref DestroyPos) < destroyRadius)
 +
                { 
 +
                        curActor.Destroy();
 +
                }
 +
            }                           
 +
        }
 +
    }     
 +
}
  
private void DestroyGroundActorAtPosition (double x, double y, double radius destroy)
 
{
 
Point3d DestroyPos;
 
DestroyPos.x = x;
 
DestroyPos.y = y;
 
DestroyPos.z = 1;
 
  
for (int i = 0; i <count mission; i + +)  
+
'''private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)''' - задаем координаты и радиус точки уничтожения.  
{
+
AiGroundActor curActor;
+
for (int j = 0; j <10; j + +)
+
{
+
string name actor = i.ToString () + ": 0_Chief" + j.ToString ();
+
curActor GamePlay.gpActorByName = (name actor) as AiGroundActor;
+
if (curActor! = null)
+
{
+
if (curActor.Pos (). distance (ref DestroyPos) <destroy radius)
+
{
+
curActor.Destroy ();
+
}
+
}
+
  
}
+
'''Point3d DestroyPos;''' - DestroyPos is declared as a Point3D, Point3D is an internal data structure of Cliffs of Dover. Access to this structure, we get the result we maddox.GP the namespace by using maddox.GP; load at the beginning of our script.  
}
+
}
+
 
+
Let's look closer.
+
private void DestroyGroundActorAtPosition (double x, double y, double radius destroy)
+
As transfer values ​​required by this self-written method, the X and Y coordinates of the target point and a radius around the point, so that you can specify the distance to the point at which an actor can be ground away.
+
Point3d DestroyPos; DestroyPos is declared as a Point3D, Point3D is an internal data structure of Cliffs of Dover. Access to this structure, we get the result we maddox.GP the namespace by using maddox.GP; load at the beginning of our script.  
+
 
Point3d contains 3 double values, one each for x, y and z are, therefore, all the information a localization in a 3rd dimensional space is required. DestroyPos is with. X = x and. Y = y by the method of transfer values ​​and through. Z = 1 determined by us, the Z-value we define by 1 because we want to disappear leaving only ground targets.  
 
Point3d contains 3 double values, one each for x, y and z are, therefore, all the information a localization in a 3rd dimensional space is required. DestroyPos is with. X = x and. Y = y by the method of transfer values ​​and through. Z = 1 determined by us, the Z-value we define by 1 because we want to disappear leaving only ground targets.  
 
To ensure that all actors can be considered from all these missions you will be using the method OnMissionLoaded (), these count from the game called whenever a mission is reloaded. First, we still need to introduce an additional global variable int count = 1 mission, this mission will be increased in OnMissionLoaded count by one.  
 
To ensure that all actors can be considered from all these missions you will be using the method OnMissionLoaded (), these count from the game called whenever a mission is reloaded. First, we still need to introduce an additional global variable int count = 1 mission, this mission will be increased in OnMissionLoaded count by one.  
public override void OnMissionLoaded (int mission number)  
+
 
{  
+
public override void OnMissionLoaded(int missionNumber)
base.OnMissionLoaded (mission number);  
+
{
mission count + +;  
+
    base.OnMissionLoaded(missionNumber);
}  
+
    MissionsCount++;          
 +
}  
  
 
So back to DestroyGroundActorAtPosition is there with the help of a for - loop  
 
So back to DestroyGroundActorAtPosition is there with the help of a for - loop  
for (int i = 0; i <count mission; i + +)  
+
 
 +
'''for (int i = 0; i < MissionsCount; i++)'''
 
The mission number incremented inside the loop then declares a new name with AiGroundActor curActor.  
 
The mission number incremented inside the loop then declares a new name with AiGroundActor curActor.  
 
Then we need a second loop for (int j = 0; j <10; j + +), with the help of two loops, we set then all currently possible Actress name by string name actor = i.ToString () + ": 0_Chief" + j. ToString (); together, it is necessary to always "caught" the Actor is correct. With curActor GamePlay.gpActorByName = (name actor) as AiGroundActor, we then assign the variables with the help of curActor gpActorByName. With if (curActor! = Null) then we check whether this exists and if Actor (curActor.Pos (). Distance (ref DestroyPos) <destroy radius), we note whether the actor is already close to our point. With curActor.Pos () we get the current location of our Actors supplied as Point3D, from this position we can determine distance (ref DestroyPos) the distance to our previously specified point. distance is a method of Point3D and expected as the transfer value is a reference to the target point. Is the actor close enough to the target point with the Actor Destroy () will be removed.  
 
Then we need a second loop for (int j = 0; j <10; j + +), with the help of two loops, we set then all currently possible Actress name by string name actor = i.ToString () + ": 0_Chief" + j. ToString (); together, it is necessary to always "caught" the Actor is correct. With curActor GamePlay.gpActorByName = (name actor) as AiGroundActor, we then assign the variables with the help of curActor gpActorByName. With if (curActor! = Null) then we check whether this exists and if Actor (curActor.Pos (). Distance (ref DestroyPos) <destroy radius), we note whether the actor is already close to our point. With curActor.Pos () we get the current location of our Actors supplied as Point3D, from this position we can determine distance (ref DestroyPos) the distance to our previously specified point. distance is a method of Point3D and expected as the transfer value is a reference to the target point. Is the actor close enough to the target point with the Actor Destroy () will be removed.  
Строка 325: Строка 294:
 
Here's the whole script:  
 
Here's the whole script:  
  
using System;  
+
using System;
using System.Collections;  
+
using System.Collections;
using maddox.game;  
+
using maddox.game;
using maddox.game.world;  
+
using maddox.game.world;
using maddox.GP;  
+
using maddox.GP;
using System.Collections.Generic;  
+
using System.Collections.Generic;
 
+
public class Mission : AMission
 
+
{
public class Mission : AMission  
+
    enum MissionCondition {Neutral, Success, Failure}  
{  
+
    MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
enum MissionCondition {Neutral, Success, Failure}  
+
    AiAircraft PlayerPlane;
 
+
    const int MaxAnzahlFeindlicheFahrzeuge = 10;
MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;  
+
    int Zeitspanne = 4000; // Zeitspanne bis letztes Fahrzeug sicher verschwunden ist.
AiAircraft PlayerPlane;  
+
    int AnzahlFeindlicheFahrzeuge = 0;
const int MaxAnzahlFeindlicheFahrzeuge = 10;  
+
    int ZerstoerteZiele = 0;
int Zeitspanne = 4000; // Zeitspanne bis letztes Fahrzeug sicher verschwunden ist.  
+
    int MissionsCount = 1;  
int AnzahlFeindlicheFahrzeuge = 0;  
+
    public override void OnMissionLoaded(int missionNumber)
int ZerstoerteZiele = 0;  
+
    {
int MissionsCount = 1;  
+
        base.OnMissionLoaded(missionNumber);
 
+
        MissionsCount++;          
public override void OnMissionLoaded(int missionNumber)  
+
    }
{  
+
    public override void OnBattleStarted()
base.OnMissionLoaded(missionNumber);  
+
    {
MissionsCount++;  
+
        base.OnBattleStarted();
}  
+
        MissionNumberListener = -1;
 
+
        PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();
public override void OnBattleStarted()  
+
    }  
{  
+
    private void serverMessage(string msg)
base.OnBattleStarted();  
+
    {
MissionNumberListener = -1;  
+
        GamePlay.gpLogServer (null, msg, new object [] {msg});
PlayerPlane = (AiAircraft)GamePlay.gpPlayer().Place();  
+
    }  
}  
+
    private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)
 
+
    {
private void serverMessage(string msg)  
+
        Point3d DestroyPos;
{  
+
        DestroyPos.x = x;
GamePlay.gpLogServer (null, msg, new object [] {msg});  
+
        DestroyPos.y = y;
}  
+
        DestroyPos.z = 1;
 
+
        for (int i = 0; i < MissionsCount; i++)
private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)  
+
        {
{  
+
            AiGroundActor curActor;
Point3d DestroyPos;  
+
            for (int j = 0; j < 10; j++)
DestroyPos.x = x;  
+
            {
DestroyPos.y = y;  
+
                string nameActor = i.ToString() + ":0_Chief" + j.ToString();
DestroyPos.z = 1;  
+
                curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
 
+
                if (curActor != null)
for (int i = 0; i < MissionsCount; i++)  
+
                {
{  
+
                    if (curActor.Pos().distance(ref DestroyPos) < destroyRadius)  
AiGroundActor curActor;  
+
                    {  
for (int j = 0; j < 10; j++)  
+
                            curActor.Destroy();
{  
+
                    }
string nameActor = i.ToString() + ":0_Chief" + j.ToString();  
+
                }                            
curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;  
+
            }
if (curActor != null)  
+
        }      
{  
+
    }  
if (curActor.Pos().distance(ref DestroyPos) < destroyRadius)  
+
    public override void OnTickGame()
{  
+
    {
curActor.Destroy();  
+
        if (AktuelleMissionCondition != MissionCondition.Failure && AktuelleMissionCondition != MissionCondition.Success)
}  
+
        {  
}  
+
            if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge)) //ca. alle 30sek die Karte laden
 
+
            {
}  
+
                Zeitspanne += 1000; // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
}  
+
                Random ZufaelligesFahrzeug = new Random();          
}  
+
                switch (ZufaelligesFahrzeug.Next(1,5))
 
+
                {
public override void OnTickGame()  
+
                    case 1:
{  
+
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
if (AktuelleMissionCondition != MissionCondition.Failure && AktuelleMissionCondition != MissionCondition.Success)  
+
                    break;
{  
+
                    case 2:
if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge)) //ca. alle 30sek die Karte laden  
+
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
{  
+
                    break;
Zeitspanne += 1000; // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu  
+
                    case 3:
Random ZufaelligesFahrzeug = new Random();  
+
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
 
+
                    break;
switch (ZufaelligesFahrzeug.Next(1,5))  
+
                    case 4:
{  
+
                        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
case 1:  
+
                    break;
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");  
+
                    default:
break;  
+
                        serverMessage("Mission nicht gefunden");
case 2:  
+
                    break;
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");  
+
                }
break;  
+
            }          
case 3:  
+
            if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)    
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");  
+
            {
break;  
+
                GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
case 4:  
+
                AktuelleMissionCondition = MissionCondition.Success;
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");  
+
            }
break;  
+
        }  
default:  
+
        DestroyGroundActorAtPosition(16761.94, 14817.99, 10.0);      
serverMessage("Mission nicht gefunden");  
+
    }  
break;  
+
    public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
}  
+
    {
}  
+
        base.OnActorCreated(missionNumber, shortName, actor);      
 
+
        if (actor is AiGroundActor)
if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)  
+
        {
{  
+
            GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung          
GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );  
+
            if (actor != null && actor.Army() == 1)   // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
AktuelleMissionCondition = MissionCondition.Success;  
+
            {
}  
+
                AnzahlFeindlicheFahrzeuge++;   // Wird nur gezählt wenn gegnerische Seite
}  
+
            }
 
+
        }
DestroyGroundActorAtPosition(16761.94, 14817.99, 10.0);  
+
    }  
 
+
    public override void OnActorDead(int missionNumber, string shortName, AiActor actor, System.Collections.Generic.List<DamagerScore> damages)
}  
+
    {
 
+
        base.OnActorDead(missionNumber, shortName, actor, damages);      
public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)  
+
        string KilledName;        
{  
+
        KilledName = missionNumber.ToString()+ ":0_Chief";        
base.OnActorCreated(missionNumber, shortName, actor);  
+
        if ((damages.Count != 0) && (PlayerPlane.Name().Equals(damages[0].initiator.Actor.Name())) && KilledName.Equals(actor.Name()))
 
+
        {           
if (actor is AiGroundActor)  
+
            if (actor != null && actor.Army() == 2)  // 2 steht für Blaue Seite
{  
+
            {
GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung  
+
                GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
 
+
                AktuelleMissionCondition = MissionCondition.Failure;
if (actor != null && actor.Army() == 1) // 1 steht für Rote Seite 2 würde für Blaue Seite stehen  
+
            }
{  
+
            ZerstoerteZiele++;
AnzahlFeindlicheFahrzeuge++; // Wird nur gezählt wenn gegnerische Seite  
+
        }
}  
+
    }
}  
+
}
}  
+
 
+
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()))
 
{
 
  
if (actor != null && actor.Army() == 2) // 2 steht für Blaue Seite
 
{
 
GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
 
AktuelleMissionCondition = MissionCondition.Failure;
 
}
 
  
ZerstoerteZiele++;
+
: ''Для установки миссий-примеров скопируйте их в папку:
}
+
..\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:31, 6 ноября 2011

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

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

Samples.zip

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

Samples.zip

В последнем уроке мы научились загружать подмиссии с заданным интервалом времени и учитывать уничтоженные объекты с помощью метода OnActorDestroyed().

В этом уроке мы научимся случайным образом выбирать и загружать подмиссии, а также подготовим небольшую ловушку для игрока в виде дружественной техники при уничтожении которой засчитывается поражение. Игроку предстоит быть более внимательным, а мы узнаем как задать принадлежность к армии для Actor . Кроме того в зачет уничтоженных целей будет идти только вражеская техника, в отличие от предыдущего урока.

Основную миссию оставляем без изменений, возьмем под-миссию из прошлого урока, поменяем в ней технику и сохраним под другим именем. Сделайте несколько таких подмиссий:

Sfdp4-1.jpg


Одну из подмиссий сделаем с дружественным транспортным средством (та самая ловушка).

Код скрипта:

using System;
using maddox.game;
using maddox.game.world;
using System.Collections.Generic;
public class Mission : AMission
{
   enum MissionCondition {Neutral, Success, Failure}    
   MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
   AiAircraft PlayerPlane;
   const int MaxAnzahlFeindlicheFahrzeuge = 10;
   int Zeitspanne = 4000; 
   int AnzahlFeindlicheFahrzeuge = 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 (AktuelleMissionCondition == MissionCondition.Neutral)
       {    
           if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge))  //ca. alle 30sek die Karte laden
           {
               Zeitspanne += 1000;  // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
               Random ZufaelligesFahrzeug = new Random();            
               switch (ZufaelligesFahrzeug.Next(1,5))
               {
                   case 1:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
                   break;
                   case 2:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
                   break;
                   case 3:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
                   break;
                   case 4:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
                   break;
                   default:
                       serverMessage("Mission nicht gefunden");
                   break;
               }
           }            
           if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)     
           {
               GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
               AktuelleMissionCondition = MissionCondition.Success;
           }
       }
   }    
   public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
   {
       base.OnActorCreated(missionNumber, shortName, actor);        
       if (actor is AiGroundActor)
       {
           GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung            
           if (actor != null && actor.Army() == 1)   // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
           {
               AnzahlFeindlicheFahrzeuge++;   // Wird nur gezählt wenn gegnerische Seite
           }          
           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()))
        {             
            if (actor != null && actor.Army() == 2)   // 2 steht für Rote Seite 1 würde für Blaue Seite stehen
           {
               GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
               AktuelleMissionCondition = MissionCondition.Failure;
           }
            ZerstoerteZiele++;
        }
   }
}


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

enum MissionCondition {Neutral, Success, Failure}
MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;

Здесь мы задаем статус миссии, подробней можно посмотреть в одном из предыдцщих уроков.

const int MaxAnzahlFeindlicheFahrzeuge = 10; - общее количество вражеской техники.

int Zeitspanne = 4000; - эта переменная нужна для задания интервалов между появлением техники (загрузкой подмиссий).

int AnzahlFeindlicheFahrzeuge = 0; - переменная для хранения текущего количества вражеской техники.

OnBattleStarted() и serverMessage(string msg) также претерпели изменения.


public override void OnTickGame()
{
   if (AktuelleMissionCondition == MissionCondition.Neutral)
   {    
       if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge))  //ca. alle 30sek die Karte laden
       {
           Zeitspanne += 1000;  // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
           Random ZufaelligesFahrzeug = new Random();        
           switch (ZufaelligesFahrzeug.Next(1,5))
           {
               case 1:
                   GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
               break;
               case 2:
                   GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
               break;
               case 3:
                   GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
               break;
               case 4:
                   GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
               break;
               default:
                   serverMessage("Mission nicht gefunden");
               break;
           }
       }        
       if (Time.tickCounter() > Zeitspanne)     
       {
           GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
           AktuelleMissionCondition = MissionCondition.Success;
       }
   }
}

Метод OnTickGame().

if (AktuelleMissionCondition == MissionCondition.Neutral) - проверяем статус миссии.

if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge)) - проверяем, прошло ли заданное время и не исчерпан ли лимит загружаемых подмиссий (целей).

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

switch (ZufaelligesFahrzeug.Next(1,5))
{
    case 1:
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
    break;
    case 2:
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
    break;
    case 3:
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
    break;
    case 4:
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
    break;
    default:
        serverMessage("Mission nicht gefunden");
    break;
}
ZufaelligesFahrzeug.Next(1,5) - где 1 - минимальное значение, 5 - максимальное, которое никогда не выбирается генератором случ. чисел. default - все остальные варианты.

if (Time.tickCounter() > Zeitspanne) - проверяем, истекло ли время. Если да - выводим сообщение о победе и устанавливаем статус миссии "Выполнено" - AktuelleMissionCondition = MissionCondition.Success;.

public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
{
   base.OnActorCreated(missionNumber, shortName, actor);    
   if (actor is AiGroundActor)
   {
       GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung        
       if (actor != null && actor.Army() == 1)   // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
       {
           AnzahlFeindlicheFahrzeuge++;   // Wird nur gezählt wenn gegnerische Seite
       }      
       Timeout(75, () => {
           if (actor != null)
           { 
               (actor as AiGroundActor).Destroy(); 
           }
       });
   }
}

В метод OnActorCreated добавляем следующее:

GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});

Используя метод .InternalTypeName() мы можем вывести на экран имена объектов AiGroundActorsиз игры:

Sfdp4-2.jpg


if (actor != null && actor.Army() == 1) - проверяем дружественный ли объект был уничтожен. Если условие верно статус миссии меняется "Провал". Если уничтожен враг - к счету уничтоженных целей прибавляется 1.

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()))
   {         
       if (actor != null && actor.Army() == 2)   // 2 steht für Blaue Seite
       {
           GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
           AktuelleMissionCondition = MissionCondition.Failure;
       }
       ZerstoerteZiele++;
   }
}

Sfdp4-3.jpg


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

private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)
{
   Point3d DestroyPos;
   DestroyPos.x = x;
   DestroyPos.y = y;
   DestroyPos.z = 1;
   for (int i = 0; i < MissionsCount; i++)
   {
       AiGroundActor curActor;
       for (int j = 0; j < 10; j++)
       {
           string nameActor = i.ToString() + ":0_Chief" + j.ToString();
           curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
           if (curActor != null)
           {
               if (curActor.Pos().distance(ref DestroyPos) < destroyRadius) 
               {   
                       curActor.Destroy();
               }
           }                             
       }
   }       
}


private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius) - задаем координаты и радиус точки уничтожения.

Point3d DestroyPos; - DestroyPos is declared as a Point3D, Point3D is an internal data structure of Cliffs of Dover. Access to this structure, we get the result we maddox.GP the namespace by using maddox.GP; load at the beginning of our script. Point3d contains 3 double values, one each for x, y and z are, therefore, all the information a localization in a 3rd dimensional space is required. DestroyPos is with. X = x and. Y = y by the method of transfer values ​​and through. Z = 1 determined by us, the Z-value we define by 1 because we want to disappear leaving only ground targets. To ensure that all actors can be considered from all these missions you will be using the method OnMissionLoaded (), these count from the game called whenever a mission is reloaded. First, we still need to introduce an additional global variable int count = 1 mission, this mission will be increased in OnMissionLoaded count by one.

public override void OnMissionLoaded(int missionNumber)
{
   base.OnMissionLoaded(missionNumber);
   MissionsCount++;           
}   

So back to DestroyGroundActorAtPosition is there with the help of a for - loop

for (int i = 0; i < MissionsCount; i++) The mission number incremented inside the loop then declares a new name with AiGroundActor curActor. Then we need a second loop for (int j = 0; j <10; j + +), with the help of two loops, we set then all currently possible Actress name by string name actor = i.ToString () + ": 0_Chief" + j. ToString (); together, it is necessary to always "caught" the Actor is correct. With curActor GamePlay.gpActorByName = (name actor) as AiGroundActor, we then assign the variables with the help of curActor gpActorByName. With if (curActor! = Null) then we check whether this exists and if Actor (curActor.Pos (). Distance (ref DestroyPos) <destroy radius), we note whether the actor is already close to our point. With curActor.Pos () we get the current location of our Actors supplied as Point3D, from this position we can determine distance (ref DestroyPos) the distance to our previously specified point. distance is a method of Point3D and expected as the transfer value is a reference to the target point. Is the actor close enough to the target point with the Actor Destroy () will be removed.

DestroyGroundActorAtPosition we bring the end of the method under OnTick DestroyGroundActorAtPosition (16761.94, 14817.99, 10.0), the XY values ​​I've taken from the submission file, the value of 10.0 for the distance from the target point is sufficient. DestroyGroundActorAtPosition we will be expanding in a later lesson, so that we "clean up" after using this method for a whole range of Actors can.

Here's the whole script:

using System;
using System.Collections;
using maddox.game;
using maddox.game.world;
using maddox.GP;
using System.Collections.Generic;
public class Mission : AMission
{
   enum MissionCondition {Neutral, Success, Failure}    
   MissionCondition AktuelleMissionCondition = MissionCondition.Neutral;
   AiAircraft PlayerPlane;
   const int MaxAnzahlFeindlicheFahrzeuge = 10;
   int Zeitspanne = 4000; // Zeitspanne bis letztes Fahrzeug sicher verschwunden ist.
   int AnzahlFeindlicheFahrzeuge = 0;
   int ZerstoerteZiele = 0;
   int MissionsCount = 1;    
   public override void OnMissionLoaded(int missionNumber)
   {
       base.OnMissionLoaded(missionNumber);
       MissionsCount++;           
   }
   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});
   }    
   private void DestroyGroundActorAtPosition(double x, double y, double destroyRadius)
   {
       Point3d DestroyPos;
       DestroyPos.x = x;
       DestroyPos.y = y;
       DestroyPos.z = 1;
       for (int i = 0; i < MissionsCount; i++)
       {
           AiGroundActor curActor;
           for (int j = 0; j < 10; j++)
           {
               string nameActor = i.ToString() + ":0_Chief" + j.ToString();
               curActor = GamePlay.gpActorByName(nameActor) as AiGroundActor;
               if (curActor != null)
               {
                   if (curActor.Pos().distance(ref DestroyPos) < destroyRadius) 
                   {   
                           curActor.Destroy();
                   }
               }                             
           }
       }       
   }    
   public override void OnTickGame()
   {
       if (AktuelleMissionCondition != MissionCondition.Failure  && AktuelleMissionCondition != MissionCondition.Success)
       {    
           if (Time.tickCounter() % 1000 == 0 && (AnzahlFeindlicheFahrzeuge < MaxAnzahlFeindlicheFahrzeuge))  //ca. alle 30sek die Karte laden
           {
               Zeitspanne += 1000;  // Bei jedem neuen Fahrzeug 30 sekunden zur GesamtZeit hinzu
               Random ZufaelligesFahrzeug = new Random();            
               switch (ZufaelligesFahrzeug.Next(1,5))
               {
                   case 1:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub1.mis");
                   break;
                   case 2:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub2.mis");
                   break;
                   case 3:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub3.mis");
                   break;
                   case 4:
                       GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen6Sub4.mis");
                   break;
                   default:
                       serverMessage("Mission nicht gefunden");
                   break;
               }
           }            
           if (Time.tickCounter() > Zeitspanne && AktuelleMissionCondition != MissionCondition.Success)     
           {
               GamePlay.gpHUDLogCenter("Sie haben "+ ZerstoerteZiele.ToString() + " von " + AnzahlFeindlicheFahrzeuge.ToString() + " Fahrzeugen zerstört" );
               AktuelleMissionCondition = MissionCondition.Success;
           }
       }    
       DestroyGroundActorAtPosition(16761.94, 14817.99, 10.0);        
   }    
   public override void OnActorCreated(int missionNumber, string shortName, AiActor actor)
   {
       base.OnActorCreated(missionNumber, shortName, actor);        
       if (actor is AiGroundActor)
       {
           GamePlay.gpLogServer (null, "Fahrzeug: {0}\n", new object [] {(actor as AiGroundActor).InternalTypeName()});//Testmeldung            
           if (actor != null && actor.Army() == 1)   // 1 steht für Rote Seite 2 würde für Blaue Seite stehen
           {
               AnzahlFeindlicheFahrzeuge++;   // Wird nur gezählt wenn gegnerische Seite
           }
       }
   }    
   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()))
       {             
           if (actor != null && actor.Army() == 2)   // 2 steht für Blaue Seite
           {
               GamePlay.gpHUDLogCenter("Sie haben eines ihrer eigenen Fahrzeuge zerstört - <<<Mission fehlgeschlagen>>>" );
               AktuelleMissionCondition = MissionCondition.Failure;
           }
           ZerstoerteZiele++;
       }
   }
}


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

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

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

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