Inhaltsverzeichnis

Tore und Durchgänge öffnen

FIXME Hier sollte zum einen noch erwähnt werden, dass es unter Umständen zu Problemen mit „festhängenden“ Entities kommen kann (durch das unterschiedliche Blocking bspw. von offenem und geschlossenem Steintor), und zum anderen eine möglichst universelle Funktion zur Lösung/ Vermeidung solcher Probleme eingefügt werden! — Netsurfer 2006/12/30 00:57


Sicherlich habt Ihr schon öfters in den vorgegebenen Karten bemerkt, dass, sobald Ihr ein feindliches Lager zerstört habt, ein „Gefängnis“ geöffnet wird oder ein bis dahin verschlossenes Tor geöffnet wurde. Dies lässt sich folgendermaßen einrichten:

Als Erstes müsst Ihr Euch die Bedingung ausdenken, wann das Tor geöffnet werden soll. Also der erste Gegner besiegt oder ein bestimmter Held ist auf einen Berg geklettert oder so… Als Zweites müsst Ihr Euch darüber im Klaren sein, ob einfach nur ein Holzzaun „verschwinden“ soll oder ob sich ein Stein- oder Holztor öffnet.

Ich habe beide Möglichkeiten mal in eine kleine Karte eingebaut, damit Ihr Euch das Ergebnis ansehen könnt. Außerdem habe ich in der verlinkten Datei das Script noch einmal als Lua-Datei und als Textdatei reingepackt, damit Ihr es Euch einfach mal mit einem Texteditor anschauen oder ausdrucken könnt, ohne die Karte im Mapeditor öffnen zu müssen.

Doch nun zum Script: Zunächst müsst Ihr im Teil FirstMapAction einen SimpleJob starten, der ständig überprüft, ob Eure Bedingung erfüllt ist.1) (Unnötiges lasse ich mal weg)

function FirstMapAction()
    StartSimpleJob("OpenDoorHolz");  -- Dies ist der Start des Holzzaun Beispiels
    StartSimpleJob("OpenDoorStein"); -- Dies ist der Start des Steintor Beispiels
end

Holzzaun entfernen

function OpenDoorHolz()
    if IsDead("player2") then -- fragt jede Sekunde: ist player2 tot?
        DestroyEntity ("door") -- wenn ja, wird der Holzzaun entfernt
        Message("Das Tor ist offen") -- und eine entsprechende Nachricht ausgegeben
        return true -- die ständige Abfrage wird beendet, da sie nicht mehr benötigt wird
    else -- ODER (player2 ist nicht tot)
        Message("Zugang versperrt") -- es gibt eine negative Nachricht
    end -- Ende der if-Abfrage
end -- Ende der Funktion

Der Funktion DestroyEntity muß ein sogenannter Parameter übergeben werden. Dies kann entweder die ID des Tores sein oder ein von Euch vergebener „Name“. Wie Ihr diesen Namen vergeben könnt bzw. wo Ihr die ID erfahrt, steht im BB Editor-Tutorial Teil 3 auf Seite 4 beschrieben. In diesem o.g. Beispiel wird eine Holzpalisade im Editor mit dem Namen „door“ versehen und der Name hier im Script verwendet.

Steintor öffnen

In diesem Fall nehmen wir nicht DestroyEntity, da wir nicht einfach etwas verschwinden lassen wollen. Wir nehmen hier ein Replace, damit können wir das geschlossene Tor gegen ein geöffnetes austauschen. Natürlich könnte man hier auch erst ein offenes Tor hin setzen, und wenn der Gegner auf eine bestimmte Entfernung heran ist, knallt Ihr ihm die Tür vor der Nase zu…, na lassen wir das

function OpenDoorStein()
    if IsDead("player2") then -- fragt jede Sekunde: ist player2 tot?
        ReplaceEntity ("tor", Entities.XD_WallStraightGate ) -- ersetzt die Entity "tor" mit einer anderen, hier das geschl. Tor durch das geöffnete
        return true -- die ständige Abfrage wird beendet, da sie nicht mehr benötigt wird
    end -- Ende von if
end -- Ende von OpenDoorStein

Diesmal habe ich extra auf die Nachrichten verzichtet, wie Ihr sehen könnt, muss man auch nicht immer ein else haben. Die Problematik if / else werden wir mal extra erklären.

Tor öffenen mit

AreEnemiesInArea

function ControlDoorOne()
    local closed = "DoorOneClosed"  -- Name des geschlossenen Tores, muss auf der Karte gesetzt werden!
    local opened = "DoorOneOpened"  -- (Name des geöffneten Tores)
 
    if IsExisting( closed) and not AreEnemiesInArea( 1, GetPosition( closed), 2000) then
        Sound.PlayGUISound(Sounds.fanfare, 0)
        Message("Männer, öffnet das Tor!")
        local entityId = ReplaceEntity( closed, Entities.XD_WallStraightGate)
        SetEntityName( entityId, opened)
    elseif IsExisting( opened) and AreEnemiesInArea( 1, GetPosition( opened), 2000) then
        Sound.PlayGUISound(Sounds.fanfare, 0)
        Message("Männer, schließt das Tor!")
        local entityId = ReplaceEntity( opened, Entities.XD_WallStraightGate_Closed)
        SetEntityName( entityId, closed)
    end
end


Beispielkarte

Die Beispielkarte mit Script kann hier heruntergeladen werden.

Zur Tutorial-Übersicht

1)
Hier noch ein Hinweis zum dem Vorschlag, SimpleJobs in der FMA zu starten:

dies kann, muss aber nicht immer sinnvoll sein. Zu bedenken ist dabei, dass SimpleJobs jede Sekunde laufen und, dass mehrere gleichzeitig laufende SimpleJobs durchaus die Performance auf älteren Rechnern beeinflussen können. Auch je nach dem, welche Aufgaben in den SimpleJobs abgearbeitet werden.
Zu bedenken ist, ob und wann ein SimpleJob wirkich gestartet werden muss. Dies muss nicht die FMA, sondern kann auch am Ende eines Briefings (Finished-Funktion), in einem Quest oder ähnlichem sein. Zudem können mehrer gleichzeitig laufende SimpleJobs u.U. den Spielablauf verändern. Beim Erstellen des Storyboards ist also darauf zu achten, welche SimpleJobs wann gestartet werden.