Autor Thema: [Scripting for Dummies] Missionen in bereits laufende Missionen laden - Teil 1  (Gelesen 3011 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Offline FG28_Kodiak

  • Blasenteetrinker
  • *****
  • Beiträge: 1.893
Cliffs of Dover bietet mit Hilfe der Scriptsprache die Möglichkeit, Missionen in bereits laufende Missionen zu laden. Das ist einerseits für Online Server interessant, andererseits ergeben sich dadurch auch für offline Missionen sehr interessante Möglichkeiten.
Man kann die Spielwelt etwa lebendiger gestalten, indem man bereits vorhandene Missionen zur aktuellen dazulädt, oder den Missionen einen gewissen Zufallscharakter verleihen indem man aus mehreren Submissionen zufällig eine auswählt und dazu lädt. Auch hat man dadurch z.B. die Möglichkeit eine in einer Submission abgelegte Bodenschlacht im richtigen Moment per Trigger zu laden, so dass der Spieler nicht erst ankommt wenn schon alles vorbei ist usw.


Zum laden einer Mission stellt uns die Gameplay-Klasse die Methode void gpPostMissionLoad(string fileName) zur Verfügung.

Aufrufbeispiel:
GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission1.mis");
Das doppelte \\ ist in C# nötig um dem System zu zeigen das das \ als Zeichen gemeint ist, da das \ in C# auch Steuersequenzen einleitet.

Es ist aber auch möglich den normalen Slash zu verwenden.
GamePlay.gpPostMissionLoad("missions/Single/Samples/TestSubmissions/TestSubMission.mis");

Angenommen man möchte ein paar SubMissionen am Anfang der Mission dazu laden.

Zu Beginn der Mission wird von Cliffs of Dover die Methode public virtual void OnBattleStarted() (wird von AMission und Campaign u.a. zur Verfügung gestellt) aufgerufen. Diese können wir überladen und so unsere SubMissionen gleich am Start laden.

Also:

public override void OnBattleStarted()
{
        base.OnBattleStarted();
        MissionNumberListener = -1;

        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission1.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission2.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission3.mis");
}

Erläuterung:
base.OnBattleStarted() dient dazu die Ursprungsmethode einmal aufzurufen um alles ordnungsgemäß zu initialisieren.

MissionNumberListener = -1 legt fest das das Script auch für alle Events der geladenen SubMissionen zuständig ist. Ansonsten könnte man hier festlegen das nur die Events der gerade laufenden Mission (MissionNumberListener = 0) oder nur eine bestimmte SubMission (die erste geladene Mission bekommt die Nummer 1, die Zweite die Nummer 2 usw.) Beachtung findet. Möchte man alle Events der Missionen beachten muss man MissionNumberListener einen negativen Wert zuweisen, z.B. -1.


So eigentlich haben wir bereits alles das nötig ist um die SubMissionen am Beginn zu laden.

Noch den Rest dazu und schon ist das Script einsatzbereit:
using System;
using maddox.game;
using maddox.game.world;

public class Mission : AMission
{

    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;

        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission1.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission2.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\TestSubMission3.mis");
    }
}

Als Missionsdesigner muss man eigentlich nur die Anzahl der zu ladenden SubMissionen und den Pfad und die Namen anpassen.


Aber da bekanntlich ein Beispiel nie schaden kann ;).
Modifizieren wir unser schon aus der vorherigen Lektion bekanntes Beispiel:



Wir löschen einfach mal die bereits erstellten Bodenziele, die Bf109 und die Trigger lassen wir aber mal unangetastet, dies ist unsere Hauptmission:


Dann erzeugen wir zwei neue Missionen, die nur Bodenziele enthalten:

und


Und da wir gerade dabei sind noch eine dritte Mission mit Bodenzielen:




Dann noch den Code, nach Anpassen der Missionspfade und Namen, in die Hauptmission einfügen:
using System;
using maddox.game;
using maddox.game.world;

public class Mission : AMission
{

    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;

        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub1.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub2.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub3.mis");
    }
}

Dann die Hauptmission gestartet, und siehe da:


Die Beispielmission befindet sich als MissionNachladen1.zip Attachment am Ende dieses Posts.


So da wir ja noch die Trigger haben können wir diese ja auch gleich wiederverwenden, wir kopieren einfach den Code - Abschnitt von OnTrigger() aus unserer letzten Lektion zu unserer Hauptmission hinzu.

Erhalten also gesamt:
using System;
using maddox.game;
using maddox.game.world;

public class Mission : AMission
{

    public override void OnBattleStarted()
    {
        base.OnBattleStarted();
        MissionNumberListener = -1;

        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub1.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub2.mis");
        GamePlay.gpPostMissionLoad("missions\\Single\\Samples\\TestSubmissions\\MissionNachladen1Sub3.mis");
    }

    public override void OnTrigger(int missionNumber, string shortName, bool active)
{
    base.OnTrigger(missionNumber, shortName, active);
   
    if ("WinCondition1".Equals(shortName) && active)
        {
        GamePlay.gpHUDLogCenter("Ziel erreicht");
        GamePlay.gpGetTrigger(shortName).Enable = false;
        GamePlay.gpGetTrigger("FailCondition1").Enable = false;
}
if ("FailCondition1".Equals(shortName) && active)
        {
        GamePlay.gpHUDLogCenter("Sie haben die Zeit überschritten");
        GamePlay.gpGetTrigger(shortName).Enable = false;
        GamePlay.gpGetTrigger("WinCondition1").Enable = false;
}
}
}

Danach starten wir die Mission (MissionNachladen2.zip), zur Erinnerung wir müssen insgesamt 6 Ziele der linken beiden Kolonnen zerstören, da diese im Triggerkreis liegen. Das natürlich bevor die Zeit abgelaufen ist (habe das Zeitlimit zu Testzwecken auf 320sek erhöht).

Nur nach zerstören von 6 Bodenzielen passiert nichts!


Auch nach dem zerstören von noch mehr Zielen immer noch NICHTS!:


Jedes mal erhalten wir nur diese Meldung:



Was ist passiert? Na ja eigentlich ganz einfach unser Trigger WinCondition1 ignoriert die neu hinzu geladenen Ziele. Während FailCondition1, da nur Zeitabhängig, eben erbarmungslos zuschlägt.

Wie kann man dieses Problem umgeben.
Als erstes haben wir natürlich die Möglichkeit unsere Mission so zu bauen, das alles was zum Auslösen der Trigger erforderlich ist sich in der Hauptmission befindet. Wäre auf Dauer halt recht unflexibel.
Zweitens wissen wir ja das wenn MissionNumberListener = -1 ist, auch die Events der Submissionen von unserem Script beachtet werden. Das bedeutet wir können die für uns nötigen Trigger in unseren Submissionen unterbringen, werden sie ausgelöst, können sie von unserem Script dann auch verarbeitet werden.
Drittens können wir durch ein Script einen neuen Trigger erstellen.
Über die zweite Möglichkeit geht es in der nächsten Lektion, die Dritte werde ich dann in einer späteren Lektion behandeln.

Ich denke das reicht mal für diesen Thread :)

In kürze mehr.

Bei den Samplemissionen den entpackten Ordner "Sample" bitte nach ..\Documents\1C SoftClub\il-2 sturmovik cliffs of dover\missions\Single kopieren.

[gelöscht durch Administrator]

[gelöscht durch Administrator]
« Letzte Änderung: 07.Juni.2011, 11:41 von Deichwart »