Quelle - ArmAWorld
Transcrição
Quelle - ArmAWorld
2 E D I T I N G G U I D E by Mr-Murray © Sascha “Mr-Murray” Hoffmann 2008 3 Vorwort Vorwort Der Inhalt dieser Editieranleitung wird dir das Leben im Armed Assault Editor wesentlich angenehmer gestalten. Du hast hiermit die Möglichkeit auch ohne Programmierkenntnisse schnell und einfach anspruchsvolle Missionen für Armed Assault zu erstellen. Ganz richtig, ohne Programmierkenntnisse! Gewisse Vorkenntnisse aus dem Vorgänger Operation Flashpoint wären natürlich von Vorteil, sind aber nicht zwingend notwendig. In dieser Anleitung werden dir die Teilbereiche des Editors erläutert und anhand von Beispielen näher erklärt. Dazu werden dir die nahezu unbegrenzten Möglichkeiten aufgezeigt, die du in diesem Spiel und dem Editor hast. Du wirst mit ein bisschen Geschick, Ideenreichtum und Kreativität deine eigenen Szenarien umsetzen und dank der Kameramöglichkeiten und dem Einbinden eigener Sounddateien Missionen erstellen, die schon fast mit einem Hollywoodfilm zu vergleichen sind und den Spieler in seinen Bann ziehen werden. Dynamische Missionen erstellen, bei denen bei jedem Start das Wetter oder die Uhrzeit anders ist, dass Erfüllen von Missionszielen bei jedem Spielablauf verschieden abläuft und dass bestimmte Einheiten oder der Spieler bei jedem Neustart an einer anderen Position der Insel startet, sollte hiermit für dich kein Problem mehr sein. Jetzt liegt es nur noch an deinem Ideenreichtum, deiner Kreativität und natürlich dir, gute Missionen erstellen zu können. Ein Drehbuch, Szenario oder eine Story für deine Mission ist hier nicht enthalten, dass musst du dir schon selbst ausdenken. Ansonsten hast du mit dem Editor und dieser Anleitung alles, was du brauchst um deine Ideen umzusetzen. Und wenn mal was nicht klappt, Editor aus, Spiel an und einfach mal entspannt in den Krieg ziehen. Dieses Spiel baut als Operation-Flashpoint-Nachfolger mit eigens entwickelter Programmiersprache auf seinen Vorgänger auf. Es sind zwar hier und da Änderungen erfolgt und viele Neuheiten eingeflossen, aber vom Grundkonzept ist alles nahezu gleich geblieben. Der Editor ist, wie auch bei seinem Vorgänger, mit gleicher übersichtlicher und benutzerfreundlicher Oberfläche zu bewundern. Und auch die Missionsordner und der Inhalt dieser, sind vom Grundsatz her gleich geblieben. Doch lies, probier und editier dich selbst mit Hilfe dieser Anleitung durch die Welt von Armed-Assault. Viel Erfolg und Spaß mit dem Editor wünschen Bohemia Interactive und Mr-Murray. 4 Anmerkung Anmerkungen Diese Anleitung ist als Einführung in den Armed Assault Editor gedacht und soll gerade dem Editieranfänger den Umgang mit dem Editor erleichtern. Hier aufgeführte Skripte oder Abläufe sind frei erfunden und können selbstverständlich weiterentwickelt und verbessert werden. Natürlich gibt es noch weit mehr Möglichkeiten im Editierbereich von Armed Assault als hier im Buch erläutert, wobei ich hier auf die offizielle Wiki http://community.bistudio.com/wiki verweisen möchte, die immer auf dem aktuellen Stand ist, was Editing, Scripting und sonstiges rund um Armed Assault betrifft. Hier wurde lediglich das grundlegendste mit eingebunden und ein paar Blicke über den Tellerrand gegeben, die dich anregen und auf eigene Ideen bringen sollen. Sämtliche Skripte aus Kapitel 6 stehen im offiziellen Forum (www.forum.german-gamers-club.de) für dich zum Download bereit. Danksagung Danksagungen Ich möchte mich mit diesem Editing Guide bei allen Operation Flashpoint und natürlich Armed Assault Fans, die dem Spiel bis heute treu geblieben sind, bedanken. Mein nächster Dank gilt dem großartigen Team von Bohemia Interactive, ohne die es ein Spiel dieses Umfangs und somit diese Anleitung gar nicht geben würde. Ein weiterer Dank richtet sich an das gesamte Mapfact-Team, BadAss, Chneemann, Flashpoint_K, JörgF., Kriegerdaemon, LockheedMartin$ch, MCPXXL, OneManGang, Silola, Sniping-Jack, Raedor, Lester und Wüstenfuchs und unseren helfenden Händen MemphisBelle, Simba, Marco-Polo-IV, Parvus, Sgt.Ace und SNKMan, welche mich in den letzten Jahren tatkräftig unterstützt haben. Wobei hier ein besonderer Dank Raedor, Chneemann und den offiziellen BIS-Betatestern gilt, die mir bei diversen Problemen mit Armed Assault tatkräftig zur Seite standen. Ein weiterer ganz besonderer Dank geht an MemphisBelle, Metal0130 und Matt Rochelle für die hervorragende englische Übersetzung und Andre Scheufeld, Andreas Holzwart, Rastavovich sowie Wolle für den hervorragenden Support. Des Weiteren bedanke ich mich noch bei allen Freunden und Bekannten und besonders bei meiner Familie und meiner Freundin, die mich in der Zeit der Realisierung dieses Werkes tatkräftig unterstützt und motiviert haben. Euer Sascha “Mr-Murray” Hoffmann 5 Community Screenshot Contest Im Rahmen der Neuauflage dieses Buches entschied ich kurzerhand die Community auf irgend eine besondere Art mit ins Buch zu integrieren. Da es leider nicht viele Möglichkeiten dafür gibt, entschied ich mich, nach Rücksprache mit Morphicon dazu, dass dies am besten mit einem Bilderwettbewerb erfolgen könnte. Ich bedanke mich hiermit nochmal bei allen Teilnehmern, die am Wettbewerb teilgenommen haben und auch bei Armed-Assault.de für die Realisierung und Umsetzung des Wettbewerbs auf selbiger Seite. Im gesamten Buchverlauf der vorausgegangenen Buchversion 1.02 sind die Ergebnisse des Wettberwerbs zumeist auf den Kapitelverzeichnissen, aber auch in den Kapiteln, zu bewundern. Die drei nun folgenden Bilder stellen die Plätze 1 bis 3 dar, welche von der Community als beste Bilder gevotet wurden. Die Gewinner sind keine anderen als: Platz 1: Marcus-Ergalla (Aljosha Rall) Platz 2: Mr. Burns (Andreas Schmitz) Platz 3: Stoned Boy (Frank Nobis) Platz 1: Marcus-Ergalla 6 Platz 2: Mr Burns Platz 3: Stoned Boy 7 Inhaltsverzeichnis Kapitel 1: Der Einstieg 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 Die Oberfläche Einheiten einfügen Gruppen einfügen Auslöser einfügen Wegpunkte einfügen Synchronisieren Markierungen einfügen Einheiten und Objekte drehen Einheiten und Marker verbinden Einheiten mit Wegpunkten bearbeiten 16 20 26 27 30 35 36 39 39 40 Kapitel 2: Die Dateien 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 Der Missionsordner Die Mission.sqm Die Description.ext Die Stringtable.csv Die Init.sqs Das Skript (.sqs) Die Funktion (.sqf ) Das Paa-Format Die PBO Die Sounddateien Die Lip-Dateien Der Overview Das Briefing 42 43 48 51 53 54 55 55 56 56 57 58 59 Kapitel 3: Die Waffen – Fahrzeuge – Einheiten – Objekte 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 8 Die Handwaffen und statische Waffen Die Waffenbezeichnungsliste Einheiten bewaffnen und ausrüsten Die Waffen- und Munitionskiste Fahrzeuge be- und entladen Waffenauswahl im Briefing Die Fahrzeugklassen Die Fahrzeugwaffen Die Einheitsklassen Die Shellklassen Die Objekt- und Gebäudeklassen Die Pflanzenklassen 64 68 70 71 71 72 73 76 77 80 81 88 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.20 3.21 3.22 Die Steinklassen Die Schilderklassen Waffen- und Magazintypen ausgeben lassen Abgefeuerten Typ ausgeben lassen Hat Einheit Waffe? Primär- bzw. Sekundärwaffe einer Einheit Hat Einheit Munition? Mine erzeugen Waffen und Magazine erzeugen Waffenblickrichtung ausgeben lassen 90 91 92 92 92 93 93 93 94 95 Kapitel 4: Die Mission 4.1 4.2 4.3 4.4 4.5 4.6 4.7 Der Missionsname Der Missionsstart Das Missionszubehör Die Missionswertung Die Missionsziele Mission beenden Mission speichern 97 97 98 99 99 101 103 Kapitel 5: Das Missionszubehör 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 5.19 5.20 Leeres oder verschlossenes Fahrzeug Fahrer/Beifahrer eines Fahrzeugs Einheit hat Fahrzeugverbot Einheit in Fahrzeug? Fahrzeug fährt erst, wenn Einheit eingestiegen ist Gruppe zu Missionsbeginn im Fahrzeug Ein- und Aussteigen lassen Geschwindigkeit einer Einheit Geschwindigkeit ausgeben lassen Einheit bleibt stehen Einheiten starten bzw. stoppen Einheit bewegt sich zum Bestimmungsort Streife laufen, fahren oder fliegen Fluchtverhalten einer Einheit oder Gruppe Einheiten, Objekte, Auslöser u. Marker versetzen Objekte versenken oder höher setzen Flughöhe einer Einheit Punktgenaue Helikopterlandung Einheit begibt sich in ein Gebäude Einheit verlässt eine Gruppe oder tritt anderer bei 106 106 106 107 107 108 108 108 108 109 109 110 110 110 111 111 112 112 112 113 9 5.21 5.22 5.23 5.24 5.25 5.26 5.27 5.28 5.29 5.30 5.31 5.32 5.33 5.34 5.35 5.36 5.37 5.38 5.39 5.40 5.41 5.42 5.43 5.44 5.45 5.46 5.47 5.48 5.49 5.50 5.51 5.52 5.53 5.54 5.55 5.56 5.57 5.58 5.59 5.60 5.61 5.62 5.63 10 Einheit ein Ziel zuweisen Einheit wendet sich anderer zu Einheit wählt Waffe Einer Einheit Schaden zufügen bzw. heilen Einrichten einer Todeszone Das Prüfen eines Bereiches Einheiten in einem Bereich ansprechen Einheitsstatus speichern oder laden Bekanntheitsgrad einer Einheit Freundlicher Feind Befreundete Parteien Der Alarm Tod als Bedingung Distanz zweier Einheiten oder Objekte Einem Fahnenmast eine Fahne zuweisen Brennende Feuerstelle Spielbare Einheit hinzufügen oder entfernen Spielerseite, -namen, typ auslesen bzw. ausgeben Spielereingabe unterdrücken Karte auf den Monitor erzwingen Sichtweite ändern Wetter einstellen Datum und Uhrzeit einstellen Zeitlupe oder Zeitsprint Einheiten und Objekte erzeugen Flares, Rauch und Explosionen erzeugen Einheiten und Objekte löschen Funkmenü verändern Einer Gruppe ein Rufzeichen zuweisen Funkspruch abgeben Sound erstellen Eigenen Sound einbinden Identität festlegen Mimiken Der Actionbefehl Der Animationsbefehl KI abschalten SetVelocity Der Informationstext Einheit bleibt liegen, kniet oder steht ID´s verwenden Einheiten in Gebäuden platzieren Einheit begibt sich zu Gebäudeposition 113 114 114 114 115 115 115 116 117 117 118 119 120 120 120 121 121 121 121 121 122 122 123 123 124 126 127 127 128 129 129 130 134 135 136 139 144 144 144 144 145 148 153 5.64 5.65 5.66 5.67 5.68 5.69 5.70 5.71 5.72 5.73 5.74 5.75 5.76 5.77 5.78 5.79 5.80 5.81 5.82 5.83 5.84 5.85 5.86 Position auslesen Der Eventhandler Texteinblendarten Stringtable Grundwerte Wegpunkte erzeugen Auslöser erzeugen Marker erzeugen Rund ums Vehikel Lichtquellen erzeugen Staub erzeugen Rauch erzeugen Feuer erzeugen Dienstgrad vergeben Einheit benutzt Fernglas Einheit ein Fahrzeug zuweisen Einheit ein Team zuweisen Einheit gibt Befehle Hat Einheit Schaden erhalten? Der Flugverkehr Grasdetails heruntersetzen Objekte schräg platzieren Mission verschlüsseln bzw. freischalten Leerer Scheinwerfer mit Licht 153 155 157 158 159 160 162 165 167 167 168 169 171 172 172 173 174 174 175 176 176 177 177 Kapitel 6: Die Missions Specials 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13 6.14 6.15 6.16 6.17 6.18 Die Fallschirmspringer Das GPS-System Der Actionmenüeintrag Der Rucksack Zufallspositionen Der Mapclick Die Artillerie Tote Einheiten bzw. Fahrzeuge löschen Spielbeschleunigung dauerhaft unterdrücken Der Bullet Mode Das Feindmeldeskript Der Airstrike Der Airvehiclecreator Der Scheinwerfer Der Zeitzähler Das House-Patrol-Script Das Minen-Skript Das Vehikeltransportskript 179 180 181 181 185 187 189 194 195 196 197 198 201 203 204 205 208 209 11 6.19 6.20 6.21 6.22 6.23 6.24 6.25 Das Möwenskript Das Insektenskript Der Bombenleger Der Aufklärer Einheit ergibt sich Der Teleport Das Verfolgungsskript 213 215 216 217 218 221 222 Kapitel 7: Multiplayer 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 7.12 7.13 7.14 7.15 7.16 7.17 7.18 7.19 7.20 7.21 7.22 7.23 Die Multiplayermission Die Respawnpunkte Flexible Respawnpunkte Die MP-Description.ext Die Respawnarten Das Deathmatch Multiplayerbereich festlegen Zeit und Wertung Punkte vergeben bzw. anzeigen lassen Die Zeitanzeige Der Class Header Der Respawndialog Stringtable MP Grundwerte Fahrzeug-Respawn Mr-Murray´s Fahrzeug-Respawn Flaggen Grundinformationen Capture The Flag Die Publicvariable Allgemeines Die Steuerungsbefehle Bewaffnung im MP Spielerbezogene Textmitteilung Join In Progress (JIP) 224 224 225 226 227 227 228 229 231 232 233 233 234 235 236 238 240 246 247 249 250 251 252 Kapitel 8: Das Camscripting 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 12 Die Steuerung Die Kamerakoordinaten Kamera erstellen Die erste Szene Kamera an ein Fahrzeug/Einheit heften Text- und Einblendeffekte Kamera-Effekte Preload - Objekte und Positionen vorladen 255 256 257 258 260 261 262 262 8.9 Kartenanimation ausführen 263 Kapitel 9: Scripting 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 9.12 9.13 Die Variable Wahrheitswerte Logische Operatoren Die While-Do-Schleife Der Zähler If-Then-Else Der Delay Random WaitUntil Die Klammer Das Semikolon Der Array Funktionen-Grundwissen 265 266 267 268 268 268 269 269 269 270 271 271 274 Kapitel 10: Dialoge 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 10.10 10.11 Was sind eigentlich Dialoge Basisdefinitionen (Konstanten) Basisklassen und Subklassen Die Schriftarten Eine Grafik einblenden Einen Text einblenden Visieransichten einblenden Eigene Landkarte einblenden Einen Button definieren Einen Rahmen definieren Die Videosequenz 279 280 283 286 287 288 289 291 292 294 297 Kapitel 11: Allgemeines 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.10 11.11 Eigenes Profil Die ArmA Cheats Der MOD-Ordner Die Verwendung von Addons Der Missionsrelease Die ArmA.rpt Das Natoalphabet Die Dienstgradabzeichen Die Squad.xml Die Startparameter Tastenkombinationen, Tipps und Tricks 299 301 302 303 304 305 306 307 308 311 313 13 14 Stichwortverzeichnis 314 Syntaxverzeichnis 322 Impressum 332 Kapitel 1 Kapitel 1 - Der Einstieg Dieses Kapitel soll dir zunächst mehr Übersicht und Durchblick über die Oberfläche des Editors verschaffen und dich auf die weiteren Kapitel vorbereiten. Mit Hilfe dieses Kapitels wirst du einen sicheren Umgang mit der Oberfläche des Editors erlangen und erste gute Ergebnisse erzielen. Es erläutert dir zunächst die Hauptfunktionen der einzelnen Bereiche. 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10 Die Oberfläche Einheiten einfügen Gruppen einfügen Auslöser einfügen Wegpunkte einfügen Synchronisieren Markierungen einfügen Einheiten und Objekte drehen Einheiten und Marker verbinden Einheiten mit Wegpunkten bearbeiten 16 20 26 27 30 35 36 39 39 40 15 1.1 - Die Oberfläche Die Oberfläche des Editors ist, wie man sieht, recht überschaubar und sehr benutzerfreundlich aufgebaut. In Zusammenarbeit mit der Maus, den Pfeil- und F-Tasten hat man die Möglichkeit relativ schnell die einzelnen Bereiche und Unterbereiche anzuwählen um damit zu arbeiten. Im Bereich Info definiert man Dinge wie Wetter, Datum, Uhrzeit, Jahreszeit und auf welcher Seite die Widerstandseinheiten kämpfen. Des Weiteren gibt man hier den Namen der Mission und darunter eine kurze Beschreibung der Mission mit an. Hier ist es möglich ein Startwetter festzulegen und anzugeben, wie es sich im späteren Missionsverlauf ändern soll. Der Nebel lässt sich hierbei unabhängig von dem Wetter einstellen. Das Verstellen der Jahreszeiten hat unter anderen auch Änderungen auf den Wasserstand und die Helligkeit zu den verschiedenen Uhrzeiten zur Folge. Wie auch im echten Leben, sind die Tage im Sommer länger als im Winter. Nachrichtendienst Name der Mission Beschreibung der Mission Datum und Uhrzeit Wettervorhersage Gegenwärtiges Wetter Gegenwärtiger Nebel Späteres Wetter Späterer Nebel Seite der Racs(Widerstand) 16 1 ermöglicht es Einheiten, Fahrzeuge und Objekte auf die Karte zu setzen und individuell einzustellen. 2 hat gleich zwei Funktionen. Zum einen kann man damit gleich ganze Gruppen auf die Karte setzen und zum anderen dient 2 als Verbindungstool, mit welchem man Einheiten und Auslöser verbinden kann. 3 Mit 3 setzt man Auslöser, welche man sehr flexibel und für viele Aktionen verwenden kann. Als Beispiel soll hier das Funkmenü dienen, welches unter anderem ja auch in den Auslösern definiert wird. 4 Mit der 4-Taste weist man Einheiten oder auch einer Logik Wegpunkte zu, welche sie dann nacheinander abarbeiten und je nach Definition an gewissen Stellen Aktionen durchführen oder auslösen 5 ist eine Funktion, welche gerne übersehen wird, obwohl sie sehr nützlich ist. Sie ermöglicht es Wegpunkte und Auslöser auf einander abzustimmen. Demnach würde der nächste Wegpunkt erst angelaufen werden, wenn der damit verbundene Wegpunkt oder Auslöser bereits ausgelöst wurde. 6 Die 6-Taste führt ins Untermenü der Marker, mit welchem die Karte sehr taktisch gestaltet werden kann und dem Spieler ein wenig mehr Übersicht über die Mission gibt. 17 Kapitel 1 F-Tasten Mit Hilfe der F-Tasten 1 bis 6 wählt man die Untermenüs an. Dieser Abschnitt soll zunächst eine grobe Erläuterung der F-Tasten darstellen, welche im Laufe des Kapitels noch einzeln und näher erklärt werden. Einsatz Im oberen Abschnitt wählt man zunächst den Arbeitsbereich aus. Hier hat man die Auswahl zwischen Einleitung, Einsatz und Abspann gewonnen und Abspann verloren. Es stehen also vier Karten pro Mission zur Verfügung, welche genutzt werden können. Dies ist sehr vorteilhaft, denn es spart eine Menge Performance, da die Einleitungs- bzw. Abspann-Einheiten und -Objekte nicht auf der eigentlichen Missionskarte sind. Zusätzlich hat man somit auch gleich mehr Übersicht beim Editieren auf der Hauptkarte. Ein weiterer Punkt ist, dass der Spieler beim mehrfachen Spielen der Mission das Intro irgendwann nicht mehr sehen mag und dann die Möglichkeit hat, dieses per Leertaste wegzuklicken. Würde das Intro auf der Hauptkarte erstellt, wäre ihm dies nicht möglich und er müsste die Sequenz jedes Mal bis zum Ende schauen, was auf Dauer etwas demotivierend sein kann. Laden Mit Laden lädt man, wie der Name schon sagt, seine Missionen in den Editor. Natürlich muss diese auch im Ordner C:\EigeneDateien\ArmA\Benutzer\Missions vorhanden sein. Sprich, man muss zunächst seine Mission abgespeichert haben. Denn nach der Installation des Spiels ist dieser Ordner noch leer! Fertige Missionen, welche im ArmA-Hauptmenü zum Spielen ausgewählt werden können, kann man ohne ein PBO-Tool nicht in den Editor laden. Diese müssen dazu erst mit einem solchen Tool entpackt werden. Zusammenführen Zusammenführen steht auch für Importieren. Man kann hiermit eine andere Mission bzw. die Einheiten, Objekte, Auslöser, Wegpunkte, Marker usw. aus einer anderen Mission importieren. Importiert wird hierbei alles, was auf dieser Karte zu finden ist, jedoch nicht der Ordnerinhalt. Das Zusammenführen ist sehr nützlich, wenn man beispielsweise eine sehr komplexe Mission, die eine Weile zum Laden benötigt, editiert. Wenn man nun an einer Position noch ein paar Objekte platzieren und ausrichten möchte, müsste man teilweise ewig warten bis die Mission zur Vorschau startet. Aus diesem Grund ist es sinnvoll eine zweite Map anzulegen, welche man dann als Mission2 abspeichert und dort die Objekte setzt und ausrichtet. Ist man damit fertig, importiert man diese Mission danach einfach auf seine Hauptmissionskarte. Eine weitere gute Möglichkeit ist, wenn man sich Vorlagen anlegt. Also zum Beispiel Karten auf welchen nur bestimmte Dinge vorgefertigt sind. Zum Beispiel ein selbsterstelltes Lager oder ähnliches. Man kann dies dann immer auf seine aktuelle Map importieren ohne es nochmal neu erstellen zu müssen. 18 Zurücksetzen Mit Zurücksetzen säubert man die Karte. Die Karte wird damit wieder in ihren Urzustand versetzt. Dabei wird lediglich alles was auf der Karte ist gelöscht. Der Missionsordner samt Inhalt bleibt aber weiterhin vorhanden. ID´s zeigen Mit dem Button ID´s zeigen lässt man sich die ID´s der Objekte auf der Karte anzeigen. Denn jedes Objekt auf der Karte hat eine ID, mit welcher man es ansprechen kann. Dies macht es möglich dem Objekt Schaden zuzufügen oder zu prüfen, ob es noch am Leben oder, anders gesagt, noch existent ist. Texturen zeigen Hiermit lassen sich die Texturen einer Karte anzeigen. Jede Variante, also mit Texturen anzeigen oder ohne, hat gewisse Vor- und Nachteile beim Editieren. Letztendlich muss jeder für sich entscheiden, wie er lieber editieren möchte. Vorschau Mit Vorschau kommt man in die Missionsvorschau, also direkt in die Mission, die man gerade editiert und kann sich so sein Editierergebnis anschauen und testen. Weiter Hiermit wechselt man die letzte Vorschau zurück. Änderungen, die man bis dahin im Editor vorgenommen hat, sind dann noch nicht sichtbar. Beenden Mit Beenden verlässt man den Editor und kommt zurück zum Hauptmenü. 19 Kapitel 1 Speichern Mit Speichern wird die Mission abgespeichert. Hierbei kann man auswählen, ob die Mission zunächst als Editormission abgespeichert oder schon als fertige Mehrspielerbzw. Einzelspielermission exportiert werden soll. Während Editormissionen im Verzeichnis C:\EigeneDateien\ArmA\Missions hinterlegt werden, findet man seine exportierten Mehrspielermissionen im Spieleverzeichnis unter MP-Missions und seine Einzelspielermission im Verzeichnis Missions wieder. Auf dem Bild sieht man den Ordner Missions unter„Eigene Dateien“. 1.2 - Einheiten einfügen (1) Mit der Taste 1 oder per Mausklick wählt man das Untermenü Einheit an, um eine Einheit, ein Objekt, ein leeres Fahrzeug, eine Logik oder ähnliches einzufügen. Hier ist es möglich sämtliche Einstellungen für jede Einheit individuell vorzunehmen. Seite Osten Westen Widerstand Zivil Leer Logik Auswahl der Seite Osteinheiten Westeinheiten Widerstand Zivilisten Leere Vehikel Logik Klasse Luft Munition Gepanzert Auto Men Minen Objekte Schiffe Sounds Statisch Unterstützung Art der Einheit Helikopter, Flugzeug Waffen- u. Munition Panzer Autos, Krad, Lkw Soldaten Minen Statische Objekte Boote Sounds Geschütze, MG´s Support-Lkw´s Kontrolle - Spieler oder Spielbar Hier wählt man aus, ob man Spieler dieser Einheit sein soll oder ob diese Einheit spielbar bzw. nicht spielbar, also eine KI ist. Spielbare Einheiten werden beispielsweise für Multiplayermissionen benötigt, bei denen ja für die Spieler mehrere Einheiten zur Auswahl stehen müssen. Für Singleplayermissionen ist Playable nötig, wenn man den Characterswitch nutzen möchte. Der Spieler kann dann in der fertigen Mission zwischen den spielbaren Soldaten umherschalten und diese einzeln steuern und in Position bringen. Player Playable Non Playable 20 Spieler Spielbar Nicht Spielbar Player as Driver Player as Pilot Player as Gunner Spieler als Fahrer Spieler als Pilot Spieler als Schütze Fahrzeugstatus - Einstellung des Fahrzeugs Default Locked Unlocked Voreinstellung Abgeschlossen Nicht abgeschlossen Die Syntax für externes Ansteuern über ein Skript oder eine Initzeile sieht wie folgt aus: Name lock true Name lock false Fahrzeug verschlossen Fahrzeug offen Dienstgrad - Dienstgrad der jeweiligen Einheit Hier wird der Rang bzw. Dienstgrad der jeweiligen Einheit eingestellt. Die Einheit mit dem höchsten Dienstgrad ist automatisch der Gruppenführer der Gruppe. Beförderungen im Spielverlauf werden im Kapitel 5.76 ausführlich erläutert. Private Corporal Sergeant Lieutenant Captain Major Colonel Soldat Gefreiter Feldwebel Leutnant Hauptmann Major Oberst Die Syntax für das Vergeben eines Ranges sieht dabei wie folgt aus: Player setRank "Sergeant" Einheit - Art der Einheit Nachdem man bei Klasse festgelegt hat, ob das Objekt ein Soldat oder Fahrzeug ist, kann man hier die Art des Objektes auswählen. Je nach Klassen-Auswahl ist hier die Unterauswahl anders. Bei Infanterie hat man die Auswahl der Soldaten vom Grenadier bis zum Scharfschützen, bei Fahrzeuge die Auswahl zwischen verschiedenen Fahrzeugen und so weiter. 21 Kapitel 1 Bei Fahrzeugen hat man zusätzlich die Auswahl, als was der Spieler im Fahrzeug sitzen soll und kann dies somit sofort festlegen. Speziell - Besonderheit einer Einheit Hier lassen sich gleich verschiedene Einstellungen vornehmen, die beim Editieren gerne übersehen werden. Denn hier ist es nicht nur möglich einzustellen, ob ein Flugzeug oder Helikopter beim Start fliegt, sondern noch weit mehr. Keine Würde man sich eine Einheit mit dem Spezial „Keine“ unterstellen und sie irgendwo weit weg auf die Karte stellen, würde sie sich, wenn sie weiß wo sich der Leader befindet, auf den Weg zu ihm begeben. Anders bei Formation… In Formation Ist beim Spezial der unterstellten Einheit „In Formation“ ausgewählt, wird die Einheit gleich, egal wo sie auf der Karte steht, an ihrer Formationsstelle neben dem Leader stehen. Im Laderaum Setzt man eine Gruppe auf eine Karte, von der eine Einheit ein Fahrzeug ist (muss nicht der Leader sein), und wählt bei allen anderen Einheiten bei Spezial „Im Laderaum“ aus, werden alle Einheiten der Gruppe in dem Fahrzeug sitzen. Fliegen Ein Flugzeug oder ein Heli sind bei Missionsstart gleich in der Luft. Name - Name der Einheit Hier wird der Name der jeweiligen Einheit oder des Objektes angegeben. Dieser ist sehr wichtig, wenn man diese Einheit per Skript oder ähnliches anprechen möchte. Der hier angegebene Wert ist gleichzeitig eine globale Variable. Fähigkeiten - Fähigkeiten einer Einheit Hier definiert man die Fähigkeiten einer Einheit. Diese bestimmt, wie gut diese schießen, reagieren und so weiter. Die Fähigkeiten werden mit einem Wert zwischen 0 und 1 definiert. 0 steht für weniger gut und 1 für sehr gut. In Syntaxform schaut das Ganze wie folgt aus: Name setSkill 0.8 Name setUnitAbility 0.6 Es ist auch möglich einen Zufallsskill einzustellen. Dazu müsste man in der Initialisierungszeile der Einheit folgende Syntax eingeben: this setSkill (Random 0.6) Jetzt würde der Einheit ein Zufallsskill im Bereich von 0 bis 0.6 zugewiesen. 22 Wenn man diese im Nachhinein nochmal drehen möchte, weil sie doch nicht in die richtige Richtung schaut, geht das auch in Kombination mit der Maus und der Shift-Taste. Dazu bleibt man auf der Karte und klickt sich nicht per Doppelklick ins EinheitenUntermenü, sondern wählt die Einheit an, indem man sie nur ein Mal anklickt. Jetzt hält man die Shift-Taste und die linke Maustaste gedrückt und bewegt die Maus. Die Einheit wird sich nun mit Hilfe der Mausbewegungen frei drehen lassen. Zum Drehen von mehreren Einheiten oder Objekten gilt das gleiche Prinzip. Dazu markiert man alle zu drehenden Einheiten und bewegt dann die Maus mit gedrückter linker Maustaste. Eine andere Möglichkeit eine Einheit beispielsweise in einer Sequenz auszurichten wäre: Name setDir Wert Name setFormDir Wert Hierzu kann man den Wert aus dem Einheiten-Untermenü mit der Tastenkombination Strg + C kopieren und für Wert einfügen. Initialisierung - Die Initialisierungszeile Jede Einheit bzw. jedes Objekt hat eine Initialisierungszeile. Befehle, welche dort eingetragen werden, werden beim Missionsstart sofort ausgeführt. Von hier aus kann man unter anderem Skripte starten oder wie oben bei Fähigkeiten eine Zufallsskillsyntax angeben. Generell lohnt es sich eine Init.sqs im Missionsordner zu erstellen, welche die Initalisierungsdatei der Mission darstellt und ohne angeben einer Syntax beim Missionsstart automatisch ausgeführt wird. Eine nähere Erklärung der Init.sqs findet man im Kapitel 2.5 – Die Init.sqs. Befehle werden hier generell mit einem ; getrennt! Sogar während einer laufenden Mission ist es möglich einen Eintrag in der Initialisierungszeile einer Einheit vorzunehmen und ausführen zu lassen. Dazu nutzt man zunächst den setVehicleInit-Befehl und zum Aufrufen dann processInitCommands. Player setVehicleInit "Player say 'Sound1' "; processInitCommands; Beschreibung - Die Infozeile In dieser Zeile gibt man einen Namen oder eine kleine Beschreibung zur jeweiligen Einheit an. Diese Beschreibung wird dann angezeigt, wenn die Einheit als spielbare Einheit definiert wurde und man das Switchmenü öffnet. 23 Kapitel 1 Azimut - Die Blickrichtung einer Einheit Hier legt man beim Einstellen der Einheit eine grobe Blickrichtung fest und kann somit auch gleich den Blickrichtungswert sehen. Die Blickrichtungswerten sind, wie im realen Leben auch, von 0 bis 360 Grad definiert. Bestätigt man nun mit OK, sieht man die Einheit mit der ausgewählten Blickrichtung auf der Karte. Gesundheit/Panzerung - Der Gesundheitsstatus Mit dem Schieberegler lässt sich der Gesundheits- bzw. Panzerungsstatus einer Einheit festlegen. Einheiten können also schon verletzt auf die Karte gestellt werden oder eben Fahrzeuge, wenn sie als Wrack dienen sollen, ohne jegliche Panzerung. Der Wert wird ebenfalls wieder von 0 bis 1 definiert und lässt sich auch extern des EinheitenUntermenüs mit einer Syntax festlegen. Diese schaut wie folgt aus: Name setDamage 1 Nun hätte die Einheit, der Panzer oder das Objekt einen Schadenswert von 1 und ist tot oder zerstört. Diesen Wert kann man natürlich wieder zurücksetzen und mit Name setDamage 0 wäre die Einheit nun wieder geheilt oder repariert. Selbstverständlich können auch Zwischenwerte verwendet werden. Mit 0.5 wäre die Einheit halt nur zur Hälfte geheilt bzw. repariert usw. Support: Supportfahrzeuge wie Treibstoff-, Munitions- und Reparaturfahrzeuge können mit einem Wert von 0 bis 1 versehen werden. Ist dieser 0, kann man diese nicht mehr zum Tanken, Reparieren oder Aufmunitionieren nutzen. Mit der Syntax Name setRepairCargo 1 weist man einem Reparatur-Lkw einen Reparaturwert zu. Treibstoff - Der Tankstatus Hier stellt man die Treibstoffmenge ein, die ein Fahrzeug haben soll. Diese lässt sich ebenfalls extern mit einer Syntax ansteuern, welche wie folgt aussieht: Support: Name setFuel 0 Name setFuel 1 steht für einen leeren Tank steht für einen vollen Tank Name setFuelCargo 0.3 weist Tank-Lkw einen Füllwert zu Munition - Der Munitionsstatus Einstellung der Munitionsmenge, die die Einheit beim Missionsstart haben soll. Support: 24 Name setAmmoCargo 0.7 weist Munitions-Lkw einen Füllwert zu Anwesenheit - Bedingung der Anwesenheit Einheit ist nur anwesend, wenn eine Bedingung erfüllt ist. Diese Bedingung wird hierbei beim Missionsstart abgefragt. Gibt man hier CadetMode ein, wird die Einheit nur im CadetMode auf der Karte sein. Radius der Platzierung - Platzierungsradius der Einheit Hier stellt man den Radius ein, in welchem die Einheit beim Spielstart stehen soll. Diese Einheit wird dann bei jedem Spielstart irgendwo in dem Radius erscheinen. Info-Alter - Bekanntheitsgrad einer Einheit Info-Alter bestimmt den Bekanntheitsgrad einer Einheit. Es sagt also aus, was die Gegnerseite über diese Einheit weiß und wie aktuell diese Information ist. Dabei gibt es folgende Auswhlmöglichkeiten: "ACTUAL" "5 MIN" "10 MIN" "15 MIN" "30 MIN" "60 MIN" "120 MIN" "UNKNOWN" Das Info-Alter lässt sich auch anhand einer Syntax vergeben. Diese lautet dann wie folgt: Player setTargetAge "10 MIN" 25 Kapitel 1 Anwesenheit - Wahrscheinlichkeit der Anwesenheit Hier lässt sich die Wahrscheinlichkeit der Anwesenheit einer Einheit in Prozent einstellen. Stellt man den Regler auf die Mitte, wird die Einheit mit einer Wahrscheinlichkeit von 50% auf der Karte sein. Dies bringt sehr viel Dynamik ins Spiel, da man nie vorhersagen kann, ob die Einheit oder Einheiten wirklich auch auf der Karte sind. 1.3 - Gruppen einfügen (2) Mit der Taste 2 wählt man das Untermenü Gruppen an, welches es einem ermöglicht gleich ganze Gruppen einzufügen. Dies spart eine Menge Zeit, da man nicht jede Einheit einzeln einsetzen muss. Hier gibt es für jede Seite vordefinierte Gruppen, welche man dann einfügen kann. Natürlich ist es auch möglich diese Gruppen nach belieben zu bearbeiten. Eine Gruppe zu vergrößern, zu verkleinern oder alle Einheiten einer Gruppe individuell einzustellen und zu bewaffnen ist sehr leicht zu handeln. Nachdem man sich bei Seite für eine Seite entschieden hat, hat man bei Typ die Wahl zwischen einer Infanterie-, Panzer, oder Helikoptergruppe, welche man so sehr schnell einfügen kann. Bei Name hat man dann die Möglichkeit sich eine von fünf Typen auszusuchen. Hier hat man zum Beispiel bei West und Ost die Auswahl zwischen: Basistrupp Waffentrupp Spezialtrupp Motorisierte Patrouille Panzergrenadiertrupp Gemischte Infanteriegruppe Kleinere Infanteriegruppe Spezialeinheit Infanteriegruppe mit Fahrzeug Infanteriegruppe mit Schützenpanzer Eine ähnliche Auswahl hat man neben den Infanterietruppen natürlich auch unter den Panzerplatoons oder den Luftgeschwadern. Bei den Air Squadrons muss man darauf achten, dass bei den einzelnen Vehikeln das Spezial auf Fliegen steht, wenn diese gleich zu Missionsbeginn fliegen sollen. Mit Azimut stellt man hierbei wieder, wie auch bei anderen Einheiten, die Blickrichtung der Gruppe ein. 26 Den Auslöser kann man als Ein- bzw. Ausschalter oder Prüfutensil benutzen. Er ermöglicht unter anderem auch das Einfügen der Funksprüche von Alpha bis Juliett. Von der Funktionsweise her unterscheiden sich Auslöser und Wegpunkte bis auf ein paar Extras nicht sonderlich. Der Auslöser ermöglicht es im Missionsablauf gewisse Aktionen zu starten oder zu stoppen. Mit Hilfe des Untermenüs Effekte hat man sogar die Möglichkeit Sounds, Musik, Ressourcen einspielen zu lassen oder auch Videoanimationen zu starten. Mit der Aktivierungszeile hat man zusätzlich die Möglichkeit beim Betreten des Auslöserbereiches Skripte oder ähnliches zu starten oder beim Verlassen des Auslöserbereiches bei Deaktivierung wieder zu stoppen. Zudem kann man den Auslöser auch als Lineal benutzen, wenn man z.B. mehrere Objekte gerade aneinander setzen möchte. Dazu würde man z.B. bei Achse A den Wert 100 und bei Achse B den Wert 1 angeben. Jetzt hat man ein prima Lineal oder Abstandsmesser. Achse A/Achse B Wirkungsbereich Winkel Winkel Ellipse/Rechteck Form der Fläche Einmal/Mehrfach Anzahl der Auslösung Aktivierung durch Westen Osten Widerstand Zivilisten Spiellogik Jeder Funk A–J Erobert von Westen Erobert von Osten Erobert von Widestand Art der Aktivierung Vorhanden Auslöser wird aktiviert, wenn bei Aktivierung zum Beispiel West ausgewählt wurde und eine westliche Einheit den Auslöserbereich betritt. Nicht vorhanden Auslöser wird deaktiviert, wenn bei Aktivierung zum Beispiel West ausgewählt wurde und keine westliche Einheit mehr in dem Auslöserbereich ist. Entdeckt durch Entdeckt durch Westen, Osten, Widerstand oder Zivilisten. Wird man im festgelegten Auslöserbereich durch eine im Auslöser festgelegt Seite entdeckt, werden die Aktionen ausgeführt, die im Auslöser definiert sind. 27 Kapitel 1 1.4 - Auslöser einfügen (3) Countdown/Timeout - Zähler Hier wird festgelegt, ob der Auslöser gleich bei Auslösung oder erst nach Ablauf einer festgelegten Zeit ausgelöst werden soll. Durch die Möglichkeit einen Min, Mid und MaxWert einzugeben hat man auch hier wieder eine gewisse Dynamik. Während der MinWert für die mindeste Wartezeit steht, stehen der Mid-Wert für den Mittelwert und der Max-Wert für den Maximalwert der Wartezeit. Durch Angabe aller drei Werte kann man die Auslösung dem Zufall überlassen. Gibt man überall den gleichen Wert ein, so wird der Auslöser nach Ablauf der angegebenen Zeit auslösen. Typ - Auslösertyp Keine Von Westen bewacht Von Osten bewacht Von Widerstand bewacht Schalter Ende 1 bis 6 Verlieren Keine Geschützt durch Westen Geschützt durch Osten Geschützt durch Widerstand Schalten Ende einer Mission Verloren am Ende Text - Der Auslösertext Den Auslösertext kann man im Editor lesen, wenn man mit der Maus über das Auslöserfähnchen fährt. Er soll die Orientierung auf komplexen Karten erleichtern. Man muss so nicht jeden Auslöser wieder öffnen und schauen was darin definiert ist, sondern erkennt ihn so am selbst festgelegten Namen schnell wieder. Des Weiteren wird hier der Text für das Funkmenü definiert. Wenn man also mehrere der Funksprüche verwendet, kann man diese hier entsprechend benennen und man sieht in der späteren Mission besser welcher Funkspruch für welche Aktion vorgesehen ist. Zum Beispiel: Auslöser 1: Aktivierung: Text: Radio Alpha Artillerie anfordern Auslöser 2: Aktivierung: Text: Radio Bravo Unterstützung anfordern Beim Funkgerät auf der Kartenansicht würde jetzt Artillerie anfordern und Unterstützung anfordern stehen, was ein gewisses Maß an Übersicht gewährleistet. Name - Der Auslösername Der Name eines Auslösers ist wichtig, wenn man diesen auf irgendeine Art ansprechen möchte. Wenn man ihn beispielsweise versetzen oder löschen will. Mehr zum Versetzen oder Löschen eines Auslösers gibt es auf Seite 30 zu lesen. 28 Verwendung einer Variablen Gibt man in der Bedingungszeile eine Variable an, wird der Auslöser erst ausgelöst, wenn diese erfüllt, also true ist. Wenn in der Bedingungszeile beispielsweise die Variable Angriff steht, wartet der Auslöser, bis Angriff auf true geschaltet wurde. Irgendwo auf der Karte muss dazu bei Aktivierung eines Auslösers, eines Wegpunktes oder in einem Skript die Variable Angriff also zunächst auf true gesetzt werden, damit dieser aktiviert wird. Das macht man mit folgender Syntax: Angriff=true Der Auslöser wurde nun aktiviert und startet die Aktionen, die darin definiert wurden. Prüfung einer Bedingung Eine andere Variante ist die Prüfung, ob eine Bedingung erfüllt ist. Zugegeben, eine Variable ist ja auch eine Bedingung, die geprüft und erfüllt werden muss. Hierbei ist eine Bedingung im vorstellbaren Sinne gemeint, welche man quasi als vorstellbare Aktion definieren kann. Zum Beispiel, dass Soldat1 nicht mehr lebt oder der Spieler(Player) im Fahrzeug Jeep1 sitzt. Dies würde dann wie folgt aussehen: Bedingung: Spieler sitz in Jeep1: Player in Jeep1 oder Bedingung: Soldat1 lebt nicht mehr: not alive Soldat1 oder vehicle Player == Jeep1 !(alive Soldat1) Bei Aktivierung In dieser Zeile kann man fast alles definieren, was ausgeführt werden soll, wenn der Auslöser ausgelöst wird. Das Starten eines Skriptes, eine Bedingung auf true schalten usw.. Es ist also möglich so ziemlich jede Syntax hier anzugeben, die Armed Assault zu bieten hat. Natürlich gibt es auch Grenzen, aber da kann man ja dann auf ein Skript ausweichen. Auch der Übersicht halber, ist es oftmals besser auf ein Skript auszuweichen, wenn hier zum Beispiel unzählige Befehle oder ähnliches angegeben werden. 29 Kapitel 1 Bedingung - Die Bedingung Das Angeben einer Bedingung ermöglicht es einen Auslöser sozusagen auf „Stand by“ zu setzen oder ihn etwas prüfen zu lassen. Dabei würde der Auslöser erst starten, wenn diese Bedingung erfüllt ist. Die Angabe von Bedingungen kann hierbei ganz verschieden aussehen. Zum Einen kann man hier die Variante Verwendung einer Variablen und zum Anderen das Prüfung einer Bedingung verwenden. Die Bedigungszeile beinhaltet bereits automatisch das IF bzw. ?. Daher wird in dieser Zeile kein ? verwendet! Bei Deaktivierung Natürlich kann man bei einem Auslöser auch eine Aktion starten lassen, wenn dieser deaktiviert wird. Als Beispiel dient hier mal die Variante mit einem Actionmenüeintrag. Wenn der Spieler den Auslöserbereich betritt, soll er einen Actionmenüeintrag namens Eintrag bekommen und wenn er den Bereich wieder verlässt, soll er wieder gelöscht werden. Dazu vergibt man: bei Aktivierung: bei Deaktivierung: ID=Player addAction ["Eintrag","skript.sqs"] Player removeAction ID Auslöser versetzen oder löschen Auslöser lassen sich bei Bedarf verschieben oder auch löschen. Dazu muss der Auslöser mit einem Namen versehen werden, um ihn direkt ansprechen zu können. Dazu werden unter anderem folgende Befehlszeilen verwendet: Auslösername setPos getPos Name Oder in Koordinatenform: Auslösername setPos [x,y,z] 1.5 - Wegpunkte einfügen (4) Mit den Wegpunkten legt man nicht nur die Route fest, auf welcher sich eine Einheit bewegen soll, sondern auch Einstellungen wie Verhalten, Formation, Kampfmodus und Geschwindigkeit. Ein Wegpunkt kann von der Funktionsweise her mit einem Auslöser verglichen werden. Wenn die jeweilige Einheit ihren Wegpunkt erreicht hat, wird eine Aktion ausgeführt bzw. begibt sie sich weiter zu ihrem nächsten Wegpunkt. Hinzu kommen aber noch eine Menge weiterer Definitionsmöglichkeiten, wie zum Beispiel Soundeffekte oder Musik am jeweiligen Wegpunkt abzuspielen oder ähnliches. 30 Move Destroy Get in Seek and destroy Join Join and lead Get out Cycle Load Unload Transport unload Hold Sentry Guard Talk Scripted Support Get in next Released Bewegen Zerstören Einsteigen Suchen und Zerstören Anschließen Anschließen und führen Aussteigen Wiederholen Laden Entladen Transport entladen Halten Aufklären Bewachen Sprechen Geskriptet Unterstützen In Nähestes einsteigen Entlassen Aufklären Besonderheit Weist man einer Einheit/Gruppe einen solchen Wegpunkt zu, wird sie bis zu diesem Punkt laufen und dort auf Feindkontakt warten, bevor sie zum Nächsten weiterläuft. Wegpunktfolge Beim Anklicken dieser Option, kann man sämtliche Wegpunkte einer Einheit mit jeweiliger Aktion auf einem Blick sehen und im Nachhinein sogar die Abfolge ändern, indem man einfach eine andere Zahl auswählt. Beschreibung Dies ist die Beschreibung eines Wegpunktes. Was hier eingetragen wird, wird dann später nur im Cadet-Mode angezeigt werden und erleichtert dem Anfänger das Spielen und die Orientierung in einer großen und komplexen Mission. Beispiel: Zerstören Sie das Ziel 31 Kapitel 1 Typ Auswählen - Die Aktionen Hier lassen sich für jeden Wegpunkt individuelle Einstellungen festlegen, welche eine Einheit beim Erreichen des Wegpunktes ausführen soll. Kampfmodus Hier definiert man den Kampfmodus, den eine Einheit oder Gruppe haben soll. Nie schießen Nicht schießen Nicht schießen, Angriff nach eigenem Ermessen Feuer eröffnen Feuer eröffnen, eigenständ. Angriff Blue Green White Yellow Red Die Syntax, um das Verhalten per Auslöser oder Skript festzulegen, schaut hierbei wie folgt aus: Name setCombatMode "Blue" Verhalten Hier lässt sich das Verhalten einer Einheit oder Gruppe definieren, wobei man folgende Auswahlmöglichkeiten hat: Careless Safe Aware Combat Stealth Achtlos Sicher Wachsam Kampf Tarnung Natürlich lässt sich das Verhalten auch wieder per Auslöser oder Skript definieren. Die Syntax hierfür lautet: Name setBehaviour "Careless" Formation Diverse Situationen auf dem Schlachtfeld erfordern gewisse Formationen, welche in der jeweiligen Situation von Vorteil sind. Diese schauen wie folgt aus, wobei der Leader hier in grün zu sehen ist: 32 Columm - Kolonne Staggered Columm - Gestaffelte Kolonne Wedge - Keil Vee - V-Förmig Line - Reihe Kapitel 1 Echelon Left - Staffel links Echelon Right - Staffel rechts Delta - 3-Reihig Column (Kolonne Kompakt) Natürlich kann man einer Gruppe auch eine Formation per Auslöser oder Skript zuweisen. Das Ganze schaut dann in Sytaxform wie folgt aus: Name setFormation "Line" Geschwindigkeit Hiermit wird die Geschwindigkeit einer Einheit am jeweiligen Wegpunkt definiert. Zum Beispiel ist es möglich, einer Einheit zum Wegpunkt 1 eine langsame und zum Wegpunkt 2 eine schnellere Geschwindigkeit zu geben. Dabei hat man die Auswahl zwischen drei Varianten. Auto / Limited / Normal / Full Hierbei ist es auch wieder möglich das Ganze in einem Auslöser oder Skript zu definieren. Syntax: Name setSpeedMode "Limited" Platzierungsradius Der Radius eines Wegpunktes bringt wieder ein wenig mehr Dynamik ins Spiel. Hierbei wird in dem Bereich der festgelegt wird eine Zufallsposition bestimmt, die bei jedem Missionsstart anders ist. Dies bedeutet dass, wenn man dort zum Beispiel den Wert 100 angibt, ein Wegpunktradius von 100 Metern definiert wird, in dem der Wegpunkt dynamisch gesetzt wird. Timeout - Verzögerung Die Verzögerung bis zur Auslösung in Sekunden. Gibt man bei allen drei Positionen den gleichen Wert an, so ist die Auszeit dem Wert entsprechend lang. Durch das Angeben verschiedener Werte wird der jeweilige Wegpunkt per Zufallszeit aktiviert. Zufallszeit zwischen Min und Max mit Tendenz zum Mittelwert. Min Max Mid Mindestzeit bis zur Aktivierung Maximale Zeit bis zur Aktivierung Mittelwert 33 Das Verwenden der Zufallszeit bringt wieder einen gewissen Grad an Spannung ins Spiel, da man nie genau vorhersagen kann, wann die Einheiten auf der jeweiligen Stelle der Karte ankommen. Kombiniert mit dem Platzierungsradius und der Bedingung der Anwesenheit hat man sogar noch mehr Dynamik. Denn nun weiß man nicht, ob es die Einheit gibt, wohin sie Punktgenau läuft und wann sie kommt. Gerade dynamische Missionen haben einen hohen Spannungs- und Wiederspielgrad. ArmA besitzt anhand solcher Möglichkeiten die besten Vorraussetzungen dafür, seine Missionen so dynamisch wie möglich zu gestalten. Bedingung Das Angeben einer Bedingung ermöglicht es einen Wegpunkt sozusagen auf „Stand by“ zu setzen oder ihn etwas prüfen zu lassen. Dabei würde der Wegpunkt erst aktiviert, wenn diese Bedingung erfüllt ist. Das Verwenden einer Bedingung ist bereits unter Bedingung beim Auslöser erklärt. Bei Aktivierung In dieser Zeile kann man fast alles definieren, was ausgeführt werden soll, wenn der Wegpunkt ausgelöst wird. Das Starten eines Skriptes, eine Bedingung auf true schalten usw. usw. Es ist also möglich so ziemlich jede Syntax hier anzugeben, die Armed Assault zu bieten hat. Natürlich gibt es auch Grenzen, aber da kann man ja dann auf ein Skript ausweichen. Auch der Übersicht wegen, ist es oftmals besser auf ein Skript auszuweichen, wenn hier zum Beispiel, unzählige Befehle angegeben werden oder ähnliches. Skript Diese Zeile ermöglicht die Verwendung von Syntaxes, wie sie sonst nur in Skripten verwendet werden können. Wegpunkt zeigen Wegpunkte lassen sich anzeigen oder verbergen. Hierbei kann man festlegen, ob sie nur im Cadet-Mode, generell oder gar nicht sichtbar sind. Never Show Show in Cadet Mode Always Show Wird nie angezeigt Nur im Cadet Mode Wird immer angezeigt Anschließen und führen Man setzt dazu zunächst zwei Gruppen auf die Karte, die an irgendeiner Position zu einer Gruppe verschmelzen sollen. Jede Gruppe bekommt jetzt einen Wegpunkt irgendwo auf der Karte. Bei dem einen Wegpunkt definiert man nun Anschließen und bei dem anderen Wegpunkt Anschließen und führen. 34 1.6 - Sychronisieren (5) Die Möglichkeit Wegpunkte mit Wegpunkten oder Wegpunkte mit Auslösern zu synchronisieren, wird gerne übersehen. Dank dieser Funktion kann man sich nämlich verschiedene Variablen sparen und man sieht auf einem Blick, wer wann wie starten darf. Auf dem Bild sieht man 2 Gruppen, die aus verschiedenen Richtungen kommen, aber das gleiche Ziel angreifen sollen. Jetzt soll die eine Gruppe am Wegpunkt verweilen, bis die andere Gruppe ihren Wegpunkt erreicht hat. Dazu wählt man mit 5 das Synchronisieren an, klickt mit der linken Maustaste auf den Wegpunkt der Gruppe 1, hält die Maus gedrückt und zieht einen Strich zum Wegpunkt der Gruppe 2. Die Synchronisation wird dann mit einer blauen Linie angezeigt. Sobald die Gruppe 1 nun ihren Wegpunkt erreicht hat, wird sie warten, bis Gruppe 2 ihren Wegpunkt erreicht hat. 35 Kapitel 1 Jetzt müssen die beiden Wegpunkte synchronisiert werden. Dazu ist die Synchronisation (5) notwendig, mit welcher die beiden Wegpunkte nun aufeinander abgestimmt werden. Wenn nun beide Gruppen ihre Wegpunkte erreicht haben und noch am Leben sind, werden sie zu einer Gruppe. Vorausgesetzt die Gruppen sind nicht zu groß. Die maximale Gruppengröße in Armed Assault beträgt inklusive Leader 144 Einheiten. Auf der Karte sieht das Ganze dann etwa so aus: Gleichermaßen läuft dies bei der Auslöser-Wegpunkt-Kombination. Die Gruppe würde erst weiterlaufen, wenn der Auslöser ausgelöst wurde. Man muss also nicht bei dem Wegpunkt einer Gruppe eine Variable (z.B. Grp1go) angeben und dann in der Aktivierungszeile des Auslösers Grp1go=true angeben, damit die Gruppe losläuft, wenn der Auslöser ausgelöst wird. Die 5-Variante ist doch viel einfacher und schneller. Ob der Auslöser dabei durch eine Einheit, ein Objekt oder Funk aktiviert wird ist dabei egal. Bei folgendem Bild werden drei Gruppen und ein Funkauslöser aufeinander abgestimmt. Wenn alle drei Gruppen ihre Position erreicht haben, gibt der Spieler per Funk 0-0-1 den Befehl zum Angriff. Erst dann werden sich die Gruppen zu ihrem nächsten Wegpunkt, also das Ziel, weiter bewegen. 1.7 - Markierungen einfügen (6) Mit den Markern gestaltet man die zu Anfang noch jungfräuliche Karte zur taktischen Karte um. Sie zeigt dem Spieler den Ablauf der Mission, die Ziele oder ähnliche Sachen an. Dies macht den Missionsablauf noch übersichtlicher. Hierbei empfiehlt es sich jedem Marker einen Namen zu geben. Diese Marker lassen sich später mit dem Briefing verlinken. Klickt man dann später auf einen der Briefing-Links, wandert das Fadenkreuz auf der Karte zu dem zugehörigen Marker. 36 Kapitel 1 Name Hier wird der Name des Markers angegeben, welcher später unter anderem für die Verknüpfung mit dem Briefing gebraucht, damit die Ziele durch das Fadenkreuz auf der Karte gezeigt werden können oder welcher es ermöglicht den Marker zu versetzen oder ihm ein anderes Symbol zuzuweisen. Art Die Auswahl der Art des Markers. Dies kann statt einem Symbol auch ein Kreis oder ein Rechteck sein, mit dem man eine größere Fläche markieren kann. Zum Beispiel ein Feindgebiet oder ähnliches. Farbe Farbe des Markers. Die Farben beschränken sich hierbei auf rot, schwarz, grün, blau, gelb und weiß Symbol Hier eine Übersicht der verschiedenen taktischen Zeichen mit Bezeichnung: Pick Up Start Marker Objective Head- Command AirTeam quarter Team Move Defend Attack Join End Unknown Warning Empty Destroy Flag Arrow Dot Empty Infantry MaintenTeam ance Team Depot Camp Light Team Heavy Team Fire Salvage Mission Supply Team Repair Town Vehicle Supply Destroyed Vehicle 37 Mit diesen taktischen Zeichen in Verbindung mit großflächigen Markern (Ellipse/Rectangle) hat man schnell eine übersichtliche Karte geschaffen. Die englischen Bezeichnungen sind zugleich auch die Klassennamen der Marker. Außer bei Objective! Objective hat seitens BIS den Klassennamen Flag bekommen. Objective Flag1 Dot Destroy Start End Warning Join PickUp Unknown Marker - Ziel (Flag) - Fahne - Punkt - Zerstören - Start - Ende - Achtung - Beitreten - Auflesen - Unbekannt - Markierung Arrow Empty Select Vehicle Defend Move Attack Headquarters Depot Camp Town - Pfeil - Leer - Leerer Kreis - Vehikel - Verteidigen - Bewegen - Angreifen - Stab - Depot - Lager - Stadt SalvageVehicle - Bergungs Fhz RepairVehicle - Reparatur Fhz SupplyVehicle - VersorgungsFhz DestroyedVehicle - Zerstörtes Fhz MaintenanceTeam - Reparatur CommandTeam - Führungsstab SupplyTeam - Versorger InfantryTeam - Infanterie LightTeam - Leichte Inf. HeavyTeam - Schwere Inf. AirTeam - Luftabwehr FireMission - Firemission Achse A/Achse B Hier wird die Größe des Markers eingestellt. Winkel Hier hat man die Möglichkeit den Winkel des Markers zu bestimmen. Text Hier wird der Text angegeben, der später auf der Karte lesbar sein soll. Zum Beispiel: Ziel Alpha. Mit folgender Syntax ist es sogar möglich dem Marker den Spielernamen oder Einheitennamen zuzuweisen: "S1M" setMarkerText Name S1 Dabei liest das Spiel den Spielernamen der Einheit mit Namen S1 automatisch aus. Dynamische Positionen Setzt man mehrere Marker auf die Karte und verbindet diese mit F2 (siehe Kapitel 1.9) mit einer Einheit, steht die Einheit bei jedem Start an einer anderen Markerposition. Marker versetzen, ändern oder löschen Marker lassen sich während des Spielverlaufs vom Symbol her ändern, versetzen oder auch löschen. Als Beispiel dient hier mal die Erfüllung eines Missionsziels, bei welchem man den Marker von rot in grün einfärben oder ihn einfach löschen könnte. Dazu muss ein Marker erstmal benannt werden. Dieser heißt jetzt für die folgend aufgeführten Syntaxformbeispiele mal Marker1. Man hat jetzt eine Menge von Möglichkeiten diesen anzusprechen. Dies kann wieder von einem Wegpunkt, Auslöser oder auch Skript erfolgen. Hierbei gibt es unter anderem folgende Syntaxformen: 38 Kapitel 1 Marker wird zur Position [x,y] versetzt: "Marker1" setMarkerPos [x,y] Marker zur Position von Objekt Ziel versetzt: "Marker1" setMarkerPos getPos Ziel Marker1 wird zur Position von Marker2 versetzt: "Marker1" setMarkerPos getMarkerPos "Marker2" Setzt Art und Aussehen von Marker1: "Marker1" setMarkerType "Start" Ändert die Farbe des Markers: "Marker1" setMarkerColor "ColorBlue" Ändert die Markergröße in [Höhe, Breite] "Marker1" setMarkerSize [2,4] Löscht den Marker: deleteMarker "Marker1" 1.8 - Einheiten und Objekte drehen Zum Drehen einer Einheit oder ganzen Gruppen und Objekten, markiert man diese zunächst, drückt dann die Shift-Taste, klickt dann mit der linken Maustaste auf eine der Einheiten oder ein Objekt, hält diese gedrückt und bewegt das Fadenkreuz in die jeweilige Richtung. So ist es auch möglich mehrere Einheiten oder Gruppen gleichzeitig zu drehen. Dazu markiert man diese und macht alles so, wie zuvor beschrieben. 1.9 - Einheiten und Marker verbinden Einzelne Einheiten lassen sich im Editor je nach Bedarf zu Gruppen verbinden oder auch wieder trennen. Dazu wählt man zunächst die Taste 2, klickt mit der linken Maustaste auf die Einheit, hält die Taste gedrückt und zieht den Verbindungsstrich zu der Einheit mit der diese verbunden werden soll oder einfach ins Leere, wenn man diese eine Einheit von einer Gruppe trennen möchte. Auf diese Weise kann man auch eine Einheit oder ein Objekt mit einem Auslöser verbinden, wenn dieser beispielsweise nur von dieser einen Einheit bzw. diesem einen Objekt ausgelöst werden soll. Auf dem linken Bild sieht man, wie eine Einheit gerade mit einer Gruppe verbunden wird und auf dem Rechten, wie ein Auslöser objektbezogen angelegt wurde. 39 Das Gleiche geht nun auch mit Einheiten und Markern. Das Besondere hieran ist, das man der Einheit oder dem Objekt damit mehrere Zugfallspositionen zuweisen kann. Verbindet man die Einheit beispielsweise mit 3 Markern, kann diese Einheit beim Spielstart entweder an der ursprünglich gesetzten Position oder an einer der 3 Zufallspositionen stehen. Dies spart ein Skript und bietet gleichzeitig Dynamik. 1.10 - Einheiten mit Wegpunkten bearbeiten Wenn man eine Einheit bereits mit einem Wegpunkt versehen hat und möchte diese im Nachhinein bearbeiten, wird man schnell feststellen, dass sich stets das Wegpunktmenü öffnet, aber nicht das Einheitsmenü. Dazu fährt man einfach mit dem Fadenkreuz auf die Einheit, drückt die Shift-Taste und hält diese gedrückt. Jetzt sieht man, dass sich die Bezeichnung ändert. Klickt man nun doppelt auf die Einheit, wird sich das Einheitsmenü öffnen. 40 Kapitel 2 - Die Dateien - 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 2.9 2.10 2.11 2.12 2.13 Der Missionsordner Die Mission.sqm Die Description.ext Die Stringtable.csv Die Init.sqs Das Skript (.sqs) Die Funktion (.sqf ) Das Paa-Format Die PBO Die Sounddateien Die Lip-Dateien Das Overview Das Briefing 42 43 48 51 53 54 54 55 56 56 57 58 59 41 Kapitel 2 Nachdem du im Kapitel 1 in die Oberfläche eingeführt wurdest, wird dich dieses Kapitel eine Ebene tiefer, nämlich zum Standgerüst einer Mission führen. Hier werden dir die einzelnen Dateien erklärt, die für eine Mission wichtig sind. In ihnen werden unter anderem wichtige Informationen gespeichert und konfiguriert. 2.1 - Der Missionsordner In einem Missionsordner werden alle Dateien abgelegt, die für eine Mission benötigt werden. Es bietet sich hierfür an viele Ordner anzulegen, um dadurch eine bessere Übersicht zu gewährleisten. Um dies zu erreichen, sollte man für jeden der Dateitypen, also Musik, Sounds, Skripte, Szenen, Bilder usw., einen extra Ordner anlegen. Wichtig ist auch, dass man alle Dateinamen klein schreibt. Ein fertiger Missionsordner schaut dann etwa so aus: Die hier zu lesenden Dateinamen sind vorgegeben und nicht variabel! Lediglich das Bild Title.paa und die Ordner könnten anders benannt werden. Hier mal die näher erläuterten Dateibedeutungen: Mission.sqm Description.ext Stringtable.csv Briefing.html Overview.html Titel.paa Missionskoordinaten Missionskonfiguration (Musik, Sound, Waffen, Identitäten, Ressourcen usw.) Textausgabe für mehrsprachige Missionen Briefing beim Missionsstart Missionsinfo in Missionsauswahlmenü Overview Bild Die verschiedenen Briefingdateien stellen das Briefing in verschiedenen Sprachen dar. Wenn man seine Mission natürlich nur mit einer Sprache ausstatten will, genügt die Briefing.html, der Rest der HTML-Dateien kann dann gelöscht werden. Bei nur einer Sprache ist es egal, ob man in der Briefing.html deutsch, englisch oder sonstiges verwendet. Mehr aber im Kapitel 2.13 im Unterbereich „Das Briefing“. Music Sound Scripts Scenes Function Pictures Für Musikdateien Für Soundateien (z.B. Sprache oder Effekte) Für die Skripte (.sqs) Für die Zwischensequenzen (z.B. Intro, Outro usw.) Für die Funktionen (.sqf ) Für die Bilder (z.B. Titel.paa) Möchte man eine Datei aus einem Unterordner aufrufen, gibt man in der Syntax den jeweiligen Ordner, dann Backslash und die jeweilige Datei an. Zum Beispiel das Aufrufen eines Skriptes: [] exec “scripts\script.sqs“ 42 2.2 - Die Mission.sqm Die Erläuterungen in diesem Unterkapitel könnten ein wenig schwieriger sein, aber sollen keinesfalls vom Editieren abschrecken. Man muss diese Datei nicht unbedingt auswendig beherrschen, aber ein paar Kenntnisse erleichtern das Editieren in einigen Bereichen ungemein. Der Anfangsbereich Auf der Folgeseite sieht man den Anfangsbereich einer Mission.sqm im Bereich Class Mission. Zunächst werden die verwendeten Addons gelistet. Hier sind nur original ArmAAddons zu sehen. Achtung! Lädt man ein externes Addon, das eine schlecht gemachte Config.ccp hat, beim Missionsstart mit, kann es vorkommen, dass sich dieses Addon einfach mit in die Liste einträgt, obwohl es in der Mission nicht verwendet wird. Man kann es dann einfach markieren und herauslöschen. Das Problem kommt dann, wenn ein anderer Spieler diese Mission spielen möchte und das Addon nicht hat. Die Mission kann dann nicht geladen werden und der Download war umsonst. Dieses Problem gab es gerade in Operation Flashpoint sehr oft. Spieler, die keine Ahnung vom Editing haben, werden so eine Mission schnell beiseite legen und sich eine andere runterladen. Nach den Addons folgend kommt man zur Class Intel, in welcher unter anderem Briefingname Widerstandseinstellung Startwetter Späteres Wetter Späterer Nebel Sichtweite Datum Uhrzeit definiert sind. addOns[]= { "cacharacters", "sara", }; addOnsAuto[]= { "cacharacters", "sara" }; randomSeed=8635907; class Intel { briefingName="@STR_M11_Name"; resistanceWest=0.000000; startWeather=0.000000; forecastWeather=0.000000; forecastFog=0.375187; viewDistance=1000.000000; month=6; day=2; hour=3; minute=50; }; 43 Kapitel 2 Die Mission.sqm ist die wichtigste von allen Dateien, denn darin sind alle wichtigen Informationen und Koordinaten einer Mission gespeichert. Darunter sind unter anderem Informationen der im Editor gesetzten Einheiten, Objekte, Marker, Wegpunkte, Auslöser usw. enthalten. Des Weiteren findet man am Anfangsbereich noch diverse andere Informationen, wie verwendete Addons oder unter Info den Missionsnamen, Wetter und Uhrzeit. Neben der Class Mission gibt es noch die Class Intro, Class OutroWin und OutroLoose, die vom Aufbau her genauso sind, wie die Class Mission. Hier sind jedoch die Einheiten, Wegpunkte usw. für die jeweilige Sequenz definiert. Es ist möglich Änderungen direkt in der Mission.sqm vorzunehmen. Dabei ist es wichtig, dass man die Änderungen richtig vornimmt. Wenn man das Ergebnis danach im Editor sehen will, muss man die Mission dort erst neu laden. Sollte das Spiel beim Laden komplett abstürzen, ist wohl ein Fehler unterlaufen. Deshalb bietet es sich an vorher immer eine Kopie der Mission.sqm zu machen, um später eine funktionierende Datei zu haben. Einheits- und Objektklassen Nach dem Anfangsbereich kommt man in der Class Mission in den Unterbereich Class Groups und damit in den Unterbereich Class Vehicles in welcher die Einheiten, Objekte und die dazugehörigen Wegpunkte definiert sind. class Groups { items=22; class Item0 { side="WEST"; class Vehicles { items=1; class Item0 { position[]={7973.895020,4.460081,9351.659180}; id=0; side="WEST"; vehicle="SoldierWB"; player="PLAYER COMMANDER"; leader=1; rank="CORPORAL"; skill=0.200000; text="aP"; init="this addWeapon ""binocular""; }; }; }; Wie man sieht, sind hier sämtliche Informationen für diese Einheit namens S1 definiert. Hier die Erläuterung der Begriffe: Items=1 Class Item0 Side Class vehicles Items=1 44 Zeigt die Anzahl der Items der Class Groups an. Also die Anzahl der Gesamtgruppen aller Seiten auf einer Karte Ist die Gruppe 0. Die nächste Gruppe hieße Class Item1 Die Seite der jeweiligen Gruppe. Auch eine einzelne Einheit wird als Gruppe definiert und angegeben! Sagt aus, dass es sich um ein Vehikel handelt Die Anzahl der Items(Einheiten) der Gruppe Class Item0 an Class Item0 Wegpunkt-Klassen Unter der jeweiligen Gruppe sind die zu der Gruppe gehörigen Wegpunkte angeordnet. Diese sind von der Anordnung her den Einheiten gleich, aber eben von der Zusammenstellung etwas anders. class Waypoints { items=1; class Item0 { position[]={7970.289551,4.731988,9346.483398}; placement=50.000000; CombatMode="RED"; Speed="FULL"; combat="COMBAT"; description="Hold this position!"; expActiv="[] exec""scripts\script.sqs"; class Effects { timeoutMin=10.000000; timeoutMid=3.000000; timeoutMax=30.000000: }; showWP="NEVER"; }; }; Wie man sieht, sind hier sämtliche Informationen für diesen Wegpunkt der Gruppe definiert. Der nächste Wegpunkt schaut, je nach Einstellung wieder ganz anders aus. Hier die dazugehörigen Erläuterungen: Items=1 Zeigt die Anzahl der Items der Class Waypoints an. Also die Anzahl der gesamten Wegpunkte der Gruppe. 45 Kapitel 2 Presence Position Azimut ID Side Vehicle Player Leader Skill Health Ammo Text Init Class Item0 ist Leader der Gruppe Class Item0. Der dem Leader unterstellte Soldat ist Class Item1, der nächste Class Item2 usw. Wahrscheinlichkeit der Anwesenheit (Nicht bei Spieler!) YXZ-Koordinaten des Spielers in der Anordnung X Z Y Blickrichtung der Einheit (Wert definierbar von 0 bis 360) ID der Einheit Spielerseite Art der Einheit Spieler Gibt an, ob die Einheit ein Leader ist. Fähigkeit der Einheit (Wert definierbar von 0 bis 1) Gesundheitsstatus (Wert definierbar von 0 bis 1) Munitionsstatus (Wert definierbar von 0 bis 1) Name der Einheit (Variable) Die Initzeile der Einheit (Angabe einer Syntax etc.) Class Item0 Position Placement CombatMode Formation Speed Combat Description ExpActiv TimeOutMin TimeOutMid TimeOutMax ShowWP Class Item0 ist der erste Wegpunkt. Der zweite würde dann Class Item1, der übernächste Class Item2 usw. heißen. YXZ-Koordinaten des Wegpunktes, in der Anordnung XZY. Ist der zufallsbedingte Platzierungsradius des Wegpunktes. Der jeweilige Kampfmodus der Gruppe ab diesem Wegpunkt. Die jeweilige Formation der Gruppe ab diesem Wegpunkt. Die Geschwindigkeit der Gruppe ab diesem Wegpunkt. Das jeweilige Verhalten der Gruppe ab diesem Wegpunkt. Die Beschreibung des Wegpunktes, welche man, wenn der Wegpunkt im Spiel angezeigt wird, lesen kann. Die Aktivierungszeile des Wegpunktes, die bei Auslösung des Wegpunktes ausgelöst wird. Hier wird ein Skript mit Namen Script.sqs aus dem Ordner Scripts aktiviert. Die kürzeste Auslösezeit des Wegpunktes in Sekunden Der Mittelwert der Auslösezeit des Wegpunktes in Sekunden Die maximalste Auslösezeit des Wegpunktes in Sekunden Gibt an, ob der der Wegpunkt im Spiel angezeigt wird oder nicht. Bei diesem Wegpunkt wurden keine Effekte definiert. Diese sind dann bei den Auslöserklassen mit erklärt. Marker-Klassen Nach den Gruppen und den dazugehörigen Wegpunkten folgt die Klasse der Marker. Ab hier werden sämtliche Marker aufgelistet, die in der Mission gesetzt werden. Das Ganze sieht etwa so aus: class Markers { items=28; class Item0 { position[]={2452.061035,0.760200,3673.595703}; name="TargetOne"; text="Objective Alpha"; type="Flag"; a=2.000000 b=2.000000 angle=0.100000 }; }; Hier die Beschreibung der einzelnen Punkte: Items=1 Class Item0 Position 46 Zeigt die Anzahl der Items der Class Markers an. Also die Anzahl der gesamten Marker in der Mission Class Item0 ist der erste Marker. Der zweite würde dann Class Item1, der übernächste Class Item2 usw. heißen. YXZ-Koordinaten des Markers, in der Anordnung XZY. Der Name des Markers. Die Beschreibung des Markers, die man später auf der Karte liest Die Art des Markers. Hier ein Fadenkreuz. Die Größe des Markers in X-Richtung Die Größe des Markers in Y-Richtung Der Winkel des Markers. Auslöser-Klassen Diese sind von der Sache her ähnlich wie ein Wegpunkt zu betrachten und auch die Anordnung ist, wie man sehen kann, fast gleich. Hier sind auch mal Effekte mit aktiviert worden, um diese mal in der Mission.sqm sehen zu können. class Sensors { items=53; class Item0 { position[]={8012.703613,6.300000,9301.049805}; a=100.000000; b=100.000000; activationBy="WEST"; timeoutMin=10.000000; timeoutMid=3.000000; timeoutMax=30.000000: age="UNKNOWN"; name="DetectorOne"; expCond="Var1"; expActiv="[] exec ""scripts\script.sqs"""; expDesactiv="[] exec ""scripts\animation-end.sqs"""; }; }; Items=1 Class Item0 a b ActivationBy TimeOutMin TimeOutMid TimeOutMax Age Name ExpCond ExpActiv ExpDesactiv Zeigt die Anzahl der Items der Class Sensors an. Also die Anzahl der gesamten Auslöser auf der Karte. Class Item0 ist der erste Auslöser. Der zweite würde dann Class Item1, der übernächste Class Item2 heißen usw. Die Größe des Auslösers in X-Richtung Die Größe des Auslösers in Y-Richtung Aktivierung durch „WEST“ Die mindest Auslösezeit des Auslösers Der Mittelwert der Auslösezeit des Auslösers Die maximalste Auslösezeit des Auslösers Unknown Der Name des Auslösers Die Bedingung der Auslösung. Hier die Variable Var1. Die Aktivierungszeile des Auslösers, die bei der Auslösung des Auslösers ausgelöst wird. Hier wird ein Skript mit Namen Skript.sqs aus dem Ordner Scripts aktiviert. Die Deaktivierungszeile des Auslösers. Hier kann man den Auslöser wieder deaktivieren. 47 Kapitel 2 Name Text Type a b Angle 2.3 - Die Description.ext Die Description.ext ist für unsere Mission genauso wichtig wie die Mission.sqm. In ihr werden zwar nicht die Einheiten gesetzt, aber eine Menge wichtiger Dinge definiert. Diese ist zuständig für das Vordefinieren von Musik, Sounds, Respawn, Ressourcen, das Auswählen von Waffen im Briefing, den Accessoires (Kompass usw.) und diversen anderen Dingen, die man zum Spielen benötigt. Die Description.ext wird in dem Missionsordner der jeweiligen Mission angelegt. Dazu erstellt man eine neue Textdatei und benennt diese in Description.ext um. Ganz wichtig hierbei ist, dass man diese mit einem Texteditor (z.B. Notepad) bearbeitet und nicht mit Word oder Excel! Hier wird die Description.ext aus Übersichtsgründen nur grob erklärt. Zu den Einzelheiten siehe in den jeweiligen Kapiteln nach, darin sind die Unterbereiche sehr ausführlich erläutert. Missionsstarttext Missionswertung Identitäten Musik Sound Respawn Waffenauswahl im Briefing Kapitel 4.2 Kapitel 4.4 Kapitel 5.53 Kapitel 5.52 Kapitel 5.52 Kapitel 7.2 Kapitel 3.6 Es ist, je nach Mission, nicht notwendig alle Bereiche in die Datei einzubauen. Man nimmt nur das, was für die Mission benötigt wird. Damit spart man sich zum Einen eine Menge Arbeit und zum Anderen auch gleich mögliche Fehlerquellen, die dabei auftauchen können. Für eine Einzelspielermission ist es schließlich völlig überflüssig, wenn man den Respawn mit angibt. Es ist auf jeden Fall darauf zu achten, dass alle Klammern { die geöffnet werden, auch wieder geschlossen }; werden. Andernfalls stürzt ArmA sofort ab! Auch andere Fehler machen sich teilweise durch einen Absturz bemerkbar! Deshalb ist hier ein gewissenhaftes Arbeiten angesagt. Möchte man Missionszubehör, wie den Kompass oder die Uhr in der Mission verbergen oder verfügbar machen, macht man das mit 1 oder true für aktiv/sichtbar oder mit 0 oder false für inaktiv/unsichtbar. Hinter die beiden // oder einem Semikolon ; hat man die Möglichkeit etwas zu schreiben, was ArmA ignoriert. Dies lediglich dient der Übersicht in Form einer Überschrift, die man bei einer großen Description schnell verlieren kann. Hat man nun Änderungen in der Datei vorgenommen und wieder in den Editor gewechselt, muss man die Mission erst nochmal speichern oder neu laden, damit die 48 Hier sieht man, wie eine Description.ext in etwa aussehen kann. // ====================== Description.ext =====================> Debriefing = 1; OnloadIntro = 1; OnLoadIntroTime = 1; OnLoadMissionTime = 1; Saving = 0; // === Titlecut ==============================================> OnloadIntro= M r - M u r r a y p r o u d l y p r e s e n t s onLoadMission= A R M E D A S S A U L T // === Punktvergabe ==========================================> minScore=200 avgScore=2500 maxScore=6000 // === Missionszubehör =======================================> ShowCompass = 1; ShowMap = 1; ShowGPS = 1; ShowWatch = 1; // === Respawn ===============================================> respawn=3; respawndelay=10; // === Waffen ================================================> class Weapons { class M4 { count = 4; }; class Javelin { count = 2; }; }; // === Magazine ===============================================> class Magazines { class 20Rnd_556x45_Stanag { count = 10; }; class Javelin { count = 6; }; }; // === Musik ================================================> class CfgMusic {tracks[]= { Track1,Track2}; class Track1 { name = "Track1"; sound[] = {\music\track1.ogg, db+0, 1.0}; }; 49 Kapitel 2 Änderungen wirksam werden. Sollte das Spiel dabei abstürzen, nicht gleich die Geduld verlieren und einfach kurz nach dem Fehler suchen. Deshalb ist es sinnvoll einen Abschnitt nach dem anderen zu definieren. Somit weiß man sofort, dass der Abschnitt betroffen ist, den man gerade bearbeitet hat. class Track2 { name = "Track2"; sound[] = {\music\track2.ogg, db+0, 1.0}; }; }; // === Sounds ===============================================> class CfgSounds { sounds[]= {Sound1}; class Sound1 { name = "Sound1"; sound[] = {\sounds\sound1.ogg, db+0, 1.0}; }; }; // === Radio ================================================> class CfgRadio { sounds[] = { }; }; // === Umgebung =============================================> class CfgSFX { sounds[] = {}; }; class CfgEnvSounds { sounds[] = {}; }; // === Identitäten ==========================================> class CfgIdentities { class MrMurray { name = "MrMurray"; face = "Face33"; glasses = "none"; speaker = "Dan"; pitch = 1.00; }; class Memphisbelle { name = "Memphisbelle"; face = "Face10"; glasses = "none"; speaker = "Howard"; pitch = 1.00; }; class Dan { name = "Dan"; face = "Face22"; glasses = "none"; speaker = "Russell"; pitch = 1.00; }; }; // End Of File 50 2.4 - Die Stringtable.csv Wenn man diese Datei nun bearbeiten will, muss man auf diverse Kleinigkeiten achten. Zunächst definiert man den Kopf mit den jeweiligen Sprachen. Dabei achte man darauf, dass diese mit Kommas getrennt werden. LANGUAGE,English,German,Czech,Notes Auch in der jeweiligen Zeile werden die Sprachen nun durch ein Komma getrennt und in " " gesetzt. In der Praxis sieht das dann in der jeweiligen Zeile so aus: STR_Titel,"Night Patrol","Nacht Patrouille","...",Missionsname Hier sieht man nun ganz gut, wie das ausschaut. Am Anfang die Adresse, mit STR_Titel, dann folgend die Sprachen und zum Schluss noch eine Beschreibung, die zur Orientierung beiträgt. STR_ wird dabei generell zuerst angegeben. Das Wort Titel dahinter ist Variable und kann daher frei definiert werden. Eine Textzeile für einen Text in einer Mission könnte dann so aussehen: STR_Mission_1,"Hold Position!","Position halten!","…",Missionstext1 Möchte man den Text zum Beispiel beim Laden der Mission aufrufen, gibt man folgende Syntax an: onLoadMission=$STR_Titel; STR_Titel kann also als individuelle Adresse gesehen werden, welche man angibt, wenn man den Text in die Mission einbinden möchte. Dieser würde dann in der jeweilig ausgewählten und vordefinierten Sprache ausgegeben. Das @ vor STR_ verwendet man im Editorbereich, also in einem Auslöser oder Wegpunkt, während man in einer Config oder der Description.ext das $ Zeichen verwendet. Aus dem Editor Text aufrufen: Aus der Description bzw. einer Config: @STR_Titel $STR_Titel Bei dem folgenden Bild, wurde ein Wegpunkt mit Text versehen, welcher direkt aus der Stringtable bezogen wird, welche dafür wie folgt definiert wurde: STR_Mission_1,"Hold Position!","Position halten!","…",Missionstext1 51 Kapitel 2 Die Stringtable.csv dient zum Hinterlegen von Textvariablen. Sie ermöglicht es, verschiedene Sprachen in eine Mission einzubinden oder einfach nur Text zu hinterlegen. Diese Datei sollte dabei generell mit dem Texteditor bearbeitet werden! Windows schlägt aber standardmäßig Excel als Bearbeitungsprogramm vor. Bei dem Wegpunkt wurde dabei folgendes in die Description-Zeile geschrieben: @STR_ Mission_1 Wie man hier sehen kann, wird der Text dann direkt so in die Mission übergeben. Natürlich ist es hierbei auch möglich in einem Satz oder Text einen Zeilenumbruch anzugeben, was gleich etwas besser aussieht. Dazu verwendet man lediglich ein \n STR_Mission_1,"Hold Position\nand wait for orders!","","…",Missionstext1 Hier wurde eine Texteinblendung verwendet, was in der Mission dann so aussieht: Hier nochmal ein kurzes Dateibeispiel einer Stringtable aus einer originalen Armed Assault Mission, wobei man hier sehr gut erkennen kann, dass darin nur eine Sprache definiert wurde. LANGUAGE,English,Notes STR_M11_Name,"Night Patrol",Mission Name STR_M11_OnLoad,"You're on duty tonight",Onload STR_M12_OnLoad,"Don´tsleep and keep your eyes open!",Onload COMMENT, -------------- Main Mission ------------STRCAMP_OBJSTART,Guard the military installation, STRM_07an01,"Southern sector, Sahrani",prebriefing STRM_07an02,"NATO base in La Riviere, Sahrani",prebriefing STRM_07an03,"Near Paraiso - One hour later, Sahrani",prebriefing Im Kapitel 5.67 findet sich eine Auswahl von Stringtable Grundwerten, welche direkt in ArmA hinterlegt sind. Ebenso auch im Kapitel 7.13 in welchem aber nur MP-Werte aufgelistet sind. Diese kann man ganz einfach für seine Mission verwenden, ohne eigene Stringtablewerte erstellen zu müssen. 52 2.5 - Die Init.sqs Wie man sieht, sind im folgenden Beispiel nun ein GPS-System, die Spielbeschleunigung und die Verdeckung der Missionsziele 1-3 vordefiniert. Zudem wird hier noch zum Editieren die Teleport.sqs gestartet, die uns das Editieren und Testen erleichtern soll. Diese sollte logischerweise dann später deaktiviert oder entfernt werden. ;Einblendung titleCut [" ", "BLACK IN"]; titleFadeOut 4 ;Funktion vorladen SearchLight = compile preprocessFile "Searchlight.sqf"; ;Identität zuweisen Player setIdentity "Mr-Murray"; ;Missionsziele werden verdeckt "MZiel1" ObjStatus "Hidden"; "MZiel2" ObjStatus "Hidden"; "MZiel3" ObjStatus "Hidden"; ;GPS-System [] exec "marker.sqs"; ;Spielbeschleunigung unterdrücken [] exec "time.sqs"; ;Editierskript. Wichtig! Nur für die Editierzeit, später entfernen bzw. deaktivieren!!! ;Teleport [] exec "teleport.sqs"; ;Ende Natürlich kann man hier noch weit mehr vordefinieren, als oben angegeben. Zum Beispiel das Verhalten von Einheiten, die Bewaffnung, Variablen, Einheitsstatus löschen, Funktionen laden und so weiter. Diese Datei sollte nur mal als Beispiel dienen. Alle hier angegebenen Skript oder ähnliches müssen natürlich extra geschrieben werden bzw. die Missionsziele auch so vordefiniert und benannt werden. Wie man außerdem sieht, ist hier alles sehr übersichtlich gehalten. Dabei wird alles, was hinter einem Semikolon steht, von ArmA ignoriert und dient hier als Beschreibung um die Übersicht zu behalten. 53 Kapitel 2 Die Init.sqs kann sozusagen als Initialisierungsdatei angesehen werden, welche beim Missionsstart automatisch abgerufen wird und nicht gesondert gestartet werden muss. Diese Datei bringt eine Menge Übersicht mit sich, da man nun nicht alle Befehle in die Initzeile einer Einheit oder des Spielers schreiben muss, welche dann, je nach Menge, sehr unübersichtlicht werden würde. Denn gerade beim Spieler sammeln sich oftmals eine Menge Befehle an. Aber was schreibt man denn nun alles dieses Skript? Eigentlich alles, was beim Missionsstart sofort ausgeführt, also initialisiert werden soll. 2.6 - Das Skript Ein Skript ist lediglich eine Datei im Missionsordner, welches für bestimmte Zwecke geschrieben ist. Dieser Abschnitt erklärt nicht das Skripten selbst, sondern beschreibt lediglich die Datei und wie man diese aufruft. Mehr zum Thema Scripting findet sich im Kapitel 9. Die Skripte in Armed Assault enden, wie auch schon bei Operation Flashpoint, mit der Endung .sqs. Zum Erstellen eines Skriptes erstellt man zunächst eine Textdatei, die man dann einfach umbenennt. Windows wird die Datei dann als unbekanntes Format deklarieren. Dem entgegnet man dann mit der Windowsmöglichkeit Rechtsklick und anschließend „Öffnen mit“ und wählt dort als Standardprogramm den Texteditor aus. Im Laufe der nächsten Kapitel wird man noch mit dem einen oder anderen Skript vertraut gemacht und wird verstehen um was es dabei geht. In einem Skript kann man sich dann relativ frei austoben, obwohl es natürlich auch hier Grenzen gibt. Die Init.sqs als solches ist ja schon ein Skript, welches ohne Verwendung einer Syntax automatisch beim Missionsstart von ArmA aufgerufen wird. Auch die Mission.sqm oder die Description.ext sind ja sozusagen auch irgendwo Skripte, nur halt mit einer anderen Endung und Funktion. Möchte man nun ein Skript per Auslöser, Wegpunkt oder aus einem anderen Skript aufrufen, benötigt man diese Syntax: [] exec "scripte\meinskript.sqs" oder this exec "scripte\meinskript.sqs" Nachdem das Skript aufgerufen wurde, wird es seine Befehle abarbeiten und dann je nach Funktion und Ablauf dann am Skriptende, wo exit stehen sollte, beendet. 2.7 - Die Funktion Die Funktion kann man von der Sache her mit einem Skript vergleichen. In beiden sind Befehle hinterlegt, aber es gibt doch kleine aber feine Unterschiede. Genauso wie ein Porsche und ein Käfer. Beides sind zunächst Autos, aber wenn man ins Detail geht, so wird man schnell feststellen, dass der Porsche dem Fortschritt nach weiter ist. Der Unterschied besteht im Wesentlichen darin, dass SQS-Skripte jedes Mal gelesen werden, wenn sie aufgerufen werden und die SQF-Funktionen nur einmal in den Speicher geladen werden. Während bei Operation Flashpoint noch größtenteils auf SQS-Basis gearbeitet wurde, wird bei Armed Assault empfohlen mehr auf SQF-Basis zu arbeiten. 54 Mehr zum Thema Funktionen kann man im Kapitel 9.13 nachlesen. 2.8 - Das Paa-Format Das Paa-Format ist lediglich eine Bilddatei, wie auch das Jpg-Format. In Armed Assault sind größtenteils alle Grafiken im Paa- oder Pac-Format vorzufinden. Hierzu gehören selbstverständlich auch die Texturen sämtliche Objekte in Armed Assault. Im Unterkapitel „Der Missionsordner“ dieses Kapitels ist eine Grafik zu sehen, auf der eine Datei namens Title.paa zu sehen ist. Diese Grafik ist für das Overview vorgesehen und ist in der Overview.html so definiert. Dieses Bild sieht man, wenn man im Einzelmissionsmenü eine Mission zum Spielen auswählt. Der Name für dieses Bild ist aber variabel und müsste dann dementsprechend auch so in der Overview.html angegeben werden. Mehr dazu aber in diesem Kapitel 2.12 im Unterbereich „Der Overview“. Arma unterstützt, wie auch schon Operation Flashpoint, das Jpg-Format. Man kann also auch Bilder in diesem Format einbinden. Ganz wichtig ist es darauf zu achten, dass die angegebene Bildergröße passt. ArmA nimmt teilweise nur Grafiken an, die einen Zweierpotenzwert haben. Aber in manchen Bereichen gibt es auch Ausnahmen, wie z.B. im Briefing oder Overview. Zweierpotenzen sind: 2,4,8,16,32,64,128,256,... usw. Als Beispiel mal diese Formate: 64x64 128x128 128x64 256x256 Zum Betrachten und zum Bearbeiten von Paa- bzw. Pac-Dateien verweise ich auf die Armed Assault Fanseiten, auf denen man die entsprechenden Tools finden wird. 55 Kapitel 2 Anwendungsmäßig sind Funktionen so zu benutzen, dass sie eine bestimmte Aufgabe lösen und dies mit einem so kurzen und bündigen Schreibaufwand wie möglich. Hinzu kommt, dass man diese Funktion dann auch in anderen Missionen jederzeit verwenden kann, ohne sie umschreiben zu müssen. Man schreibt sie lediglich ein einziges Mal zum Erfüllen eines ganz bestimmten Zweckes. Beispielsweise ist es möglich mit Hilfe einer Funktion einen Vektor zu berechnen. Oder auch viele andere Bereiche lassen sich mit Funktionen wesentlich einfacher realisieren. Es ist besser viele kleine Funktionen zu haben, als nur ein langes Skript. Hierbei geht es weniger um die Performance. Wichtiger ist die Wiederverwertbarkeit dieser Funktion. 2.9 - Die PBO Die PBO ist eine gepackte Datei in der alle Dateien, die sich vorher beim Editieren einer Mission im Missionsordner angesammelt haben, verpackt sind. Man könnte sie also mit einer Rar- oder Zip-Datei vergleichen, nur dass die gepackten Dateien von der Größe her nicht verkleinert werden. Die PBO entsteht, wenn man seine fertige Mission im Editor als Single- oder Multiplayermission abspeichert. Während Singleplayermissionen im Verzeichnis ArmA/Missions hinterlegt werden, sind die Multiplayermissionen im Verzeichnis ArmA/MPMissions zu finden. PBO´s beschränken sich natürlich nicht nur auf die Missionen. Auch sämtliche Addons von Armed Assault sind, wie auch schon in Operation Flashpoint, in PBO´s gepackt. Diese Dateien lassen sich mit Hilfe von diversen Tools packen und auch wieder entpacken. So dass man beispielsweise schon vorhandene Missionen oder Addons entpacken und aus ihnen lernen bzw. Skripte oder ähnliches verwenden kann. Für die Tools verweise ich wieder auf die Armed Assault Fanseiten. 2.10 - Die Sounddateien Der überwiegende Teil der Sounddateien in Armed Assault ist im Wss-Format oder OggFormat konvertiert. Es ist aber auch möglich Wavedateien zu verwenden. Jedoch sollte man hier auf die Größe der Datei achten, da man ja die Mission auch irgendwann zum Download anbieten möchte. Das Wss- oder Ogg-Format ist hierfür genau das richtige, weil die Dateien je nach Soundlänge eine minimale Größe haben. Dies ermöglicht die Verwendung von vielen Sounds in einer Mission, ohne dass diese am Ende eine überdimensionale Dateigröße hat. Eine nähere Erklärung zum Einbinden von Sounds findet man im Kapitel 5.52 im Bereich -Eigenen Sound einbinden-. Sounddateien, bis auf Musik, sollten Mono mit einer Frequenz von 44.100 kHz konvertiert sein. Mono daher, damit man den Entfernungseffekt nutzen kann. Möchte man nämlich ein Objekt oder eine Einheit mit Name say "Soundname" etwas sagen bzw. erklingen lassen, würde man es auf der ganzen Karte hören, was ja unlogisch wäre. Deshalb Mono! Sind die Dateien also Stereo, erklingen die Sounds global. Die Konvertierungsprogramme für diese Dateien findet man auf den Armed Assault Fanseiten oder auch sonst bei anderen Anbietern im Internet. 56 2.11 - Die LIP-Dateien Hierbei gibt es lediglich 3 Werte(1,2,3), die man dafür benötigt. Zuerst legt man die Framerate der einzelnen Bewegungsbilder, hier mit dem Wert 0.040, fest. Man kann diesen Wert quasi als Zeitabschnitt bezeichnen. Alle 0.040 Sekunden bzw. Frames ändert sich nun die Mundbewegung. Nach der Festlegung der Framezeit beginnt der eigentliche Bewegungsablauf der Lippen, welche die Öffnungsgrade 0 bis 3 haben. Wobei der Wert 0 für geschlossenen und 3 für weit geöffneten Mund steht. Hier wurde eine Sounddatei verwendet, die genau eine Sekunde lang ist. Teilt man 1 Sekunde durch 0.040 so erhält man 25. Hier sind aber gar keine 25 Zeilen enthalten, sondern nur 20. Das liegt daran, dass man es auch so schreiben kann: Zum Beispiel von Zeit 0.560 setzt man den Lippenwert 1 und pausiert bis Zeit 0.720 und setzt dann den Lippenwert 2. Hier wurde also eine 4 Frame lange Bewegungspause der Lippen einsetzt. frame = 0.040 0.000, 0 0.040, 1 0.080, 2 0.120, 3 0.160, 2 0.200, 1 0.240, 0 0.280, 1 0.320, 2 0.360, 1 weiter --> 0.400, 0 0.440, 1 0.480, 3 0.520, 0 0.560, 1 4 Frame-Pausen 0.720, 2 2 Frame-Pausen 0.800, 1 0.840, 2 0.920, 1 1.000, 2 Dieses Beispiel ist ja nur für eine Sekunde. Man kann sich dann schon vorstellen, wie lang eine 10 oder 15 Sekunden lange Lip-Datei aussehen kann. Damit man das aber alles nicht per Hand machen muss, gibt es Tools, die für die Erstellung solcher Dateien konzipiert sind. Hier verweise ich mal wieder auf die Armed Assault Fanseiten, auf denen man die entsprechenden Tools finden und runterladen kann. 57 Kapitel 2 Die Lip-Datei ist für die Bewegung der Lippen zuständig. Jede Sounddatei, die für die Sprachausgabe ausgelegt ist, kann mit einer Lip-Datei versehen werden, damit sich die Lippen der jeweiligen Einheit beim Sprechen auch bewegen. 2.12 - Das Overview Das Overview ist der Abschnitt, den man bei der Einzelspielermissionsauswahl als kurzen Infoteil zur Mission sehen kann. Dieser wird in der Overview.html zusammen mit einem Bild erstellt. Im Spiel sieht das dann etwa wie auf dem Bild aus. Rechts ist die Missionsauswahl und links die Info mit Bild zu der Mission zu sehen. Zum Erstellen eines Overviews wären gewisse Html-Kenntnisse von Vorteil, aber auch wer sich damit nicht auskennt, bekommt das ohne weiteres hin. Am besten ist es immer, wenn man sich die Overview aus einer anderen Mission herauskopiert, einfach umschreibt und mit einen eigenem Bild versieht. Zu Beginn erstellt man zunächst einmal eine Textdatei, welche man später, wenn man alles fertig konfiguriert hat, dann in Overview.html umbenennt. Diese Textdatei öffnet man dann und trägt dort etwa folgenden Quelltext ein, welcher aus einer original Armed Assault Mission stammt. <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1250"> <meta name="GENERATOR" content="VB"> <title>Overview</title> </head> <body bgcolor="#FFFFFF"> <br> <!--Nachtwache--> <br> <p align="center"><img src="Title.paa" width="230" height="115"></p> <BR> <p> <! ---Missionsinfo> Wieder steht eine langweilige Nachtwache an. Es ist eine warme Nacht… <! ---Ende Missionsinfo> </p></body> </html> 58 2.13 - Das Briefing Im folgend zu sehenden Briefingausschnitt sieht man ganz gut den Missionsinfotext und darunter die Missionsziele, von welchen das Erste bereits abgehakt ist und die anderen noch zu erfüllen sind. Mehr Informationen zu den Missionszielen gibt es im Kapitel 4.5. Hier geht es zunächst erstmal darum eine Briefing.html zu erstellen und diese zu verstehen. Der einfachste Weg hierzu ist, wenn man sich eine Briefing.html aus einer schon bestehenden Mission herauskopiert und diese an seine eigenen Bedürfnisse bzw. Mission anpasst. Ein weiter einfacher Weg wäre, eines der vielen Briefingtools, die es auf den Armed Assault Fanseiten zum Download gibt, zu verwenden. Möchte man ein vorhandenes Briefing ändern, klickt man mit Rechtsklick auf die Datei und wählt “Öffnen mit” und öffnet die HTML-Datei dann ganz einfach mit dem Texteditor. Trotz allem folgt hier jetzt der trockene Weg zum Erstellen eines Briefings. Im Briefing selbst gibt es ja, wie man oben sieht, den Abschnitt Plan und den Abschnitt Notes. Beide stellen zwei verschiedene Seiten dar, die aber in einer Datei verarbeitet werden. Zum Erstellen eines Briefings wird zunächst wieder eine ganz normale Textdatei benötigt. Diese wird zunächst wieder normal als Textdatei geöffnet und in ihr der Quelltext nach den eigenen Bedürfnissen verfasst. Nach Abschluss der Arbeit, wird die Datei geschlossen und in Briefing.html umbenannt. 59 Kapitel 2 Die Briefing.html, die das Briefing direkt zur jeweiligen Mission darstellt, ist schon etwas umfangreicher als die Overview.html zu schreiben. Sie umfasst wesentlich mehr Text in Form von Informationen zur Mission und die dazugehörigen Missionsziele. Wie man im Kapitel 2.1 -Der Missionsordner- sehen kann, gibt es mehrere Briefingdateien, welche in den jeweiligen Sprachen verfasst sind. Normalerweise ist in der normal benannten Briefing.html alles in Englisch geschrieben. Aber wenn man nur eine Sprache für seine Mission vordefiniert, ist es egal welche Sprache darin vorkommt. Möchte man beispielsweise mehrere Sprachen einbinden, so sollte man sich schon an die Regel halten und die Dateien dementsprechend benennen. Briefing.German.html Overview.German.html Briefing.France.html Overview.France.html Das englische Briefing und Overview würde in diesem Fall einfach nur wie folgt benannt: Briefing.html Overview.html Auf den folgenden zwei Seiten ist nun das passende Briefing zum Briefingbild auf der Vorseite zu sehen. Es wurden lediglich die Notizen hinzugefügt, die im Bild als Notes benannt sind. Mit ein wenig Geduld, Ideenreichtum und Kreativität kann jeder mit ein bisschen Übung ein gut ausgefeiltes Briefing erstellen. So kann ein Briefing einer Mission später im Quelltext etwa aussehen: <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1250"> <meta name="GENERATOR" content="vb"> <title>Briefing</title> </head> <body bgcolor="#FFFFFF"> <h2> <a name="Main"></a> </h2> <! --- Die Notizen – ab hier werden die Notizen(Notes) eingetragen.> <h6> Damn that’s my first shooting lesson. <br> </h6> <! --- Ende der Notizen> <hr> <! --- Der Missionsplan – Ab hier wird die Missionsbeschreibung angegeben.> <p><a name="Plan"></a> Successfully finish weapon qualification.<br> 60 Kapitel 2 Expert Marksman rifle qualification required to unlock sniper course in line 6. </p> <hr> <! --- Die Missionsziele – Ab hier erfolgt die Eintragung der Missionsziele> <p><a name="OBJ_1"></a> Listen to your drill instructor until he lets you go. </p><hr> <p><a name="OBJ_2"></a> Qualify with rifle in line 1. </p><hr> <p><a name="OBJ_3"></a> Qualify with automatic weapon in line 2. </p><hr> <p><a name="OBJ_4"></a> Qualify with granade launcher in line 3. </p><hr> <p><a name="OBJ_5"></a> Familiarize with hand granades in line 4. </p><hr> <p><a name="OBJ_6"></a> Qualify with M9 pistol in line 5. </p><hr> <! --- Ende des Missionsplans> <! --- Abschlussbriefing – Festlegung des Abschlussbriefings> <hr><br> <h2><p><a name="Debriefing:End1">Qualified</a></p></h2> <br><p> Now I'm a qualified infantryman. </p><br> <hr><br> <h2><p><a name="Debriefing:End2">Title</a></p></h2> <br><p></p><br> <hr><br> <h2><p><a name="Debriefing:End3">Title</a></p></h2> <br><p></p><br> <hr><br> <h2><p><a name="Debriefing:End4">Title</a></p></h2> <br><p></p><br> <hr><br> <h2><p><a name="Debriefing:End5">Title</a></p></h2> <br><p></p><br> <hr><br> <h2><p><a name="Debriefing:End6">Give UP</a></p></h2> <br><p> I gave it up. The infantry training is boring. </p><br> <! --- END debriefing ---> </body> </html> 61 Mit <html> und <head> wird die Html-Datei zunächst eröffnet. Danach folgen einige hier jetzt nicht so wichtige Standartzeilen. Die Hintergrundfarbe wird mit <body bgcolor="#FFFFFF"> definiert, obwohl die bei Armed Assault ohnehin fest ist. Viel wichtiger ist zum Beispiel <br>, was für einen Zeilenumbruch steht. Hinzu kommen noch Befehle wie <hr> für eine horizontale Linie, welche man aber nicht sehen kann, dann das <p>, welches für einen Absatz steht und zu guter letzt das <a>, welches einen Link hervorhebt. Mann hat ja die Möglichkeit Wörter mit Marker zu verbinden, wo das Fadenkreuz dann hinwandert, wenn man diesen Link im Briefing anklickt. Folgend ein kurzes Beispiel: Hat man im Briefing beispielsweise einen Marker mit dem Namen Ziel gesetzt, verlinkt man diesen im Briefing wie folgt. Der Satz im Briefing lautet: Erobern Sie das Ziel. Von diesem Satz soll das Wort Ziel mit dem Marker namens Ziel verlinkt werden. Im Quelltext sieht das dann so aus: Erobern Sie das <a href="marker:ziel">Ziel</a> Wie man sieht, ist der Marker namens Ziel angegeben und zwischen dem <a> und </a> das Wort Ziel. Wenn man jetzt im Briefing auf das Wort Ziel klickt, wandert das Fadenkreuz beim Anklicken auf den Marker namens Ziel, wie auf dem unteren Bild sehr gut zu sehen ist. Befehle, die mit einem Backslash versehen sind, beenden die jeweilige Aktion. 62 Kapitel 3 – Waffen – Fahrzeuge – Einheiten – Objekte – 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14 3.15 3.16 3.17 3.18 3.19 3.20 3.21 3.22 Die Handwaffen und statische Waffen Die Waffenbezeichnungsliste Einheiten bewaffnen und ausrüsten Die Waffen- und Munitionskiste Fahrzeuge be- und entladen Waffenauswahl im Briefing Die Fahrzeugklassen Die Fahrzeugwaffen Die Einheitsklassen Die Shellklassen Die Objekt- und Gebäudeklassen Die Pflanzenklassen Die Steinklassen Die Schilderklassen Waffen- und Magazintypen ausgeben lassen Abgefeuerten Typ ausgeben lassen Hat Einheit Waffe? Primär- bzw Sekundärwaffe einer Einheit Hat Einheit Munition Minen erzeugen Waffen und Magazine erzeugen Waffenblickrichtung ausgeben lassen 64 68 70 71 71 72 73 76 77 80 81 88 90 91 92 92 92 93 93 93 94 95 63 Kapitel 3 Nachdem du in den ersten beiden Kapiteln mit der Oberfläche und den Dateien vertraut gemacht wurdest, kommen wir nun zu den etwas spezielleren Bereichen. Du bist nun fähig Einheiten zu setzen, diese mit Wegpunkten zu verbinden und weißt sogar, in welchen Dateien du welchen Bereich finden und konfigurieren kannst. Hier werden dir nun alle Bereiche erläutert, die mit Waffen, Fahrzeugen, Einheiten und Objekten verbunden sind. 3.1 - Die Handwaffen und statische Waffen Hier eine Übersicht sämtlicher Hand- und Statikwaffen, mit den jeweiligen Bezeichnungen, den Magazinen und dem Zubehör. WESTEN / WIDERSTAND – Leichte Handwaffen Waffe: Magazin: M16A2 M16A2GL M4GL - M4A1GL 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 1Rnd_HE_M203 FlareWhite_M203 FlareGreen_M203 FlareRed_M203 FlareYellow_M203 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 1Rnd_HE_M203 FlareWhite_M203 FlareGreen_M203 FlareRed_M203 FlareYellow_M203 M4 M4A1SD M4AIM Granate: Flares: Waffe: Magazin: Waffe: Magazin: 20Rnd_556x45_Stanag 20Rnd_556x45_Stanag 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_StanagSD 30Rnd_556x45_StanagSD 30Rnd_556x45_StanagSD M16A4 - M4A1 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag Granate: Flares: Waffe: Magazin: 64 M16A4_GL M16A4_ACG_GL 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 1Rnd_HE_M203 FlareWhite_M203 FlareGreen_M203 FlareRed_M203 FlareYellow_M203 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 1Rnd_HE_M203 FlareWhite_M203 FlareGreen_M203 FlareRed_M203 FlareYellow_M203 M16A4_ACG MP5A5 MP5SD 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_9x19_MP5 30Rnd_9x19_MP5SD 30Rnd_9x19_MP5 30Rnd_9x19_MP5SD Waffe: Magazin: M4SPR M249 M240 20Rnd_556x45_Stanag 20Rnd_556x45_Stanag 100Rnd_762x51_M240 30Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_StanagSD 30Rnd_556x45_StanagSD 200Rnd_556x45_M249 G36a G36C G36K 30Rnd_556x45_ G36 30Rnd_556x45_G36 30Rnd_556x45_ G36 Waffe: Magazin: M24 M107 5Rnd_762x51_M24 10Rnd_127x99_M107 Waffe: Magazin: M9 M9SD 15Rnd_9x19_M9 15Rnd_9x19_M9SD 15Rnd_9x19_M9 15Rnd_9x19_M9SD Kapitel 3 Waffe: Magazin: WESTEN / WIDERSTAND – Schwere Handwaffen Waffe: Magazin: Stinger M136 Javelin Stinger M136 Javelin WESTEN / WIDERSTAND – Statische Waffen Waffe: M119 M2StaticMG M2HD_mini_TriPod Magazin: 30Rnd_105mmHE_M119 100Rnd_127x99_M2 SearchLight 65 Waffe: Magazin: MK19_TriPod TOW_TriPod Stinger_Pod 48Rnd_40mm_MK19 6Rnd_TOW_Tripod 2Rnd_Stinger OSTEN – Leichte Handwaffen Waffe: Magazin: Granate: Flares: AK74 AK74GL AKS74U 30Rnd_545x39_AK 30Rnd_545x39_AK 1Rnd_HE_GP25 FlareWhite_GP25 FlareGreen_GP25 FlareRed_GP25 FlareYellow_GP25 30Rnd_545x39_AK Waffe: Magazin: AKS74UN PK SVD 30Rnd_545x39_AK 30Rnd_545x39_AKSD 100Rnd_762x54_PK 10Rnd_762x54_SVD Waffe: Magazin: AKS74PSO KSVK 30Rnd_545x39_AK 5Rnd_127x108_KSVK Waffe: Magazin: Makarov MakarovSD 8Rnd_9x18_Makarov 8Rnd_9x18_MakarovSD 8Rnd_9x18_Makarov 8Rnd_9x18_MakarovSD 66 OSTEN – Schwere Handwaffen Waffe: Magazin: 6G30 RPG7V Strela 6Rnd_HE_6G30 PG7V Strela OSTEN – Statische Waffen Kapitel 3 Waffe: Magazin: D30 DSHKM DSHkM_Mini_TriPod 30Rnd_122mmHE_D30 50Rnd_127x107_DSHKM 50Rnd_127x107_DSHKM Waffe: Magazin: TOW_TriPod_East Stinger_Pod_East AGS 6Rnd_TOW_Tripod 2Rnd_Stinger 29Rnd_30mm_AGS30 NVGoggles Binocular Ausrüstung allgemein Waffe: Magazin: LaserDesignator Waffe: Magazin: Handgrenade HandGrenadeTimed Pipebomb Handgrenade HandGrenadeTimed Pipebomb Waffe: Magazin: Mine MineE SmokeShell Mine MineE SmokeShell SmokeShellRed SmokeShellGreen LaserBatteries 67 3.2 - Die Waffenbezeichnungsliste Hier nochmal die Handwaffen und Magazine in Listenform mit kurzer Bemerkung dazu. Natürlich macht es bei einer Waffe ohne Schalldämpfer keinen Sinn ein Magazin mit dem Anhang SD zu vergeben. Westen / Widerstand Waffenklasse Bezeichnung Munition M16A2 M16A2 Magazin: M16A4 M16A4 M16A4_ACG M16A4 - Zielfernrohr 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_StanagSD M4 M 4 - Standard M4A1 M 4 A1 - Standard M4A1SD M 4 - Schalldämpfer M4AIM M4 - Aimpoint M4SPR M 4 - Zielfernrohr M16A2GL Sturmgewehre mit Granatwerfer Magazin: 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 30Rnd_556x45_StanagSD Granate: 1Rnd_HE_M203 Flares: FlareWhite_M203 FlareGreen_M203 FlareRed_M203 FlareYellow_M203 20Rnd_556x45_Stanag 30Rnd_556x45_Stanag 200Rnd_556x45_M249 30Rnd_556x45_StanagSD 100Rnd_762x51_M240 30Rnd_556x45_G36 M16A4_GL M16A4_ACG_GL M4GL M4A1GL M249 M249 SAW Magazin: M240 G36a M240 G 36 – Standard Magazin: Magazin: G36C G 36 - Kommando G36K G 36 – Kommando II M24 M107 MP5A5 Scharfschützengewehr Scharfschützengewehr MP5 - StandardMP5 Schalldämpfer Magazin: Magazin: Magazin: 5Rnd_762x51_M24 10Rnd_127x99_M107 30Rnd_9x19_MP5 30Rnd_9x19_MP5SD Pistole Magazin: Pistole - Schalldämpfer M136 - Panzerfaust Javelin - Panzerfaust Stinger - Fliegerfaust 15Rnd_9x19_M9 15Rnd_9x19_M9SD Magazin: Magazin: Magazin: M136 Javelin Stinger MP5SD M9 M9SD M136 Javelin Stinger 68 Osten Munition AK74 AK74GL Magazin: Magazin: 30Rnd_545x39_AK 30Rnd_545x39_AK Granate: 1Rnd_HE_GP25 Flares: FlareWhite_GP25 FlareGreen_GP25 FlareRed_GP25 FlareYellow_GP25 30Rnd_545x39_AK 30Rnd_545x39_AKSD 30Rnd_545x39_AK AK74PSO 100Rnd_762x54_PK 5Rnd_127x108_KSVK AK 74 AK 74 mit Granatwerfer AKS74U AKS74UN AKS74PSO PK KSVK AKS 74 U - Standard AKS74UN - Schalldämpfer AKS74 - Zielfernrohr MG Scharfschützengewehr Magazin: SVD Makarov MakarovSD 6G30 RPG7V Strela Scharfschützengewehr Pistole Pistole - Schalldämpfer Granatwerfer Panzerfaust Fliegerabwehr Magazin: Magazin: Magazin: Magazin: Magazin: Magazin: Magazin: Magazin: 10Rnd_762x54_SVD 8Rnd_9x18_Makarov 8Rnd _9x18_MakarovSD 6Rnd_HE_6G30 RPG7V Strela Ausrüstung Waffenklasse Bezeichnung Munition Handgrenade HandGrenadeTimed Grenade TimeBomb PipeBomb SmokeShell SmokeShellRed SmokeShellGreen Mine MineE Binocular NVgoggles LaserDesignator CarHorn SportCarHorn TruckHorn BikeHorn Handgranate Handgranate (zeitverzögert) Granate Zeitbombe Sprengsatz Weiße Rauchgranate Rote Rauchgranate Grüne Rauchgranate Panzermine Schützenmine Fernglas Nachsichtgerät Lasermarkiergerät Autohupe Sportautohupe Lkw-Hupe Fahrradklingel Handgrenade HandGrenadeTimed Grenade TimeBomb PipeBomb SmokeShell SmokeShellRed SmokeShellGreen Mine MineE Binocular NVgoggles LaserBatteries CarHorn SportCarHorn TruckHorn BikeHorn 69 Kapitel 3 Waffenklasse Bezeichnung 3.3 - Einheiten bewaffnen und ausrüsten Sämtliche Einheiten aus Armed Assault lassen sich be- bzw. entwaffnen. Dazu muss man wissen, dass eine Einheit immer nur ein Gewehr tragen kann. Als zweite große Waffe kann maximal eine Panzer- oder Flugabwehrwaffe mitgeführt werden. Man kann einer Einheit also erst eine Waffe zuteilen, wenn man zuvor eine andere entfernt hat. Diese kann man dabei einzeln oder auch komplett entfernen. Mit folgender Syntax entfernt man eine einzelne Waffe: this removeWeapon "M4" oder Name removeWeapon "M4" Die Magazine, Handgranaten usw. bleiben dabei weiterhin vorhanden. Würde man dieser Einheit nun eine Waffe zuweisen, die die gleichen Magazine benötigt, wäre diese gleich zu Anfang geladen, was nicht immer so ist. Wenn man nämlich mit dem Befehl removeAllWeapons Name arbeitet, werden der Einheit alle Waffen und alle Magazine abgenommen. Wenn man diese Einheit nun bewaffnen möchte, muss man eine gewisse Reihenfolge beachten, da die Waffe sonst zu Missionsbeginn nicht geladen sein wird. Man gibt zuerst die Magazine und erst zuletzt die Waffe an! Nachdem man bei der Einheit nun das M4 entfernt hat, weist man ihr mit dieser Syntax eine neue zu: this addWeapon "M4A1SD" oder Name addWeapon "M4A1SD"; Die Eintragungen kann man in der Initzeile der jeweiligen Einheit oder auch woanders vornehmen. Als Beispiel in Skripten, Auslösern oder Wegpunkten. Zum Entfernen eines Magazins gilt diese: this removeMagazine "30Rnd_556x45_Stanag" und zum zuweisen eines neuen Magazins diese Syntax: this addMagazine "30Rnd_556x45_StanagSD" Möchte man alle oder nur einige Magazine entfernen, kann man auch folgende Syntax nutzen. Dabei gelten wieder alle werte zwischen 0 und 1. Name setVehicleAmmo 0.5 Natürlich treffen diese Befehle nicht nur auf die Waffen, sondern auch auf die nötige Ausrüstung zu. Der normale Soldat trägt in der Regel kein Fernglas oder Nachtsichtgerät bei sich. Da aber ein Fernglas in den Weiten von Sahrani sehr von Vorteil wäre und auch ein Nachtsichtgerät in dunkler Nacht den notwendigen Durchblick verleiht, gibt man in der Initzeile der Einheit die jeweils aufgeführte Syntax an. für das Fernglas und für das Nachsichtgerät 70 this addWeapon "Binocular"; this addWeapon "NVGoggles"; 3.4 - Die Waffen- und Munitionskiste Alle Waffen- und Munitionskisten lassen sich individuell, also je nach Bedarf, ausstatten. Dabei ist es vollkommen egal, ob man Waffen und Munition in eine oder verschiedene Kisten packt. Um eine Waffen- bzw. Munitionskiste selbst zu definieren, muss man diese zunächst entleeren. Das macht man mit: clearWeaponCargo this oder clearWeaponCargo Name clearMagazineCargo this oder clearMagazineCargo Name Im folgenden Beispiel wird eine Kiste mit 2 schallgedämpften M4A1, den dazu passenden 10 Magazinen und 6 Handgranaten beladen. this addWeaponCargo ["M4A1SD",2]; this addMagazineCargo ["30Rnd_556x45_StanagSD",10]; this addMagazineCargo ["Handgrenade",6]; Tipp! Auch Fässer lassen sich mit Waffen und Munition befüllen. Dort wird das gleiche Verfahren, wie bei den Munitionskisten verwendet, nur dass man die Fässer eben vorher nicht mit den Clearbefehlen leeren muss. 3.5 - Fahrzeuge be- und entladen Viele Fahrzeuge in Armed Assault sind bereits mit Magazinen, Handgranaten und ähnlichem beladen. Man hat dort also auch dort als Soldat jederzeit die Möglichkeit sich neu zu bewaffnen. Natürlich kann man die Fahrzeuge im Editor auch selbst mit Magazinen und Waffen bestücken. Hierzu wird das gleiche Verfahren, wie bei den Munitionskisten verwendet. Das Entladen erfolgt wieder mit: clearWeaponCargo this clearMagazineCargo this und das Beladen mit der jeweiligen Syntax: this addWeaponCargo ["M4A1SD",2]; this addMagazineCargo ["30Rnd_556x45_StanagSD",10]; Hier wurden nun 2 schallgedämpfte M4A1 Sturmgewehre mit den dazugehörigen Magazintypen, hier 10 Magazine, in das Fahrzeug geladen. 71 Kapitel 3 Diese Einträge nimmt man in der Initzeile der jeweiligen Kiste vor, ist aber auch in Bereichen wie Skripten, Auslösern usw. möglich. Nachdem die Kiste nun entleert wurde, fügt man die Waffen und Ausrüstung hinzu, welche die Kiste später enthalten soll. Für this kann auch jeweils der Name der Kiste angegeben werden. 3.6 - Waffenauswahl im Briefing Als Leader einer Mehrspielergruppe hat der Spieler später über das Briefing in der Mission die Möglichkeit sich und seine Gruppe selbst auszustatten, vorausgesetzt man hat dies vorher so in der Description.ext, siehe Kapitel 2.3, vordefiniert. Dazu muss eine Klasse für die jeweilige Waffe und eine Klasse für die dazugehörige Magazinsorte vordefiniert werden. Im folgenden Beispiel wurden 6 schallgedämpfte M4A1 mit 20 dazugehörigen Magazinen, 2 M136 Panzerfäuste mit 6 Schuss und dazu noch 20 Handgranaten festgelegt. // Hier beginnt der Part Class Weapons class Weapons { class M4A1SD { count = 6; }; class M136 { count = 2; }; }; // Hier endet der Part Class Weapons // Hier beginnt der Part Class Magazines class Magazines { class 30Rnd_556x45_StanagSD { count = 20; }; class M136 { count = 6; }; class HandGrenade { count = 20; }; }; // Hier endet der Part Class Magazines Die Art der Waffe Die Anzahl der Waffen Die Art der Waffe Die Anzahl der Waffen Die Art der Magazine Die Anzahl der Magazine Die Art der Magazine Die Anzahl der Magazine Die Art der Waffe Die Anzahl der Magazine Möchte man die Waffenauswahl erweitern, fügt man lediglich die jeweilige Klasse der Waffe und die Klasse der Magazine selbst in diesen Abschnitt der Description.ext ein. 72 3.7 - Die Fahrzeugklassen WESTEN Fahrzeug Beschreibung Klassenname Land Kampfpanzer Schützenpanzer Sanitätsschützenpanzer M113 - Mobiles Hauptquartier (Warfare) Flugabwehrpanzer Schützenpanzer mit M2-Maschinengewehr Schützenpanzer mit Granatwerfer Schützenpanzer mit Panzerabwehrwaffe Hummer Hummer mit M2 Hummer mit Panzerabwehrwaffe Hummer mit Granatwerfer Lkw 5 Tonner Lkw 5 Tonner - offen Lkw 5 Tonner mit Maschinengewehr Lkw 5 Tonner - Reparaturfahrzeug Lkw 5 Tonner - Munitionsfahrzeug Lkw 5 Tonner - Tankfahrzeug Lkw 5 Tonner - Munitionsfahrzeug (Warfare) Lkw 5 Tonner - Transporter (Warfare) Lkw 5 Tonner - Bergungsfahrzeug(Warfare) Motorrad AH 1 Z AH 6 AV 8 B AV 8 B (GBU) A10 MH 6 UH 60 UH 60 (FFAR) Camel Parachute Cobra-Kampfhubschrauber Little Bird Helikopter bewaffnet Harrier mit Raketen Harrier mit Bomben A10 mit Raketen und GAU12 Little Bird Helikopter unbewaffnet Blackhawk - Helikopter mit MG Blackhawk - Helikopter mit Raketenwerfer Doppeldecker Fallschirm CRRC RHIB RHIB 2 Turret Schlauchboot Patrouillenboot mit Maschinengewehr Patrouillenboot mit MG und Granatwerfer M1Abrams M113 M113Ambul M113_MHQ Vulcan Stryker_ICV_M2 Stryker_ICV_MK19 Stryker_TOW HMMWV HMMWV50 HMMWVTOW HMMWVMK Truck5t Truck5tOpen Truck5tMG Truck5tRepair Truck5tReammo Truck5tRefuel WarfareTruck5tReammo WarfareWestSupplyTruck WarfareWestSalvageTruck M1030 Kapitel 3 M1Abrams M113 M113Ambul M113 Mobile HQ Vulcan Stryker ICV M2 Stryker ICV MK19 Stryker TOW HMMWV HMMWV M2 HMMWV TOW HMMWV MK 19 Truck 5 t Truck 5 t Open Truck 5 t MG Truck 5 t Repair Truck 5 t Reammo Truck 5 t Refuel Truck 5 t Ammo Truck Truck 5 t Supply Truck 5 t Salvage Motorcycle Luft AH1W AH6 AV8B2 AV8B A10 MH6 UH60MG UH60 Camel ParachuteWest Wasser Zodiac RHIB RHIB2Turret 73 OSTEN Fahrzeug Beschreibung Klassenname Land T72 BMP2 BMP2Ambulance BMP2 Mobile HQ ZSU BRDM2 BRDM2_ATGM UAZ UAZMG Ural Ural Open Ural Repair Ural Reammo Ural Refuel Ural Ammo Ural Supply Ural Salvage Motorcycle Datsun DshKm - 1 Datsun DshKm - 2 Datsun Pk -1 Datsun Pk -2 Hilux DshKm - 1 Hilux DshKm - 2 Hilux Pk -1 Hilux Pk -2 Kampfpanzer Schützenpanzer Sanitätsschützenpanzer BMP2 - Mobiles Hauptquartier (Warfare) Shilka Flugabwehrpanzer Schützenpanzer Schützenpanzer mit Panzerabwehrwaffe Jeep Jeep mit Maschinengewehr Lkw Lkw - offen Lkw - Reparaturfahrzeug Lkw - Munitionsfahrzeug Lkw - Tankfahrzeug Lkw - Munitionsfahrzeug (Warfare) Lkw - Transporter (Warfare) Lkw - Bergungsfahrzeug (Warfare) Motorrad Pick-up mit schwerem MG Pick-up mit schwerem MG Pick-up mit MG Pick-up mit MG Pick-up mit schwerem MG Pick-up mit schwerem MG Pick-up mit MG Pick-up mit MG SU 34 SU 34B Mi 17 Mi 17 KA-50 Camel E Parachute SU 34 mit Raketen, FFAR, Bordkanone SU 34 mit Raketen und Bordkanone Helikopter mit Maschinengewehr Helikopter mit Raketenwerfer Kampfhubschrauber Doppeldecker Fallschirm PBX Boat Schlauchboot T72 BMP2 BMP2Ambul BMP2_MHQ ZSU BRDM2 BRDM2_ATGM UAZ UAZMG Ural UralOpen UralRepair UralReammo UralRefuel WarfareUralReammo WarfareEastSupplyTruck WarfareEastSalvageTruck TT650G DATSUN_DSHKM1 DATSUN_DSHKM2 DATSUN_PK1 DATSUN_PK2 HILUX_DSHKM1 HILUX_DSHKM2 HILUX_PK1 HILUX_PK2 Luft SU34 SU34B Mi17_MG Mi17 KA50 Camel2 ParachuteEast Wasser 74 PBX WIDERSTAND Fahrzeug Beschreibung Land Klassenname T72 RACS M113 RACS Vulkan RACS 4x4 4x4 MG 4x4 Open Kampfpanzer Schützenpanzer Flugabwehrpanzer Jeep geschlossen Jeep mit Maschinengewehr M2 Jeep offen T72_RACS M113_RACS Vulcan_RACS Landrover LandroverMG Landrover_Closed AH6 RACS MH6 RACS UH60 (FFAR) RACS UH-60 RACS Parachute Kampfhubschrauber Little Bird UH-60 (FFAR) RACS UH-60 RACS Fallschirm CRRC Schlauchboot Zodiac2 Fahrzeug Bemerkung Land Klassenname Pick-Up Pick-Up 2 Pick-Up 3 Offroad Offroad2 Offroad3 Sedan Hatchback Skoda Skoda (Blue) Skoda (Red) Skoda (Green) Policecar HMMWV (Civil) Bus UralCivil UralCivil 2 Traktor Motorcycle Pick-Up blau Pick-Up rot geschlossen Pick-Up grün Geländewagen grau offen Geländewagen rotes Verdeck Geländewagen weiß offen Auto weiß Auto rot Skoda weiß Skoda blau Skoda rot Skoda grün Polizeijeep HMMWV (Zivil) Stadtbus Lkw gelb geschlossen Lkw blau geöffnet Traktor Motorrad Datsun1_civil_1_open Datsun1_civil_2_covered Datsun1_civil_3_open Hilux1_civil_1_open Hilux1_civil_3_open Hilux1_civil_2_covered Car_sedan Car_hatchback Skoda SkodaBlue SkodaRed SkodaGreen Landrover_Police HMMWV_civil Bus_city UralCivil UralCivil2 Tractor TT650C Parachute Parachute DC3 Fallschirm Leerer Fallschirm DC3 Luft Kapitel 3 AH6_RACS MH6_RACS UH60RACS UH60MGRACS ParachuteG Wasser ZIVILISTEN Luft ParachuteC Parachute DC3 75 3.8 - Die Fahrzeugwaffen Luft Fahrzeug Waffe Magazin UH60 Black Hawk MG UH60 Black Hawk FFAR AH 1 Supercobra M134 FFARLauncher HellfireLauncher FFARLauncher M197 TwinM134 FFARLauncher GAU12 SidewinderLauncher BombLauncher GAU12 MaverickLauncher GAU8 TwinVickers CamelGrenades 2A42 200Rnd_762x51_134 38Rnd_FFAR 8Rnd_Hellfire 38Rnd_FFAR 750Rnd_M197_AH1 4000Rnd_762x51_M134 14Rnd_FFAR 300Rnd_25mm_Gau12 4Rnd_Sidewinder_AV8B 5Rnd_GBU12_AV8B 300Rnd_25mm_Gau12 5Rnd_Maverick_A10 1350Rnd_30mmAP_A10 500Rnd_TwinVickers 6Rnd_Grenade_Camel 230Rnd_30mmHE_2A42 230Rnd_30mmAP_2A42 40Rnd_80mm 12Rnd_Vikhr_KA50 2000Rnd_762x54_PKT 96Rnd_57mm 4Rnd_R73 42Rnd_S8T 180Rnd_30mm_GSh301 6Rnd_Ch29 180Rnd_30mm_GSh301 AH6 Littlebird FFAR, MG AV-8B Harrier AV-8B Harrier GBU A10 Camel KA-50 MI-17 MG MI-17 FFAR SU 34 SU 34 B 80mmLauncher VikhrLauncher PKT 57mmLauncher R73Launcher S8Launcher GSh301 Ch29Launcher GSh301 Land/Wasser BMP 2 2A42 BRDM 2 ATGM M113 MTW M113 Vulcan M1A2 Abrahams PKT AT5Launcher KPVT PKT AT5Launcher M2 M168 M256 T72, T72Racs M240_Veh D81 Shilka Stryker ATGM Stryker ICV MG Stryker MK19 HMMWV TOW HMMWV MK19 5to LKW MG UAZ AGS 30 UAZ MG Army 4x4 M2 RHIB AZP85 TOWLauncher M2 MK19 TOWLauncherSingle MK19 M2 AGS30 DSHKM M2 M2 BRDM 2 76 250Rnd_30mmHE_2A42 250Rnd_30mmAP_2A42 2000Rnd_762x54_PKT 8Rnd_AT5_BMP2 500Rnd_145x115_KPVT 150Rnd_762x54_PKT 5Rnd_AT5_BRDM2 100Rnd_127x99_M2 2100Rnd_20mm_M168 20Rnd_120mmSABOT_M1A2 20Rnd_120mmHE_M1A2 1200Rnd_762x51_M240 23Rnd_125mmSABOT_T72 23Rnd_125mmHE_T72 2000Rnd_23mm_AZP85 2Rnd_TOW 100Rnd_127x99_M2 48Rnd_40mm_MK19 6Rnd_TOW_HMMWV 48Rnd_40mm_MK19 100Rnd_127x99_M2 29Rnd_30mm_AGS30 50Rnd_127x107_DSHKM 100Rnd_127x99_M2 100Rnd_127x99_M2 3.9 - Die Einheitsklassen WESTEN Beschreibung AA Specialist AT Specialist Automatic Rifleman Camel Pilot Crewman Engineer Grenadier Machinegunner Medic Officer Pilot Rifleman Rifleman SF Assault SF Marksman SF Recon SF Saboteur SF Saboteur 2 Sniper Squad Leader Team Leader Prisoner USMC Fire Team Leader USMC Machinegunner USMC AASpecialist USMC Rifleman USMC Rifleman (GL) USMC Rifleman (Mines) USMC Rifleman (M136) USMC Corpsman USMC Squad Leader USMC Automatic Rifleman USMC AT Specialist (Javelin) USMC Sniper USMC Spotter (WDL) Rifleman (WDL) Medic (WDL) Grenadier (WDL) AT Specialist (WDL) AA Specialist (WDL) Machinegunner (WDL) Engineer (WDL) Designated Marksman (WDL) Automatic Rifleman (WDL) Team Leader (WDL) Squad Leader Mercenary Team Leader Mercenary Grenadier Mercenary Machinegunner Mercenary Engineer Mercenary Sniper Mercenary Saboteur Fliegerabwehrsoldat mit Stinger SoldierWAA Panzerabwehrsoldat mit M136 SoldierWAT MG-Schütze mit M249 SoldierWAR Doppeldecker Pilot mit M9 BISCamelPilot Fahrzeugbesatzung mit M4A1 SoldierWCrew Pionier mit M4 AIM SoldierWMiner Grenadier mit M4 203 SoldierWG MG-Schütze mit M240 SoldierWMG Sanitätssoldat mit M4 AIM SoldierWMedic Offizier mit M9 OfficerW Pilot mit M4A1 SoldierWPilot Schütze mit M4AIM SoldierWB Schütze mit M4AIM SoldierWNOG Special Forces mit M4A1GL SoldierWSaboteurAssault Special Forces mit M4 SPR SoldierWSaboteurMarksman Special Forces mit M4 A1 SD SoldierWSaboteurRecon Special Forces mit M4 A1 SD SoldierWSaboteurPipe Special Forces mit MP 5 SD SoldierWSaboteurPipe2 Scharfschütze mit M24 SoldierWSniper Zugführer mit M4 AIM SquadLeaderW Gruppenführer mit M4 AIM TeamLeaderW Gefangener ohne Waffe SoldierWCaptive Gruppenführer M16A4 ACOG GL USMCD_Soldier_TL MG-Schütze mit M240 USMCD_Soldier_MG Fliegerabwehrsoldat mit Stinger USMCD_Soldier_AA Schütze mit M16A4 USMCD_Soldier_R Schütze mit M16A4 ACOG GL USMCD_Soldier_GL Schütze mit M16A4 und Minen USMCD_Soldier_Engineer Panzerabwehrsoldat mit M136 USMCD_Soldier_AT Sanitätssoldat mit M4 AIM USMCD_Soldier_Med Zugführer mit M16A4 ACOG USMCD_Soldier_SL MG-Schütze mit M249 USMCD_Soldier_AR Panzerabwehrsoldat mit Javeline USMCD_Soldier_HAT Scharfschütze mit M24 USMCD_Soldier_Sniper Schütze mit M16A4 ACOG USMCD_Soldier_Spotter Schütze mit M16A4 (WDL) US_Soldier_WDL Sanitäter mit M16A4 (WDL) US_Soldier_WDL_Med Schütze mit M16A4 RCO GL (WDL) US_Soldier_WDL_GL Panzerabwehrsoldat mit M136 (WDL) US_Soldier_WDL_AT Fliegerabwehrsoldat mit Stinger (WDL) US_Soldier_WDL_AA MG-Schütze mit M240 (WDL) US_Soldier_WDL_MG Schütze mit M16A4 und Minen (WDL) US_Soldier_WDL_Engineer Scharfschütze mit M24 (WDL) US_Soldier_WDL_Sniper MG-Schütze mit M249 (WDL) US_Soldier_WDL_AR Gruppenführer mit M4 AIM (WDL) US_Soldier_WDL_TL Zugführer mit M16A4 ACOG (WDL) US_Soldier_WDL_SL Söldner Anführer SoldierMTeamLeader Söldner Grenadier SoldierMG Söldner MG SoldierMMG Söldner Reparatur SoldierMR Söldner Sniper SoldierMS Söldner Sprengcommando SoldierMD Klassenname Kapitel 3 Einheit 77 OSTEN Einheit Beschreibung AA Specialist Fliegerabwehrsoldat mit Strela AT Specialist Panzerabwehrsoldat mit RPG 7 V Camel Pilot Doppeldecker Pilot Crewman Fahrzeugbesatzung Engineer Pionier Especas Speznaz mit AKS 74 U Especas Marksman Speznaz mit AKS74PSO Especas Saboteur Speznaz mit AKS 74 UN Grenadier Grenadier Machinegunner Soldat mit Maschinengewehr PK Medic Sanitätssoldat Rifleman Soldat mit AK-74 Rifleman Soldat mit AK-74 Officer Offizier Pilot Pilot Sniper Scharfschütze mit Dragunov (SVD) Squad Leader Zugführer Team Leader Gruppenführer Prisoner Gefangener Partisan Team Leader Partisane Anführer Partisan AT Specialist Partisane PzAbw Partisan Saboteur Partisane Saboteur Partisan Machinegunner Partisane MG Partisan Medic Partisane Sanitäter Partisan Rifleman Partisane Schütze Klassenname SoldierEAA SoldierEAT BISCamelPilot2 SoldierECrew SoldierEMiner SoldierESaboteurPipe SoldierESaboteurMarksman SoldierESaboteurBizon SoldierEG SoldierEMG SoldierEMedic SoldierEB SoldierENOG OfficerE SoldierEPilot SoldierESniper SquadLeaderE TeamLeaderE SoldierECaptive SoldierPTeamLeader SoldierPAT SoldierPSaboteur SoldierPMG SoldierPMedic SoldierPB WIDERSTAND Einheit Beschreibung Klassenname AA Specialist AT Specialist Crewman Engineer Grenadier Machinegunner Medic Officer Pilot Rifleman Rifleman Royal Commando Royal Guard Royal Marksman Sniper Squad Leader Team Leader Prisoner Spy Fliegerabwehrsoldat mit Stinger Panzerabwehrsoldat mit M136 Fahrzeugbesatzung Pionier Grenadier Soldat mit Maschinengewehr M240 Sanitätssoldat Offizier Pilot Soldat mit M16 A2 Soldat mit M16 A2 Königliches Kommando mit MP 5 SD Königliche Garde mit G36c Königlicher Scharfschütze mit G36a Scharfschütze mit M24 Zugführer Gruppenführer Gefangener Spion SoldierGAA SoldierGAT SoldierGCrew SoldierGMiner SoldierGG SoldierGMG SoldierGMedic Officer G SoldierGPilot SoldierGB SoldierGNOG SoldierGCommando SoldierGGuard SoldierGMarksman SoldierGSniper SquadLeader TeamLeader SoldierGCaptive SoldierSpy 78 ZIVILISTEN Einheiten, die hier mit N/A angegeben sind, sind im Editor selbst nicht verfügbar. Diese kann man, wie in Kapitel 5.45 erläutert, mit dem CreateVehicle-Befehl erzeugen. Einheit Beschreibung Civilian bis Civilian21 Nähere Beschreibung nicht erforderlich. Civilian Durchnummeriert von Civilian bis Civilian21 Klassenname Civilian Man Civilian Man King War Correspondent Bodyguard Prime Minister Reporter (Female) Reporter (Female) Reporter (Female) Reporter (Female) Zombie Zombie Zombie Zombie Prisoner 1 Prisoner 2 Prisoner 3 Prisoner 4 Prisoner 5 Prince (civil) Prince (Army) Prince (Partisan) Chancellor Adjutant (Uniform) Adjutant (Prisoner) Arms trader SLA President SLA President Zivilist mit roter Mütze Zivilist mit Rockershirt König Kriegsberichterstatter Leibwächter Premierminister Reporterin Reporterin Reporterin Reporterin Zombie Zombie Zombie Zombie Gefangener 1 Gefangener 2 Gefangener 3 Gefangener 4 Gefangener 5 Prinz(Zivil) Prinz(Armee) Prinz(Partisane) Kanzler Adjutant(Uniform) Adjutant(Gefangener) Waffenhändler SLA Präsident SLA Präsident Kapitel 3 D2_RCM03_Civilian1 D2_RCM03_Civilian2 King FieldReporter Anchorman NorthPrimeMinister MarianQuandt MarianQuandt02 MarianQuandt03 MarianQuandt04 Civil_Undead_1 Civil_Undead_2 Civil_Undead_3 Civil_Undead_4 Prisoner01 Prisoner02 Prisoner03 Prisoner04 Prisoner05 Prince_civil Prince_army Prince_resistance Chancellor AdjutantUniform AdjutantPrisoner ArmsTrader civil_nprem2 civil_nprem2_NoGeom INSEKTEN Typ Beschreibung Klassenname N/A N/A N/A N/A N/A N/A Möwe Libelle Hausfliege Honigbiene Mosquito Schmetterling Seagull Dragonfly HouseFly Honeybee Mosquito Butterfly 79 3.10 - Die Shellklassen Hier eine Auswahl von Shellklassen. Shells sind die Geschosse der einzelnen Waffen. Mit ihnen kann man die verschiedensten Dinge umsetzen. Zum Beispiel eine Explosion erzeugen oder anderen Beschuss simulieren. Diese könne ganz einfach, wie in Kapitel 5.45/5.46 erläutert mit dem CreateVehicle-Befehl erzeugt werden. Als Beispiel: Bombe="SH_125_HE" createVehicle [x,y,z] Bombe="SH_125_HE" createVehicle position Player B_9x18_Ball B_9x18_SD B_9x19_Ball B_9x19_SD B_127x108_Ball B_127x99_Ball_noTracer B_545x39_Ball B_545x39_SD B_556x45_Ball B_556x45_SD B_762x51_Ball B_762x54_Ball R_Hydra_HE R_57mm_HE R_80mm_HE R_M136_AT R_PG7V_AT R_KSVK R_PG7VR_AT M_Javelin_AT M_Stinger_AA M_Strela_AA M_AT5_AT´ Klassenname FxExploGround1 FxExploGround2 FxExploArmor1 FxExploArmor2 FxExploArmor3 FxExploArmor4 FxCartridge Bomb LaserTargetW LaserTargetE LaserTargetC 80 Geschosstypen B_762x54_noTracer B_77x56_Ball B_127x99_Ball B_127x107_Ball B_145x115_AP B_20mm_AP B_20mm_AA B_23mm_AA B_25mm_HE B_30mm_AP B_30mm_HE B_30mmA10_AP Raketen- und Granattypen M_Sidewinder_AA M_TOW_AT M_Hellfire_AT M_Maverick_AT M_Vikhr_AT BO_GBU12_LGB SH_125_HE SH_120_HE SH_122_HE SH_105_HE G_40mm_HE_6G30 Sonstiges Bezeichnung Steinbrocken Steinbrocken Splitter Splitter Splitter Splitter Patronenhülse Sprengkopf (benötigt setDamage-Befehl) Laser Ziel West Laser Ziel Osten Laser Ziel Zivil 3.11 - Die Objekt- und Gebäudeklassen Hier eine Auflistung verschiedener Objekte, welche man direkt oder auch nicht direkt im Editor setzen kann. Diese Objekte lassen sich nun ganz einfach per CreateVehicle-Befehl, wie in Kapitel 5.45 erläutert, an einer beliebigen Position auf der Karte erzeugen. Beschreibung Klassenname A Camp Bmp2 Wreck Barrels Barrel (red) Barrel (brown) Barrel (yellow) Barrel (green rosty) Barrel (green rosty) Barrel (white purple) Body Blackhawk Wreck Camera Camp Camp Empty Camp East Camp East C Computer Danger DangerWest DangerGUE DangerEAST Datsun Wreck 1 Datsun Wreck 2 Fence Fire FireLit FlagCarrierWest FlagCarrierNorth FlagCarrierSouth Fortress1 Fortress2 FenceWood FenceWoodPalet JeepWreck1 JeepWreck2 JeepWreck3 Grave GraveCross1 GraveCross2 Grave CrossHelmet Heli Heli-H Empty Heli-H Civil Heli-H Rescue Hilux Wreck Land_ladder Land Radar Obstacle Training Training 2 Training 3 Carousel Zelt (klein) Bmp2 Wrack Fässer Fass rot Fass brown Fass gelb Fass grün rostig Fass grün rostig Fass weiß-lila Leiche Hubschrauber Wrack Kamera auf Dreibein Zelt (offen) Zelt (offen) Zelt Ost (offen) Zelt Ost (offen) Computer Warnschild Warnschild Westen Warnschild Unabhängig (RACS) Warnschild Ost (SLA) Jeepwrack (Zivil) Jeepwrack (Zivil) Ecksandsack Feuer Feuer (angezündet) Fahnenmast WEST Fahnenmast OST (SLA) Fahnenmast Unabhängig (RACS) Festung 1 (klein) Festung 2 (groß) Sandsackmauer Sandsackmauer mit Palette Jeep Wrack 1 Jeep Wrack 2 Jeep Wrack 3 Grabhügel Grab mit Kreuz Grab mit Kreuz Grab mit Kreuz u. Helm Heli-H Heli-H Unsichtbar Heli-HZivil Heli-H Rettung Jeep Wrack (Zivil) Leiter Radar Hindernis Übung Übung 2 Übung 3 Karussell ACamp Bmp2Wreck Barrels Barrel1 Barrel2 Barrel3 Barrel4 Barrel5 Barrel6 Body BlackhawkWreck Camera1 Camp CampEmpty CampEast CampEastC Computer Danger DangerWest DangerGUE DangerEAST Datsun01Wreck Datsun02Wreck Fence Fire FireLit FlagCarrierWest FlagCarrierNorth FlagCarrierSouth Fortress1 Fortress2 FenceWood FenceWoodPalet JeepWreck1 JeepWreck2 JeepWreck3 Grave GraveCross1 GraveCross2 GraveCrossHelmet Heli HeliHEmpty Heli_H_Civil Heli_H_rescue HiluxWreck Land_ladder Land_radar Land_obihacka Land_podlejzacka Land_prolejzacka Land_prebehlavka Land_kolotoc Kapitel 3 Typ 81 Typ Beschreibung Klassenname Carousel small Swing Prolezacka SandPit Obstakle Fuel Tank Small Fuel Tank Big Fuel Tank Letter Land Water Tank Land Water Tank MASH M113 Wreck Paleta1 Paleta2 Radio Shed Shed Small Shed Big TargetE TargetEpopup Wood tank TV Studio TV Studio (Building) TV Radio Tower TV Radio Tower Gangway Ural Wreck Bale Of Straw Closet Vysilacka Wall Map RahmadiMap Sleeping Bag Wire Wire Fence Barrier AmmoBoxWest SpecialBoxWest WeaponBoxWest AmmoBoxEast SpecialBoxEast WeaponBoxEast AmmoBoxGuer SpecialBoxGuer WeaponBoxGuer Little Church Big Church Middle Church Mexican Church Church House House House House House House House House House House Kleines Karussell Swing Klettergerüst Sandkasten 3-Bein Hindernis Kleiner Treibstofftank Großer Treibstofftank Großer Treibstofftank mit Leiter Wassertank Wassertank Feldlazarett M113 Wrack Palette Paletten Radio Tarnnetz (klein) Tarnnetz (groß) Unterstand (groß) Zielscheibendummy Zielscheibendummy (Popup) Holzpanzer Fernsehstudio Fernsehstudio (Gebäude) TV-Sendeturm TV-Sendeturmverbindung Ural Wrack Strohballen Dixiklo Funkgerät Landkarte Landkarte Rahmadi Schlafsack Stacheldraht Drahtzaun Schranke Munitionskiste West Gemischte Kiste West Waffenkiste West Munitionskiste Ost Gemischte Kiste Ost Waffenkiste Ost Munitionskiste Racs Gemischte Kiste Racs Waffenkiste Racs Kleine Kirche Große Kirche Mittlere Kirche Kirche (mexikanisch) Kapelle Hafenhaus Hafenhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus (begehbar) Land_maly_kolotoc Land_houpacka Land_kulata_prolezacka Land_Piskoviste Land_jezekbeton Land_fuel_tank_small Land_fuel_tank_big Land_fuel_tank_stairs Land_water_tank Land_water_tank2 MASH M113Wreck Paleta1 Paleta2 Radio Shed ShedSmall ShedBig TargetE TargetEpopup TargetGrenade TVStudio Land_Vysilac_budova Land_Vysilac_vez Land_Vysilac_chodba UralWreck Vec03 Land_Toilet Vysilacka WallMap RahmadiMap Land_SleepingBag Wire WireFence ZavoraAnim AmmoBoxWest SpecialBoxWest WeaponBoxWest AmmoBoxEast SpecialBoxEast WeaponBoxEast AmmoBoxGuer SpecialBoxGuer WeaponBoxGuer Land_kostel Land_kostel2 Land_kostel3 Land_kostel_mexico Land_kostelik Land_sara_domek01 Land_sara_domek02 Land_sara_domek05 Land_sara_zluty_statek_in Land_sara_Domek_sedy Land_dum_mesto2 Land_sara_domek_sedy_bez Land_sara_domek_rosa Land_sara_zluty_statek Land_sara_domek_zluty 82 Beschreibung Klassenname House House Houseblock (small) Houseblock (middle) Houseblock (big) Hotel Hotelruin Holiday-In Holiday-In Holiday-In-Ruin Holiday-In-Ruin Weekend Flat House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental/Open) House (Oriental/Open) House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental/Open) House (Oriental) House (Oriental) House (Oriental) House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) House House House House House House House House (Classic) Little House Old House Red House Red House Red House City House (yellow) House House House House House House House House House House Houseblock (small) Houseblock (middle) Wohnhaus Wohnhaus Wohnblock (klein) Wohnblock (mittel) Wohnblock (groß) Hotel Hotelruine Ferienanlage Ferienanlage Ferienanlagenschutthaufen Ferienanlagenschutthaufen Wochenendhaus Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch/begehbar) Haus (orientalisch /begehbar) Haus (orientalisch) Wohnanlage (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch/begehbar) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Haus Haus Haus Haus Haus Haus Haus Haus (klassisch) Kleines Haus Altes Haus Backsteinhaus Backsteinhaus Backsteinhaus Stadthaus (gelb) Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus Wohnhaus (begehbar) Wohnhaus Wohnhaus Wohnblock (klein) Wohnblock (mittel) Land_sara_domek_zluty_bez Land_OrlHot Land_Panelak Land_Panelak2 Land_Panelak3 Land_Hotel Land_Hotel_ruins Land_hotel_riviera1 Land_hotel_riviera2 Land_hotel_riviera1_ruins Land_hotel_riviera2_ruins Land_house_y Land_dum_olez_istan1 Land_dum_olez_istan2 Land_dum_olez_istan2_maly Land_dum_olez_istan2_maly2 Land_dum_istan2 Land_dum_istan2b Land_dum_istan2_01 Land_dum_istan2_02 Land_dum_istan2_03 Land_dum_istan2_03a Land_dum_istan2_04a Land_dum_istan3 Land_dum_istan3_hromada Land_dum_istan3_hromada2 Land_dum_istan3_pumpa Land_dum_mesto3_istan Land_dum_istan4 Land_dum_istan4_big Land_dum_istan4_big_inverse Land_dum_istan4_detaily1 Land_dum_istan4_inverse Land_dumruina Land_dumruina_mini Land_sara_domek_kovarna Land_dum_rasovna Land_Statek_kulna Land_stanice Land_ryb_domek Land_statek_hl_bud Land_bouda1 Land_sara_domek_ruina Land_cihlovej_dum Land_cihlovej_dum_in Land_cihlovej_dum_mini Land_kasarna_rohova Land_sara_domek05 Land_sara_zluty_statek_in Land_sara_Domek_sedy Land_dum_mesto2 Land_sara_domek_sedy_bez Land_sara_domek_rosa Land_sara_zluty_statek Land_sara_domek_zluty Land_sara_domek_zluty_bez Land_OrlHot Land_Panelak Land_Panelak2 Kapitel 3 Typ 83 Typ Beschreibung Klassenname Houseblock (big) Hotel Hotelruin Holiday-In Holiday-In Holiday-In-Ruin Holiday-In-Ruin Weekend Flat House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental/Open) House (Oriental/Open) House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental) House (Oriental/Open) House (Oriental) House (Oriental) House (Oriental) House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) Tall House (Oriental) House House House House House House House House (Classic) Little House Old House Red House Red House Red House City House (yellow) City House (yellow) City House (yellow) City House (yellow) Pub Building Landhouse Landhouse Landhouse Landhouse City House (Classic) City House (Classic) House with House House (long) House (flat) Big House Wohnblock (groß) Hotel Hotelruine Ferienanlage Ferienanlage Ferienanlagenschutthaufen Ferienanlagenschutthaufen Wochenendhaus Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch/begehbar) Haus (orientalisch /begehbar) Haus (orientalisch) Wohnanlage (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch/begehbar) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Haus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Hochhaus (orientalisch) Haus Haus Haus Haus Haus Haus Haus Haus (klassisch) Kleines Haus Altes Haus Backsteinhaus Backsteinhaus Backsteinhaus Stadthaus (gelb) Stadthaus (gelb) Stadthaus (gelb) Stadthaus (gelb) Gaststätte Amtsgebäude Landhaus Landhaus Landhaus Landhaus Stadthaus (klassisch) Stadthaus (klassisch) Eckhaus Haus mit Tor Haus (lang) Haus (flach) Großes Haus Land_Panelak3 Land_Hotel Land_Hotel_ruins Land_hotel_riviera1 Land_hotel_riviera2 Land_hotel_riviera1_ruins Land_hotel_riviera2_ruins Land_house_y Land_dum_olez_istan1 Land_dum_olez_istan2 Land_dum_olez_istan2_maly Land_dum_olez_istan2_maly2 Land_dum_istan2 Land_dum_istan2b Land_dum_istan2_01 Land_dum_istan2_02 Land_dum_istan2_03 Land_dum_istan2_03a Land_dum_istan2_04a Land_dum_istan3 Land_dum_istan3_hromada Land_dum_istan3_hromada2 Land_dum_istan3_pumpa Land_dum_mesto3_istan Land_dum_istan4 Land_dum_istan4_big Land_dum_istan4_big_inverse Land_dum_istan4_detaily1 Land_dum_istan4_inverse Land_dumruina Land_dumruina_mini Land_sara_domek_kovarna Land_dum_rasovna Land_Statek_kulna Land_stanice Land_ryb_domek Land_statek_hl_bud Land_bouda1 Land_sara_domek_ruina Land_cihlovej_dum Land_cihlovej_dum_in Land_cihlovej_dum_mini Land_kasarna_rohova Land_kasarna_brana Land_kasarna Land_kasarna_prujezd Land_hospoda_mesto Land_skola Land_deutshe Land_deutshe_mini Land_domek_rosa Land_dum_m2 Land_dum_mesto Land_dum_mesto_in Land_dum_mesto2l Land_dum_mesto3 Land_dum_olezlina Land_dum01 Land_dum02 84 Beschreibung Klassenname House with House with Villa Convent Building (Corner) Convent Building Garage Garage Garage Beach Hut Beach Hut Beach Hut (open) Beach Hut Beach Hut Holiday Hut Little Hut Little Shanty Shelter (little) Shanty Latrine Big Barn (closed) Big Barn (open) Barn Barn (open) Barn (Closed) Barn (open) Old Barn Building (burned) Houseruin (burned) Houseruin (burned) Houseruin (burned) Pubruin (burned) Houseruin Houseruin Houseruin Houseruin (open) Churchruin Bus Stop Bus Stop 2 Market Stall Market Stall 1 Market Stall 2 Military Shelter Military Building (open) Military Building (little) Military Building (open) Military Building (closed) Military Building (open) Bus Stop Ammunition Bunker Ammunition Bunker Ammunition Bunker Metal Tower Wood Tower Metal Tower Airport Tower Military Building Military Building Military Building Military Building Haus mit Vordach Haus mit Vordach Villa Klostergebäude (Eckhaus) Klostergebäude Garage ohne Tor Garage (lang) Garage (kurz) Strandhütte Strandhütte Strandhütte (offene Seiten) Strandhütte Strandhütte Ferienhütte Hundehütte Kleine Holzhütte Schuppen (mini) Holzschuppen Latrine Große Scheune (geschlossen) Große Scheune (begehbar) Scheune Holzscheune (begehbar) Holzscheune (offene Seiten) Holzscheune (geschlossen) Alte Scheune (begehbar) Wohnblock (abgebrannt) Hausruine (abgebrannt) Hausruine (abgebrannt) Hausruine (abgebrannt) Gaststätte (abgebrannt) Hausruine Hausruine Hausruine Hausruine (begehbar) Kirchenruine Bushaltestelle Bushaltestelle2 Marktstand Marktstand 1 Marktstand 3 Unterstand (Garagenart) Militärunterkunft (begehbar) Militärgebäude (klein) Militärgebäude (begehbar) Militärgebäude (geschlossen) Militärgebäude (begehbar) Bushaltestelle Munitionsbunker (offen) Munitionsbunker Munitionsbunker Metallwachturm (groß) Holzwachturm (groß/Dach) Wachturm (klein/Dach) Flugplatztower Kasernengebäude Kasernengebäude Kasernengebäude Kasernengebäude Land_sara_domek_hospoda Land_sara_domek_podhradi_1 Land_sara_domek_vilka Land_sara_dum_podloubi03klaster Land_sara_dum_podloubi03rovny Land_sara_hasic_zbroj Land_garaz Land_garaz_mala Land_hut01 Land_hut02 Land_hut03 Land_hut04 Land_hut06 Land_ZalChata Land_psi_bouda Land_bouda2_vnitrek Land_kulna Land_bouda3 Land_KBud Land_stodola_old Land_stodola_old_open Land_strazni_vez Land_sara_stodola Land_sara_stodola2 Land_sara_stodola3 Land_hut_old02 Land_afbarabizna Land_afdum_mesto2 Land_afdum_mesto2L Land_afdum_mesto3 Land_afhospoda_mesto Land_dulni_bs Land_dum_zboreny Land_dum_zboreny_total Land_hruzdum Land_kostel_trosky Land_zastavka_jih Land_zastavka_sever Land_stanek_1 Land_stanek_1B Land_stanek_1C Land_army_hut_storrage Land_army_hut_int Land_army_hut2 Land_army_hut2_int Land_army_hut3_long Land_army_hut3_long_int Land_aut_zast Land_garaz_s_tankem Land_garaz_bez_tanku Land_ammostore2 Land_hlaska Land_posed Land_vez Land_letistni_hala Land_budova1 Land_budova2 Land_budova3 Land_budova4 Kapitel 3 Typ 85 Typ Beschreibung Klassenname Military Building Guardhouse Military Hospital Repair Center Hangar (green) Hangar (grey) Hangar Hangar ruin Fuelstop (small) Fuelstop (small) Fuelstop (big) Fuelstop (Military) Factory Factory Tall Tower Metall Hut Little Metal Hut Glass Tower Transformer Station Transformer Station Radiotower Radiotower Radiotower Water Tower Silo Lighthouse Lighthouse Lighthouse with podest Lighthousepodest Harbour piece Harbour piece Harbour piece Bridge with roof Bridge Bridge (end) Fence Fencegate Wall Stonegate Archway Archway Stonefence Woodfence Basefence (camo) Basefence (grey) Basefence (Desert) Stoplight Stoplight 2 Landfield light Landfield light Landfield light Landfield light Power supply line Electricity pylon Power supply line Power supply line Ladder (big) Scaffold Scaffold Kasernengebäude Wachhäuschen Kasernenhospital Werkstatt Hangar (grün) Hangar (grau) Lagerhalle (Hangar) Hangarschutthaufen Tankstelle (klein) Tankstelle (klein) Tankstelle (groß) Tankstelle (Militär) Fabrikgebäude Fabrikgebäude Hoher Schornstein Metallbude (Kontrollposten) Kleine Blechhütte Glas Aussichtsturm Trafostation Trafostation Sendeturm Sendeturm Sendeturm (groß) Wasserturm Hochsilo Leuchturm Leuchturm Leuchturm mit Podest Leuchturmpodest Hafenanlage Hafenanlage Hafenanlage Steg (überdacht) Steg Steg (Endstück) Zaun Zauntor (Stein) Mauer mit Loch Steintor Torbogen mit Tor Torbogen ohne Tor Steinzaun (kaputt) Holzzaun (kaputt) Kasernenzaun (tarn) Kasernenzaun (grau) Kasernenzaun (Wüste) Ampel Ampel 2 Landebahnbeleuchtung Landebahnbeleuchtung Landebahnbeleuchtung Landebahnbeleuchtung Stromleitung (Trafostation) Strommast (groß) Stromleitung Stromleitung Leiter (groß) Gerüst Gerüst Land_budova4_in Land_budova5 Land_hospital Land_repair_center Land_SS_hangar Land_SS_hangarD Land_hangar_2 Land_SS_hangar_ruins FuelStation Land_fuelstation Land_benzina_schnell Land_fuelstation_army Land_Tovarna1 Land_Tovarna2 Land_komin Land_Hlidac_budka Land_bouda_plech Land_strazni_vez Land_trafostanica_velka Land_trafostanica_mala Land_Vysilac_FM Land_vysilac_FM2 Land_telek1 Land_watertower1 Land_Nasypka Land_majak Land_majak2 Land_majak_v_celku Land_majak_podesta Land_molo_beton Land_molo_krychle Land_molo_krychle2 Land_molo_drevo Land_molo_drevo_bs Land_molo_drevo_end Land_pletivo_dira Land_plot_zed_drevo1_branka Land_plot_istan1b_hole Land_plot_istan1_rovny_gate Land_brana02 Land_brana02nodoor Land_plot_zboreny Land_Plot_Ohrada_Pruchozi Land_zed_dira Land_zed_dira_desert Land_zed_dira_civil Land_Stoplight01 Land_Stoplight02 Land_Runway_PAPI Land_Runway_PAPI_2 Land_Runway_PAPI_3 Land_Runway_PAPI_4 Land_trafostanica_velka_draty Land_sloup_vn Land_sloup_vn_dratZ Land_sloup_vn_drat Land_ladder Land_leseni2x Land_leseni4x 86 Beschreibung Klassenname Castletower Castlewall Castlewall Castlewall Castlewall Wall with door Wall ruin Wall ruin Wall with gate (closed) Wall with gate (open) Fountain Oil pump Citywall Citywall Citywall Citywall Citywall Citywall Citywall Citywall Citywall Citywall Citywall Stoned area Stoned area Scrapheap Scrapheap Scrapheap Minaret Old Silo Bam - Sawmill Old Silo Bam - Sawmill Big Carport Big Carport with camo net Tower with searchlight Camouflaged water tower Aircraft Factory Aircraft Factory (West) Aircraft Factory (SLA) Airport Barracks Barracks (West) Barracks (East) Camp Contruction Site (West) Contruction Site (West) Contruction Site (East) Contruction Site (East) Crate Depot Headquarters (West) Headquarters (East) HeavyFactory HeavyFactory (West) HeavyFactory (East) LightFactory LightFactory (West) LightFactory (East) Mobile HQ (West) M113 Mobile HQ (East) BMP2 Burgturm Burgmauer Burgmauer Burgmauer Burgmauer Mauer mit Durchgang Mauerruine Mauerruine Mauer mit Tor (geschlossen) Mauer mit Tor (offen) Brunnen (Handpumpe) Ölpumpe Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Podest) Stadtmauer (Treppen) Stadtmauer (Treppen) Stadtmauer (Treppen) Stadtmauer (Treppen) Gepflasterte Fläche Gepflasterte Fläche Schutthaufen Schutthaufen Schutthaufen Minarett Alte Siloscheune - Sägewerk Alte Siloscheune - Sägewerk Großes Carport Großes Carport (Tarnnetz) Wachturm mit Scheinwerfern Getarnter Wasserturm Flugzeug Fabrik Flugzeug Fabrik (Westen) Flugzeug Fabrik (Osten) Hangar Zelt mit Sandsäcken Zelt mit Sandsäcken (Westen) Zelt mit Sandsäcken (Osten) Sandsackstellung Container (Westen) Container (Westen) Container (Osten) Container (Osten) Holzkiste Großer Sandsackbunker (2-Stock) Hauptquartier (Westen) Hauptquartier (Osten) Große Fabrik Große Fabrik (Westen) Große Fabrik (Osten) Kleine Fabrik Kleine Fabrik (Westen) Kleine Fabrik (Osten) Mobiles Hauptquartier (Westen) Mobiles Hauptquartier (Osten) Land_helfenburk Land_helfenburk_brana Land_helfenburk_budova2 Land_helfenburk_cimburi Land_helfenburk_zed Land_zidka_branka Wallend Land_zidka03 Land_statek_brana Land_statek_brana_open Land_pumpa Land_vez_ropa Land_podesta_1_cube Land_podesta_1_cube_long Land_podesta_1_cornl Land_podesta_1_cornp Land_podesta_1_mid_cornl Land_podesta_1_mid_cornp Land_podesta_1_mid Land_podesta_1_stairs Land_podesta_1_stairs2 Land_podesta_1_stairs3 Land_podesta_1_stairs4 Land_podesta_5 Land_podesta_10 Land_AFbarabizna_ruins Land_AFDum_mesto2_ruins Land_AFDum_mesto2L_ruins Land_R_Minaret Land_Kamenolom_budova Land_pila Land_pristresek Land_pristresek_camo Land_Vez_svetla Land_vodni_vez WarfareBAircraftFactory WarfareBWestAircraftFactory WarfareBEastAircraftFactory WarfareBAirport WarfareBBarracks WarfareBWestBarracks WarfareBEastBarracks WarfareBCamp WarfareBWestContructionSite WarfareBWestContructionSite1 WarfareBEastContructionSite WarfareBEastContructionSite1 WarfareBCrate WarfareBDepot WarfareBWestHeadquarters WarfareBEastHeadquarters WarfareBHeavyFactory WarfareBWestHeavyFactory WarfareBEastHeavyFactory WarfareBLightFactory WarfareBWestLightFactory WarfareBEastLightFactory M113_MHQ_unfolded BMP2_MHQ_unfolded Kapitel 3 Typ 87 Typ Beschreibung Klassenname Hesco Site Hesco 5x Hesco 10x Hesco 10x Tall Sandbag Site Nest Low Nest MG Nest M240 (West) MG Nest PK (SLA) MG Nest_M240 (Resistance) MG Static M2 (Resistance) Sandsackmauer Kleine Sandsackmauer Große Sandsackmauer Hohe Sandsackmauer Sandsackmauer Kleines Schützennest (knien) Kleines Schützennest (liegen) Schützennest mit M240 (Westen) Schützennest mit PK (Osten) Schützennest mit M240 (Widerstand) Maschinengewehr M2 (Widerstand) WarfareBHescoSite WarfareBHesco5x WarfareBHesco10x WarfareBHesco10xTall WarfareBSandbagSite WarfareBNest WarfareBLowNest WarfareBWestMGNest_M240 WarfareBEastMGNest_PK WarfareBResistanceMGNest_M240 WarfareBResistanceM2StaticMG 3.12 - Die Pflanzenklassen Typ Beschreibung Klassenname Bare tree Banana tree Banana tree Banana tree Banana tree Thistles High grasses Cep Flowers Brake Desert grass Gras flowers Grass Long grass White flowers Grass Yellow flowers Mushroom Fly agaric Fly agaric Mushroom Flowers Grass White flowers Tall conifer Tall conifer Bush Bush Desert grass Mixed grass Tree Tree Leaves Small bush Middle bush small bush Mini bush Grass bush Double grass Baum (blattlos) Bananenbaum Bananenbaum Bananenbaum Bananenbaum Disteln Hohe Gräser Steinpilz Blumen Farne Wüstengras Grasblumen Gras Langes Gras Weiße Blumen Gras Gelbe Blumen Pilz Fliegenpilz Fliegenpilz Pilz Blumen Gras Weiße Grasblumen Hoher Nadelbaum Hoher Nadelbaum Busch Busch Wüstengras Gemischtes Gras Laubbaum Laubbaum Laub (liegend) Busch (klein) Busch (mittel) Busch (klein) Busch (mini) Grasbusch Doppelgras AAPL000 AAPL001 AAPL002 AAPL003 AAPL004 AAPL005 AAPL006 AAPL007 AAPL008 AAPL009 AAPL010 AAPL011 AAPL012 AAPL013 AAPL014 AAPL015 AAPL016 AAPL017 AAPL018 AAPL019 AAPL020 AAPL021 AAPL022 AAPL023 AAPL024 AAPL025 AAPL026 AAPL027 AAPL028 AAPL029 AAPL030 AAPL031 AAPL032 AAPL033 AAPL034 AAPL035 AAPL036 AAPL037 AAPL038 88 Beschreibung Klassenname Stocks of a trees Stocks of a trees Stock of a tree Grass Middle bush Tall bush Long bush Small bush Long bush Big tree Big tree Big tree Middle tree Tall conifer Tall conifer Big leave grass Bush tree Middle palm tree Middle palm tree Middle palm tree Middle palm tree Double palm tree Palm bush Tall palm tree Middle palm tree Tree stump Tree stump Conifer bush Small conifer Broad conifer Tall conifer Birch tree Tree Tree Tree Small tree Middle decoration tree Small tree Small tree Tree Small tree Tree Small tree Small bush Willow Birch tree Birch tree Bush tree Tree Bush tree Small bush Tall decoration tree Avenue tree Avenue tree Branchwood Branchwood Branchwood Branchwood Holzstämme (liegend) Holzstämme (liegend) Holzstamm (liegend) Gräserbüschel Busch (mittel) Busch (hoch) Busch (lang) Busch (klein) Busch (lang) Laubbaum (groß) Laubbaum (groß) Laubbaum (groß) Laubbaum (mittel) Nadelbaum (hoch) Nadelbaum (hoch) Großblattgras Buschartiger Baum Palme (mittel) Palme (mittel) Palme (mittel) Palme (mittel) Doppelpalme Palmenbusch Palme (groß) Palme (mittel) Baumstumpf Baumstumpf Nadelbusch Nadelbaum (klein) Nadelbaum (breit) Nadelbaum (groß) Birke Laubbaum Laubbaum Laubbaum Laubbaum (schmal) Zierbaum (mittel) Laubbaum (klein) Laubbaum (schmal) Laubbaum Laubbaum (schmal) Laubbaum Laubbaum (klein) Busch (schmal) Weide Birke Birke Buschbaum Laubbaum Buschbaum Busch (schmal) Zierbaum (groß) Alleebaum Alleebaum Geäst (liegend) Geäst (liegend) Geäst (liegend) Geäst (liegend) AAPL039 AAPL040 AAPL041 AAPL042 AAPL043 AAPL044 AAPL045 AAPL046 AAPL047 AAPL048 AAPL049 AAPL050 AAPL051 AAPL052 AAPL053 AAPL054 AAPL055 AAPL056 AAPL057 AAPL058 AAPL059 AAPL060 AAPL061 AAPL062 AAPL063 AAPL064 AAPL065 AAPL066 AAPL067 AAPL068 AAPL069 AAPL070 AAPL071 AAPL072 AAPL073 AAPL074 AAPL075 AAPL076 AAPL077 AAPL078 AAPL079 AAPL080 AAPL081 AAPL082 AAPL083 AAPL084 AAPL085 AAPL086 AAPL087 AAPL088 AAPL089 AAPL090 AAPL091 AAPL092 AAPL093 AAPL094 AAPL095 AAPL096 Kapitel 3 Typ 89 3.13 - Die Steinklassen Typ Beschreibung Klassenname Clutter Stone Small Granite stone Sandstone (big) Sandstone (big) Limestone (big) Limestone (big) Sandstone (big) Limestone (middle) Limestone (middle) Sandstone (big) Limestone (middle) Limestone (middle) Sandstone (middle) Limestone (middle) Limestone (middle) Sandstone (middle) Limestone (middle) Limestone (middle) Sandstone (little) Granite stones Granite stones Limestone rock (little) Limestone rock (big) Limestone rock (big) Limestone rock (big) Limestone rock (big) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (middle) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (middle) Sandstone (middle) Sandstone (middle) Sandstone (middle) Sandstone (middle) Limestone rock (big) Limestone rock (big) Sandstone (little) Limestone (middle) Sandstone (little) Sandstone (little) Sandstone (little) Sandstone (little) Kieselsteine Granitstein Sandstein (groß) Sandstein (groß) Kalkstein (groß) Kalkstein (groß) Sandstein (mittel) Kalkstein (mittel) Kalkstein (mittel) Sandstein (mittel) Kalkstein (mittel) Kalkstein (mittel) Sandstein (mittel) Kalkstein (mittel) Kalkstein (mittel) Sandstein (mittel) Kalkstein (mittel) Kalkstein (mittel) Sandstein (klein) Granitsteine Granitsteine Kalkstein Felsen (klein) Kalkstein Felsen (groß) Kalkstein Felsen (groß) Kalkstein Felsen (groß) Kalkstein Felsen (groß) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (mittel) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) Sandstein (mittel) Sandstein (mittel) Sandstein (mittel) Sandstein (mittel) Sandstein (mittel) Kalkstein Felsen (groß) Kalkstein Felsen (groß) Sandstein (klein) Kalkstein (klein) Sandsteine (klein) Sandstein (klein) Sandstein (klein) Sandstein (klein) AARO000 AARO001 AARO002 AARO003 AARO004 AARO005 AARO006 AARO007 AARO008 AARO009 AARO010 AARO011 AARO012 AARO013 AARO014 AARO015 AARO016 AARO017 AARO018 AARO019 AARO020 AARO021 AARO022 AARO023 AARO024 AARO025 AARO026 AARO027 AARO028 AARO029 AARO030 AARO031 AARO032 AARO033 AARO034 AARO035 AARO036 AARO037 AARO038 AARO039 AARO040 AARO041 AARO042 AARO043 AARO044 AARO045 AARO046 AARO047 AARO048 AARO049 AARO050 90 3.14 - Die Schilderklassen Beschreibung Klassenname Cyclist ahead! Walkers ahead! Walkers ahead! (old) Double bend L ahead! (old) Double bend L ahead! Double bend R ahead! (old) Double bend R ahead! Right of Way (old) Right of Way End (old) Right of Way End Right of Way Military Sign (SLA/RACS) Military Sign (SLA) Military Sign (RACS) Picnic area Camping ground Not attached curb ahead! Rustle shoot ahead! (old) Rustle shoot ahead! Cross-way ahead! (old) Right of way ahead! (old) Right of way ahead! Cross-way ahead! Air traffic ahead! (old) Air traffic ahead! Ahead! First aid (old) First aid Gravel ahead! Roadway repair service (old) Roadway repair service Rockfall ahead (old) Rockfall ahead Parking place (old) Parking place Ahead! Direction panel L Direction panel R Road works ahead! Crosswalk ahead! Right of way ahead! (old) Right of way ahead! Gas station (old) Gas station Straightforward RoadCone RoadBarrierlong RampConcrete Achtung Fahrradfahrer! Achtung Fussgänger! Achtung Fussgänger! (alt) Achtung S-Kurve L! (alt) Achtung S-Kurve L! Achtung S-Kurve R! (alt) Achtung S-Kurve R! Vorfahrt (alt) Vorfahrt Ende (alt) Vorfahrt Ende Vorfahrt Militärschild (SLA/RACS) Militärschild (SLA) Militärschild (RACS) Rastplatz Campingplatz Achtung nicht befestigter Seitenstreifen! Achtung Viehaustrieb! (alt) Achtung Viehaustrieb! Achtung Kreuzung! (alt) Achtung Vorfahrts-Kreuzung! (alt) Achtung Vorfahrts-Kreuzung! Achtung Kreuzung! Achtung Flugverkehr! (alt) Achtung Flugverkehr! Achtung! Erste Hilfe (alt) Erste Hilfe Achtung Schotter! Pannenhilfe (alt) Pannenhilfe Achtung Steinschlag (alt) Achtung Steinschlag Parkplatz (alt) Parkplatz Gefahrenstelle! Richtungstafel L Richtungstafel R Achtung Baustelle! Achtung Fussgängerüberweg! Vorfahrt achten! (alt) Vorfahrt achten! Tankstelle (alt) Tankstelle Geradeaus Straßenhütchen Straßensperre Rampe AASI012 AASI015 AASI016 AASI019 AASI020 AASI021 AASI022 AASI025 AASI026 AASI027 AASI028 AASI169 AASI181 AASI186 AASI189 AASI190 AASI195 AASI196 AASI197 AASI198 AASI199 AASI200 AASI201 AASI204 AASI205 AASI259 AASI260 AASI261 AASI268 AASI273 AASI274 AASI275 AASI276 AASI277 AASI278 AASI283 AASI284 AASI285 AASI286 AASI287 AASI288 AASI289 AASI290 AASI291 AASI292 RoadCone RoadBarrier_long RampConcrete Kapitel 3 Typ 91 3.15 - Waffen- und Magazintypen ausgeben lassen Mit folgend erläuterter Syntax hat man die Möglichkeit sich die Waffen- und Magazintypen einer Einheit in Form einer Texteinblendung ausgeben zu lassen. Dabei verwendet man für das Ausgeben der Waffentypen: hint format ["%1", weapons this]; hint format ["%1", weapons Name]; und für das Ausgeben der Magazintypen: hint format ["%1", magazines this]; 3.16 - Abgefeuerten Typ ausgeben lassen Neben dem Ausgeben von Waffen- und Magazintypen, hat man natürlich noch die Möglichkeit sich ausgeben zu lassen, welche Einheit gerade mit was geschossen hat. Dabei werden folgende Daten anhand einer Texteinblendung ausgegeben: Name der Einheit Der Waffentyp Der Geschosstyp Die Schussart (Single/Burst) Nachdem die Einheit Name im Spiel die Waffe abfeuert, blendet dieser Text ein: Dazu macht man sich einen Eventhandler zu Nutze, mit welchem die Syntax in der Initzeile einer Einheit, wie im folgenden Beispiel, angelegt wird: this addEventHandler ["Fired", {hint format ["%1", _this]}] Das Ganze geht natürlich auch namenbezogen für externe Aktionen: Name addEventHandler ["Fired", {hint format ["%1", _this]}] 3.17 - Hat Einheit Waffe? Manche Situationen erfordern das Prüfen, ob eine bestimmte Einheit eine bestimmte Waffe hat. Dies kann man dann unter anderem als Bedingung oder ähnliches verwenden. Dazu wird folgende Syntax verwendet: Player hasWeapon "M4" 92 bzw. im Skript ? Player hasWeapon "M4" Als kleines Beispiel nun nochmal zwei Beispiel Syntaxes: ?! (Player hasWeapon "M4") : hint "Der Spieler hat sein M4 verloren!" ? (Player hasWeapon "M4") : hint "Der Spieler hat sein M4 wieder!" Bei der ersten Syntax kommt nun eine Meldung, dass der Spieler sein M4 verloren hat und bei der zweiten eine Meldung, dass er sein M4 zurück hat. Auch die Primärwaffe einer Einheit lässt sich jederzeit Abfragen oder auch als Bedingung für etwas verwenden. Von der Sache her, lassen sich nun die gleichen Dinge, wie auch schon mit dem hasWeapon-Befehl realisieren. Hierzu wieder mal ein paar Beispiele. Primär- oder Sekundärwaffe ausgeben lassen: hint format ["%1", primaryWeapon Player]; hint format ["%1", secondaryWeapon Player]; Primär- oder Sekundärwaffe als Bedingung: ? (primaryWeapon Player != "M4") : hint "Der Spieler hat kein M4!" ? (primaryWeapon Player == "M4") : hint "Der Spieler hat ein M4 !" ? (secondaryWeapon Player != "Stinger") : hint "Der Spieler hat keine Stinger!" 3.19 - Hat Einheit Munition? Die folgende Syntax gibt wieder, ob der Spieler noch Munition hat. Hat er kein Magazin mehr, wird die Variable auf true gesetzt. Dies kann man nun unter anderem als Bedingung für etwas verwenden. ?!(someAmmo Player) : hint "Der Spieler hat keine Munition mehr!" ?(someAmmo Player) : hint "Der Spieler hat noch Munition!" hint format ["%1", someAmmo Player]; Dieser Befehl verbietet einer Einheit das Nachladen der Waffe, wenn das Magazin leer ist. Name enableReload false 3.20 - Mine erzeugen Mit folgend aufgeführter Syntaxform lassen sich Minen ganz einfach an einer jeweilig gewünschten Position erzeugen. Mine = createMine ["MineMine", position player, [], 0] 93 Kapitel 3 3.18 - Primär- bzw. Sekundärwaffe einer Einheit 3.21 - Waffen und Magazine erzeugen Waffen und Magazine lassen sich nicht so ohne Weiteres erzeugen. Dazu benötigt man den Weaponholder-Befehl. Ein Weaponholder ist vergleichbar mit einer Waffenkiste, nur mit dem Unterschied, dass der Weaponholder unsichtbar ist. Diesen kann man nun mit dem gleichen Befehl, wie auch bei den Waffenkisten, mit Waffen und Magazinen versehen. Nach dem Erzeugen liegen die Waffen dann frei auf dem Boden und können vom Spieler aufgenommen werden. An welcher Position diese Waffen erzeugt werden soll, kann man nun frei entscheiden. Also beispielsweise an an der XYZ-Position oder auch an der Position eines Objectes. Folgend mal ein paar Beispiele: Waffe1 = "WeaponHolder" createVehicle getpos Obj1 Waffe1 = "WeaponHolder" createVehicle position Player Waffe1 = "WeaponHolder" createVehicle [x,y,z] Nachdem man nun seinen Weaponholder erzeugt hat, weist man ihm die Waffen und Magazine zu. Dies macht man ganz normal mit den AddCargo-Befehlen. Waffe1 addMagazineCargo ["10Rnd_127x99_M107",2]; Waffe1 addWeaponCargo ["M107",1]; Natürlich kann man seinen Weaponholder auch ausrichten oder in der Höhe versetzen. Zum Beispiel, wenn man die Waffe auf einen Tisch oder ähnliches legen möchte. Um die Waffe auszurichten benutzt man die normale SetDir-Syntax: Waffe1 setDir Wert Und wie erwartet, gilt für die Höhe die altbekannte Syntax: Waffe1 setPos [getPos Waffe1 select 0,getPos Waffe1 select 1,Wert] Im Spiel sieht das dann später etwa wie folgt aus: 94 3.22 - Waffenblickrichtung ausgeben Mit den folgend aufgeführten Syntaxformen hat man die Möglichkeit, sich die Blickrichtung einer Waffe ausgeben zu lassen oder diese später als eine Bedingung für etwas zu verwenden. Diese Möglichkeit wird oft in Verbindung mit Fahrzeugen, wie einem Panzer oder ähnliches verwendet, um die Blickrichtung des Turmes zu ermitteln. Kapitel 3 Zunächst zwei Syntaxformen zum Ausgeben der XYZ-Werte: hint format ["Blickrichtung: %1", Name weaponDirection "M56"] hint format ["%1", Name weaponDirection primaryWeapon Name] In folgendem Beispiel wird nur die Höhe ausgegeben: hint format ["%1", Name weaponDirection "M56" select 2] hint format ["%1", Name weaponDirection primaryWeapon Name select 2] Dies erklärt sich wie folgt. X benötigt select 0, Y erfordert select 1 und Z dann select 2. Folgend auch nochmal zwei Beispielverwendungsarten in einem Script: _dir = _unit weaponDirection "Klassenname" select 0 ? _dir <= Wert : hint "Falsche Schussrichtung!" Aufsplitten der XYZ-Werte _Direction = Name weaponDirection primaryWeapon Name _xDir = _Direction select 0 _yDir = _Direction select 1 _zDir = _Direction select 2 95 Kapitel 4 - Die Mission Nachdem du in den ersten drei Kapiteln die Oberfläche, die Dateien und die Waffen kennen gelernt hast, kommen wir nun zu den etwas spezielleren Bereichen des Missionsdesigns. Hier wirst du lernen, wie man eine Mission startet, die Ziele festlegt, die Erfüllung angemessen bewertet und am Ende die Mission ordentlich beendet. 4.1 4.2 4.3 4.4 4.5 4.6 4.7 96 Der Missionsname Der Missionsstart Das Missionszubehör Die Missionswertung Die Missionsziele Mission beenden Mission speichern 97 97 98 99 99 101 103 4.1 - Der Missionsname Wenn man eine neue Karte erstellt, gibt man unter Info zunächst den Namen der Mission an. Dies ist zwar nicht unbedingt erforderlich, aber wenn man dass nicht macht, wird die Mission später im Einzelmissionsauswahlmenü mit dem Inselnamen angezeigt. Das sieht dann etwa so aus: Bei Beispielmission wurde bei Info unter Name auch der Text Beispielmission eingetragen. Bei Beispielmission2 war das nicht der Fall und deshalb steht dort Beispielmission2.Intro. Beim Intro- und Missionsstart hat man die Möglichkeit eine Texteinblendung und Uhrzeit in individueller Form anzuzeigen zu lassen. Der Text dafür ist variabel, sollte aber auch nicht zu lang sein. Zum Anzeigen dieses Textes und der Uhrzeit muss man die Description.ext bearbeiten und falls diese im eigenen Missionsordner noch nicht vorhanden ist, muss man eine erstellen. Nähere Informationen zum Thema Description.ext findet man im Kapitel 2.3. Zum Vordefinieren des Textes und der Uhrzeit trägt man im Kopf der Description.ext etwa folgendes ein: onLoadIntro = Mr-Murray proudly presents onLoadMission = Convoy Attack onLoadIntroTime = true bzw. false onLoadMissionTime = false oder 1 bzw. 0 Möchte man keines von Beiden anzeigen lassen, setzt man den Wert dazu lediglich auf 0 oder schreibt stattdessen die Wortform false hinter das Gleichheitszeichen und schon werden der Text und die Uhrzeit nicht angezeigt. 97 Kapitel 4 4.2 - Der Missionsstart Als Text kann man hier natürlich auch die Adresse zur Stringtable.csv definieren. Das sieht dann etwa so aus: onLoadIntro = $STR_Missionsstart Mehr Informationen zum Thema Stringtable.csv sind im Kapitel 2.4 zu finden. 4.3 - Das Missionszubehör Der Missionsersteller hat die Möglichkeit zu bestimmen, ob man das jeweilige Missionszubehör in einer Mission zur Verfügung stehen soll oder eben nicht. Dazu müssen wieder diverse Zeilen in der Description.ext definiert werden, um die Zubehörteile anzeigen oder verbergen zu lassen. Zum Anzeigen wird wieder der Wert 1 oder true und zum Verbergen der Wert 0 oder false verwendet. Folgend die Übersicht der dazu benötigen Befehle: ShowGPS = 1; - GPS ShowCompass = 1; - Kompass ShowRadio = 1; - Funkgerät ShowMap = 1; - Karte ShowNotePad = 1; - Briefing ShowWatch = 1; - Uhr ShowDebriefing = 1; - Abschlussbriefing Seit Version 1.08 ist es nun auch möglich diese Komponenten ganz ohne Description.extEintrag während des Spielverlaufes ein- oder gar auszublenden, was in den ersten ArmAVersionen und früher in OFP nicht so ohne Weiteres möglich war. Dazu setzt man den Wert lediglich auf true oder false. ShowMap true 98 4.4 - Die Missionswertung Wie in jedem Spiel kann der Spieler in jeder Mission Punkte erreichen. Diese müssen dazu vorher in der Description.ext definiert werden. Die Anzahl der zu erreichenden Punkte kann dabei frei bestimmt werden. In der Description.ext wird das wie folgt angegeben: minScore=200 avgScore=3000 maxScore=6000 - Die Mindestpunkte - Die Mittelpunkte - Die Höchstpunkte Der Spieler bekommt bereits im Spiel automatisch für jede getötete Einheit Punkte zugewiesen. Wenn man aber nun machen möchte, dass der Spieler für das Erfüllen eines gewissen Missionziels eine gewisse Wertung erhält, macht man das mit folgender Syntax: Natürlich kann man dem Spieler auch Punkte abziehen. Dann, wenn zum Beispiel etwas zerstört oder getötet wurde, was nicht hätte passieren dürfen. Dazu müsste dann bei obiger Syntax ein Minuswert verwendet werden. Player addRating -Wert Möchte man eine Abfrage starten dass, wenn der Spieler eine gewisse Punktzahl erreicht hat, die Mission zum Beispiel beendet wird, erstellt man einen Auslöser mit der Größe (Achse a/b) 0 und schreibt in die Bedingungszeile: Rating Player > Wert oder Rating Player >= Wert Bei Typ wählt man nun einfach Ende1 aus. Wenn der Spieler nun den Wert erreicht oder überschritten hat, wird die Mission beendet und das Briefing wird mit der jeweiligen Wertung angezeigt. 4.5 - Die Missionsziele Die Missionsziele sind wohl das wichtigste an einer Mission. Denn ohne Missionsziel gibt es ja bekanntlich auch keine Mission! Diese müssen natürlich wieder auf irgendeine Art vordefiniert werden. Die Missionsziele werden, wie man im Kapitel 2.13 nachlesen kann, angelegt und eventuell auch in der Init.sqs, siehe Kapitel 2.5, vordefiniert, wenn man diese zunächst verdecken möchte. Verdecken heißt, dass der Spieler das verdeckte Ziel zuerst nicht im Briefing sehen kann. In der Mission müssen jetzt natürlich noch die jeweiligen Ziele definiert und konfiguriert werden. 99 Kapitel 4 Player addRating Wert Beispielmission Der Spieler sieht im Briefing den Auftrag „Erobern Sie diese Ortschaft“. Der zweite Auftrag „Zerstören Sie den Munitionstruck“ wird zunächst durch den Eintrag in der Init.sqs verdeckt. Wenn der Ort von Feinden befreit wurde, soll das erste Ziel abgehakt und das zweite Ziel sichtbar gemacht werden. Dazu setzt man über die Ortschaft einen Auslöser mit der Beispielgröße 300 (bei Achse a/b), wählt bei Aktivierung die Seite aus, die den Ort bewachen soll und wählt bei Art der Aktivierung Nicht vorhanden aus. Der Auslöser würde also ausgelöst werden, wenn die jeweilig ausgewählte Seite nicht mehr im Auslöserbereich vorhanden ist. In der Aktivierungszeile gibt man nun die Befehle an, die ausgeführt werden sollen, wenn der Auslöserbereich von Feinden befreit wurde. Dazu gehörten Ziel 1 abhaken und Ziel 2 sichtbar machen. Als kleinen Infotext fügt man ggf. noch einen Hint hinzu. Das Ganze schaut dann so aus: "1" ObjStatus "Done"; "2" ObjStatus "Visible"; hint "Missionsplan aktualisiert" Auf der Karte setzt man über der Ortschaft, wie in der folgenden Briefing.html schon definiert, einen Marker namens ZielX, welchen das Briefingfadenkreuz ansteuert, wenn der Spieler im Briefing auf den Link „diese Ortschaft“ klickt. Beispielabschnitt der dazugehörigen Briefing.html: <p> <a name="OBJ_1"></a> Erobern Sie <a href="marker:ZielX">diese Ortschaft </a> </p> <hr> <p><a name="OBJ_2"></a> Zerstören Sie den Munitionstruck! </p> <hr> Der dazugehörige Eintrag in der Init.sqs, der das zweite Missionsziel zunächst verdeckt, muss hierbei "2" ObjStatus "Hidden" lauten. Nun folgend die unterschiedlichen Befehle, die für den jeweiligen Missionszielstatus gebraucht werden: Hidden Visible Active Done Failed 100 - Missionsziel wird verdeckt - Missionsziel wieder sichtbar - Missionsziel wird wieder aktiviert - Missionsziel wird abgehakt - Missionsziel fehlgeschlagen 4.6 - Mission beenden Nach dem Erfüllen der Missionsziele sollte eine Mission normalerweise beendet werden. Natürlich gibt es da viele Möglichkeiten diese zu beenden. Diese hängen aber einzig und allein von der Story, den Missionszielen oder dem Verlauf der Mission ab. Hier mal ein paar mögliche Beispiele für die Beendigung einer Mission. Einheitsbezogen aus lokaler Sicht Auf dem rechten Bild sind mehrere Einheiten zu sehen. Ziel soll es sein den Schützenpanzer zu beseitigen. Dieser wurde mit der Taste 2 mit dem Auslöser verbunden und der Auslöser wie folgt definiert: 50 Ende #1 Nicht vorhanden Kapitel 4 Achse a/b: Typ: Aktivierung: Wird der Panzer nun zerstört oder verlässt er den Auslöserbereich, wird die Mission beendet. Da der Panzer aber auf jeden Fall zerstört werden soll und die Mission nicht beendet werden soll, wenn dieser den Bereich verlässt kommen wir zur globalen Sichtweise. Einheitsbezogen aus globaler Sicht Dazu setzt man ebenfalls einen Auslöser, aber legt keinen Auslöserbereich fest, und stellt diesen wie folgt ein: Achse a/b: Typ: Bedingung: 0 Ende #1 ! (alive Panzer1) Der Panzer wurde nun Panzer1 benannt und der Auslöserwirkungsbereich mit dem Wert 0 auf globales Prüfen geschaltet. Man kann den Auslöser nun frei auf der Map platzieren, da er global prüft, ob Panzer1 noch lebt. Als Bedingung der Auslösung wurde ja bei Bedingung die Syntax ! (alive Panzer1) angegeben. 101 Der Panzer kann sich nun frei auf der Karte bewegen und die Mission wird erst beendet, wenn dieser zerstört ist. Natürlich könnte man bei der lokalen Sichtweise die Prüfweite auf 5000 oder so stellen , dann würde der Panzer den Bereich auch nicht verlassen können, aber der Übersicht halber ist die globale Sichtweise zu bevorzugen. Je weniger Auslöserkreise auf einer Karte, desto besser die Übersicht beim Editieren. Einheitsbezogen aus globaler Sicht mit mehreren Einheiten Hierzu gelten die gleichen Vorgaben wie bei Einheitsbezogen aus globaler Sicht, nur werden in der Bedingungszeile, noch weitere Bedingungen angegeben. ! (alive Panzer1) AND ! (alive MG1) AND ! (alive Soldat1) Das AND steht für UND und verbindet somit diese Bedingungen zu einer. Die Mission wird nun erst beendet, wenn die Objekte namens Panzer1, MG1 und Soldat1 tot sind. Mission wird beendet, wenn der Auslöserbereich feindleer ist Auf dem unteren Bild sind mehrere Einheiten zu sehen. Ziel soll es sein die Ortschaft (Auslöserbereich) vom Feind zu befreien. Dabei ist es egal, ob diese eliminiert oder aus dem Auslöserbereich vertrieben werden. Der Auslöser wird hierbei wie folgt definiert: Achse a/b: Typ: Aktivierung: 50 Ende #1 OSTEN Nicht vorhanden Ab der Version 1.05 gibt es auch die Möglichkeit einen Auslöser so zu konfigurieren, dass der Auslöser erst auslöst, wenn alle Feindeinheiten eliminiert bzw. nicht präsent sind und mindestens eine befreundete Einheit im Auslöserbereich ist. Dazu definiert man beim Auslöser unter Aktivierung einfach, von welcher Seite (Erobert durch...) dieser Bereich erobert werden soll. Die verfeindete Gegenseite ist dabei egal. 102 Variablenbezogene Beendung der Mission Die variablenbezogene Auslösung einer Mission ist nicht unbedingt schwerer, aber je nach Ausmaß ein klein wenig aufwendiger. Als Beispiel könnte nun folgendes dienen. Drei unterschiedliche Auslöserbereiche sollen vom Feind befreit werden. Erst wenn diese 3 Bereiche, als Beispiel 3 Ortschaften, befreit sind, soll die Mission beendet werden. Das Ganze kann man nun wie folgt lösen: Auslöser 1 (Bereich 1): Achse a/b: 100 Aktivierung: OSTEN (nicht vorhanden) bei Aktivierung: Ziel1=true Kapitel 4 Auslöser 2 (Bereich 2): Achse a/b: 150 Aktivierung: OSTEN (nicht vorhanden) bei Aktivierung: Ziel2=true Auslöser 3 (Bereich 3): Achse a/b: 100 Aktivierung: OSTEN (nicht vorhanden) bei Aktivierung: Ziel3=true Auslöser 4 (Prüfer): Achse a/b: Typ: Bedingung: 0 Ende #1 Ziel1 AND Ziel2 AND Ziel3 Wie man nun oben sehen kann, wird bei jedem der drei Auslöser bei der Auslösung eine Variable (Ziel1, Ziel2, Ziel3) auf true geschaltet. Beim Auslöser 4 wurden diese 3 Variablen als Bedingung angegeben, um diesen auszulösen. Sind diese nun erfüllt, wird die Mission beendet. Es bietet sich an bei Timeout noch ein paar Werte anzugeben, um die Beendungszeit etwas flexibel zu gestalten. 4.7 - Mission speichern Dieser Befehl ermöglicht das Speichern während des Spielens. Der Missionsersteller kann so auf der Karte also Speicherpunkte setzen. Zum Beispiel, wenn der Spieler einen bestimmten Punkt auf der Karte erreicht oder ein Missionsziel erfüllt hat, wird das Spiel so automatisch gespeichert. Die Syntax hierfür lautet lediglich: Savegame Wählt man später im Menü Neuer Versuch, beginnt der Spieler wieder an der Stelle, an welcher das Spiel gespeichert wurde. Möchte man Speichern komplett verbieten, schreibt man in die Description.ext lediglich: saving = 0; 103 Kapitel 5 - Missionszubehör In diesem Kapitel ist alles erläutert, was in einer Mission zu gebrauchen ist. Hier solltest du Antworten auf deine offenen Fragen und zudem noch eine Menge Anregungen für deine Mission bekommen. 5.1 5.2 5.3 5.4 5.5 5.6 5.7 5.8 5.9 5.10 5.11 5.12 5.13 5.14 5.15 5.16 5.17 5.18 5.19 5.20 5.21 5.22 5.23 5.24 5.25 5.26 5.27 5.28 5.29 5.30 5.31 5.32 5.33 5.34 5.35 5.36 5.37 5.38 5.39 104 Leeres oder verschlossenes Fahrzeug Fahrer/Beifahrer eines Fahrzeugs Einheit hat Fahrzeugverbot Einheit in Fahrzeug? Fahrzeug fährt erst, wenn Einheit eingestiegen ist Gruppe zu Missionsbeginn im Fahrzeug Ein- und Aussteigen lassen Geschwindigkeit einer Einheit Geschwindigkeit ausgeben lassen Einheit bleibt stehen Einheiten starten bzw. stoppen Einheit bewegt sich zum Bestimmungsort Streife laufen, fahren oder fliegen Fluchtverhalten einer Einheit oder Gruppe Einheiten, Objekte, Auslöser u. Marker versetzen Objekte versenken oder höher setzen Flughöhe einer Einheit Punktgenaue Helikopterlandung Einheit begibt sich in ein Gebäude Einheit verlässt eine Gruppe oder tritt anderer bei Einheit ein Ziel zuweisen Einheit wendet sich anderer zu Einheit wählt Waffe Einer Einheit Schaden zufügen bzw. heilen Einrichten einer Todeszone Das Prüfen eines Bereiches Einheiten in einem Bereich ansprechen Einheitsstatus speichern oder laden Bekanntheitsgrad einer Einheit Freundlicher Feind Befreundete Parteien Der Alarm Tod als Bedingung Distanz zweier Einheiten oder Objekte Einem Fahnenmast eine Fahne zuweisen Brennende Feuerstelle Spielbare Einheit hinzufügen oder entfernen Spielerseite, -namen, -typ auslesen bzw. ausgeben Spielereingabe unterdrücken 106 106 106 107 107 108 108 108 108 109 109 110 110 110 111 111 112 112 112 113 113 114 114 114 115 115 115 116 117 117 118 119 120 120 120 121 121 121 121 Karte auf den Monitor erzwingen Sichtweite ändern Wetter einstellen Datum und Uhrzeit einstellen Zeitlupe oder Zeitsprint Einheiten und Objekte erzeugen Flares, Rauch und Explosionen erzeugen Einheiten und Objekte löschen Funkmenü verändern Einer Gruppe ein Rufzeichen zuweisen Funkspruch abgeben Sound erstellen Eigenen Sound einbinden Identität festlegen Mimiken Der Actionbefehl Der Animationsbefehl KI abschalten SetVelocity Der Informationstext Einheit bleibt liegen, kniet oder steht ID´s verwenden Einheiten in Gebäuden platzieren Einheit begibt sich zu Gebäudeposition Position auslesen Der Eventhandler Texteinblendarten Stringtable Grundwerte Wegpunkte erzeugen Auslöser erzeugen Marker erzeugen Rund ums Vehikel Lichtquellen erzeugen Staub erzeugen Rauch erzeugen Feuer erzeugen Dienstgrad vergeben Einheit benutzt Fernglas Einheit einen Fahrzeugplatz zuweisen Einheit ein Team zuweisen Einheit gibt Befehle Hat Einheit Schaden erhalten? Der Flugverkehr Grasdetails heruntersetzen Objekte schräg platzieren Mission verschlüsseln bzw. freischalten Leerer Scheinwerfer mit Licht 121 122 122 123 123 124 126 127 127 128 129 129 130 134 135 136 139 144 144 144 144 145 148 153 153 155 157 158 159 160 162 165 167 167 168 169 171 172 172 173 174 174 175 176 176 177 177 Kapitel 5 5.40 5.41 5.42 5.43 5.44 5.45 5.46 5.47 5.48 5.49 5.50 5.51 5.52 5.53 5.54 5.55 5.56 5.57 5.58 5.59 5.60 5.61 5.62 5.63 5.64 5.65 5.66 5.67 5.68 5.69 5.70 5.71 5.72 5.73 5.74 5.75 5.76 5.77 5.78 5.79 5.80 5.81 5.82 5.83 5.84 5.85 5.86 105 5.1 - Leeres oder verschlossenes Fahrzeug Zum Erstellen eines leeren Fahrzeuges wählt man zunächst die Taste 1 und klickt doppelt auf die Karte. Nach dem Öffnen des Menüs schaltet man bei Auswahl der Seite auf Leer, wählt bei Klasse und Einheit den Vehikeltyp aus und klickt dann auf OK. Wenn das Fahrzeug verschlossen bzw. nicht nutzbar sein soll, wählt man bei Fahrzeugstatus einfach Abgeschlossen für verschlossen aus. Möchte man das Fahrzeug später nutzbar machen geht das wie folgt: Fahrzeugname lock true Fahrzeugname lock false - Verschließt das Fahrzeug - Öffnet das Fahrzeug 5.2 - Fahrer/Beifahrer eines Fahrzeugs Mit den folgenden Befehlen lassen sich Einheiten an beliebige Positionen eines Fahrzeuges beamen. Dies lässt sich unter anderem in der Initzeile der jeweiligen Einheit oder auch in einem Skript etc. definieren. Gibt man das in der Initzeile der jeweiligen Einheit an, kann für Name auch this stehen! Name moveInDriver Fhz1 Name moveInCargo Fhz1 Name moveInCommander Fhz1 Name moveInGunner Fhz1 Name moveInTurret Fhz1 Name moveInTurret [Fhz1,1]; Name moveInCargo [Fhz1,3] - Fahrer des Fahrzeugs - Beifahrer des Fahrzeugs - Kommandant des Fahrzeugs - Schütze des Fahrzeugs - Schütze des Fahrzeugs (i.d.R. MG) - Schütze Nr. 2 des Fahrzeugs (i.d.R. MG 2) - Mitfahrer auf beliebiger Cargoposition 5.3 - Einheit hat Fahrzeugverbot Diesen Befehl verwendet man, wenn man möchte, dass eine bestimmte Einheit ein Fahrzeug nicht nutzen kann oder soll. Dazu trägt man in der Initzeile des Fahrzeugs folgende Syntax ein. [Name1, Name2, Name3] allowGetIn false In dieses Fahrzeug dürfen Name1, Name2, Name3 nun nicht einsteigen. Möchte man das Fahrzeug später wieder für diese Einheiten nutzbar machen, schaltet man wieder auf true. [Name1, Name2, Name3] allowGetIn true 106 5.4 - Einheit in Fahrzeug? Manche Abläufe erfordern das Prüfen, ob sich eine Einheit noch in einem Fahrzeug befindet oder auch nicht. Dieses kann man z.B. als Bedingung nehmen, um damit einen Auslöser oder ein Skript zu starten. Um zu prüfen, ob Name in dem Fahrzeug sitzt, nutzt man diese Syntax: Name in Fahrzeugname Player in (crew Fahrzeugname) und gibt sie in die Bedingungszeile eines prüfenden Auslösers ein. Steigt die Einheit nun in das definierte Fahrzeug, wird der Auslöser aktiviert. In einem Skript muss das Ganze so aussehen: ? Name in Fahrzeugname NOT (Name in Fahrzeugname) Für das NOT kann auch ein ! verwendet werden. Gleiche Eigenschaft! 5.5 - Fahrzeug fährt erst, wenn Einheit eingestiegen ist Angenommen man hat ein Fahrzeug auf der Karte, welches auch schon mit Wegpunkten versehen ist, welches erst losfahren soll, wenn eine bestimmte Einheit, als Beispiel der Spieler, eingestiegen ist. Dies kann ein normales Auto, Boot oder auch ein Helikopter sein. Dazu gibt man in der Bedingungszeile als Bedingung folgende Syntax an: Name in Fahrzeugname oder Vehicle Name == Fahrzeugname Gruppenbezogen Natürlich geht das Ganze auch gruppenbezogen. Das Fahrzeug soll warten, bis die Gruppe eingestiegen ist. Dazu wird bei der folgenden Syntax auch der Fahrer mitgezählt, der schon im Truck sitzt. Man muss also die Größe der Gruppe plus den Fahrer rechnen. Dazu gibt man in der Bedingungszeile folgendes an: count crew Truck1 >= 10 oder count crew Truck1 == 10 107 Kapitel 5 Um zu prüfen ob eine Einheit nicht mehr in einem Fahrzeug sitzt, benötigt man folgende Syntax: 5.6 - Gruppe zu Missionsbeginn in Fahrzeug Wenn eine Gruppe gleich zu Missionsbeginn in einem Fahrzeug, als Beispiel einem Helikopter sitzen soll, muss in der Initialisierungszeile des Leaders der Gruppe folgende Syntax angegeben werden: oder {_x moveInCargo Heli1} forEach units group this {_x moveInCargo Heli1} forEach units Group1 5.7 - Ein- und aussteigen lassen Dafür setzt man zunächst ein leeres Fahrzeug und einen Soldat auf die Karte. Dann weist man dem Soldaten einen Wegpunkt zu, welchen man genau auf das Fahrzeug setzt und wählt bei Typ Einsteigen aus. Dann setzt man den nächsten Wegpunkt an der Zielposition und wählt dort Aussteigen aus. Möchte man Einheiten per Syntax aussteigen lassen, geht das wie folgt: unassignVehicle Fahrzeug1 {unassignVehicle _x} forEach units Grp1 - Einheit verlässt Fahrzeug - Einheiten verlassen Fahrzeug Leader befehlen dabei ihren Einheiten auszusteigen 5.8 - Geschwindigkeit einer Einheit Die Geschwindigkeit einer Einheit kann bei einem Wegpunkt unter Geschwindigkeit oder auch per Syntax bestimmt werden. Diese lauten wie folgt: Name setSpeedMode "Full" Name forceSpeed 120 Name limitSpeed 60 Name1 setSpeed getSpeed Name2 - Verfügbar in Auto,Limited,Normal,Full - Wert in km/h - Wert in km/h - Name1 bekommt Speed v. Name2 5.9 - Geschwindigkeit ausgeben lassen Die Geschwindigkeit einer Einheit oder eines Fahrzeugs lässt sich jederzeit abfragen oder sogar als Bedingung für etwas verwenden. Dazu gelten unter anderem folgend aufgeführte Syntaxbeispiele. hint format ["Geschwindigkeit: %1" , speed Name] ? speed Name > 30 : hint " Du fährst zu schnell!" 108 5.10 - Einheit bleibt stehen Der Befehl dostop this in der Init-Zeile einer Einheit bewirkt, dass diese an ihrer gesetzten Position stehen bleibt. Dies ermöglicht eine Gruppe auf die Karte zu setzen und die Mitglieder frei zu verteilen, ohne dass diese wieder zu ihrem Leader zurücklaufen und sich somit wieder in Formation begeben. Teambezogen Sehr nützlich, wenn man Anführer einer Gruppe ist und nicht möchte, dass seine Untergebenen bei Missionsbeginn gleich hinter einem her laufen und sie selbst in Stellungen unterbringen möchte. Sie bleiben somit an der zuvor im Editor gesetzten Stelle stehen, wenn man bei der jeweiligen Einheit dostop this in die Initialisierungszeile einträgt. Zusätzlich ist es wichtig bei der jeweiligen Einheit unter Speziell den Wert Keine zu definieren! 5.11 - Einheiten starten bzw. stoppen Als Beispiel dient hier eine Gruppe, die ihre zugewiesenen Wegpunkte anlaufen soll, wenn der Spieler einen Wegpunkt oder einen Auslöser ausgelöst hat. Dem Leader dieser Gruppe schreibt man dabei this stop true in die Initzeile, während man bei dem Wegpunkt des Spielers oder dem Auslöser, den der Spieler auslösen soll, folgendes angibt: Name stop false Die Gruppe wird dann ihre Wegpunkte anlaufen. Oben wurde der Wert this verwendet, weil die Syntax in der Initzeile des Leaders der Gruppe angegeben wurde, während beim zweiten Befehl der Name des Leaders benötigt wird, weil der Befehl von dem Wegpunkt bzw. Auslöser kommt. Der Leader muss also auch mit einem Namen versehen werden. 109 Kapitel 5 Feindbezogen Auch hier ist dieser Befehl sehr nützlich, denn nun kann man ein feindliches Team sehr gut in der Landschaft verteilen. Hierbei ist es ebenfalls wichtig bei der Einheit bei Speziell Keine auszuwählen. Wird der Feind nun angegriffen, werden die Einheiten auf ihrer festgelegten Position in Stellung gehen. 5.12 - Einheit bewegt sich zu Bestimmungsort Man kann Einheiten auch ohne Wegpunkte zu bestimmten Punkten auf der Karte schicken, ohne sie zuvor mit Wegpunkten versehen zu haben. Hierbei gibt es verschiedene Möglichkeiten. Objektbezogen: ID-bezogen: Koordinatenbezogen: Markerbezogen: Name doMove getPos Name Name doMove getPos (position Name nearestObject ID) Name doMove [X,Y,Z] Name doMove getMarkerPos "Markername" Möchte man eine Gruppe zu einer dort oben aufgeführten Position schicken, lässt man das do von doMove weg, da sich sonst zunächst nur der Leader zu der angegebenen Position bewegen wird und die Gruppe erst folgt, wenn er sein Ziel erreicht hat. Hier ein Syntaxbeispiel für Objektbezogen: Name move getPos Name oder Leader Name move getPos Name Sehr interessante Beispiele findet man im Kapitel 6.6 unter -Der Mapclick- und Kapitel 6.2 -Das GPS-System-. 5.13 - Streife laufen, fahren oder fliegen Eine Streife soll ständig um ein Lager Streife laufen bzw. fahren. Dazu weist man der Streife die Wegpunkte zu und schließt den Kreis, indem man den letzten Wegpunkt in den Bereich des ersten setzt und im Wegpunktmenü bei Typ den Befehl Wiederholen auswählt. 5.14 - Fluchtverhalten einer Einheit oder Gruppe Hiermit legt man das Fluchtverhalten von Einheiten fest. Diese werden, wenn die Situation aussichtslos erscheint, je nach Einstellung früher oder später die Flucht ergreifen und irgendwo in den Weiten Sahranis untertauchen. Doch Achtung: Manchmal kommen sie auch zurück und greifen nochmal an. Hierbei gelten alle Werte zwischen 0 und 1, also auch die Dezimalwerte, wobei die 0 für kein und 1 für maximales Fluchtverhalten steht. Schreibt man in die Initzeile eines Gruppenführers diese Syntax: this allowFleeing 0.8 bezieht sich der Befehl auf die ganze Gruppe, welche je nach Einstellung die Flucht ergreifen wird. Viel abwechslungsreicher ist die Verwendung eines Zufallwertes: this allowFleeing (random 0.8) 110 5.15 - Einheiten, Objekte, Auslöser u. Marker versetzen Einheiten, Objekte und Auslöser lassen sich auch während des Spielverlaufs beliebig versetzen oder besser ausgedrückt, an eine beliebige Positionen beamen. Dazu muss man das jeweilige zum Versetzen bestimmte Objekt zunächst mit einem Namen versehen. Danach lässt sich ein Objekt wie folgt versetzen: Objektbezogen: Vor, hinter, neben Objekt: ID-bezogen: Koordinatenbezogen: Markerbezogen: Marker zu Marker: Marker zu Objekt: Vehikelbezogen: Vehikelbezogen II: Name1 setpos getPos Name2 Name2 setpos Name1 modelToWorld [0,3,0] Name setPos getPos (position Name nearestObject ID) Name setPos [X,Y,Z] Name setPos getMarkerPos "Marker1" "M1" setMarkerPos getMarkerPos "M2" "Marker1" setMarkerPos getPos Name Name setPos getPos vehicle Player "Marker1" setMarkerPos getPos vehicle Player Name1 würde nun an die Position von Name2 in 10 Meter Höhe versetzt werden. Eine Gruppe versetzt man hierbei mit dem jeweiligen Befehl von oben zum Ziel: {_x setpos getPos Name} foreach units Group1 Folgende Syntax ermöglicht es, eine Einheit oder ein Objekt an eine Zufallsposition zu versetzen. Dabei setzt sich die Syntax aus XYZ-Koordinaten und Markern zusammen, woraus die Engine dann automatisch eine der Zufallspositionen auswählt. Name setVehiclePosition [[1000,2000], ["Marker1", "Marker2", "Marker3"], 0] 5.16 - Objekte versetzen oder höher setzen Sämtliche in irgendeiner Form setzbaren Objekte lassen sich versenken bzw. höher setzen. Eine Ausnahme sind Fahrzeuge und Einheiten, welche sich nicht im Boden versenken, aber dennoch höher setzen lassen. Hiermit ist es beispielweise möglich, Soldaten in Häusern oder auf Dächern höhengenau zu platzieren. Setzt man einen Soldaten oder ein Fahrzeug in eine Höhe X, wird dieser schwerkraftbedingt wieder zu Boden fallen. Statische Objekte, wie beispielsweise ein Sandsack, würden aber trotz allem in der Luft schweben. Hierbei gibt es verschiedene Varianten. Die in der Initzeile eines Objektes eingetragene Syntax: this setPos [(getPos this select 0),(getPos this select 1),10]; lässt das Objekt an der im Editor gesetzten Position in einer Höhe von 10 Metern schweben. Im Multiplayer funktioniert dieser Befehl seit ArmA erst ab Version 1.08! 111 Kapitel 5 Ein weiterer Befehl mit Höhenangabe, hier mit dem Wert 10 definiert, wäre: Name1 setPos [(getPos Name2 select 0),(getPos Name2 select 1),10] Der Inhalt des Arrays [ ] wird wie folgt definiert. Die erste ( ) stellt den Erhalt der XPosition, die zweite ( ) den Erhalt des Y-Position und die Zahl nach den Klammern die Z-Position des Objektes dar. Ersetzt man die beiden this, also das this vor der Klammer, welches für das Objekt welches zu this, also dem this in der [] versetzt werden soll, durch einen Namen, wird es auch dieser Satz verständlicher. Name1 soll zu Name2 versetzt werden: Name1 setPos [(getPos Name2 select 0),(getPos Name2 select 1),10]; Übersetzt heißt das: Name1 setze zu erhaltener X-Position und zu erhaltener Y-Position von Name2 auf Höhe 10 Meter. Neben dem setPos- und getPos-Befehlen gibt es noch setPosASL und getPosASL Befehle, welche die Höhe des Objektes über dem Meeresspiegel wiedergeben. 5.17 - Flughöhe einer Einheit Die Flughöhe einer Einheit lässt sich unterschiedlich bestimmen. Dies kann man an dem jeweiligen Wegpunkt der Einheit oder auch per Auslöser oder Skript bestimmen. Hierzu gilt folgende Syntax: Name flyInHeight 120 5.18 - Punktgenaue Helikopterlandung Setzt man für einen Helikopter einen Wegpunkt an der Position an der er landen soll, weicht die KI oftmals weit vom Landepunkt ab und landet, wo es ihr gerade möglich ist. Dies kann man umgehen, wenn man zunächst ein Heli-H setzt. Hierbei ist es vollkommen egal, ob es ein sichtbares oder unsichtbares Heli-H ist. Danach erst setzt man den Landewegpunkt direkt auf das Heli-H und wählt im Wegpunktmenü bei Typ Transport Entladen oder Aussteigen aus. Der Helikopter wird nun an der festgelegten Position landen. Eine weitere Möglichkeit bietet diese Syntaxform: Heli1 land "Positionsname" 5.19 - Einheit begibt sich in ein Gebäude Dazu weist man der Einheit einen Wegpunkt zu, wobei man direkt auf das begehbare Gebäude, bei dem die Bezeichnung am Fadenkreuz erscheint, wenn man mit der Maus über das Gebäude fährt, klickt und im Wegpunktmenü bei Position im Haus die jeweilige Position auswählt. Die Einheit wird sich dann sofort zu der jeweiligen Position im Haus begeben. 112 5.20 - Einheit verlässt Gruppe oder tritt anderer bei Dies lässt sich zum Einen mit Wegpunkten, wie im Kapitel 1.5 –Wegpunkte einfügen– im Unterbereich Anschließen und führen (Join and Lead) erklärt, oder zum Anderen mit einer Syntax realisieren. Mit folgender Syntax würde Name1 eine Gruppe verlassen: [ Name1] join grpNull und mit dieser einer anderen Gruppe beitreten: [Name1] join Name2 Name1 wurde also zunächst einer Nullgruppe, die nicht existent ist, und danach der Gruppe Name2 unterstellt. Für mehrere Einheiten sieht das Ganze so aus: [ Name1, Name2, Name3] join grpNull und danach: Hiermit ist es sogar möglich seiner Gruppe einen Feindsoldaten zu unterstellen, der dann auf der eigenen Seite kämpft, nur eben wie ein Feindsoldat gekleidet ist. 5.21 - Einheit ein Ziel zuweisen Auch hier gibt es verschiedene Definitionsmöglichkeiten, wobei die Einheiten keinen Unterschied zwischen Freund oder Feind machen. Die Syntaxes hierfür lauten wie folgt: Name1 Name1 Feuern Name1 Name1 Name1 Name1 doTarget Name2 commandTarget Name2 doFire Name2 doFire ObjNull fire "Waffentyp“ commandFire Name2 Name1 wendet sich Name2 zu Name1 befiehlt einer Einheit auf Name2 zu zielen Name1 schießt auf Name2 Name1 schießt auf nichts mehr Name1 feuert die Waffe blind ab Name1 befiehlt einer Einheit auf Name2 zu schießen 113 Kapitel 5 [ Name1, Name2, Name3] join Name4 5.22 - Einheit wendet sich anderer zu Um eine Einheit dazu zu bringen auf ein Objekt/Einheit zu schauen, benötigt man folgende Syntaxes. Unterschied: Bei der einen Befehlsform dreht sich die Einheit mit eigener Bewegung und bei der anderen Befehlsform wird sie in Blickrichtung gebeamt. Name1 setDir 160 - Name wird in Richtung 160 gedreht Name1 setFormDir 160 - Name dreht sich in Richtung 160 Name1 setDir getDir Name2 - Name bekommt Azimut von Name2 Name1 doWatch Name2 - Schaut zu Name2 (dreht sich bei Bedarf um) Name1 lookAt Name2 - Schaut zu Name2 (dreht sich bei Bedarf um) Name1 glaceAt Name2 - Schaut kurz zu Name2 (nur Kopfbewegung) _Pos=Name modelToWorld [0,0,0] - _Pos erhält Koordinaten u. Versatz [x,z,y] von Name Name2 setPos _Pos Name2 wird mit Versatz [x,z,y] zu Name versetzt Textausgabe: hint format ["Blickrichtung: %1", getDir Name1] 5.23 - Einheit wählt Waffe Mit folgender Syntax bringt man eine Einheit dazu die Zweitwaffe zu wählen. Natürlich muss hierbei die Bezeichnung der Waffenklasse stimmen und die Einheit die entsprechende Waffe auch im Inventar haben. Name selectWeapon "Stinger" 5.24 - Einer Einheit Schaden zufügen bzw. heilen Man kann Einheiten/Objekten per Syntax einen direkten Schadenswert zuweisen. Hierbei steht die 0 für keinen Schaden und die 1 für maximalen Schaden. Die Dezimalwerte zwischen 0 und 1 stellen die Zwischenwerte dar. Setdamage gibt es mit einem oder auch zwei m, wobei es getDammage nur mit doppelten m gibt! Name wird ein Schadenswert zugewiesen: Name1 setDamage 1 oder Name1 setDammage 1 Name1 setVehicleArmor 0.5 Name1 wird der Schadenswert von Name2 zugewiesen: Name1 setDamage getDammage Name2 Möchte man den Schadenswert als Bedingung verwenden, sieht das Ganze so aus: ? damage Name1 >= 0.5 oder ? getDammage Name1 >= 0.5 Um sämtliche Objekte rund um ein Objekt zu zerstören hinterlegt man diese zunächst in einer Variable (Bereich1). Danach zerstört man Diese durch Aufruf der zweiten Syntax. Bereich1 = nearestObjects [Objekt1,[],300] - Objekte um Objekt1 listen {_x setDamage 1} foreach Bereich1 - Zerstören (z.B. Radio Alpha) 114 5.25 - Einrichten einer Todeszone Das Einrichten einer Todeszone kann verschiedene Gründe haben. Wenn man zum Beispiel auf die Schnelle ein Schlachtfeld mit vielen Gefallenen erstellen möchte oder wenn man einen Bereich absperren möchte den eine oder alle Seiten nicht betreten dürfen. Dazu schreibt man in die Initzeile eines Auslösers, bei dem zuvor die gewünschte Größe eingestellt wurde, folgendes: {_x setDamage 1} foreach thisList Bei Art der Auslösung muss man nun nur noch die Seite definieren, durch die der Auslöser ausgelöst werden soll. Wenn der Auslöser mehrfach auslösen soll, muss man ihn natürlich noch auf mehrfach stellen. 5.26 - Das Prüfen eines Bereiches hint format ["%1", (WEST countSide list Area1)+(WEST countside list Area2)] 5.27 - Einheiten in einem Bereich ansprechen Mit der folgenden Befehlsform lassen sich Einheiten eines festgelegten Bereiches ansprechen. Dabei kann man dies wieder, wie im Kapitel 5.26 schon erläutert, seitenbezogen oder komplettbezogen definieren. Hierzu muss wieder ein Bereich mit Namen festgelegt werden und die folgende Syntax irgendwo in einem Wegpunkt, Skript oder wie in Kapitel 5.26 einem anderen Auslöser angegeben werden. {_x setBehaviour "Stealth"} forEach list Bereich1 Alle Einheiten dieses Bereiches würden nun in Deckung gehen. Statt dem Befehl setBehaviour "Stealth" kann man natürlich auch einen anderen Befehl verwenden. 115 Kapitel 5 Mit diesem Befehl kann man sich die Einheiten eines Auslöserbereiches anzeigen lassen. Je nach Auslösereinstellung ist es möglich sich nur die jeweilige Seite oder alle Einheiten dieses Bereiches anzeigen zu lassen. Dazu verwendet man zwei Auslöser, welche wie folgt definiert werden. Bei dem prüfenden Auslöser setzt man zunächst die Achse a/b auf die Größe des Bereiches, der geprüft werden soll. Bei Art der Auslösung wird die jeweilige Seite, die gelistet werden soll, ausgewählt und bei Name der Name Area1 eingegeben. Den Funkauslöser definiert man bei Achse a/b mit 0, stellt ihn auf mehrfach und gibt in die Aktivierungszeile folgendes ein: hint format ["%1",list Area1] oder hint format ["%1", WEST countSide Area1] Wenn man nun den Funk benutzt, werden die Einheiten aus dem Bereich Area1 angezeigt. Nun hat man auch die Möglichkeit Bereiche zu addieren. Erstellt man nun noch einen zweiten Bereich namens Area2, kann man diese beiden Bereiche addieren und den Wert zum Beispiel als Bedingung für etwas verwenden. 5.28 - Einheitsstatus speichern oder laden Dieser Befehl lässt sich hervorragend in Kampagnen verwenden, bei denen der Spieler oder auch die anderen Einheiten bei Beginn der Folgemission den Endstatus von der vorhergehenden Mission haben sollen. Möchte man diesen Befehl in seiner Kampagne nutzen, sollte man darauf achten, dass die Einheit, von der der Status gespeichert wird, auch noch am Leben ist. Zumindest dann, wenn dieser Status später auf den Spieler übertragen werden soll. Mit Savestatus kann man, wie das Wort schon sagt, den Status einer Einheit speichern. Dies geht allerdings nur in Verbindung mit einer Kampagne , da der Wert direkt in der Objects.sav der Kampagne gespeichert wird. Im Single- sowie Multiplayerbereich ist dieser Befehl von daher nicht funktionsfähig. Savestatus Status1 ist eine Variable, die daher auch anders heißen kann. Mit der folgenden Syntax wird nun der Status von Name1 unter der Variable Status1 gespeichert. xy=Name1 saveStatus "Status1" Dieser Speicherwert beinhaltet nun einige Informationen dieser Einheit. Hierzu gehören unter anderem: - die Identität - der Gesundheitsstatus - der Waffenstatus - der Munitionsstatus Wenn man jetzt einem anderen Soldaten genau diesen gespeicherten Status zuweisen will, macht man dies wie nun folgend erklärt. Loadstatus xy=Name2 loadStatus "Status1" Der Einheit mit Name2 wird dann der gespeicherte Status1 von Name1 zugewiesen. Das heißt, dass Name2 genauso wie Name1 aussieht, genau die gleiche Waffe trägt, den gleichen Munitionsstatus und den gleichen Gesundheitsstatus hat. Name2 ist dann also ein Klon von Name1. DeleteStatus Natürlich lässt sich jeder Satus auch löschen. Dies erfolgt mit: deleteStatus "Status1" 116 5.29 - Bekanntheitsgrad einer Einheit Diese Syntax lässt sich für viele nützliche Bereiche verwenden. Zum Beispiel kann man so einer Einheit die Information über eine andere Einheit geben oder den Bekanntheitsgrad auch als Bedingung für eine dann auszuführende Aktion verwenden. Hierbei gelten wieder alle Werte zwischen 0 und 4. 0 Name1 hat keine Kenntnisse von Name2 2 Name1 hat geringe Kenntnisse von Name2 3 Name1 hat ausreichend Kenntnisse von Name2 4 Name1 hat volle Kenntnisse über Name2 Möchte man eine Einheit über eine andere in Kenntnis setzen, weist man ihr einen den Kenntniswert wie folgt zu: Name1 reveal Name2 Name1 hat nun Kenntnis von Name2. Wenn Name1 nun mehr als 1 von Name2 weiß, wird der Auslöser ausgelöst und damit die Aktionen die darin definiert wurden durchgeführt. Die Kenntnis wird im Laufe der Zeit weniger und landet irgendwann wieder beim Wert 0. Demnach lässt sich die obige Syntax auch andersrum, also mit kleiner als, verwenden. Name1 knowsAbout Name2 < 0.8 Dies ist ganz nützlich, wenn die Einheit immer in der Nähe der anderen bleiben soll. Ist sie das nicht oder wird sie getötet, sinkt ja der Wert irgendwann unter, wie oben definiert, 0.8 und der Auslöser wird ausgelöst. Natürlich lässt sich dieser Wert auch wieder als Text ausgeben. Die Syntax lautet hierbei: hint format ["Bekannheitsgrad: %1", Name1 knowsAbout Player] 5.30 - Freundlicher Feind Beendet man die folgend aufgeführte Syntax für eine Einheit an, so wird sie nicht mehr vom Feind beschossen und auch auf andere Weise ignoriert werden. Hiermit kann man zum Beispiel eine feindliche Einheit als Gefangenen definieren, die ja andernfalls sofort erschossen werden würde. Das Ganze macht man dann mit: this setCaptive true oder Name setCaptive true Zurücksetzen kann man das dann wieder, indem man true wieder auf false setzt. 117 Kapitel 5 Möchte man den Kenntniswert als Bedingung für die Auslösung eines Auslösers verwenden, schreibt man in die Bedingungszeile folgendes: Name1 knowsAbout Name2 > 1 5.31 - Befreundete Parteien Die feindlichen Seiten in Armed Assault lassen sich frei bestimmen. Hierbei ist es nun möglich West und Ost auf einer Seite gegen den Rest kämpfen zu lassen oder die Zivilisten als böse zu definieren. Man hat dabei einen so großen Spielraum, dass man dies sogar wieder mit einem Wahrscheinlichkeitswert(Random) belegen kann. Somit weiß man nie genau, wie der Feind am nächsten Tag so drauf ist. Hierbei sind folgende Seiten frei gegeneinander definierbar: West - East - Guerrila - Civilian - Enemy - Logic Es kann auch festgelegt werden, dass die eine Seite friedlich zur anderen ist, aber nicht umgekehrt. Das heißt, dass die eine Seite sofort das Feuer eröffnet, aber die andere Seite schießt nicht zurück. Statt Guer kann übrigens auch Resistance verwendet werden. Der SetFriend-Wert bewegt sich auch hierbei wieder zwischen 0 und 1, wobei alle Werte über 0.6 für befreundet, und alle unter 0.6 für feindlich stehen. Folgend mal ein paar Syntaxbeispiele: WEST setFriend [EAST,1] Jetzt wäre West freundlich zu Ost, aber nicht umgekehrt, dazu braucht man eine zweite Syntax dieser Form. WEST setFriend [EAST,0.7]; EAST setFriend [WEST,0.7] Nun sind beide Seiten freundlich zueinander, was sich ja im Missionsverlauf dank dieser Syntax noch ändern kann oder auch nicht. Setzt man den Wert wieder runter, verfeinden sich beide Parteien wieder. WEST setFriend [EAST,0]; EAST setFriend [WEST,0] Zufallsbezogen Natürlich ist auch hier wieder alles per Zufall möglich, was eben dieses Spiel ausmacht. Man kann alles auch so definieren, dass man beim Missionstart gar nicht weiß, ob sein gegenüber Freund oder Feind ist. Dazu verwendet man dann diese Syntaxform: GUER setFriend [EAST,(Random 0.9)] Hier wurde nun Random mit eingetragen, welcher einen Zufallswert für 0.9 ermittelt. Dieser kann dann mit 0.9 (freundlich), aber genauso gut mit 0.3 (feindlich) ausgegeben werden. Deathmatchbezogen Dies ist im Kapitel 7.6 ausführlich erläutert. Kurz, man kann eine Seite auch mit sich selbst verfeinden. EAST setFriend [EAST,0] 118 5.32 - Der Alarm Mit den in Kapitel 5.27 erläuterten Syntaxes lassen sich nun einige verschiedene Alarmformen realisieren. Natürlich liegt es am Ende immer an der Mission, wann ein Alarm ausgelöst werden soll. Hier mal ein paar Beispiele. Beispiel 1 – Alarmierung bei Entdeckung in einem Auslöserbereich Hierzu setzt man einen Auslöser mit folgenden Einstellungen auf die Karte: Aktivierung BLUFOR Von Osten entdeckt Effekte Alarm Wird in diesem Auslöserbereich nun eine westliche Einheit von östlichen Einheiten entdeckt, wird der Auslöser aktiviert und der Alarm ausgelöst. Beispiel 3 – Alarm, wenn Einheit oder Objekt nicht mehr present (tot) ist Aktivierung Den Auslöser mit der Einheit oder dem Objekt verbinden Nicht vorhanden Effekte Alarm Beispiel 4 – Alarm, wenn die Gruppe namens Grp1 kleiner als Wert ist Aktivierung Keine Achse a/b 0 Bedingung Count Units Grp1 < Wert Effekte Alarm Beispiel 5 – Alarm, wenn eine Einheit schießt Bei dieser Variante bekommen alle Einheiten aus dem Bereich einen Eventhandler zugewiesen. Schießt nun eine Einheit, wird der Alarm ausgelöst und das Skript gestartet. Aktivierung Jeder Achse a/b 500/500 Aktivierung {_x addEventhandler ["Fired",{_this exec "Alarm.sqs"}]} foreach thisList Effekte Alarm Zusätze Bei allen Alarmvarianten kann man zusätzlich diverse Aktionen über die Aktivierungszeile starten lassen. Zum Beispiel, dass alle Einheiten des Alarmbereiches namens Bereich1 über die Einheit, hier der Spieler(Player), informiert werden. {_x reveal Player} forEach list Bereich1 119 Kapitel 5 Beispiel 2 – Einheitsbezogene Alarmierung Hierbei soll nur Alarm ausgelöst werden, wenn eine bestimmte Einheit entdeckt wird. Aktivierung Den Auslöser mit der Einheit oder dem Spieler verbinden Von Osten entdeckt Effekte Alarm 5.33 - Tod als Bedingung Um zu prüfen ob eine Einheit noch am Leben ist, benötigt man einen Auslöser mit den folgenden aufgeführten Einstellungen. Natürlich gibt es auch hier wieder verschiedene Varianten. Hier mal eine sehr oft verwendete Methode. Aktivierung Achse a/b Bedingung Keine 0 ! (alive Name) oder not alive Name Der Auslöser prüft nun durch Achse 0/0 global, ob Name noch lebt und löst bei Tod die bei Aktivierung oder Effekte gesetzten Aktionen aus. 5.34 - Distanz zweier Einheiten oder Objekte Manche Situationen machen es notwendig, dass man die Distanz zweier Einheiten oder Objekte als eine Bedingung für die Auslösung eines Auslösers oder ähnliches benötigt wird. Die Syntaxes hierfür sehen unter anderem wie folgt aus: Player distance Jeep1<= 50 oder Player distance Jeep1 == 50 Lokaler Variable Wert zuweisen: _distance = Player distance Jeep1 Textausgabe: titleText [format["%1 Meter", Player distance Jeep1], "plain down"] 5.35 - Einem Fahnenmast eine Flagge zuweisen Alle Fahnenmasten lassen sich individuell mit Fahnen bestücken. Das geht auch, wenn sie bereits eine Fahne haben, wie es ja in ArmA der Fall ist. Dazu packt man die jeweilige Fahne in den Missionsordner und gibt in der Initzeile der Fahne einfach den Namen der Datei mit der Dateierweiterung an. this setFlagTexture "Name.paa" Möglich sind die Dateiformate PAC, PAA und JPG in der Größe 512 x 256 Pixel. Spielintern sind folgende Flaggen mit dieser Syntax und diesem Pfand setzbar: this setFlagTexture "\ca\misc\data\usa_vlajka.paa" USA usa_vlajka_co.paa Sowjetunion rus_vlajka_co.pac Russland rus_vlajka_co.paa 120 Racs jih_vlajka.paa SLA sever_vlajka.paa 5.36 - Brennende Feuerstelle Möchte man ein Feuer erst zu einem späteren Zeitpunkt anzünden oder erlöschen, gibt man dem Feuer zunächst einen Namen und nutzt folgende Syntax: this inFlame true bzw. Name inFlame false 5.37 - Spielbare Einheit hinzufügen oder entfernen Mit den folgenden Befehlen ist es möglich dem Spieler während einer Mission switchbare Einheiten zuzuweisen oder auch zu entfernen. addSwitchableUnit Name - Einheit wird spielbar removeSwitchableUnit Name - Einheit wird unspielbar Möchte man als Spieler zu einer anderen Einheit wechseln, oder eine Einheit zum Leader machen, nutzt man folgende Syntaxes: selectPlayer Name oder group Name selectLeader Name Der einfache Befehl Teamswitch ruft das Teamswitchmenü auf. Die Seite eines Spielers im Mehspielerbereich lässt sich wie folgt auslesen: ? side Player == West ? name Player = = "Mr-Murray" Textausgabe: titleText [format["%1 -Soldat", side Player],"plain down"] titleText [format["Hey %1", name Player],"plain down"] titleText [format["Typ: %1", typeOf Player],"plain down"] 5.39 - Spielereingabe unterdrücken Für einige Dinge, wie zum Beispiel Sequenzen, ist es manchmal von Vorteil die Spielereingabe zu unterdrücken. Zum Aktivieren setzt man disableUserInput auf true und zum Deaktivieren wieder aus false. disableUserInput true 5.40 - Karte auf den Monitor erzwingen Das Erzwingen der Karte auf den Monitor ist ganz gut für Sequenzen oder ähnliches zu gebrauchen. Hier hat man dann die Möglichkeit die verschiedensten Dinge zu simulieren. Zum Beispiel Truppenbewegungen und vieles mehr. forceMap true Jetzt hat man u.a. die Möglichkeit Marker auf der Karte wandern zu lassen, um den Spieler in eine Situation einzuweisen. Dabei bietet es sich an die Spielereingabe zu unterdrücken. 121 Kapitel 5 5.38 - Spielerseite , -namen, -typ auslesen bzw. ausgeben 5.41 - Sichtweite ändern Für manche Bereiche oder Aktionen bietet es sich an die Sichtweite zu erhöhen oder herabzusetzen. Zum Beispiel bei einer Zwischensequenz, auf einem Berg, wo eine gute Aussicht dargestellt werden soll. So könnte man für diese kurze Szene die Sichtweite kurzzeitig erhöhen und später wieder herabsetzen um Performance einzusparen. Als Sichtweite kann hierbei zwischen 500 bis 10.000 gewählt werden. setViewDistance 500 5.42 - Wetter einstellen Das Wetter wird ja zunächst ganz normal im Editor definiert. Möchte man es aber im Missionsverlauf oder einer Sequenz ändern benötigt man folgend aufgeführte Syntax mit Werten zwischen 0 und 1. Je nach Mission bietet es sich immer an ein Zufallwetter zu bestimmen. Dies verbunden mit Zufallszeit und Zufallsnebel bringt gleich ein wenig mehr Abwechslung in die Mission. 120 setOvercast 0.8 Der erste Wert stellt die Zeit in Sekunden dar, in der das Wetter umschwenken soll. Der zweite Wert steht für die Wetterart. Ist dieser 0, scheint die Sonne und der Himmel ist Wolkenleer. Mit jedem Dezimalwert, der nun dazu kommt, tauchen mehr Wolken am Himmel auf. Bei einem Wert von 0.5 ist der Himmel komplett bewölkt und bei einem Wert von 1 ist mit starken Gewittern zu rechnen. Zufallswetter: Dieses lässt sich mit einer Zufallssyntax bestimmen, welche den Wetterwert per Zufall bestimmt und festlegt. Lässt man diese Syntax gleich zu Missionsbeginn starten, ist bei jedem Missionsstart mit einem anderen Wetter zu rechnen. 0 setOvercast (random 0.8) Regen: Der Regen lässt sich auch unabhängig von SetOvercast einstellen. 0 setRain 0.8 10 setRain (random 0.8) Nebel: Die Nebelwerte werden nach gleichem Verfahren wie beim Wetter oder Regen bestimmt. Jedoch lautet die Syntax hierfür: 10 setFog 0.6 60 setFog (random 0.8) 122 5.43 - Datum und Uhrzeit einstellen Auch dies ist während eines Missions- oder Kampagnenverlaufs möglich und kann dabei entweder mit einem festen Wert oder einer Zufallszeit bestimmt werden. Jahr, Datum, Uhrzeit: Mit folgend aufgeführter Syntax bestimmt man gleich das Jahr, den Tag, die Stunde und die Minute auf einmal. Das Ganze definiert man dabei wie folgt: setDate [2006, 11, 30, 9, 0] Hier wurde jetzt der 30.11.2006 mit der Uhrzeit 09:00 bestimmt. Natürlich lassen sich hier auch wieder einige Werte per Zufall generieren. Hier mit Uhrzeitbeispiel: setDate [2006, 11, 30, (ceil random 8), (random 60)] Uhrzeit: Die Uhrzeit kann man mit dieser Syntax auch einzeln bestimmen. - Stellt die Zeit um 1 Stunde vor - Stellt die Zeit um 1 Stunde zurück Kapitel 5 skipTime 1 skipTime –1 5.44 - Zeitlupe oder Zeitsprint Mit der nun folgenden Syntax ist es möglich das Spiel zu verlangsamen, also in Zeitlupe zu versetzen oder aber auch zu beschleunigen. Gerade bei Zwischensequenzen kann man hiermit geniale Zeitlupenszenen gestalten. Des Weiteren ist es aber auch möglich einen Bullet Mode, wie in Kapitel 6.10 erläutert, in die Mission einzubauen, was zwar nicht sonderlich realistisch ist, aber dennoch als Feature verwendet werden kann. Zeitlupe: Alle Werte unter 1 stehen hierbei für Zeitlupe, wobei gerade die Dezimalwerte den Effekt ausmachen. Je kleiner der Wert, desto langsamer der Ablauf. setAccTime 1 setAccTime 0.0500 - Normale Zeit - Zeitlupe Zeitsprint: So, wie man die Zeit verlangsamen kann, kann man sie auch beschleunigen, wofür es aber eigentlich im Missionsbereich selbst keine richtige Verwendung geben sollte. Hierbei gelten alle Werte zwischen 1 und 8, welche der KI und dem Spieler schnelle Füße verleihen. 123 5.45 - Einheiten und Objekte erzeugen Es ist während eines Missionsablaufs möglich Einheiten, ganze Gruppen oder auch Objekte frei auf der Karte zu erzeugen und auch wieder zu löschen. Damit kann man eine Menge Performance einsparen und die Einheiten erst erzeugen, wenn sie benötigt werden. Dabei gibt es verschiedene Varianten. Hier ein paar Beispiele. Objektbezogen: In folgendem Beispiel wird ein Geschütz mit Typ D30 an Position XYZ erzeugt: Ari1="D30" createVehicle [x,y,z] Mit dem setDir-Befehl richtet man dieses dann zusätzlich aus. Ari1 setDir 190 Es kommt vor, dass ein Vehikel nach dem Erzeugen nicht nutzbar ist. Dafür gibt man dann zusätzlich beim Erstellen den folgenden Befehl mit an: Ari1 lock false Somit ist es nun auf jeden Fall nutzbar. Möchte man ein Objekt direkt an der Position eines anderen Objektes oder eines Markers erzeugen, dann sieht das so aus: Bombe="SH_120_HE" createVehicle position Player Bombe="SH_120_HE" createVehicle getMarkerPos "Marker1" Folgend wird eine Bombe über der Einheit S1 in der Höhe von 50 Metern erzeugt. Bombe=“SH_120_HE” createVehicle [(getpos S1 select 0),(getpos S1 select 1),50] Einheitsbezogen: Zum Erzeugen einer Einheit wird die Zeile schon etwas länger. Hier wird ein Westsniper namens Name1 auf der Position seines Leaders namens S1, der vorher schon auf der Karte sein muss, erstellt. Der Leader könnte dabei auch eine Logik sein. Der nun erzeugte Soldat hat einen Skillwert von 0.4 und ist vom Dienstgrad her Corporal. "SoldierESniper" createUnit [position player, S1, "Name1=this",0.4,"Corporal"] Man kann das natürlich auch anders definieren, indem man als Position einen Marker angibt, welchen man zuvor auf die Karte an die Position des Leaders gesetzt hat. Diesem würde man bei Achse a/b einfach den Wert 0 geben, damit der Marker nicht sichtbar ist "SoldierESniper" createUnit [getMarkerPos "Marker1",EGrp1,0.8,"Corporal"] Dieser hat jetzt mal keinen Namen zugewiesen bekommen, weil man das nur machen muss, wenn man diese Einheit später auf irgendeine Art ansprechen möchte. Der Leader hieße in diesem Fall EGrp1. Folgend nochmal mit der Zuweisung einer Waffe: "SoldierWSniper" createUnit [position Player, Player, "this addweapon ""binocular"" ", 0.8, "Corporal"] 124 Gruppenbezogen: Neben einzelnen Einheiten lassen sich auch Gruppen erstellen. Dazu kann man die Gruppen gleich individuell mit Namen versehen und sie so dann später ganz einfach ansprechen. Als Beispiel soll hier folgendes Skript dienen, bei welchem eine Gruppe an der Position des Markers "GrpM" erstellt wird, den man zuvor auf die Karte gesetzt hat. Grp1 = Creategroup EAST; _Leader="SquadLeaderE" createUnit [getMarkerPos "GrpM", Grp1, "Grp1=this", 1, "Sergeant"]; _Unit2="SoldierEB" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; _Unit3="SoldierEB" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; _Unit4="SoldierEG" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; _Unit5="SoldierEMG" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; _Unit6="SoldierEAT" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; _Unit7="SoldierESniper" createUnit [getMarkerPos "GrpM", Grp1, "", 1, "Corporal"]; exit Merke: Erstellt man feindliche Einheiten erst im Laufe der Mission, ohne dass zuvor irgendwelche Einheiten dieser Seite auf der Karte platziert waren, muss man der Seite ein Center zuweisen, damit diese Einheiten miteinander kommunizieren können. Danach verwendet man den SetFriend-Befehl und verfeindet die Seiten miteinander. Macht man das nicht, wird die KI nicht auf gegnerische Einheiten feuern. Es bietet sich hierbei an, das Center und den SetFriend-Befehl in der Init.sqs zu initialisieren. Hat man jedoch von Anfang an Einheiten aller Kriegsparteien auf der Karte, so werden diese Center beim Missionsstart automatisch von der Engine erstellt. Folgend die Einträge in einer Beispiel-Init.sqs: Init.sqs Createcenter EAST Createcenter WEST WEST setFriend [EAST,0] EAST setFriend [WEST,0] Center So wie man ein Center erstellen kann, kann man es mit deleteCenter SEITE auch wieder löschen, was aber eher unsinnig und unwirksam ist. 125 Kapitel 5 Wie man sieht, wurde hier der ersten Einheit, die lokal Leader benannt wurde, ein höherer Dienstgrad zugewiesen, was sie automatisch zum Leader der Gruppe macht. Der Name der Gruppe ist nun, wie am Anfang des Skriptes definiert, GrpOne. Damit diese Gruppe nun auch in der Mission richtig agiert, muss man noch einen weiteren, sehr wichtigen Punkt beachten. 5.46 - Flares, Rauch und Explosionen erzeugen Zum Erzeugen einer Flare oder einer Rauchgranate über einem Objekt oder einer XYZPosition gilt zwar der gleiche Befehl, wie im Kapitel 5.45, aber die Klassennamen weichen von den Magazinnamen ab. Deshalb hier nochmal explizit. Flare1="F_40mm_Green" createVehicle [x,y,z] Oder über oder an der Position eines anderen Objektes: Rauch="Smokeshell" createVehicle [(getPos Name1 select 0),( getPos Name1 select 1), 10] Wobei dies in einer Zeile stehen muss, was hier nicht möglich ist. Oder in kurz: Rauch=" Smokeshell" createVehicle position Name Merke! Flares sollten generell ab einer Höhe von 100 Metern erzeugt werden! Dabei stehen folgende Flares F_40mm_White F_40mm_Red F_40mm_Green F_40mm_Yellow und folgende Rauch- und Gewehrgranaten zur Auswahl: Smokeshell SmokeshellRed SmokeshellGreen B_40mm_HE Natürlich kann man statt einer Flare oder einer Rauchgranate auch ganz andere Arten erzeugen. Zum Beispiel eine SH_125_HE oder ähnliches für eine Explosion. Dazu bitte im Kapitel 3.10 nachschlagen. Unter den Shellklassen sind diverse Explosionskörper aufgelistet. In der Vorschau sieht das dann später etwa so aus: 126 5.47 - Einheiten und Objekte löschen Während man zum Löschen von Objekten nur eine Syntaxform verwendet, benötigt man zum Löschen von Einheiten verschiedene Syntaxformen. Wenn man beispielsweise nur den Bordschützen eines Helikopters löschen will, der ja nicht mit einem Namen versehen wurde. Die Syntaxes schauen wie folgt aus: deleteVehicle Name - Löscht alles, was einen festen Namen besitzt. Möchte man nun den Bordschützen des Helikopters löschen, muss dieser das Fahrzeug zunächst verlassen. Vorher gibt man ihm aber noch einen Namen, indem man folgende Syntax in die Initzeile des Helis schreibt: Name=(Gunner Heli1) Jetzt lässt man ihn aussteigen, wobei man hier auch (Gunner Heli1) schreiben kann. Name action ["Eject", Heli1] oder einfach doGetOut Name Der Name wird erst beim Löschen wichtig, da (Gunner Heli1) nicht funktionieren würde. deleteVehicle Name Einheiten in Bereich löschen Dazu setzt man einen Auslöser beliebiger Größe und benennt ihn beliebig(hier: Zone1). Dann wählt man die Seite aus, die gelöscht werden soll oder stellt ihn mit Jeder auf alle Seiten und Objekte. Die Syntax für das Löschen schreibt sich dann: {deleteVehicle _x} forEach list Zone1 5.48 - Funkmenü verändern Hiermit hat man die Möglichkeit während einer Mission die Einträge im Funkmenmü umzubenennen. Diese sind von der Engine her von 1 bis 10 durchnummeriert. 1=Alpha, 2=Bravo, 3=Charlie, ... Umbenennen kann man Diese mit folgender Syntax: 1 setRadioMsg "Alpha-Team" Der erste Eintrag von Radio Alpha wurde nun in Alpha Team umbenannt. Möchte man einen leeren Funkmenüeintrag haben, setzt man statt einem Text einfach ein Leerzeichen zwischen die Anführungsstriche. Die Funkmöglichkeit ist zwar eigentlich noch da, aber der Spieler sieht sie nicht und denkt, dass sie nicht verfügbar ist. Statt dem Text wäre dann nichts zu sehen. Dies kann man nutzen, wenn zum Beispiel ein Team ausfällt oder ähnliches. 127 Kapitel 5 Außer dem Gunner gibt es noch den Commander, den Driver und die Crew. 5.49 - Einer Gruppe ein Rufzeichen zuweisen Mit setGroupId ist es möglich verschiedenen Gruppen verschiedene Rufzeichen zuzuweisen. Somit weiß man immer genau, wer gerade gesprochen hat oder einen Sidechat abgegeben hat. Mit Armed Assault hat man im Gegensatz zu Operation Flashpoint nun auch die Möglichkeit seinen Gruppen uneingeschränkt eigene Namen zu geben. und eine freie Farbe zu definieren. Hier die Syntaxbeispiele: Standard: Name setGroupID ["Alpha","GroupColor0"] Freier Text: Name setGroupID ["Assault-Team-Alpha","GroupColor2"] Standardmäßig stehen folgende Werte für Gruppenname und -farbe zur Auswahl: Gruppennamen: "Alpha" "Bravo" "Charlie" "Delta" "Echo" "Foxtrot" "Golf" "Hotel" "Kilo" "Yankee" "Zulu" "Buffalo" "Convoy" "Guardian" "November" "Two" "Three" Gruppenfarben: 0 – keine Farbe 1 – Schwarz 2 – Rot 3 – Grün 4 – Blau 5 – Gelb 6 – Orange 7 – Rosa Tipp: Seitens des Spiels gibt es ab und dann Probleme, dass die Farbe nicht ausgegeben wird, was aber schon seit Operation Flashpoint bekannt ist. Dies umgehen wir einfach, indem wir beides in eine Zeile schreiben. Die Farbe gibt man dabei manuell an und lässt den hinteren Part, wo man diese normalerweise angibt, einfach offen. Bei folgendem Beispiel heißt das Team Assault-Team-Alpha und hat die Farbe Red bekommen. Name setGroupID ["Assault-Team-Alpha - Red",""] 128 5.50 - Funkspruch abgeben Hierbei gibt es verschiedene Möglichkeiten diese auszugeben. Dabei können diese global, seiten-, gruppen- oder vehikelbezogen angezeigt werden. Hier die Syntaxform mit den verschiedenen Varianten: Name sideChat "Test 1-2" Name groupChat "Test 1-2" Name globalChat "Test 1-2" Name vehicleChat "Test 1-2" Name spricht zu seiner Truppenseite Name spricht nur zu seiner Gruppe Name spricht zu allen Seiten Name spricht zu Leuten innerhalb seines Fahrzeuges Möchte man einen Funkspruch durch das Hauptquartier abgeben lassen: [Seite,"HQ"] sideChat "Move to your position and wait for further orders!" Der Befehl enableRadio false blendet die Funksprüche aus und macht sie unsichtbar. Was in Operation Flashpoint nicht möglich war, wurde in Armed Assault berücksichtigt. Das trifft neben den vielen anderen neuen Möglichkeiten auch auf diesen Bereich zu. Man hat jetzt die Möglichkeit, die spielinternen Sounds an einer bestimmten Position zu erstellen. Im folgenden Beispiel wird der Sound namens LittleDog an der Position des Spielers erstellt. Hund1=createSoundSource ["LittleDog",position Player,[],10] Der Wert 10 steht dabei für die Entfernung vom Spieler. Natürlich kann man diesen jetzt beliebig versetzen, da er beim Erstellen den Namen Hund1 bekommen hat und somit ansprechbar ist. Das geht dann, wie schon bekannt, mit: Hund1 setPos getPos Name So kann man sich nun beliebig die Sounds aus ArmA erstellen lassen, ohne irgendwas auf der Karte setzen zu müssen. Die Sounds findet man hierbei unter Leer/Sounds oder in einem Auslöser bzw. Wegpunkt unter Effekte. Unter anderem gibt es folgende Sounds: Stream, Alarm, BadDog, BirdSinging, Chicken, Cock, Cow, Crow, Crickets1, Crickets2, Crickets3, Crickets4, Dog, Frog, Frogs, LittleDog, Music, Owl, Wolf Möchte man eigene Sounds mit diesem Befehl irgendwo erstellen, so müssen diese erst in der Description.ext vordefiniert werden und können dann ganz normal mit der Angabe des in der Description.ext festgelegten Namens aufgerufen werden. MeinSound=createSoundSource ["Soundname",position Player,[],10] 129 Kapitel 5 5.51 - Sound erstellen 5.52 - Eigenen Sound einbinden Wenn man eigenen Sound oder Musik in eine Mission einbinden möchte, so geht das nur über die Description.ext, die bereits im Kapitel 2.3 erklärt wurde. Hier nun die explizite Erklärung zum Thema Musik und Sounds einfügen. Zunächst legt man im Missionsordner einen Ordner namens Sounds und einen Ordner namens Music, natürlich klein geschrieben, an und packt dort seine Sounddateien rein. Die Description bietet dafür verschiedene Unterbereiche, so dass man diese einzeln steuern kann, wenn man zum Beispiel die Melodie von der Lautstärke her runterfadet, soll der Funkspruch, der gleichzeitig läuft seine Lautstärke behalten. Deshalb gibt es dafür verschiedene Unterbereiche(Soundklassen). Die Sound- oder Musikdefinierung sieht in der Description.ext etwa wie folgt aus: Description.ext // === Musik ================================================> class CfgMusic { tracks[]= { Track1,Track2 }; class Track1 { name = "Track1"; sound[] = {\music\track1.ogg, db+0, 1.0}; }; class Track2 { name = "Track2"; sound[] = {\musik\track2.ogg, db+0, 1.0}; }; }; // === Sounds ===============================================> class CfgSounds { sounds[]= { Artillerie }; class Artillerie { name = " Artillerie "; sound[] = {\sounds\ artillerie.ogg, db+0, 1.0}; }; }; Weiter auf nächster Seite. 130 // === Radio/Funk ============================================> class CfgRadio { sounds[] = {Funk1}; class Funk1 { name = "Funk1"; sound[] = {"sound\funk1.ogg", db+5, 1.0}; title = “Das ist ein Funkspruck!; }; }; // === Umgebung ============================================> class CfgSFX { sounds[] = {}; }; Kapitel 5 class CfgEnvSounds { sounds[] = {}; }; Wie man oben sehen kann, sind dann noch Bereiche wie Funk (Radio) und zwei verschiedene Umgebungssoundklassen definiert. class CfgMusic { tracks[]= { Track1,Track2 }; class Track1 { name = "Track1"; sound[] = {\music\track1.ogg, db+0, 1.0}; titles[] = { }; }; }; - Klasse CfgMusic - Trackliste - Klasse Track1 - Name Track1 - Quelle, db = Laustärke, 1.0 = Geschwindigkeit - Texteinblendung zum Sound Mit db hat man die Möglichkeit die Lautstärke der Sounddatei festzulegen. Dabei kann man kann gut zu laute oder zu leise Dateien entsprechend anpassen. Die Geschwindigkeit, welche oben mit 1.0 festgelegt ist, bestimmt die Geschwindigkeit mit der die Sounddatei abgespielt wird. Somit kann man Sprachsamples höher oder tiefer klingen lassen. Doch sollte man den Wert nicht zu hoch setzen, sonst hat man schnell den M-Mouse Effekt. 131 Möchte man dann eine Sounddatei im Editor abspielen, so wählt man die im Wegpunkt oder einem Auslöser im Untermenü Effekte aus. Dazu muss man die Mission erst neu geladen oder gespeichert haben, damit ArmA die Description neu einlesen kann. Die nun definierten Sounds lassen sich natürlich auch per Syntax starten. playMusic "Track1" playMusic ["Track1", 30] (Spielt Track1 ab Sekunde 30) playSound "Artillerie" Name say "Soundname" Die lassen sich natürlich auch, wie schon erwähnt in der Laustärke herunterfaden. 10 Fadesound 0.5 10 Fademusic 1 0 FadeRadio 0.1 Der erste Wert steht für die Zeit in der das geschehen soll und der zweite Wert für den jeweiligen Lautstärkenwert, den der Sound erhalten soll. Der Befehl preLoadSound ermöglicht es, den Sound vorab in den Speicher zu laden. preLoadSound "Track1" Sounds mit Text verknüpfen Sounds lassen sich ohne Weiteres mit Text verknüpfen. Dabei kann man auf einen Stringtablewert zurückgreifen oder einen eigenen Text direkt in der Description.ext mit angeben. Der Text wird dann beim Abspielen des Sounds mit angezeigt. Im Normalfall nutzt man das bei der Wiedergabe von Sprach- oder Funksounds. In der Description.ext sieht das dann etwa wie folgt aus: // === Radio ================================================> class CfgRadio { sounds[] = {RadioMsg1, RadioMsg2}; class RadioMsg1 { name = "RadioMsg2"; sound[] = {"\sound\ radiosound1.ogg", db+10, 1.0}; title = "It´s done. Now I´m ready for further orders."; }; class RadioMsg2 { name = "RadioMsg2"; sound[] = {"\sound\radiosound2.ogg", db+10, 1.0}; title = {$STR_RADIO_2}; }; }; 132 Zufallssound aus einem Array abspielen Auch im Soundbereich ist es durchaus möglich so einiges per Zufall zu bestimmen. Eine beliebte Methode ist dabei, die Sounds in einem Array zu definieren und diese dann später per Zufall auswählen zu lassen. Dies wird in folgendem Beispiel mal mit einem Skript umgesetzt, wobei die eingetragenen Musikstücke keine Description.ext erfordern, weil sie direkt in der Engine definiert sind. Dieses von uns angelegte Script kann nun ganz normal mit [] exec “scripts\music.sqs” aufgerufen werden. Hierbei wird nun bei jedem Skriptaufruf ein Sound per Zufall aus dem vordefinierten Array ausgewählt und abgespielt. _music = ["ATrack1","ATrack6", "ATrack10", "ATrack11", "ATrack12", "ATrack13", "ATrack14", "ATrack15", "ATrack19", "ATrack22"]; playMusic ( _music select floor(random((count _music) - 0.5 ))); exit; playMusic format ["ATrack%1",ceil random 27]; Tipp: Folgende Tracks benötigen ebenfalls keine Description.ext-Einträge: WithCare_Smile - WithCare_Suicide - WithCare_War - WithCare_What Selbstverständlich kann man statt der Musik eben auch ganz andere Soundarten verwenden. Wenn diese nicht in der Engine defniert sind, muss man sie eben selbst in seiner eigenen Description.ext definieren. Folgendes Syntaxbeispiel zeigt das Ganze nochmal mit dem Befehl Say. Name1 say format ["Hilfe%1",ceil random 3]; Da die generierten Zufallswerte nie genau rund sind, werden sie mit dem Ceil-Befehl aufoder abgerundet, damit es einen runden Wert ergibt und die Engine weiß, welcher Sound abgespielt werden soll. 133 Kapitel 5 Zufallssound ohne Skript aufrufen Eine weitere sehr gute Methode der Sounddynamic wäre das nun folgende Syntaxbeispiel, wobei man bei diesem aber die Auswahl der Sounds weniger gut selbst bestimmen kann. Wichtig ist hierbei, dass die Sounds, alle den gleichen Namen haben und am Ende eine Zahl. Also zum Beispiel: Track1, Track2, u.s.w.. Hierbei werden nun wieder armainterne Sounds verwendet, welche nach dem gleichen Prinzip von ATrack1 bis ATrack27 definiert sind. Die Namen der Queen´s Gambit Tracks gehen von QGTrack1 bis QGTrack9. Bei der nun folgenden Sytax steht statt der eigentlichen Zahl nur %1, welches in dem Fall als Platzhalter für die Zahl steht. Im hinteren Teil der Syntax wird festgelegt aus welchem Wert von 0 bis, in diesem Fall 27, die Zahl generiert werden soll und für %1 eingesetzt. 5.53 - Identität festlegen Es lässt sich für jede Einheit in einer Mission eine Identität festlegen. Dies ist aber nicht unbedingt ratsam, weil es ein riesiger Aufwand wäre. Deshalb sollte man sich mit dem Vergeben von Identitäten lieber auf die Schlüsselpersonen beschränken. Eine Identität wird zunächst in der Description.ext vordefiniert, bevor sie eingebunden werden kann. Das Ganze sieht dann ungefähr so aus. class CfgIdentities { class MrMurray { name = "MrMurray"; face = "Face33"; glasses = "none"; speaker = "Dan"; pitch = 1.00; }; class MemphisBelle { name = "MemphisBelle"; face = "Face10"; glasses = "none"; speaker = "Howard"; pitch = 1.00; }; class Dan { name = "Dan"; face = "Face22"; glasses = "none"; speaker = "Russell"; pitch = 1.00; }; }; Wie man erkennen kann, kann man die Namen frei vergeben. Lediglich die Gesichter und der Sprecher sind hierbei vorgegeben. Bitte auch wieder auf die Einhaltung der Klammern in der Description.ext achten! Möchte man im Spiel dann die Identität der jeweiligen Einheit zuweisen, schreibt man lediglich den vordefinierten Namen mit der Syntax in die Initzeile: Name setIdentity "DeinName" oder this setIdentity "Mr-Murray" 134 Diese Indentität lässt sich in Verbindung mit einer Kampagne auch speichern und später wieder laden. Der Wert wird dabei direkt in der Objects.sav der Kampagne gespeichert und kann mit deleteIdentity "xyz" ganz leicht wieder gelöscht werden. Name saveIdentity "Name1Save" oder Name loadIdentity "Name1Save" Man kann einer Einheit auch nur ein Gesicht zuweisen, das geht dann hiermit: Name setFace "Face33" oder this setFace "Face33" In Armed Assault stehen 57 Faces, die mit Face1 bis Face53 und FaceR01 bis FaceR04 durchnummeriert sind, zur Auswahl. Hat man eine eigene Facedatei im Missions- bzw. Userordner: Name setFace "MeinBild.jpg" Kapitel 5 Mögliche Größen: 1024*1024; 512*512; 256*256 Optimale Größe: 512*512; Dateigröße 100 Kb Brille (Glasses): Hier eine Übersicht der Brillenarten, die man in ArmA vergeben kann: glasses = "spectacles"; glasses = "sunglasses"; glasses = "none"; Normale Brille Sonnenbrille Keine Brille Sprecher: Folgende Sprecher stehen bis jetzt in ArmA zur Auswahl: Amy Dan Howard Robert Brian Dusan Mathew Russell Ryan Pitch: Mit dem Pitchwert (pitch = 1.00) wird hierbei die Sprachhöhe oder -tiefe definiert. 5.54 - Mimiken Mit folgenden Befehlen kann man den Einheiten Mimiken zuweisen. Das bedeutet, dass man ihnen verschiedene Stimmungen wie fröhlich, ernst oder traurig zuweisen kann. Name setMimic "Smile" Normal - Surprised - Agresive - Hurt - Ironic - Smile - Cynic - Angry - Sad - Default Folgende Animation verändert die Gesichtszüge mit den Werten 0 bis 1. Name setFaceAnimation 0.5 135 5.55 - Der Actionbefehl Die Actionbefehle weisen der jeweiligen Einheiten einen Befehl zu, was diese zu machen hat. Dabei gibt es verschiedene Varianten wie man diese definieren kann. Hier die nähere Erläuterung dazu: Object: Type: Target: Die Einheit(Name), die diese Aktion ausführen soll. Nimmt man ein Fahrzeug, wird der Commander gewählt. Name der Aktion (siehe Actionbefehlsübersicht) Meistens der gleiche Name, wie Name Syntaxformen: Hier die verschiedenen Syntaxformen, die dafür in Frage kommen können: Name action [<type>] Name action [<type>, <target>] Name action [<type>, <target>, zusätzliche Parameter] Für zusätzliche Parameter trägt man beispielsweise die Waffe oder die Magazine ein, wie es in der Liste beschrieben ist. Neben Action gibt es noch Fire, was sich aber auf die wenigsten Befehle bezieht. Folgend nun mal ein paar Beispiele: Name fire ["PipebombMuzzle", "PipebombMuzzle", Pipebomb] - legt Sprengsatz ["M203Muzzle", "M203Muzzle", "1Rnd_HE_M203"] - schießt Granate ["M203Muzzle", "M203Muzzle", "FlareGreen_M203"] - schießt Flare ["HandGrenadeMuzzle", "HandGrenadeMuzzle", "HandGrenade"] - wirft Granate ["SmokeShellRedMuzzle", "SmokeShellRedMuzzle", "SmokeShellRed"] - Wirft Rauch ["bombLauncher", "BombLauncher", "6Rnd_GBU12_AV8B"] - Harrier wirft Bombe ab Name action 136 ["TouchOff",Name] ["Eject",Heli1] - löst Sprengsatz aus - steigt aus ["Hidebody", Name2] ["CancelAction", Name] - versteckt Leiche - bricht Aktion ab Actionbefehlsübersicht Folgend nun eine Befehlsübersicht über die wichtigsten Aktionbefehle. Einige funktionieren von Haus aus nicht bzw. sind von Haus aus noch nicht aktiviert worden. Kapitel 5 ["None", <target>] ["GetInCommander", <target>] ["GetInDriver", <target>] ["GetInGunner", <target>] ["GetInCargo", <target>] ["Heal", <target>] ["Repair", <target>] ["Refuel", <target>] ["Rearm", <target>] ["GetOut", <target>] ["LightOn", <target>] ["LightOff", <target>] ["EngineOn", <target>] ["EngineOff", <target>] ["SwitchWeapon", <target>, <weapon index>] ["UseWeapon", <target>, <weapon index>] ["TakeWeapon", <target>, <weapon name>] ["TakeMagazine", <target>, <magazine type name>] ["TakeFlag", <target>] ["ReturnFlag", <target>] ["TurnIn", <target>] ["TurnOut", <target>] ["WeaponInHand", <target>, <weapon name>] ["WeaponOnBack", <target>, <weapon name>] ["SitDown", <target>] ["Land", <target>] ["CancelLand", <target>] ["Eject", <target>] ["MoveToDriver", <target>] ["MoveToGunner", <target>] ["MoveToCommander", <target>] ["MoveToCargo", <target>] ["HideBody", <target>] ["TouchOff", <target>] ["SetTimer", <target>] 137 ["Deactivate", <target>] ["NVGoggles", <target>] ["ManualFire", <target>] ["AutoHover", <target>] ["StrokeFist", <target>] ["StrokeGun", <target>] ["LadderUp", <target>, <ladder index>, <ladder position>] ["LadderDown", <target>, <ladder index>, <ladder position>] ["LadderOnDown", <target>, <ladder index>, <ladder position>] ["LadderOnUp", <target>, <ladder index>, <ladder position>] ["LadderOff", <target>, <ladder index>] ["FireInflame", <target>] ["FirePutDown", <target>] ["LandGear", <target>] ["FlapsDown", <target>] ["FlapsUp", <target>] ["Salute", <target>] ["ScudLaunch", <target>] ["ScudStart", <target>] ["ScudCancel", <target>] ["User", <target>, <action index>] ["DropWeapon", <target>, <weapon name>] ["DropMagazine", <target>, <magazine type name>] ["UserType", <target>, <action index>] ["HandGunOn", <target>, <weapon name>] ["HandGunOff", <target>, <weapon name>] ["TakeMine", <target>] ["DeactivateMine", <target>] ["UseMagazine", <target>, <magazine creator>, <magazine id>] ["IngameMenu", <target>] ["CancelTakeFlag", <target>] ["CancelAction", <target>] ["MarkEntity", <target>] ["Talk", <target>] ["Diary", <target>] ["LoadMagazine", <target>, <magazine creator>, <magazine id>, <weapon name>, <muzzle name>] 138 5.56 - Der Animationsbefehl Ein Animationsbefehl lässt eine Einheit eine Animation ausführen. Hierbei gibt es aber Unterschiede. Da gibt es einmal den Befehl SwitchMove, mit welchem die Einheit in die Animation geswitcht/geschaltet wird und PlayMove, mit welchem sie die Animation abspielt. Manche Befehle arbeiten nicht mit dem PlayMove-Befehl, wobei man dann auf den SwitchMove-Befehl zurückgreift. Des Weiteren dauert jede Animation eine gewisse Zeit. Diese sollte man berücksichtigen, wenn die Einheit danach eine weitere Animation ausführen soll. Dazu setzt man einfach einen Delay (z.B.: ~10) zwischen die Befehlszeilen in seinem Skript. Animationsbefehle sind eine nettes Feature für das Drumherum. Zum Beispiel ein Lager, in welchem Einheiten Sport treiben, sich Unterhalten oder ein Soldat grüßt, wenn jemand durch das Tor fährt. All das regelt man mit den Animationsbefehlen. Die Syntaxformen für das Ausführen einer Animation sehen dabei so aus: Name playMove "Animationsbefehl" Name switchMove "Animationsbefehl" Für das Erstere gibt es zum Beispiel folgende Möglichkeit: (Units group Grp1 select 2) playMove "Animation" Hier würde jetzt die Einheit 3 der Grp1 die Animation ausführen. Aber wieso eigentlich die Einheit 3, wenn dort select 2 steht? Das erklärt sich wie folgt: select 0 select 1 select 2 - Leader Einheit 2 Einheit 3 Gruppenzufalls-Variante Das Ganze ist natürlich auch wieder per Zufall. möglich. Das sieht dann wie folgt aus: ((Units group Grp1) select ceil random 5) playMove "AnimationsName" Hierbei würde nun mit ceil random 5 ein Zufallswert zwischen 0 und 5 erzeugt, welcher nun die jeweilige, per Zufall ausgewählte Einheit der Gruppe Grp1, die Animation ausführen lässt. Die Gruppe sollte hierbei natürlich auch die richtige Größe von mindestens 6 haben. 139 Kapitel 5 Gruppenbezogen Neben den Standartbefehlen gibt es natürlich wieder die verschiedensten Möglichkeiten per Zufall zu bestimmen wer eine solche Animation ausführen soll oder welche Animation einer bestimmten Sorte ausgeführt werden soll. Zufallsanimation Hierbei gibt es verschiedene Varianten, wobei wir uns hier jetzt mal auf zwei beschränken. Zunächst gibt es die Variante, bei der die Animationen nummeriert sind, wie zum Beispiel die Panik-Animation, die von ActsPercMstpSnonWnonDnon_Panicking1 bis 7 durchnummeriert ist. Wichtig ist hierbei, dass der Name der Animation exakt gleich ist und nur der angehangene Wert, in Form einer Zahl, von einer anderen Animation unterscheidet. Name playMove format ["Animation%1",ceil random 7]; Zufallsanimation aus einem Array beziehen Die andere Variante wählt eine Animation aus einem Array aus. Der Vorteil daran ist, dass man in diesem Array diverse verschiedene Animationen festlegen kann. Dies macht man gewöhnlich mit einem Skript, welches dabei wie folgt aussehen kann: [Name] exec "scripts\animation.sqs" _Unit = _this select 0 _Anim = ["Anim1", "Anim2", "Anim3", "Anim4", "Anim5", "Anim6"]; _Unit playMove ( _Anim select floor(random((count _Anim) -0.5 ))); exit; Animationsstatus Der Animationsstatus gibt wieder, ob die Animation noch läuft oder schon beendet ist. Dies lässt sich nun natürlich wieder für diverse Dinge zu Nutze machen. ? animationState _Unit == "Anim1" : hint “Anim läuft” Animationswechsel verhindern Wer kennt das nicht, dass eine Einheit nach einer gewissen Zeit die Animation abbricht und wieder in die Ausgangshaltung wechselt. Dies tut sie genau dann, wenn die Animation beendet ist. Möchte man aber, dass die Einheit in jedem Fall in der gegebenen Animation verharren soll, muss man sich den DisableAI-Befehl zu Nutze machen. Dazu gibt man der Einheit zunächst den Befehl die Animation auszuführen und direkt im Anschluss verwendet man den Befehl DisableAI, was wie folgt aussieht: Name playMove "Animationsbefehl" Name disableAI "Anim" Möchte man, dass die Einheit irgendwann wieder aus der gehaltenen Animation auftaut und wieder in die normale Haltung wechselt, ruft man einfach folgende Syntax auf: Name enableAI "Anim" Eine weitere Möglichkeit einer Animationsschleife ist die Vergabe eines Eventhandlers. Name switchMove "Animation"; Name addEventHandler ["AnimDone", {Name switchMove "Animation"}]; 140 Folgend eine Liste der wichtigsten Animationsbefehle: Animation Bezeichnung 141 Kapitel 5 Setzt sich hin AmovPsitMstpSlowWrflDnon Sitzt ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_Loop1 Sitzt und redet ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_Loop2 Sitzt und redet ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_Loop3 Sitzt und redet ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_Loop4 ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_LoopLong Sitzt und redet Steht rum ActsPercMstpSnonWnonDnon_MarianQ_WarReporter Wirft liegend Granate AwopPpneMstpSgthWnonDnon_throw Wirft Granate AwopPercMstpSgthWrflDnon_Throw1 Schwimmt AswmPercMrunSnonWnonDf_AswmPercMstpSnonWnonDnon Stirbt DeadState SprintBaseDf (SprintBaseDfL=rennt links / SprintBaseDfR rennt rechts) Rennt mit Waffe SprintCivilBaseDf (SprintCivilBaseDfL=links / SprintCivilBaseDfR=rechts) Rennt ohne Waffe Benutzt Fernglas AmovPercMstpSnonWnonDnon_AwopPercMstpSoptWbinDnon Nimmt Haltung an AmovPercMstpSnonWnonDnon_Ease AmovPercMstpSnonWnonDnon_AmovPknlMstpSnonWnonDnon Kniet auf einem Knie Hände hinter Kopf AmovPercMstpSsurWnonDnon Legt etwas hin (Pipebomb) AmovPercMstpSnonWnonDnon_AinvPknlMstpSnonWnonDnon Setzt sich auf Boden AmovPercMstpSlowWrflDnon_AmovPsitMstpSlowWrflDnon Kniet nieder und keucht AinvPknlMstpSnonWnonDnon_AmovPknlMstpSrasWpstDnon Kniet nieder und keucht AinvPknlMstpSlayWrflDnon_AmovPknlMstpSrasWrflDnon Heilanimation AinvPknlMstpSlayWrflDnon_healed Heilanimation AinvPknlMstpSlayWrflDnon_healed2 Heilanimation AinvPknlMstpSnonWnonDnon_healed_1 Heilanimation AinvPknlMstpSnonWnonDnon_healed_2 Verarztet Opfer AinvPknlMstpSlayWrflDnon_medic Verarztet Opfer AinvPknlMstpSnonWnonDnon_medic_1 Verarztet Opfer AinvPknlMstpSnonWnonDnon_medic_2 Schultert Waffe AidlPercMstpSnonWnonDnon08 Kniet nieder (Waffenkiste) AinvPknlMstpSnonWnonDnon_1 Kniet nieder (Waffenkiste) AinvPknlMstpSnonWnonDnon_2 Kniet nieder (Waffenkiste) AinvPknlMstpSnonWnonDnon_3 Kniet nieder (Waffenkiste) AinvPknlMstpSnonWnonDnon_4 Geht in Stellung AmovPercMrunSlowWrflDf_AmovPpneMstpSrasWrflDnon Fahrzeugkontrolle AmovPercMstpSnonWnonDnon_carCheckPush Fahrzeugkontrolle AmovPercMstpSnonWnonDnon_carCheckWheel Wäscht Fahrzeug AmovPercMstpSnonWnonDnon_carCheckWash Macht Kampfsport AmovPercMstpSnonWnonDnon_exerciseKata Kniebeugen lang. AmovPercMstpSnonWnonDnon_exercisekneeBendA Kniebeugen schell AmovPercMstpSnonWnonDnon_exercisekneeBendB Liegestütze AmovPercMstpSnonWnonDnon_exercisePushup Wird am Bein getroffen AmovPercMwlkSlowWrflDf_ActsPercMstpSlowWrflDnon_HitLeg AmovPercMstpSlowWrflDnon_ActsPercMstpSlowWrflDr_HideFromFire Weicht Beschuss aus ActsPpneMstpSnonWnonDnon_AmovPercMstpSnonWnonDnon_Injured3 Lehnt getroffen an etwas an Vorwärts Männer AsigPercMstpSlowWrflDnon_AmovPercMrunSlowWrflDnon_GoGo Animation Bezeichnung AmovPercMstpSlowWrflDnon_Salute AmovPercMstpSnonWnonDnon_seeWatch AmovPercMstpSnonWnonDnon_talking AmovPercMstpSlowWrflDnon_talking ActsPercMstpSnonWnonDnon_MarianQ_shot1man ActsPercMstpSnonWnonDnon_MarianQ_shot3man ActsPercMstpSnonWnonDnon_MarianQ_shot4man ActsPercMstpSnonWnonDnon_MarianQ_shot5man ActsPercMstpSnonWnonDnon_MarianQ_TVstudioMan_Loop1 AmovPsitMstpSlowWrflDnon_Smoking AmovPsitMstpSlowWrflDnon_WeaponCheck1 (Gilt von 1-2) AmovPsitMstpSnonWnonDnon_ground AmovPsitMstpSlowWrflDnon ActsPercMstpSnonWpstDnon_InterrogationSoldier ActsPercMstpSnonWnonDnon_InterrogationVictim ActsPercMstpSnonWrflDnon_ArrestingSoldier ActsPercMstpSnonWnonDnon_ArrestingMan ActsPercMstpSnonWnonDnon_ArrestingManLoop AmovPlieMstpSnonWnonDnon ActsPknlMstpSnonWnonDnon_TreatingInjured ActsPpneMstpSnonWnonDnon_Injured1 (Zahl gilt von 1-2) ActsPknlMstpSnonWrflDnon_TreatingSoldier AsigPercMstpSlowWrflDnon_SendMenInAction ActsPercMstpSlowWrflDnon_listeningOrdersUnderFire ActsPknlMstpSnonWnonDnon_ThingPassingStill ActsPercMrunSlowWrflDf_FlipFlopPara AsigPercMstpSlowWrflDnon_GoGo ActsPercMstpSnonWnonDnon_ThingPassingStill ActsPercMstpSlowWrflDnon_ThingPassingMoving ActsPercMwlkSlowWrflDnon_PatrolingBase1 (Zahl gilt von 1-4) ActsPercMstpSlowWrflDnon_Lolling ActsPercMstpSnonWnonDnon_DancingDuoIvan ActsPercMstpSnonWnonDnon_DancingDuoStefan ActsPercMstpSnonWnonDnon_DancingStefan ActsPpneMstpSnonWnonDnon_Panicking ActsPercMstpSnonWnonDnon_Panicking1 (Gilt von 1 bis 7) ActsPercMrunSlowWrflDf_TumbleOver ActsPknlMstpSlowWrflDnon_ThingPassingMoving ActsPercMstpSlowWrflDnon_Listening ActsPercMstpSnonWnonDnon_Listening ActsPercMstpSnonWnonDnon_Talking1 (Zahl gilt von 1-2) ActsPercMstpSlowWrflDnon_Talking1 (Zahl gilt von 1-2) m2s1kancler m2s2kancler m2s1pobocnik m2s2Zoldak1 Soldat grüßt Schaut auf die Uhr Unterhält sich Unterhält sich Unterhält sich Unterhält sich Sicherung Sicherung 2 Sitzt Sitzt und raucht Sitzt, checkt Waffe Sitzt/Hände hinten Sitzt / Waffe auf dem Schoß Verhör Verhöropfer Verhaftung einer Person Verhaftungsopfer Liegt gefesselt Legt sich getroffen auf Boden Windet sich vor Schmerzen Windet sich vor Schmerzen Behandelt Verletzten im Kampf Gibt geduckt Anweisungen Hört Anweisungen geduckt zu Kniet auf Boden und redet Läuft und mach Vorwärtsrolle Vorwärts Männer Ausweiskontrolle Ausweiskontrolle Langweilige Wache Gähnt und streckt sich Tanzt fröhlich Tanzt fröhlich Tanzt fröhlich Panikanimation Panikanimation Stoplert, rennt weiter Läuft geduckt und sichert Hört sich Ansprache an Hört sich Ansprache an Steht ohne Waffe und redet Steht mit Waffe und redet Läuft/ gibt Zeichen Steht und hört zu Steht und erzählt Steht und ziehlt 142 Bezeichnung m2s2Zoldak2 m2s2Orlando_centered m2s2Wicks_centered m2s2Lamb_centered m2s2kancler_centered m2s2bodyguard_centered XOutroZoldak1 XOutroZoldak2 XOutroLamb XOutroOrlando m1s1Wicks m1s2Wicks m2s1wicks m2s2Wicks m2s3Wicks x01Wicks m5s1orlando m2s2Orlando m2s3Orlando m6aS1Orlando m6aS2Orlando x03Orlando x04Orlando m5s1Gonzales m6aS1Gonzales m6aS2Gonzales M6bs2Gonzales M6bs3Gonzales x04Gonzales x05s1Gonzales x05s2Gonzales x05s4Gonzales x05s5bGonzales m1s1Pedros x05s1Lamb x05s2Lamb x05s3Lamb x05s4Lamb x05s5aLamb x05s5bLamb M6bs2Lamb M6bs3Lamb x01Lamb x03Lamb m1s2lamb m5s1Lamb Steht / ziehlt aus Hüfte Hebt Hände / schützt sich Steht mit Gewehr in Hüfte Hält Waffe nach oben Läuft panisch umher Steht mit erhobenen. Händen und fällt Steht nach vorn gebeugt Leht sich an jemanden an Waffe in Hüfte und nickt Steht mit verschränkten Armen Hält Waffe am Tragegriff Hält Waffe auf Hüfte hoch/gibt Zeichen Hält Waffe auf Hüfte hoch Hält Waffe in Vorhalte Liegt getroffen am Boden Hält Waffe am Tragegriff/gibt Zeichen Läuft mit gesch. Waffe umher/gestikuliert Hebt Hände, läuft umher und schützt sich Steht mit geschulteter Waffe Steht mit verschränkten Armen Steht mit verschränkten Armen Läuft herum Läuft herum und gestikuliert Läuft herum und gestikuliert Steht und hört zu Läuft herum und gestikuliert Läuft herum und gestikuliert Steht, gestikuliert und verschränkt Arme Schaut auf Boden und läuft umher Steht mit Hand am Kinn Steht mit Hand am Kinn und gestikuliert Joggt nach vorne und erzählt Faltet Hände und erklärt Ruft um Hilfe und zeigt auf etwas Steht mit erhobener Waffe Steht mit erhobener Waffe Steht mit erhobener Waffe u. gestikuliert Steht mit erhobener Waffe und läuft Steht mit erhobener Waffe u. gestikuliert Steht mit erhobener Waffe u. gestikuliert Läuft mit Waffe unterm Arm und gestikuliert Steht mit Waffe unterm Arm Läuft mit erhobener Waffe Läuft mit Waffe in Vorhalte Hält Waffe hoch und Hand auf den Rücken Hält Waffe hoch und Hand auf Magazin Kapitel 5 Animation 143 5.57 - KI abschalten Mit folgenden Befehlen lassen sich KI´s abschalten. Das bedeutet, dass sie dann nicht mehr schießen oder auch sich nicht mehr bewegen. Hierbei gibt es folgende Formen: Name disableAI "Move" Name disableAI "Target" Name disableAI "Autotarget" Name disableAI "Anim" Name disableAI "Watch" - Einheit bewegt sich nicht mehr - Einheit lässt von Ziel ab - Einheit verfolgt und beobachtet nichts - KI kann Animation nicht mehr wechseln - Einheit schaut sich nicht mehr um Mit enableAI macht man das Ganze am Ende wieder rückgängig und die Einheit wird sich wieder normal verhalten. 5.58 - SetVelocity Mit dem setVelocity-Befehl hat man die Möglichkeit, ein Objekt in eine Richtung gleiten zu lassen. Dabei fliegt das Objekt in die angegebene Richtung, welche mit XYZ-Werten bestimmt wird. Die Syntax dafür schaut wie folgt aus: Name setVelocity [0,100,100] 5.59 - Der Informationstext Mit den folgend erläuterten Befehlen hat man die Möglichkeit kurze Infomationszeilen erscheinen zu lassen. Dabei gibt es Unterschiede welche wie folgt aussehen: hint "Text" hintC "Text" hintCadet "Text" - Erscheint nach Aufruf - Erscheint nach Aufruf und Spiel stoppt - Erscheint nur im Kadettmodus 5.60 - Einheit bleibt liegen, kniet oder steht Möchte man machen, dass eine Einheit egal was passiert steht, liegen bleibt oder kniet, nutzt man dafür die folgend aufgeführten Befehle. Kneel und KneelDown sind seitens BI vorgesehen, funktionieren aber noch nicht (Stand Version 1.15). Eventuell funktionieren diese Befehle in Zukunft und daher hier die Auflistung. Name setUnitPos "Up" Name setUnitPos "Middle" Name setUnitPos "Kneel" Name setUnitPos "KneelDown" Name setUnitPos "Down" Name setUnitPos "Auto" 144 - Einheit bleibt stehen - Einheit kniet - Einheit kniet - Einheit kniet und wählt zwischen Liegen und Knien - Einheit bleibt liegen - Einheit entscheidet selbst 5.61 - ID´s verwenden Jedes der Objekte auf der Karte bzw. im Editor hat eine ID. Diese kann man sich im Editor mit dem Button IDs zeigen anzeigen lassen. Diese lassen sich nun direkt ansprechen. Man hat also die Möglichkeit zu prüfen, ob ein Objekt noch vorhanden, beschädigt oder ähnliches ist. Dies bringt gleich eine Menge Möglichkeiten mehr, was zum Beispiel die Missionsziele betrifft. Der alte Befehl aus Operation Flashpoint lautete dabei wie folgt: (Object 12345) setDamage 1 Dieser läuft allerdings in Armed Assault in dieser Form nicht mehr. In ArmA nimmt man sich nun den NearestObject- oder den NearestBuilding-Befehl zur Hilfe und regelt das damit. Dazu setzt man im Idealfall zunächst eine Spiellogik auf das Objekt, merkt sich die ID des anzusprechenden Objekts und trägt in die Initzeile der Logik folgende Syntax ein: House=position this nearestObject 441616 oder House=nearestObject this bzw. House=nearestBuilding this Im Editor sieht das Ganze dann etwa so aus: Nachdem man nun dem Objekt bzw. der ID einen Namen (oben: House) zugewiesen hat, kann man es auf verschiedene Weise ansprechen. Auf der folgenden Seite sind ein paar Möglichkeiten zur Auswahl, welche unter anderem möglich sind. Objekt Schaden zuweisen: Nachdem man nun das Objekt mit einem Namen versehen hat, kann man ihm Schaden zufügen oder es ganz normal heilen. Dies erfolgt dann wie folgt mit der gewohnten SetDamage-Syntax: House setDamage 1 145 Kapitel 5 Hierbei ist House ein variabler Wert, welcher daher frei festgelegt werden kann. Hier könnte also auch Objekt1 stehen. Wichtig dabei ist der Rest der Syntax, bei welcher ja am Ende die eigentliche ID des Objektes steht, welches angesprochen werden soll. Diese Logik setzt man nun unmittelbar auf das anzusprechende Objekt. Statt einer Logik kann man alternativ natürlich auch ein anderes x-beliebiges Objekt verwenden. Wichtig ist, dass es auf oder im unmittelbaren Bereich der ID sitzt und die Initzeile richtig definiert wird. Verwendet man den Befehl mit direkter ID-Angabe, kann man die Logik frei setzen. Objektschaden auslesen: Mit Hilfe der folgend aufgeführten Syntax hat man die Möglichkeit, den Schaden eines Objektes auszulesen und diesen dann für andere Zwecke zu verwenden. getDammage House Diese Syntax könnte man zum Beispiel jetzt für die Verwendung einer Bedingung nutzen, um zu prüfen, ob das Gebäude bzw. Objekt einer Schaden größer als Wert hat. In einem Prüfauslöser könnte das wie folgt aussehen: Prüfauslöser: Achse a/b: Bedingung: bei Aktivierung: 0 getdammage House > 0.7 hint “Das Haus ist stark beschädigt!” Zerstörung als Bedingung oder Missionsziel: Wie auf der Vorseite bereits erwähnt, gibt es nun die Möglichkeit die Zerstörung eines Objektes als Bedingung oder Missionsziel zu definieren. Möchte man beispielsweise eine Bedingung haben, setzt man diese in die Bedingungszeile eines Auslösers oder Wegpunktes ein. Bedingung: ! (alive House) oder not alive House Möchte man das zerstörte Objekt als Missionsziel definieren, geht das unter anderem, indem man einen Prüfauslöser auf die Map setzt und diesen als Ende 1 definiert. Prüfauslöser: Typ: Achse a/b: Text: Bedingung: Ende 1 Einmal 0 Missionsziel ! (alive House) Hier bietet es sich wieder an den Countdown zu verwenden, damit Ende 1 nicht gleich bei Zerstörung, sondern erst ein wenig später ausgelöst wird. Ich verweise hier zusätzlich auf das Kapitel 4.6, in welchem das Beenden einer Mission sehr gut erläutert ist. 146 Unzerstörbares Objekt: Möchte man in seiner Mission Objekte haben, die absolut nicht zerstörbar sein sollen, hat man unter anderem folgende Möglichkeit. Zunächst weist man, wie in Kapitel 5.61 bereits erklärt, dem Objekt einen Namen zu und setzt dann einen Prüfauslöser mit folgenden Einstellungen: Prüfauslöser: Typ: Achse a/b: Bedingung: bei Aktivierung: Mehrfach 0 getDammage House > 0.1 House setdamage 0 Wenn das Objekt nun einen größeren Schaden als 0.1 ausweist, wird der Schaden wieder auf 0 gesetzt. Da der Auslöser auf Mehrfach steht, wird das Objekt also nie zerstört werden können. House animate ["Dvere1",1] Dvere1ist Tür 1. Für jede weitere Tür dann eben Dvere2, Dvere3 usw. Mit 0 schließt man sie in der Regel und mit 1 öffnet man sie dann wieder. Weiter Möglichkeiten sind: Schranke animate ["Bargate",1] - zum Bedienen der Schranke Ziel animate ["Terc",1] - zum Bedienen der Zielscheibe Laternen bzw. Lichter ausschalten: Mit Hilfe der ID´s hat man auch die Möglichkeit Lampen oder Lichter auszuschalten. Hierzu muss man dem Objekt zunächst erstmal mittels dieser Syntax einen Namen zuweisen: Lampe1=nearestObject this Dazu also einen Logikpunkt neben die Lampe setzen, die obige Syntax in die Initzeile eintragen und danach von wo aus auch immer ansprechen (Wegpunkt, Auslöser, etc.). Dafür benötigt man nun noch diesen Befehl: Lampe1 switchLight "Off" Trägt man die beiden Befehlszeilen komplett in die Logikinit ein, ist die Lampe gleich von Beginn an ausgeschaltet. Lampe1=nearestObject this; Lampe1 switchLight "Off" 147 Kapitel 5 Türen eines Objektes öffnen/schließen: Einige Objekte verfügen über eine animierte Tür, welche man per Actionmenü öffnen bzw. schließen kann. Diese kann man nun auch steuern, wenn man das Objekt zuvor, wie in Kapitel 5.61 erläutert, mit einem Namen versehen hat. Die Syntax hierfür lautet: 5.62 - Einheiten in Gebäuden platzieren Viele Gebäude in Armed Assault sind, wie auch schon in Operation Flashpoint, begehbar. Als Neuheit ist ja hinzugekommen, dass man als Anführer einer Gruppe seinen Soldaten direkte Häuserpositionen per Mausklick zuweisen kann, welche sie dann beziehen. Dies sind im Modell des Gebäudes fest vergebene Hauspositionen, von denen jede Position eine feste Nummer hat. Als Editierer kann man nun gezielt Einheiten oder auch Objekte in und auf den Gebäuden an den jeweiligen Positionen platzieren. Als hervorragendes Beispiel dient hier das Hotel, welches mit seinen 265 festgelegten Positionen die meisten davon aufweist. Da dieses zum Teil sehr unübersichtlich ist, sind auf den folgenden Seiten alle fünf Etagen mit den Hauspositionen aufgeführt. Als besonderes Feature ist im Kapitel 6.16 der Missionsspecials ein Haus-Patroillenskript zu finden, welches Einheiten in dem Hotel Streife laufen lässt. Um eine Einheit nun in einem Gebäude zu platzieren setzt man diese direkt auf das Gebäude und trägt folgende Syntax in die Initialisierungszeile ein: this setPos (nearestBuilding this buildingPos Positionsnummer) Dieser Befehl ist wesentlich unkomplizierter als Name SetPos [x,y,z], weil man nicht zusätzlich die Koordinaten ermitteln muss. Hat man dem Gebäude vorher einen Namen zugewiesen, wie in Kapitel 5.61 erklärt, geht auch diese Syntax: this setPos (Hausname buildingPos Positionsnummer) Möchte man eine Einheit auf einer Zufallsposition eines Gebäudes platzieren, nimmt man den Randombefehl: this setPos (nearestBuilding this buildingPos Random 265) Mit diesem wird jetzt eine Zufallsposition im Hotel von 0-265 bestimmt. Erdgeschoss (Positionen 0 bis 42) 148 1. Etage (Positionen 44 bis 101 + 262, 263, 264, 265) Kapitel 5 2. Etage (Positionen 104 bis 165 + 260) 149 3. Etage (Positionen 166 bis 227 + 259) Dach (Positionen 228 bis 258) 150 Rundfunkstudio Erdgeschoss (Positionen 0 bis 27) 1. Etage (Positionen 28 bis 47) 151 2. Etage (Positionen 48 bis 70) Dachgeschoss (Positionen 71 bis 90) 152 5.63 - Einheit begibt sich zu Gebäudeposition So wie man Einheiten an Gebäudepositionen setzen kann, kann man natürlich auch Einheiten den Befehl erteilen, sich an eine x-beliebige Position im Gebäude zu begeben. Hierzu verwendet man eine der folgenden Syntaxes: Name doMove (nearestBuilding this buildingPos 123) Name doMove (Haus1 buildingPos 123) Oder zu einer Zufallsposition: Name doMove (Haus1 buildingPos random 123) Wie man einem Gebäude oder einem Objekt einen Namen gibt, ist im vorherigen Kapitel 5.61 ausreichend erläutert. Zum Beispiel: Haus1=nearestBuilding this 5.64 - Position auslesen getPos getPosASL gibt die Höhe über dem Land bzw. einem Objekt aus gibt die exakte Höhe über dem Meeresspiegel aus X-Position Y-Position Z-Position – – – getPos Name select 0 getPos Name select 1 getPosASL Name select 2 Textausgabe einer Position: Hierzu macht man sich die Hint format oder der Titletext format Syntax zunutze, welche verschieden und je nach Bedarf definiert werden kann. Man kann sich hier einen einzelnen Wert oder auch alle drei Werte gleichzeitig ausgeben lassen. Die folgende Syntax gibt alle drei Werte in der XYZ-Reihenfolge mit exakter Höhe über dem Meeresspiegel aus. GetPosASL ist bei X und Y uninteressant. hint format ["%1", getPosASL Name] oder hint format ["%1", position Name] Möchte man nur einen einzelnen Wert haben, definiert man die Syntax mit dem entsprechenden Select-Wert. Hier als Beispiel die Ermittlung der Höhe ü. Meer. hint format ["%1", getPosASL Name select 2] hint format ["Ihre Flughöhe beträgt %1", getPosASL Name select 2] titleText [format["%1 Meter", getPosASL Name select 2],"plain down"] 153 Kapitel 5 Die Position einer Einheit lässt sich auslesen und dann als Text ausgeben oder als Bedingung für etwas verwenden. Hierbei gelten ganz normal die XYZ-Werte, wobei der Unterschied zwischen getPosASL und getPos zu beachten ist. Natürlich sollte man es mit den Positionen ausgeben lassen auch nicht übertreiben. Position als Bedingung: Die Position kann man nun auch als Bedingung für etwas verwenden. Zum Beispiel soll ein Auslöser ausgelöst werden, wenn Heli1 höher als 100 Meter fliegt oder der Spieler gewarnt wird, wenn er in einen größeren Y-Wert erreicht, als er darf. Also zu weit nach Norden oder Süden gelaufen, gefahren oder geflogen ist. Man kann so eine Spielfläche ganz einfach beschränken. Für die Flughöhe sieht die Syntax hierbei wie folgt aus: ? getPosASL Heli select 2 > 100 Oder als Beispiel die Prüfung ob die Einheit den Y-Wert schon überschritten hat. ? getPosASL Name select 1 > 10600 154 5.65 - Der Eventhandler Einen Eventhandler kann man als eine Bedingung sehen, welche man einer oder mehreren Einheiten oder Objekten zuweisen kann. Ist diese Bedingung erfüllt, wird die entsprechend festgelegte Aktion ausgeführt. Man fügt einer Einheit also einen Event bzw. ein Ereignis zu, welches als Bedingung für etwas definiert wird. Eventhandler lassen sich ganz einfach vergeben (addEventhandler) oder auch wieder entfernen (removeEventhandler). Eventhandler vergeben Um einen Eventhandler zu vergeben verwendet man folgende Syntax: Name addEventHandler ["Eventhandler", Code] Code steht für die Aktion, welche ausgeführt werden soll, wenn das Ereignis eintritt. Hierbei hat man vollen Handlungsspielraum, was man dort definieren möchte. In folgendem Beispiel wird der Eventhandler Killed vergeben und als Code ein Skript definiert, welches ausgelöst werden soll, wenn das Ereignis, also der Tod der Einheit, eingetreten ist. Name addEventHandler ["Killed", {_this exec "Skript.sqs"}] Als hervorragendes Beispiel dient hier auch eine Textausgabe, welche anzeigen soll, welche Einheit wen getötet hat. Dies ist für den Multiplayerbereich sehr interessant. Dabei vergibt man den Eventhandler an alle Einheiten, die dabei berücksichtigt werden sollen. Die Syntax schaut hierbei wie folgt aus. {_x addEventHandler ["Killed", {hint format["%1 killed by %2", _this select 0, _this select 1]}]} foreach [S1, S2, S3, S4] Wird jetzt die Einheit S1 durch S2 getötet, wird der im Editor definierte Name, also S1, per Texteinblendung angezeigt. S1 killed by S2. Hier nochmal der hint format Abschnitt einzeln aufgeführt: hint format ["%1 killed by %2",_this select 0, _this select 1] Eventhandler für Einheiten in einem Bereich vergeben Eventhandler lassen sich auch gleich für mehrere Einheiten in einem Auslöserbereich vergeben. Hier zum Beispiel der Fired-Eventhandler, der das Skript Alarm.sqs auslöst. {_x addEventHandler ["Fired",{_this exec "Alarm.sqs"}]} foreach thisList Eventhandler entfernen: So einfach wie sich Eventhandler vergeben lassen, kann man sie auch wieder entfernen. Hierzu verwendet man lediglich folgende Syntax: Name removeEventHandler ["Killed", 0] 155 Kapitel 5 In folgendem Beispiel wird der Eventhandler an mehrere Einheiten vergeben. Tritt jetzt bei einer der festgelegten Einheiten der Tod ein, kommt die definierte Textmeldung "Test". {_x addEventHandler ["Killed", {hint "Test"}]} foreach [Name1, Name2,...] Eventhandler-Übersicht: Hier eine Übersicht mit verschiedenen Syntaxbeispielen zu den Eventhandlern. Eventhandler Beispiel AnimChanged Syntax: Name addEventHandler ["AnimChanged", {[Einheit, Animation]}] Wird immer ausgelöst, wenn die definierte Animation gestartet wird. AnimDone Syntax: Name addEventHandler ["AnimDone", {[Einheit, Animation]}] Wird immer ausgelöst, wenn die definierte Animation beendet wird. Dammaged Syntax: Name addEventHandler ["Dammaged", {hint str (_this)}] Wird ausgelöst, wenn die Einheit beschädigt wird und zeigt an was an der Einheit beschädigt bzw. getroffen wurde. Engine Syntax: Name addEventHandler ["Engine", {hint str (_this)}] Wird ausgelöst, wenn das Fahrzeug angeschaltet wird. Fired Syntax: Name addEventHandler ["Fired", {hint "Feuer einstellen"}] Dieser Eventhandler wird aktiviert, wenn die Einheit ihre Waffe abfeuert. Fuel Syntax: Name addEventHandler ["Fuel", {hint str (_this)}] Wird ausgelöst, wenn sich der Tankstatus ändert. (1=voll/0=leer) Gear Syntax: Name addEventHandler ["Gear", GearState] GearState: TRUE - Fahrwerk ausgefahren / FALSE – Fahrwerk drin GetIn Syntax: Name addEventHandler [Name, Fahrzeugposition, Fahrzeugname] Wird ausgelöst, wenn die Einheit in das Fahrzeug einsteigt. Positionen: Driver, Gunner, Commander, Cargo GetOut Syntax: Name addEventHandler [Name, Fahrzeugposition, Fahrzeugname] Wird ausgelöst, wenn die Einheit aus dem Fahrzeug aussteigt. Hit Syntax: Name addEventHandler ["Hit", {hint "Diese Einheit wurde getroffen"}] Diese Aktion löst nicht immer aus. Init Syntax: Name addEventHandler [] Macht nur in einer Config Sinn! Wird beim Missionsstart ausgeführt, aber eher unfunktionell und unwichtig. IncomingMissile Syntax: Name addEventHandler ["IncomingMissile", {hint "Treffer"}] Wird ausgelöst, wenn Einheit mit einer Rakete beschossen wird. Killed Syntax: Name addEventHandler ["Killed", {_this exec "script.sqs"}] Wird ausgelöst, wenn die Einheit getötet wurde. 156 5.66 - Texteinblendarten Texteinblendungen sind, wie sicher schon festgestellt, nicht nur wichtig für eine Mission, sondern vor allem auch für das Editing oder Scripting. Man hat hiermit die Möglichkeit sich Informationen ausgeben zu lassen, um später darauf aufbauen zu können oder diese für andere Bereiche verwenden zu können. Folgend nun eine Zusammenfassung der Texteinblendarten in Armed Assault. Hierbei wird auch nochmal erläutert, wie welche Texteinblendung gemacht wird und wie Textvariablen mit eingebunden werden können. Die Hint-Variante Zunächst gibt es da die Hint-Variante, mit welcher man oben links am Bildschirmrand eine Meldung bekommt. Diese kann man nun auf seine Bedürfnisse anpassen. Standard: hint "Mein Text" Hier die Ausgabe der Koordinaten des Spielers über Meeresspiegel: hint format ["Koordinaten: %1", getPosASL Player] hint format ["Ihre Flughöhe beträgt %1", getPosASL Player select 2] Oder die Ausgabe der Waffen bzw. Munitionstypen oder der Seite dieser Einheit: Kapitel 5 hint format ["%1", weapons Name]; hint format ["%1", magazines this]; hint format ["%1", side Name]; hint format ["%1 gegen %2", side Name1, side Name2]; Hier in Verbindung mit einem Eventhandler: Name addEventHandler ["Fired", {hint format ["%1", _this]}] Und hier mit Zugriff auf einen Stringtablewert: hint localize "STR_MP_04" Die TitleText-Variante Die TitleText-Variante funktioniert vom Prinzip her genauso, wie die der Hint-Variante. Hier erfolgt die Einblendung nur eben dort, wo man sie definiert. Also zum Beispiel mitten auf dem Bildschirm oder am unteren Rand. Standard: titleText ["Paraiso\nOne day later…","Plain",4] Variante zum Ausgeben einer Entfernung zweier Einheiten bzw. Position Spieler: titleText [format["%1 Meter", Name1 distance Name2],"Plain Down"] titleText [format["%1 Meter", getPosASL Player select 2],"Plain Down"] Und hier mit Zugriff auf einen Stringtablewert: titleText [format [localize "STR_ART_H7"], "Plain Down"]; 157 5.67 - Stringtable Grundwerte In Armed Assault sind von Haus aus Unmengen an Textvariablen vordefiniert, welche ja im gesamten Spiel in Form von Texteinblendungen im Menü sowie im Spiel usw. auftauchen. Einige davon kann man somit hervorragend für seine Mission verwenden, ohne eine eigene Stringtable.csv schreiben zu müssen. Hier eine kleine Übersicht einiger mehr oder weniger wichtiger Stringtablewerte, welche man ganz einfach mit dem Hintoder Titletext-Befehl verwenden kann. Quelle STR_ARMEDASSAULT_CAPITAL STR_ARMEDASSAULT STR_ARMA_SPLASH_1 STR_SAHRANI_ISLAND STR_SAHRANI STR_SAHRANI_SOUTH STR_SAHRANI_NORTH MISSION_COMPLETED_CA MISSION_FAILED_CA MISSION_SUCCESFULL MISSION_DEFEATED STR_MISSION_OBEY STR_MP_GAME_DESC_OBJECTIVES STR_MP_GAME_DESC_PILOTDOWN STR_MP_GAME_DESC_CSWEAP STR_MP_GAME_DESC_ESCAPE STR_MP_GAME_DESC_WARCRY STR_MP_GAME_DESC_CITYCONFLICT STR_ART_H1 STR_ART_H8 STR_ART_H7 STR_ART_H3 STR_ART_H6 STR_ART_H9 STR_ART_H10 STR_MARKER_START STR_WP_HOLD STR_WP_BASE STR_WP_ENEMYBASE STR_WP_MEETINGPOINT STR_WP_PICKUP STR_WP_SAD STR_WP_ATTACK STR_WP_DESTROY Text Armed Assault ARMED ASSAULT Präsentiert Sahrani Island Sahrani Das Königreich Süd-Sahrani Demokratische Republik Sahrani Einsatz abgeschlossen Einsatz fehlgeschlagen Einsatz erfolgreich Feindliche Truppen besiegt Einsatz gescheitert. Sie haben die Befehle nicht befolgt. Zerstören Sie die feindlichen Ziele Finden und retten Sie die Piloten. Kehren Sie lebend zurück! Entkommen Sie im Hubschrauber von der Insel! Eine großangelegte Operation: Befreien Sie die Stadt. Erobern und verteidigen Sie die Stadt. Klicken Sie auf die Karte ZUERST GÜLTIGE ZIELKOORDINATEN EINGEBEN! ZIELKOORDINATEN AKZEPTIERT FEUERMISSION WIRD GESTARTET AUSSER REICHWEITE! NEUE ZIELPOSITION WÄHLEN! FEUERMISSION VORBEI KANN NICHT FEUERN Infiltrationspunkt Position halten Basis Feindliche Basis Treffpunkt Abholpunkt Suchen und zerstören Angreifen Zerstören STR_WP_DESTROYTARGET Ziel zerstören STR_WP_SEIZEANDHOLD Erobern und verteidigen STR_WP_EXTRACT Exfiltrationspunkt STR_MP_GAME_DESC_HUNTING Transportieren Sie unter Beschuss strategische Ressourcen 158 5.68 - Wegpunkte erzeugen Armed Assault bietet die Möglichkeit Wegpunkte für Gruppen bzw. Einheiten während des Spielens zu erstellen oder auch zu löschen und diese Wegpunkte auch mit Wegpunkttypen, also Wegpunktfunktionen zu versehen. Syntax: WP1 = Name addWaypoint [position, Radius] In folgendem Beispiel wird für die Gruppe Group1 ein Wegpunkt mit Namen WP1 und einem Radius von 100 Metern an der Position des Spielers erstellt. WP1 = Group1 addWaypoint [position Player, 100] Dieser bekommt jetzt noch eine Wegpunktfunktion zugewiesen, welche im Kapitel 1.5 aufgelistet sind. In diesem Beispiel bekommt der WP1 die Funktion „Sentry“. WP1 setWaypointType "SENTRY" [Group1, 2] setWaypointType "SENTRY" Befehl Beispiel [Name, Wegpunktnummer] setWaypoint… … setWaypointBehaviour [Group1, 2] setWaypointBehaviour "AWARE" Wegpunktname setWaypointBehaviour "AWARE" setWaypointCombatMode [Group1, 2] setWaypointCombatMode "RED" setWaypointDescription [Group1, 2] setWaypointDescription "Beziehen Sie Stellung" setWaypointFormation [Group1, 2] setWaypointFormation "LINE" setWaypointHousePosition [Group1, 2] setWaypointHousePosition 1 setWaypointPosition [Group1, 2] setWaypointPosition [position player, 0] setWaypointScript [Group1, 2] setWaypointScript "target.sqs player" setWaypointSpeed [Group1, 2] setWaypointSpeed "FULL" setWaypointStatements [Group1, 2] setWaypointStatements ["true", ""] setWaypointTimeout [Group1, 2] setWaypointTimeout [5, 10, 6] setWaypointType [Group1, 2] setWaypointType "HOLD" showWaypoint [Group1, 2] showWaypoint "ALWAYS" [Group1, 2] setWpPos [x, y, z] setWpPos _Pos = getWpPos [Group1,1] getWpPos Wegpunkte entfernen So wie sich Wegpunkte erstellen lassen, kann man sie auch wieder entfernen. Dazu verwendet man folgende Syntax: deleteWaypoint [Name, Wegpunktnummer] deleteWaypoint Wegpunktname 159 Kapitel 5 Dazu gibt es jetzt noch eine Menge weiterer Möglichkeiten, diesen Wegpunkt zu definieren. Die grundlegenden Definitionen für einen Wegpunkt findet man im Kapitel 1.5 unter -Wegpunkte einfügen-. Zusätzlich gelten folgende Befehle: 5.69 - Auslöser erzeugen So einfach, wie sich Wegpunkte, Einheiten und auch Objekte erzeugen lassen, lassen sich natürlich auch Auslöser erzeugen, was eine Menge neuer Möglichkeiten mit sich bringt. Hier wird erläutert und anhand von Beispielen gezeigt, wie man Auslöser erzeugen und mittels Syntaxes konfigurieren kann. Da ein Auslöser, je nachdem was man machen möchte, ein wenig mehr als nur eine kurze Syntax benötigt, schlage ich vor, diesen per Skript oder Funktion zu erstellen. Hier eine genauere Übersicht mit den jeweiligen Erläuterungen dazu. CreateTrigger Mit diesem Befehl wird zunächst ein Auslöser erstellt. Diesen kann man dann ganz normal mit einem Namen erstellen. Zunächst ist er aber dann noch roh und muss mit den hiernach erklärten Befehlen konfiguriert werden. Zunächst die Erstellung: ASL1 = createTrigger ["EmptyDetector", position Player] ASL1 = createTrigger ["EmptyDetector", [X,Y,Z]] Der Auslöser mit Namen ASL1 wird damit an der Position vom Player oder eben der angegebenen Koordinate erstellt. SetTriggerArea Jetzt braucht der Auslöser ASL1 noch eine Größe, Winkel und Form, welche nun wie folgt definiert werden. Dabei gibt man alles bis auf die Form in Zahlen an. Die Form, also Kreis oder Rechteck wird mit True und False definiert, wobei True für Rechteck steht und False für den Kreis. ASL1 setTriggerArea [X, Y, Winkel, Form] SetTriggerText Jetzt hat man die freie Wahl dem Auslöser auch einen Text zuzuweisen. Dies macht vor allem Sinn, wenn man einen Funkauslöser erstellen möchte. Dann hat man nämlich im Funkmenü den entsprechenden Text dazu. ASL1 setTriggerText "Artillerie-Support" SetTriggerTimeout Hiermit lässt sich die Auszeit des Auslösers festlegen und, ob er als Countdown oder Timeout fungieren soll. Die Werte für die Zeiten werden hierbei wieder ganz normal als Zahlwert eingetragen. ASL1 setTriggerTimeout [Min, Mid, Max, False] 160 SetTriggerType Zusätzlich kann für den Auslöser ASL1 noch ein Typ festgelegt werden. Diese Typen sind ganz normal wie im Editor vordefiniert. ASL1 setTriggerType "WIN" Typenübersicht: Keine Von West bewacht Von Ost bewacht Von Widerstand bewacht Schalter Ende 1 Ende 2 Ende 3 Ende 4 Ende 5 Ende 6 Verlieren Gewinnen Erobert durch Westen Erobert durch Osten Erobert durch Widerstand Kapitel 5 "NONE" "WEST G" "EAST G" "GUER G" "SWITCH" "END1" "END2" "END3" "END4" "END5" "END6" "LOOSE" "WIN" "WEST SEIZED" "EAST SEIZED" "GUER SEIZED" SetTriggerActivation Hiermit definiert man die Art der Aktivierung, also ob der Auslöser durch West, Ost, per Funk oder wie auch immer ausgelöst werden soll. Die Syntax dafür lautet: ASL1 setTriggerActivation ["WEST", "EAST D", true] Dieser Auslöser wurde nun wie folgt definiert: Aktivierung durch West // von Osten entdeckt // Mehrfach Erster Arrayteil: Seite: Funk: Sonstige: "NONE", "EAST", "WEST", "GUER", "CIV", "LOGIC", "ANY" "ALPHA", "BRAVO", "CHARLIE", "DELTA", "ECHO", "FOXTROT", "GOLF", "HOTEL", "INDIA", "JULIET", "STATIC", "VEHICLE", "GROUP", "LEADER", "MEMBER". Zweiter Arrayteil: "PRESENT", "NOT PRESENT", "WEST D", "EAST D", "GUER D", "CIV D". Dritter Arrayteil: True steht hierbei für Mehrfach- und False für Einmal-Auslösung des Auslösers. 161 SetTriggerStatements Hiermit definiert man nun die Bedingungszeile, die Aktivierungszeile und die Deaktivierungszeile des zuvor erstellten Auslösers. Hier bitte auch die richtige Schreibweise im Array achten! ASL1 setTriggerStatements [Bedingung, Aktivierung, Deaktivierung] ASL1 setTriggerStatements ["this", "Wert = true", "Wert = False"] SetMusicEffect Mit diesem Befehl wird der Musikeffekt des Auslösers festgelegt. ASL1 setMusicEffect "ATrack1" Die originalen Musikstücke erfordern keine Description.ext und lauten ATrack1 bis ATrack27. Die Namen der Queen´s Gambit Tracks gehen von QGTrack1 bis QGTrack9. SetSoundEffect Mit diesem Befehl versieht man den Auslöser oder mit einem Soundeffect. ASL1 setSoundEffect [Anonym, Stimme, Umgebung, Auslöser] ASL1 setSoundEffect ["Alarm”, ” ”, ” ”, ” ”] Hier nochmal eine kleine Übersicht einiger Soundarten: Stream, Alarm, BadDog, BirdSinging, Chicken, Cock, Cow, Crow, Crickets1, Crickets2, Crickets3, Crickets4, Dog, Frog, Frogs, LittleDog, Music, Owl, Wolf 5.70 - Marker erzeugen Bei den Markern hat man die Möglichkeit diese lokal oder global zu erstellen. Dies hat bei lokal den Vorteil, dass nicht mehr jeder die Marker sehen kann, sondern nur diejenigen die vorbestimmt sind. Also so kann man beispielsweise Marker nur für die jeweilige Spielseite oder nur für einen bestimmten Spieler erstellen. CreateMarker Mit diesem Befehl erstellt man den Marker zuerst, wobei man ihm einen Namen und eine Position zuweist. Merke: Normalerweise setzt man Marker beim Ansprechen in die " " . Die ist bei erstellten Markern nicht unbedingt notwendig. Grundsätzlich ist es aber nicht schlecht die " " auch für nachträglich erstellte Marker zu verwenden. _Marker1 = createMarker ["M1", position Player] _Marker1 = createMarker ["M1", [X,Y]] 162 SetMarkerType Mit SetMarkerType legt man, wie der Name schon sagt, den Typ des Markers fest. "M1" setMarkerType "Arrow" Hier eine Übersicht der verfügbaren Icon-Typen: Objective Flag1 Dot Destroy Start End Warning Join PickUp Unknown Marker - Ziel (Flag) - Fahne - Punkt - Zerstören - Start - Ende - Achtung - Beitreten - Auflesen - Unbekannt - Markierung Arrow Empty Select Vehicle Defend Move Attack Headquarters Depot Camp Town - Pfeil - Leer - Leerer Kreis - Vehikel - Verteidigen - Bewegen - Angreifen - Stab - Depot - Lager - Stadt SalvageVehicle - Bergungs Fhz RepairVehicle - Reparatur Fhz SupplyVehicle - VersorgungsFhz DestroyedVehicle - Zerstörtes Fhz MaintenanceTeam - Reparatur CommandTeam - Führungsstab SupplyTeam - Versorger InfantryTeam - Infanterie LightTeam - Leichte Inf. HeavyTeam - Schwere Inf. AirTeam - Luftabwehr FireMission - Firemission SetMarkerShape Hier definiert man die Form des Markers. Also ob es ein Icon, Rechteck, oder Kreis sein soll. Bei Icons ist es nicht unbedingt nötig die Größe des Markers festzulegen, weil die normal angezeigt werden. Nicht aber bei Rechteck oder Kreis, da ist es wichtig dem Marker noch eine Größe zuzuweisen. "M1" setMarkerShape "ELLIPSE" Hierbei hat man die Auswahl zwischen: "RECTANGLE" – "ELLIPSE" – "ICON" SetMarkerBrush Mit dem SetMarkerBrush-Befehl kann man das Aussehen eines Marker mit dem MarkerShape Rectangle oder Ellipse bestimmen. "M1" setMarkerBrush "FDiagonal" Dabei stehen folgende Designs zur Verfügung: Horizontal - Horizontale Linien Vertical - Vertikale Linien Grid - Horizontales Raster DiagGrid - Schräges Raster FDiagonal - Schräge Linien BDiagonal - Schräge Linien Cross - Kreuz-Raster 163 Kapitel 5 SetMarkerText Hiermit legt man den Text für den Marker fest. "M1" setMarkerText "Hold Position" SetMarkerColor Hiermit erfolgt die Festlegung der Farbe. Standardmäßig werden diese in rot erstellt was, wenn man diese Farbe behalten möchte, diesen überflüssig macht. "M1" setMarkerColor "ColorBlue" Hierbei stehen folgende Farben zur Auswahl: "ColorRed" "ColorRedAlpha" "ColorBlack" "ColorGreen" "ColorGreenAlpha" "ColorWhite" "ColorBlue" "ColorYellow" "Default" SetMarkerSize Definition der Größe des Markers. Die Syntax dafür schaut wie folgt aus: "M1" setMarkerSize [100, 200] SetMarkerDir Mit SetMarkerDir erfolgt die Ausrichtung des Markers in Angabe von Grad. "M1" setMarkerDir 90 Marker löschen Für das Löschen eines Marker gilt der altbewährte Befehl: deleteMarker "M1" Lokale Marker erzeugen Das Erzeugen und Definieren der Eigenschaften eines lokalen Markers erfolgt genauso, wie auch bei den Globalen, nur dass der Befehl eben nur lokal gilt. Hierbei gelten genau die gleichen Befehle, welche nur die Erweiterung Local tragen. Ansonsten ist das Verfahren genau das Gleiche. Hier trotzdem nochmal die Übersicht der Befehle für lokale Marker: CreateMarkerLocal SetMarkerSizeLocal SetMarkerTextLocal DeleteMarkerLocal SetMarkerTypeLocal SetMarkerShapeLocal SetMarkerDirLocal SetMarkerColorLocal SetMarkerBrushLocal SetMarkerPosLocal Weitere wichtige und vor allem grundlegende Informationen findet man im Kapitel 1.7 unter Markierungen einfügen. 164 5.71 - Rund ums Vehikel In diesem Unterkapitel sollen nochmal ein paar Dinge rund um Vehikel, also Fahrzeuge, erläutert werden. Hier gibt es ja die verschiedensten Dinge, die man machen oder auch abfragen kann. Deshalb nochmal diese durchaus wichtige Zusammenfassung. Schaden abfragen oder zuweisen Ein Schaden lässt sich gezielt zuweisen, abfragen oder es kann geprüft werden, ob das Fahrzeug überhaupt noch fahren kann bzw. am Leben ist. ? getDammage Fahrzeug1 > 0.5 - Wenn Schaden größer als 0.5, dann... ?!(canMove Fahrzeug1) - Wenn Vehikel nicht mehr fahren kann, dann... ? !(alive Fahrzeug1) - Wenn Vehikelnicht mehr lebt, dann... Fahrzeug1 setDamage 0.5 - Setzt einen Schaden von 0.5 {_x setDamage 1} forEach crew Fahrzeug1 - Komplette Besatzung erhält Schaden Die ersten drei Syntaxes lassen sich, wie gewohnt, in einem Prüfauslöser unter Bedingung eintragen. Dort bitte das Fragezeichen weglassen! Im Skript bleibt die Syntax so bestehen. Kapitel 5 Einheit in Fahrzeug Hiermit lässt sich prüfen, ob sich eine Einheit in einem Fahrzeug befindet: Name in Fahrzeug Player in (crew Fahrzeug) Typ des Vehikels abfragen Wenn eine bestimmte Einheit oder der Spieler ein bestimmtes Fahrzeug benutzt, soll etwas ausgeführt werden. Dazu verwendet man die nun folgende Syntax, wobei zwischen den Anführungszeichen der Klassenname des Vehikeltyps angegeben wird. typeOf vehicle Player == "M1030" typeOf vehicle Name == "AH1W" Fahrzeug für bestimmten Einheitstyp sperren Mit TypeOf lässt sich nun der Typ einer Einheit prüfen und somit auch ein Fahrzeug für gewisse Einheitstypen sperren. Dies bietet sich an, wenn man machen möchte, dass nur der Einheitentyp Pilot ein Luftfahrzeug fliegen darf. Dies lässt sich unter anderem neben einem Skript auch per Prüfauslöser realisieren. Prüfauslöser: Aktivierung: Achse a/b: Bedingung: bei Aktivierung: Mehrfach 0 typeOf driver Fahrzeug1 != "SoldierWPilot" Driver Fahrzeug1 action ["Eject",Fahrzeug1] Steigt jetzt ein Spieler mit einem anderen Einheitstyp in das Fahrzeug ein, löst der Auslöser aus und der Spieler mit dem Actionbefehl Eject wieder aus dem Fahrzeug entfernt. 165 Fahrzeug für Name sperren Möchte man ein Fahrzeug oder eine Fahrzeugposition für den Spieler oder für Einheit Name1 sperren, kann man dies unter anderem mit den nun folgenden Syntaxes machen. Als Beispiele sind ein Prüfauslöser und die Skriptvarianten angegeben. Prüfauslöser: Aktivierung: Achse a/b: Bedingung: bei Aktivierung: Mehrfach 0 Vehicle Name1 == Fahrzeug1 Name1 action [“Eject”, Fahrzeug1] Skriptsyntaxes: ? vehicle Name1 == Fahrzeug1 : Name1 action ["Eject",Fahrzeug1] ? driver Fahrzeug1 == Name1 : Name1 action ["Eject",Fahrzeug1] ? gunner Fahrzeug1 == Name1 : Name1 action ["Eject",Fahrzeug1] ? commander Fahrzeug1 == Name1 : Name1 action ["Eject",Fahrzeug1] Geschwindigkeit eines Fahrzeugs abfragen/setzen Um die Geschwindigkeit eines Fahrzeugs als Bedigung für etwas zu nutzen gilt: speed Fahrzeug1 > 30 und zum Festlegen einer Geschwindigkeit (Full,Normal,Limited,Auto): Fahrzeug1 setSpeedMode "Full" Fahrzeug1 forceSpeed 120 - Wert in km/h Fahrzeug1 limitSpeed 60 - Wert in km/h Fahrer oder Gunner vorhanden? Der Befehl isNull prüft, ob die Position im Fahrzeug leer ist. Als Bedingungsabfrage gilt: isNull driver Fahrzeug1 - Ist Position Fahrer leer, dann... ! isNull driver Fahrzeug1 - Ist Position Fahrer besetzt, dann... Laufendes Fahrzeug Der Befehl isEngineOn prüft, ob der Motor des Fahrzeugs eingeschaltet ist. isEngineOn Fahrzeug1 - Ist Motor von Fahrzeug1 an, dann... Tankstatus Folgende Befehle werden für Tankstatus eines Fahrzeugs verwendet: Fuel Fahrzeug1 == 0.5 Fahrzeug1 setFuel 0.8 Fahrzeug1 setFuelCargo 1 166 - Ist Tankfüllung gleich Wert, dann... - Setzt einen Tankfüllwert - Setzt Tankwert für Tankfahrzeug 5.72 - Lichtquellen erzeugen Lichtquellen lassen sich unter anderem per Skript oder auch Funktion erzeugen. In folgendem Beispiel wird eine Lichtquelle per Skript an der Position eines Objektes erzeugt. Dieses startet man dann mit folgender Syntax: [Objektname] exec "skripte\light.sqs" Light.sqs _object = _this select 0; _light = "#lightpoint" createVehicle position _object; _light setLightColor [0, 0, 8]; _light setLightAmbient [0.9, 0.9, 0.9]; _light setLightBrightness (0.1 / 0.1); exit; Hierbei hat man nun ganz einfach die Möglichkeit das Licht farblich frei zu gestalten. Dabei kommen, je nach Einstellung, die skurrilsten Farben zum Vorschein. Man muss dazu lediglich die Werte im jeweiligen Array ändern, was sich dann bei der nächsten Vorschau dann sofort bemerkbar macht. Die Nutzung der Dezimalwerte macht den Effekt aus! - Festlegung der Lichtfarbe - Festlegung des Umgebungslichts - Festlegung der Helligkeit Kapitel 5 _light setLightColor [0, 0, 1] _light setLightAmbient [0, 0, 1] _light setLightBrightness (0.1 / 0.1) Ein solches Licht lässt sich natürlich auch nur lokal erzeugen. Das macht man dann mit dem lokalen Createbefehl, der wie folgt lautet: _light = "#lightpoint" createVehiclelocal _pos 5.73 - Staub erzeugen Folgend ein Beispiel einer kleinen Staubwolke. Diese kann man natürlich durch das verändern der Werte ganz schnell vergrößern, verfärben oder natürlich auch verformen. [Objektname] exec "skripte\dust.sqs" Dust.sqs _object = _this select 0 _dust = "#particlesource" createVehicle position _object; _dust setParticleParams [["\Ca\Data\Cl_basic.p3d", 1, 0, 1], "", "Billboard", 1, 0.7, [0, 0, 0], [0,0,0], 5, 0.2, 0.2, 0.0, [0.8, 1], [[0.7,0.6,0.5,0.25],[0.7,0.6,0.5,0.0]], [0, 1], 1, 0, "", "", _object]; _dust setParticleRandom [0, [0.5, 1.5, 0], [1, 1, 0], 0, 0, [0, 0, 0, 0], 0, 0]; _dust setParticleCircle [0, [0, 0, 0]]; _dust setDropInterval 0.02; ~2 deleteVehicle _dust exit; 167 5.74 - Rauch erzeugen Hier ein kleines Beispiel, wie man eine Rauchsäule in ArmA realisieren kann. Das dies noch ausbaufähig ist, sollte gänzlich klar sein, aber dieses kleine Beispiel ist mehr als nur ein guter Ansatz dafür. Rauch sowie Feuer erzeugt man mit so genannten Drop-Befehlen. Diese sind unter Umständen meistens etwas länger, wie man unten gut erkennen kann. Denn die beiden Zeilen ab Drop stellen wieder eine Zeile dar, was hier nicht möglich ist. In diesen Array´s werden die verschiedensten Dinge, wie Farbe, Form, Verhalten und Geschwindigkeit definiert. Das Ganze wurde hier in eine Schleife gepackt. Bei jedem Durchlauf wird der lokale Wert _i um den Wert 1 vergrößert. Erreicht _i, wie im unteren Teil des Skriptes angegeben, den Wert 800, wir das Skript beendet und der Rauch hört auf. Die Werte sind alle variable und können nach belieben angepasst werden. Das Skript startet man am Ende mit folgender Syntax: [Objektname] exec "skripte\smoke.sqs" Smoke.sqs _vehicle = _this select 0 _position = [0, 0, 0] _i = 0 #Loop _i = _i + 1 drop ["\ca\data\cl_basic", "", "Billboard", 6, 6, _position, [0,0,0], 1, 1, 1.5, 0.02, [1,30], [[0,0,0,0],[0,0,0,0.7],[0,0,0,0]], [0], 1.2, 1, "", "", _vehicle] ~0.1 ? _i == 800 : exit goto "Loop" Dieses Skript kann man nun hervorragend auslösen, wenn zum Beispiel ein Tankfahrzeug oder ähnliches zerstört wurde. Hier mal ein Prüfauslöserbeispiel: Prüfauslöser: Aktivierung: Achse a/b: Bedingung: bei Aktivierung: Einfach 0 not alive Fahrzeug1 [Fahrzeug1] exec "smoke.sqs" Des Weiteren kann man noch die Position um das Objekt oder Fahrzeug bestimmen. Hierzu werden wieder die XYZ-Werte benutzt, welche im Array festgelegt sind. _position = [0, 0, 0] 168 5.75 - Feuer erzeugen Mit folgendem Beispiel hat man die Möglichkeit ein Feuer an der Position eines Objektes zu erzeugen. Auch hier hat man wieder vollen Modifikationsspielraum. Dazu kann man die skriptinternen Werte jederzeit seinen Ansprüchen anpassen. Auch der Startauslösearray bietet einige freie Definitionsmöglichkeiten. [Objekt,60,0] exec "skripte\fire.sqs" Objekt steht für Name des Objektes, der zweite Wert für die Brenndauer in Sekunden und der dritte Wert für die Höhe über dem Objekt. Fire.sqs _object=_this select 0; _time=_this select 1; _zpos=_this select 2; _delay=0.15; _timecheck=0; _i=0 Kapitel 5 ; Die Folgende Zeile stellt eine Zeile dar, was hier nicht möglich ist: _light = "#lightpoint" createVehicle [(getPos _object select 0), (getPos _object select 1),_zpos]; _light setLightBrightness 0.03; _light setLightAmbient[0.03, 0.028, 0.0]; _light setLightColor[1.0, 0.9, 0.0]; #Loop _pos=getPos _object _x=(_pos select 0) _y=(_pos select 1) _z=(_pos select 2) _vx=0.2-(random 0.4) _vy=0.2-(random 0.4) _vz=random 0.15 _m=(2.1-(random 0.1)) _Fire=[2,6] select (random 1.5) ; Die Folgende Zeile stellt eine Zeile dar, was hier nicht möglich ist: drop [["\ca\data\ParticleEffects\FireAndSmokeAnim\FireAnim",8,_Fire,32], "", "Billboard", 9, (0.7+(random 0.3)), [_x,_y,_z+_zpos+(random 1)], [_vx,_vy,_vz], 0, _m, 2, 1, [0.5,1,2],[[1,1,1,0.5],[1,1,1,1],[1,1,1,0]],[0], 0,0,"","",logic] Weiter auf der Folgeseite! 169 ? _i<=3: goto "Loop2" _Smoke=3; _s=(2.2-(random 0.1)); ; Die Folgende Zeile stellt eine Zeile dar, was hier nicht möglich ist: drop [["\ca\data\ParticleEffects\FireAndSmokeAnim\SmokeAnim",8, _Smoke,32], "", "Billboard", 9, (2.5+(random 0.5)), [_x,_y,_z], [_vx,_vy,_vz], 0, _s, 2, 2, [0.2,5],[[0,0,0,0],[1,1,1,0.8],[1,1,1,0]],[0], 0,0,"","",logic]; _i=0; #Loop2 ~_delay _i=_i+1 _timecheck=_timecheck+_delay ? _time>=_timecheck: goto "Loop" deleteVehicle _light exit Dieses Skript enthält unter anderem eine Lichtquelle, einen Feuerdropbefehl und dazu einen Rauchdropbefehl und fast damit die Unterkapitel 5.73, 5.74 und 5.75 zu einer Aktion zusammen. Die Dropbefehle müssen logischerweise wieder in einer Zeile stehen! Das folgende Bild simuliert einen Motorbrand. 170 5.76 - Dienstgrad vergeben Einheiten lassen sich auch während des Spielverlaufs befördern. Das bedeutet, dass man den Spieler im Verlauf einer Mission oder Kampagne aufgrund seiner guten Leistungen befördern oder bei schlechten Leistungen wieder degradieren kann. Dabei stehen folgende Dienstgrade zur Verfügung: Private Corporal Sergeant Lieutenant Captain Major Colonel Soldat Gefreiter Feldwebel Leutnant Hauptmann Major Oberst Diese Dienstgrade lassen sich jetzt mit folgender Syntax vergeben: Name1 setRank "Major" oder Player setRank "Major" Prüfauslöser: Aktivierung: Achse a/b: Bedingung: bei Aktivierung: Einfach 0 Rating Player >= Wert Player setRank "Major"; hint format ["Sie wurden soeben zum %1 befördert",rank Player] Der Spieler wird nun befördert, wenn er die Punktzahl erreicht hat. Als Bedingung Den Rang einer Einheit kann man jetzt auch als Bedingung für etwas verwenden. Zum Beispiel bei der Vergabe von Waffen oder dem Nutzen von Fahrzeugen. Zum Beispiel könnte man dem Spieler so das Nutzen von Fahrzeugen oder bestimmten Waffensorten zunächst verbieten. Da Leistung gerne belohnt wird, wird er sich nun mehr anstrengen und versuchen Punkte zu sammeln, um möglichst schnell befördert zu werden. ? rank player == "Major" : exit ? rank Name1 != "Major" : exit 171 Kapitel 5 Anwendungsbeispiel Der Spieler soll befördert werden, wenn er eine gewisse Punktezahl überschritten hat. Das könnte man jetzt auf verschiedene Art und Weise machen. Hier soll mal die Variante mit einem Prüfauslöser als Beispiel dienen. 5.77 - Einheit benutzt Fernglas Diese Möglichkeit bietet zwar keinen großen Nutzen, aber ist für Kamerasequenzen durchaus ein nettes Feature. Bevor die Einheit aber das Fernglas benutzt, muss man ihr erstmal eins zuweisen. Dies geht wie gewohnt mit: Name1 addWeapon "Binocular"; Nachdem die Einheit nun mit einem Fernglas ausgerüstet ist, nimmt man sich den SelectWeapon-Befehl zur Hand und befielt der Einheit per Auslöser oder Skript, wie nun folgt definiert, das Fernglas zu benutzen. Name1 selectWeapon "Binocular"; Name1 setBehaviour "safe"; Natürlich lässt sich dies auch mit einem Animationsbefehl umsetzen, wie in Kapitel 5.56 ausreichend erklärt ist. 5.78 - Einheit einen Fahrzeugplatz zuweisen Es besteht die Möglichkeit einer Einheit einen Fahrzeugplatz zuzuweisen. Diese Einheit wird aber nach der Zuweisung nicht in dem Fahrzeug sitzen. Wozu soll das also nun gut sein? Man hat damit die Möglichkeit die Einheiten erstmal neben dem Fahrzeug zu positionieren und zum Beispiel bei Alarm den Befehl geben einzusteigen. Denn kein normaler Soldat sitzt ewig auf seinem Gunnersitz, wenn eigentlich gar kein Grund dazu besteht. So könnten also auch MG´s oder Scheinwerfer erstmal unbesetzt bleiben und wenn beispielsweise der Alarm ausgelöst wird, stürmen die Einheiten zu ihren zugewiesenen Fahrezeugen etc.. Hinzu kommt, dass so auch der Spieler die Möglichkeit hat die Besatzung einer Panzers vorher schon auszuschalten, bevor sie eingestiegen ist. Dazu gelten die nun folgenden Befehle: Name assignAsCargo Truck1 Name assignAsDriver Panzer1 Name assignAsGunner Panzer1 Name assignAsCommander Panzer1 - Bekommt einen Mitfahrerplatz - Bekommt den Fahrerplatz - Bekommt den Schützenplatz - Bekommt den Kommandantenplatz Mit unAssignVehicle Name, verweist man die Einheit wieder eines Fahrzeugs. Sie weiß dann, dass das unassigned Vehikel nicht mehr ihr Fahrzeug ist und steigt nach dem Aussteigebefehl auch nicht automatisch wieder ein. Nachdem man der Einheit ein Fahrzeug zugewiesen hat kann man ihr Befehlen ihren Platz darin einzunehmen. Dafür gilt folgende Syntax: [Name] orderGetIn true [Name] orderGetIn false - Einheit steigt ein - Einheit steigt aus Für mehrere Einheiten gilt folgende Syntaxform: [Name1, Name2, Name3] orderGetIn true 172 Es besteht auch die Möglichkeit sich ausgeben zu lassen welches Fahrzeug der Einheit zugewiesen wurde oder welchen Platz sie darin gerade bezogen hat. Gerade ein Spieler kann ja mehrere oder gar alle Positionen im Fahrzeug beziehen. Diese kann man dann als Bedigung für etwas verwenden (siehe Kapitel 5.71). Zugewiesenes Fahrzeug ausgeben lassen: hint format ["Zugewiesenes Fahrzeug: %1", assignedVehicle Player] Gegenwärtige Position im Fahrzeug ausgeben lassen: hint format ["Position im Fahrzeug: %1", assignedVehicleRole Player] 5.79 - Einer Einheit ein Team zuweisen und hiermit lässt man ihn wieder austreten: unassignTeam Name Man kann das Team auch wieder auflösen. Dazu verwendet man folgende Syntaxform: dissolveTeam "BLUE" Als Teamfarben steht hierbei folgende Auswahl zur Verfügung: MAIN RED GREEN BLUE YELLOW Im Editor sieht das Ganze dann wie folgt aus: Kein Team Blaues und rotes Team Blaues, rotes, grünes Team 173 Kapitel 5 Als Leader einer Einheit hat man die Möglichkeit seine Gruppenmitglieder in Teams aufzuteilen, welche dann Farbnamen bekommen. Dies ist natürlich auch im Editor möglich. Man kann so vorab schon die Gruppe des Spielers in unterschiedliche Teams aufteilen. Mi folgender Syntax teilt man eine Einheit einem Team zu: Name assignTeam "BLUE" 5.80 - Einheit gibt Befehle Mit folgender Syntax gibt die jeweilige Einheit mit Namen Name1 den Befehl etwas auszuführen und führt es dabei selbst aus. Als Beispiel das erste Syntaxbeispiel. Bei diesem führt Name1 den Befehl CommanFire aus und schießt auf Name2. Name1 Name1 Name1 Name1 commandFire Name2 commandTarget Name2 commandMove Name2 commandStop Name2 - Name1 schießt auf Name2 - Name1 bekommt als Ziel Name2 - Name1 begibt sich zu Name2 - Name1 bleibt stehen Das Ganze kann man natürlich noch gruppenbezogen auführen. Jetzt kommt auch der Sinn des Command... etwas hervor. Wenn man nun dem Leader und den Einheiten den Befehl gibt, spricht der Leader oder die angegebene Einheit dieser Gruppe den Befehl hörbar aus, worauf die Untergebenen dann auch reagieren und den Befehl ausführen. (units group Name1) commandFire Name2 5.81 - Hat Einheit Schaden erhalten? Generell lässt sich der Schaden einer jeden Einheit oder auch eines Objektes abfragen und ausgeben bzw. als Bedingung verwenden. Hierbei gibt es unterschiedliche Möglichkeiten. Zum Beispiel, ob eine Einheit noch laufen kann oder in der Lage ist zu schießen. Hierfür machen wir uns die folgenden Befehle zu Nutze: canStand - canMove - canFire - handsHit - getDammage Folgend nun ein paar Syntaxbeispiele in Skriptform: ?! (canStand Name) : Name sideChat "Aah... meine Beine!" ?! (canMove Name) : Name sideChat "Mein Auto ist defekt!" ?! (canFire Name) : hint "Name kann nicht feuern!" ? (handsHit Name == 1) : Name sideChat "Aah... meine Hände!" ? (getDammage Player) > 0.5 : hint "Du bist verletzt!" Bedenke: In der Bedingungszeile eines Auslösers setzt man kein ?, weil das schon integriert ist. Deshalb folgend nochmal kurz das Auslöserbeispiel. Achse a/b: Bedigung: bei Aktivierung: 174 0 (handsHit Name == 1) Name sideChat "Aah... meine Hände!" 5.82 - Der Flugverkehr Auch der Flugverkehr hat sein System und seine Ordnung. Und so gibt es auch dabei so einiges zu beachten. Zunächst ist wichtig zu wissen, dass der Startflugplatz auch immer der Heimatflugplatz ist. Der Flieger bekommt den Wert des Heimatflugplatzes automatisch zugewiesen. Wenn also die Engine bemerkt, dass der Heli1 auf Flugplatz A steht, bekommt er automatisch den Wert des Flugplatzes A zugewiesen. Startet der Flieger zu Missionsbeginn aber irgendwo in der Luft, so bekommt er automatisch den nächstgelegenen Flugplatz als Heimatflugplatz zugewiesen. Jeder Flugplatz hat also einen Wert, welchen man einem Flieger zuteilen kann. Die Werte für die einzelnen Flugplätze sind dabei wie folgt zugeordnet: 0 1 2 3 - Paraiso - Rahmadi - Pita - Antigua Kapitel 5 Möchte man nun einen Flieger einen Flugplatz zuweisen, macht man dies mit: Flieger1 assignToAirport 1 Diesem Flieger1 kann man nun auch befehlen auf einem der Flugplätze zu landen. Flieger1 landAt 1 Nachdem nun bekannt ist, dass die Fluplätze eine festen Index haben und dass man seinen Flugzeugen und Hubschraubern einen Flugplatz zuweisen und diese dort landen lassen kann, fehlt eigentlich nur noch eines. Der Flugplatz braucht noch eine Seite. Diese vergibt man mit folgender Syntax: 0 setAirportSide WEST WEST EAST GUER CIV LOGIC 175 5.83 - Grasdetails heruntersetzen Die Grasdetails lassen sich während des Missionsverlaufs ganz einfach herabsetzen oder gar ganz entfernen. Damit wäre die Landschaft dann frei von Gras. Das Herabsetzen des Grasbewuchses könnte man zum Beispiel nutzen, wenn Frames gerade wichtiger sind, als es das Gras ist. Zum Beispiel eine Sequenz oder was auch immer. Die Syntax dafür lautet: setTerrainGrid 12.5 Dafür gibt es fest vergebene Werte. Gibt man stattdessen einen anderen Wert an, wählt die Engine automatisch den näch definierten Wert. Hierbei gil, je kleiner der Wert, desto größer der Grasanteil. Die Werte lauten dabei wie folgt: 50 25 12.5 6.25 3.125 - Kein Gras - Weniger Gras - Mittelmäßiges Gras - Standardgras - Hoher Grasanteil 5.84 - Objekte schräg platzieren Mit folgenden Syntaxformen lassen sich Objekte schräg platzieren. Dies ermöglicht es ganz leicht, Fahrzeuge, Objekte, oder was auch immer, auf die Seite zu kippen oder gar aufs Dach zu legen. Dazu gelten alle Werte zwischen -1 und 1. Dabei gelten folgende Syntaxes: Objekt setVectorUp [0,0,0] Objekt setVectorDir [0,0,0] Beide Arten gibt es auch als Kombination: Objekt setVectorDirAndUp [[0,0,0],[0,0,0]] Die Reihenfolge der Koordinaten ist bei allen Varianten nicht xyz, sondern xzy! Objekt setVectorUp [x,z,y] 176 5.85 - Missionen verschlüsseln bzw. freischalten Einige originale Armed Assault Missionen greifen auf diese Verschlüsselung zurück. Das bedeutet, dass man sie erst spielen kann, wenn man vorher die Ausbildungen absolviert hat oder gewisse andere Missionen zuvor gespielt hat. Das Ganze macht für eine einzelne Mission nicht unbedingt viel Sinn, da sie der User, der sie zuvor heruntergeladen hat, ja spielen möchte. Als Beispiel könnte man zwei Missionen releasen, bei der man die Zweite verschlüsselt und erst freischaltet, wenn der Spieler die erste gespielt hat. Die Keys müssen in der Description.ext aufgeführt werden.Dabei gelten folgende Regeln: keys[] = {"Key1", "Key2", "Key3"}; - Hier werden die geforderten Keys aufgeführt keysLimit = 2; - Mindeste Anzahl der benötigten Keys, um die Mission freizuschalten doneKeys[] = {"Key4"}; - Name des Keys welcher in den SP-Missionen als abgehakt dargestellt wird. Nach erfolgreicher Beendigung der Mission, gibt man nun folgende Syntax an: activateKey "Key1" Mehr zu diesem Thema findet sich im Kapitel 11.2 - Die ArmA-Cheats -. 5.86 - Leerer Scheinwerfer mit Licht Setzt man einen, mit einer KI besetzten, Scheinwerfer auf die Karte, so wird dieser bei Nacht automatisch angeschaltet sein. Bei einem leeren Scheinwerfer sieht das Ganze schon wieder anders aus. Wenn man ihn leuchten lassen möchte, ohne dass eine Einheit dahinter steht, geht das unter anderem mit der Verwendung einer Spiellogik. Dazu setzt man zunächst einen leeren Scheinwerfer mit dem Namen Lampe1 und eine Spiellogik auf die Karte, wobei man in die Initialisierungszeile der Logik folgendes angibt: this moveInGunner Lampe1 Die Spiellogik ist damit sozusagen die KI, die den Scheinwerfer bedient. Nachteil dabei ist, dass die Logik den Scheinwerfer nicht bewegt. In Verbindung mit dem Skriptbeispiel aus Kapitel 6.14 besteht natürlich die Möglichkeit diesen beweglich zu machen. Das Ganze gilt natürlich auch für Fahrzeuge. Möchte man ein leeres Fahrzeug mit eingeschaltetem Licht auf der Karte platzieren, regelt man das auch mit einer Logik! 177 Kapitel 6 - Missions Specials Nachdem du nun alle Kapitel aufmerksam durchgelesen haben solltest, kommen hier ein paar Besonderheiten für deine Mission, die sich mit ein klein wenig mehr Aufwand schnell realisieren lassen. Deine Mission wird Dank dieser Zusätze um einiges interessanter und spannender werden. All die Features dieses Kapitels sind zwar auf Skriptbasis aufgebaut, sind deshalb aber keineswegs weniger funktionell oder weniger gut als Funktionen. Die Scripte sind teiweise so aufgebaut, dass du sie verstehen kannst, um besser in die Thematik einsteigen zu können. Verbesserungs- oder Erweiterungsmöglichkeiten gibt es bei jedem dieser Skripte. Da diese Beispiele teilweise sehr umfangreich sind und ein Abtippen oft zu Fehlern führt, werden diese auch in Foren wie www.forum.german-gamers-club.de oder www.mapfact.net von mir, mit geeigneter Beispielmission, zum Download angeboten. 6.1 6.2 6.3 6.4 6.5 6.6 6.7 6.8 6.9 6.10 6.11 6.12 6.13 6.14 6.15 6.16 6.17 6.18 6.19 6.20 6.21 6.22 6.23 6.24 6.25 178 Die Fallschirmspringer Das GPS-System Der Actionmenüeintrag Der Rucksack Zufallspositionen Der Mapclick Die Artillerie Tote Einheiten bzw. Fahrzeuge löschen Spielbeschleunigung dauerhaft unterdrücken Der Bullet Mode Das Feindmeldeskript Der Airstrike Der Airvehiclecreator Der Scheinwerfer Der Zeitzähler Das House-Patrol-Script Das Minen-Skript Das Vehikeltransportskript Das Möwenkript Das Insektenskript Der Bombenleger Der Aufklärer Einheit ergibt sich Der Teleport Das Verfolgungsskript 179 180 181 181 185 187 189 194 195 196 197 198 201 203 204 205 208 209 213 215 216 217 218 221 222 6.1 - Die Fallschirmspringer Fallschirmspringer sind ein nettes Feature für jede Mission. Hier wird eine von vielen möglichen Varianten erläutert. Der Helikopter Zunächst erstellt man einen Helikopter, hier mit dem Namen Heli1. Wenn dieser zunächst noch nicht fliegen soll, setzt man den Spritwert des Heli´s zunächst mit dem Befehl this setFuel 0 auf leer. Wenn der Heli später starten soll, muss der Wert wieder auf 1 gesetzt werden. Zur Zeit steigt die Besatzung noch aus, wenn Fuel auf 0 steht. Patchhoffnung. Die Flughöhe Die Flughöhe sollte schon mindestens 80 bis 100 Meter betragen, da sich die Einheiten sonst verletzen könnten. Diese legt man mit folgender Syntax fest: Heli1 flyInHeight 120 Die Landezone Die Landezone sollte fernab von Ortschaften und dichten Wäldern sein, um der KI eine gute Landemöglichkeit zu bieten. Andernfalls könnten Verletzungen oder ähnliche Probleme auftreten. Die Gruppe Damit die Gruppe am Missionsstart schon im Helikopter sitzt, bekommt der Leader der Gruppe, welche hier mal Gruppe1 heißt, folgenden Eintrag in seine Initzeile: Kapitel 6 {_x moveInCargo Heli1} foreach units Gruppe1 Das Skript Das Skript, welches frei benannt werden kann, sieht dabei wie folgt aus: _aunits = units Gruppe1; _i = 0; _j = count _aunits; #Here (_aunits select _i) action ["EJECT", Heli1] ; unAssignVehicle (_aunits select _i) ; _i=_i+1; ~1 ?_j>_i : goto "Here" exit; Das Skript kann man dann beispielsweise am Absprungpunkt per Wegpunkt oder Auslöser mit der Syntax this exec "skripte\heli.sqs" starten. Eine weitere Möglichkeit, ohne ein eigenes Skript anlegen zu müssen wäre die Verwendung eines im Spiel integrierten Skriptes, welches wie folgt ausgelöst wird: [Gruppe,Heliname] exec "para.sqs" 179 6.2 - Das GPS-System Dieses System ist sehr nutzvoll, wenn man mehrere Einheiten auf dem Schlachtfeld mit taktischen Zeichen versehen will bzw. einfach nur den eigenen Standort oder den einer anderen Einheit auf der Karte verfolgen möchte. Hierzu wird wieder ein Skript verwendet, welches in der Init.sqs oder Initzeile des Spielers gleich zu Missionsbeginn gestartet wird. Dieses nun erläuterte Skript setzt nicht nur die Marker an die Position der angegebenen Einheiten, sondern prüft dazu noch, ob diese noch am Leben sind. Ist dies nicht der Fall, wird der Marker gelöscht. Beispiel 1: "S1-Symbol" setMarkerText Name Soldat1; #Start ; Prüfen, ob Soldat1 lebt. Wenn nicht, springt das Skript zum Label Ende. ? (!(alive Soldat1)) : goto "Ende"; ; Marker setzen #Marker "S1-Symbol" setMarkerPos getpos Soldat1; ~1 ;Skript springt wieder zum Start goto "Start"; #Ende deleteMarker "S1-Symbol"; exit; Beispiel 2: Dies lässt sich natürlich auch per If-Then-Else-Syntax realisieren, welche in einer Zeile stehen sollte, was hier leider aus Platzgründen nicht möglich ist. Diese Variante ist kürzer, da man alles in wenige Befehlszeile packen kann. #Start If(alive Soldat1)Then{"S1-Symbol" setMarkerPos getpos Soldat1} Else{"S1-Symbol" setMarkerType "Empty";exit}; ~0.5 Goto “Start” ; Erklärung: Wenn (If) Soldat1 lebt dann (Then) setze S1-Symbol auf Soldat1 ansonsten (Else) lösche S1-Symbol und verlasse Skript (Exit). Anmerkung: Ein weiteres beliebtes GPS-Verfahren, welches hier nicht erklärt wird ist, die Marker für die jeweilige Einheit erst mit dem Skript zu erstellen und an sie zu heften. Wer aber dieses Buch sogfältig durcharbeitet, ist im Anschluss selbst in der Lage so etwas zu skripten. 180 6.3 - Der Actionmenüeintrag Das Actionmenü ist jenes, welches sich rechts unten in der Ecke befindet. Hier ist es möglich Einträge hinzuzufügen und diese später auch wieder zu entfernen. Zum Hinzufügen eines Eintrages benötigt man zunächst diese Syntax: ID = Player addAction ["Eigener Eintrag","skript.sqs"] während man zum Entfernen diese Syntax verwendet: Player removeAction ID Zum Löschen des Eintrages gibt man lediglich den Namen des Eintrags an, welcher hier kurz mit ID festgelegt wurde. Möchte man einen Eintrag haben, wenn die Einheit in einem Fahrzeug sitzt, gibt man dazu den Fahrzeugnamen an. ID = Fahrzeug addAction ["Eigener Eintrag","skript.sqs"] Auslöserbeispiel: Zunächst setzt man einen Auslöser auf die Karte, verbindet ihn mit dem Spieler, so dass nur er ihn auslösen kann und nimmt etwa folgende Einstellungen vor: Aktivierung: Achse a/b: bei Aktivierung: bei Deaktivierung: Mehrfach 5 ID = Player addAction ["Eigener Eintrag","skript.sqs"] Player removeAction ID 6.4 - Der Rucksack Mit Hilfe der Actionmenüeinträge kann man nun hervorragend einen Rucksack, Beintaschen oder ähnliches simulieren. Hier mal als kleines Feature das Rucksackbeispiel, an welchem man gut erkennen kann, was mit den Einträgen so alles möglich ist. Dieses Beispiel ist zunächst nur für Einzelspieler ausgelegt. Zunächst setzt man dazu den Spieler mit folgendem Eintrag in der Initzeile: RID = Player addAction ["Open Backpack","backpack\rucksack.sqs"] Für den Rucksack legt man nun im Missionsordner einen eigenen Unterordner namens Backpack an. Dateien im Missionsordner bitte immer klein schreiben! In diesen Ordner kommen nun die Skripte für die verschiedenen Aktionen. Für diesen Fall werden jetzt mal die vier folgenden Skripte angelegt. rucksack.sqs firstaid.sqs save.sqs close.sqs 181 Kapitel 6 Zum Testen läuft man nun ein paar Mal in den Bereich und wieder raus. Das Ergebnis wird sein, dass der Eintrag beim Betreten erscheint und beim Verlassen wieder verschwindet. Rucksack.sqs Hier wird zunächst der Eintrag -Rucksack öffnen- entfernt und erst dann werden die anderen Einträge hinzugefügt. Die Besonderheit hierbei ist, dass man nur drei Mal die Möglichkeit hat sich zu heilen. Damit nun immer der richtige Eintrag erscheint, wird bei jedem Heilen eine Variable auf true gesetzt und beim Wideraufruf des Skriptes berücksichtigt. Angenommen man hätte jetzt schon 3 Mal gespeichert (siehe: ? verband3 : goto "Close“), wäre die Variable Verband3 schon true und somit springt das Skript zum Label #Close über und führt die Close.sqs aus. Das Skript wäre somit beendet. ; Eintrag wird entfernt Player RemoveAction RID Playsound "Rucksackauf" ; Einträge werden hinzugefügt RIID = Player AddAction ["- Speichern","backpack\save.sqs"]; #Verband ? verband3 : goto "Close"; ? verband2 : goto "Verband3"; ? verband1 : goto "Verband2"; #Verband1 RIIID = Player AddAction ["- First aid (3)","backpack\firstaid.sqs"]; goto"Close"; #Verband2 RIIID = Player AddAction ["- First aid (2)","backpack\firstaid.sqs"]; goto"Close"; #Verband3 RIIID = Player AddAction ["- First aid (1)","backpack\firstaid.sqs"]; #Close RIIIID = Player AddAction ["- Close Backpack","backpack\close.sqs"]; exit; Eine weitere Besonderheit bei diesen Skripten ist, dass hier für die jeweiligen Aktionen Sounds angegeben wurden. Siehe: Playsound "Rucksackauf". Diese, welche natürlich nicht unbedingt wichtig sind und daher auch wegfallen könnten, müssen natürlich zuvor in der Description.ext definiert werden. Ein zweites Feature hierbei ist, dass der Spieler bei der jeweilig durchgeführten Aktion eine Animation ausführen soll, um es etwas realistischer zu gestalten. Als Beispiel hierfür dient die nun folgende FirstAid.sqs, bei der der Spieler, wenn er sich heilt, auf dem Boden liegen soll. Achtung! Diese vier Skripte sind miteinander verschachtelt! 182 Firstaid.sqs Hier sieht man nun, dass das Skript zunächst prüft, ob und wie oft schon gespeichert wurde. Würde man zum ersten Mal speichern, wäre noch keine Variable auf true geschaltet. Das Skript würde zum Label #Verband1 durchlaufen, die Variable Verband1 auf true setzen und von dort aus auf das Label #Heilen springen, wo alle Untereinträge wieder gelöscht werden, der Spieler wieder den Eintrag Open Backpack bekommt und die Aktionen durchgeführt werden, die zur Heilung führen. Beim zweiten Speichern würde das Skript beim Prüfen zum Label #Verband2 springen, da ja Verband1 bereits true ist. Beim dritten Speichern würde es gleich von der zweiten Zeile aus zu Label #Verband3 springen. Jetzt wäre auch Verband3 true und das Skript würde beim nochmaligen Ausführen sofort beendet (? verband3 : exit). ? verband3 : exit; ? verband2 : goto "Verband3"; ? verband1 : goto "Verband2"; #Verband1 verband1=true; goto "Heilen"; #Verband2 verband2=true; goto "Heilen"; Kapitel 6 #Verband3 verband3=true; goto "Heilen"; #Heilen RID = Player AddAction ["Open Backpack","backpack\rucksack.sqs"]; Player RemoveAction RIID; Player RemoveAction RIIID; Player RemoveAction RIIIID; ~0.2 Player playmove "AinvPknlMstpSlayWrflDnon_healed"; ~1 Playsound "Sanipack"; ~2 Player switchmove "AinvPknlMstpSlayWrflDnon_healed"; ~5 Playsound "Schmerz"; ~1 Player setdammage 0; exit; 183 Save.sqs Hier kommt nun die Save.sqs, mit welcher das Spiel gespeichert wird. Zunächst werden wieder alle Einträge gelöscht, in dem von hier aus die Close.sqs gestartet wird und dann das Spiel gespeichert. [] exec " backpack\close.sqs"; Savegame; exit; Close.sqs Und hier natürlich noch die letzte Datei, die gebraucht wird, wenn man den Eintrag Close Backpack betätigt. Playsound "Rucksackzu"; Player RemoveAction RIID; Player RemoveAction RIIID; Player RemoveAction RIIIID; RID = Player AddAction ["Open Backpack","backpack\rucksack.sqs"]; exit; Jetzt nur nochmal eine nähere kurze Beschreibung der vergebenen Eintrags-namen, dann kann der Rucksack erfolgreich gepackt werden. Name: RID Der Eintrag, der für das Öffnen des Rucksackes zuständig ist. RID = Player addAction ["Open Backpack","backpack\rucksack.sqs"] Name: RIID Der Name, der für das Speichern festgelegt wurde. RIID = Player addAction ["- Speichern","backpack\save.sqs"] Name: RIIID Wurde für alle Firstaid-Einträge definiert, da ja immer nur einer aktiv ist. RIIID = Player addAction ["- First aid (1)","backpack\firstaid.sqs"] RIIID = Player addAction ["- First aid (2)","backpack\firstaid.sqs"] RIIID = Player addAction ["- First aid (3)","backpack\firstaid.sqs"] Name: RIIIID Ist der Name, der für das Schließen des Rucksacks definiert wurde. RIIIID = Player addAction ["- Close Backpack","backpack\close.sqs"] 184 6.5 - Zufallspositionen Eine Mission, die immer gleich abläuft, kann mit der Zeit sehr langweilig werden und wird daher schnell zur Seite gelegt oder gelöscht. Hat man aber eine Mission geschaffen, welche eine Menge Überraschungen aufweist und man nie genau weiß woher die Feinde kommen werden, ist doch da schon mal ein wenig mehr Spannung vorhanden. Gerade im Mehrspielerbereich kann es sehr anstrengend sein, wenn man dauernd gesagt bekommt, wo was steht und von wo der Feind kommt. Dazu kann man noch verschiedene Startpunkte für den Spieler oder auch verschiedene Zielpunkte definieren. Natürlich hat man ja im Editor bei jeder Einheit die Möglichkeit den Radius der Platzierung festzulegen, was ja auch eine Menge Dynamik bringt. Diese nun erläuterte Variante ist aber eher für feste Punkte bestimmt, die zuvor definiert wurden. Dieses Skript startet man von der Initzeile des Spielers oder der Init.sqs, um ganz zu Anfang die Positionen festzulegen. Beispiel: Dynamische Startpunkte Hierbei macht man sich den Random-Befehl zunutze. Das Ganze kann dann in Skriptform etwa wie folgt aufgeführt aussehen: #P1 Player setpos [x,y,z]; exit; Ist er kleiner als 1 springt das Skript zu #P1 Ist er kleiner als 2 springt das Skript zu #P2 Ist er kleiner als 3 springt das Skript zu #P3 #P2 Player setpos [x,y,z]; exit; Hinter dem jeweiligen Label, also beispielsweise #P1, kann man nun die Position angeben. #P3 Player setpos getpos HP1; exit; Kapitel 6 ? _start < 1 : goto "P1"; ? _start < 2 : goto "P2"; ? _start < 3 : goto "P3"; Hier wurde ein Randomwert von 3 verwendet. Beim Starten des Skriptes wird ein Wert ausgelost und danach geprüft wie groß dieser Wert ist. Dann folgt der nächste Schritt. _start = random 3; Bei #P1 und #P2 wurde jeweils eine XYZ-Position definiert, während der Spieler bei #P3 auf ein unsichtbares Heli-H namens HP1 gesetzt wird, was auch eine Möglichkeit ist. Man spart sich dann den Aufwand die XYZ-Positionen zu ermitteln und setzt stattdessen lediglich ein paar unsichtbare Heli-H´s auf die Karte und benennt sie entsprechend. Hierbei bietet sich zusätzlich an, den Radius der Platzierung des einzelnen Heli-H´s auszunutzen und ihm einen großen Radius zu geben. Jetzt hätte man zum Einen die Dynamik, dass man nicht weiß, an welche Position (P1,P2,P3) der Spieler gesetzt wird und zum Anderen, dass das jeweilige Heli-H ja auch noch einen Platzierungsradius hat, so dass der jeweilige Punkt auch nicht genau definiert werden kann. 185 Beispiel: Dynamische Startpunkte Koordinatenbezogen In dem folgend erläuterten Beispiel wird ein XYZ-Punkt bestimmt, welcher mit einem zusätzlichen variablen Platzierungsradius (_radius = 500) versehen wird. Zunächst wird die Position _pos mit [0,0,0] definiert, der Radius bestimmt und für _start ein Randomwert von 3 definiert, welchen das Skript beim Start zufällig bestimmt. Danach prüft das Skript, wie groß dieser Wert ist und springt an die jeweilige Position. _pos bekommt dann einen der drei XYZ-Werte zugewiesen (_pos = [X,Y,Z]), welche man vorher rausgesucht und definiert hat. Nun hat _pos eine feste XYZ-Position erhalten und bekommt jetzt noch einen zusätzlichen Radius (_radius = 500) um diese Position zugewiesen, in welchem die Einheit, hier der Spieler, dann per Zufall gesetzt wird. _pos = [0,0,0] ; _radius = 500; _start = random 3; ? _start < 1 : _pos = [X,Y,Z]; ? _start < 2 : _pos = [X,Y,Z]; ? _start < 3 : _pos = [X,Y,Z]; ; Diese Zeile sollte in einer Zeile definiert werden, was hier nicht möglich ist: _pos = [(_pos select 0) + _radius/2 - random _radius, (_pos select 1) + _radius/2 - random _radius, _pos select 2]; Player setPos _pos; exit; Auf eine Karte kann man sich das etwa so vorstellen, wobei die grünen Marker die Startpunkte des Spielers oder der Einheit darstellen. 186 6.6 - Der Mapclick Der Mapclick eröffnet jedem Missionsdesigner eine Menge Möglichkeiten, wie man anhand dieses Kapitels im Unterbereich „Die Artillerie“ sehr gut erkennen kann. Natürlich gibt es noch viel mehr Möglichkeiten diesen einzusetzen. Als Beispiele dienen hier das steuern von anderen Gruppen, Anforderung eines Airstrikes, steuern von Nachschubbewegungen und vieles mehr. Dieses Beispiel ist für Einzelspieler ausgelegt. Anhand des folgenden Beispiels soll eine KI-Gruppe namens Alpha1 durch den Spieler per Funkmenü frei auf der Karte gesteuert werden. Dabei wird die Zielposition zunächst mit einem Mapklick festgelegt und dazu ein Marker mit Namen AMoveP an die geklickte Stelle gebeamt. Im gleichen Moment bekommt der Leader der Einheit den Befehl sich zum Marker AmoveP zu bewegen und bestätigt dies mit einem eingespielten RogerSound, welchen man dazu selbst in der Description.ext definieren muss. Die Gruppe selbst wird, wie in diesem Kapitel unter „Das GPS-System“ erklärt, mit einem Marker auf der Karte gekennzeichnet und verfolgt, was hier jetzt aber nicht weiter erklärt wird. Der Marker AmoveP soll dann wieder von der Karte verschwinden und erst beim nächsten Mapclick wieder auftauchen. Dazu wird dieser Marker am Skriptende so lange an die Position [0,0] gebeamt. Funkauslöser: Aktivierung: Alpha1 Alpha1=group this Frei festlegbar Achse a/b: Text: bei Aktivierung: Radio Alpha Mehrfach 0 0-0-1 Alpha 1 [] exec “Scripts\Alpha.sqs" Marker: Name: Text: Symbol: Achse a/b: AmoveP Alpha 1 Movepoint Dot 1 Kapitel 6 Gruppe Alpha 1: Name: Initzeile: Gruppengröße: 187 Alpha.sqs Bei dem Skript geschieht nun folgendes. Zunächst wird die Variable alphaclick auf true gesetzt und auf dem Monitor erscheint ein Text, der den Spieler auffordert auf die Karte zu klicken. Danach merkt sich ArmA, was bei onMapSingleClick festgelegt wurde und das Skript pausiert bei @!alphaclick, bis der Spieler auf die Karte geklickt hat und damit alle Befehle nach OnMapSingleClick in den " " ausgeführt werden. Unter anderem wird dort die Variable alphaclick wieder auf false gesetzt. Jetzt wird der Einblendtext wieder gelöscht und ein Soundsample namens Roger abgespielt. Nach einer Pause von 20 Sekunden, wird der Marker AmoveP zu einer nicht sichtbaren Position gebeamt und verschwindet somit bis zum nächsten Klick wieder. alphaclick=true; titletext ["Klicke auf die Karte!","plain down"]; ;Die folgende Zeile muss in einer Reihe stehen, was hier nicht möglich ist. onMapSingleClick "Leader Alpha1 move _pos; alphaclick=false;""AMoveP"" setMarkerPos _pos"; @!alphaclick; onMapSingleClick ""; titleText ["","plain down"]; ~1 playSound "Roger"; ~20 "AMoveP" setMarkerPos [0,0] ; exit; 188 6.7 - Die Artillerie Ein ganz besonderes Feature in einer Mission ist die Artillerie. Sei es, dass der Spieler die Möglichkeit hat dieser per Mapclick einen Zielpunkt zu geben oder, dass die KI Artillerieunterstützung zu der Position einer entdeckten Feindeinheit, zum Beispiel dem Spieler, ruft. Die Besonderheit an dieser Artillerie ist, dass diese auch wirklich auf der Karte existent ist, was für ein Artillerieskript eigentlich nicht unbedingt wichtig ist. Hinzu kommt, dass man den Geschützen jederzeit zuschauen kann, wie sie ihre Rohre ausrichten und danach in die für sie festgelegte Richtung feuern. Dies ist leider nicht ohne ein wenig Skriptaufwand möglich, welcher aber noch recht überschaubar ist. Zunächst nimmt man einige Einstellungen im Editor vor und erstellt im Missionsordner einen Unterordner namens: Artillerie (klein geschrieben!) Spielerbezogen: Der Spieler soll per Funk die Möglichkeit haben Artillerie zu rufen und dieser per Mapclick auf der Karte einen Zielpunkt zuweisen können. Dabei soll ein Marker namens Firepoint diesen Punkt während des Feuervorgangs markieren und danach wieder verschwinden. Funkauslöser: Aktivierung: Kapitel 6 Achse a/b: Text: bei Aktivierung: Radio Alpha Mehrfach 0 0-0-1 Artillerie [] exec “Artillerie\Setfire.sqs" Marker: Name: Symbol: Achse a/b: Firepoint Destroy 1 Unsichtbares Heli H: Name: Position: ATarget Irgendwo auf die Karte Die Geschütze: Dieses Beispiel ist mit 6 Geschützen der Seite BLUEFOR und dem Geschütztyp M119 definiert. Diese setzt man auf die Karte und benennt diese wie folgt: Namen: W1, W2, W3, W4, W5, W6 Ein anderer Geschütztyp funktioniert bei diesem Beispiel nicht! Erklärung folgt. 189 Setfire.sqs Beim Benutzen des Funkauslösers, wird das nun folgende Skript gestartet. Dabei wird die Variable setfire auf true gesetzt und es erscheint ein Text (titleText), der den Spieler auffordert auf die Karte zu klicken, um so den Feuerpunkt zu bestimmen. In der darauf folgenden Zeile wird die Definition des Mapclicks gestartet und das Skript pausiert an der Position @!setfire und wartet darauf, dass der Spieler auf die Karte klickt. Beim Klicken wird das unsichtbare Heli-H namens ATarget an die angeklickte Position _pos gebeamt, die Variable setfire wieder auf false gesetzt und somit die Bedingung !setfire (not setfire) erfüllt. Das Skript kann nun weiterlaufen. Als nächstes wird der Marker Firepoint an die Position des Heli-H´s ATarget gesetzt und der onMapSingleClick deaktiviert. Danach wird das Skript ari.sqs aufgerufen und der Text, der den Spieler auffordert auf die Karte zu klicken wieder entfernt. setfire=true; titletext ["Click on the map to set your firedirection","plain down"]; onMapSingleClick "ATarget setPos _pos;setfire=false"; @!setfire; "Firepoint" setMarkerPos getPos ATarget; onMapSingleClick ""; [] exec "artillerie\ari.sqs"; titleText ["","plain down"]; ~15 "Firepoint" setMarkerPos [0,0] ; exit; Ari.sqs Nachdem dieses Skript durch den Mapklick aktiviert wurde, wird zunächst ein Funksound mit einer Länge von 10 Sekunden abgespielt, den man natürlich erst in der Description.ext definieren muss und erst nach dem Delay von ~10 wird das Skript fire.sqs durch das jeweilige Geschütz und dem ATarget gestartet. Dies wäre jetzt nur eine Schussfolge! playsound "Firedirection"; ~10 ;Feuer {[_x, ATarget] exec "Artillerie\Fire.sqs"} foreach [W1,W2,W3,W4,W5,W6] exit; Möchte man mehrere Schussfolgen haben, kopiert man den Abschnitt Feuer einschließlich dem Delay und fügt ihn zwischen dem letzten Feueraufruf (W6) und Exit ein. Die Geschütze würden dann nach einer Nachladepause nochmal feuern. 190 Fire.sqs Nachdem dieses Skript durch die Objekte, also Geschütz und ATarget, dieses Arrays [_x,ATarget] in der Ari.sqs aufgerufen wurde, richten sich die Geschütze aus und schießen auf die angeklickte Position. Dabei wird das erste Objekt des Arrays, also beispielsweise W1, mit der lokalen Variable _K und das zweite Objekt des Arrays, also das ATarget mit der lokalen Variable _Z belegt. Danach bekommt die lokale Variable _X die X-Position vom ATarget(also _Z) und die lokale Variable _Y den Y-Wert von ATarget zugewiesen. Mit dem Befehl _K doWatch [_X,_Y,5000] sagt das Skript zu W1(also _K), dass dieser zu ATarget und in Höhe 5000 schauen soll. Nach einem kurzen Delay von 5 Sekunden bekommt W1 mit _K fire "M119" den Befehl zu schießen. Kurz darauf werden die Granaten in einem bestimmten Randombereich _X+((random 80)-40) und _Y = _Y+((random 80)-40), welcher variabel definierbar ist, einschlagen. Mit dem Befehl _H say "Ari" wird ein Artilleriesound, welcher zunächst auch in der Description.ext definiert werden muss, mit dem Geräusch eines anfliegenden Artilleriegeschosses abgespielt. Diesen hört man auch nur, wenn man sich in der Nähe des Einschlagbereiches befindet. Kapitel 6 _K = _this select 0; _Z = _this select 1; _X = getPos _Z select 0; _Y = getPos _Z select 1; _K doWatch [_X,_Y,5000] ; _A =_K Ammo "M119"; ~5 _K fire "M119"; @ _A > _K Ammo "M119"; ~2 _N = nearestObject [_K,"HeatM119"]; _X = _X+((random 80)-40) ; _Y = _Y+((random 80)-40) ; _H = "HeliHEmpty" createVehicle [_X,_Y] ; ~1 _H say "Ari"; ~1 _N setPos [_X,_Y,0]; "SH_125_HE" createVehicle [_X,_Y,0] ; deleteVehicle _H; exit 191 Dieses Beispiel funktioniert nur mit dem Geschütz M119, da es in diesem Skript so definiert wurde. Möchte man ein Geschütz eines anderen Typs verwenden, muss man die Klasse des Geschützes (hier: M119) und der Munition (hier: HeatM119) dementsprechend angeben. Die Klassen der Geschütze findet man im Kapitel 3.2 in der Waffenbezeichnungsliste. Feindbezogen: Der Spieler oder befreundete Einheiten sollen in einem definierten Auslöserbereich, wenn sie durch die Gegnerseite entdeckt werden, mit Artillerie beschossen werden. Das Verfahren ist das Gleiche, wie bei der der zuvor erklärten Variante, nur dass die Skripte nun im Unterordner Feindartillerie liegen und eine Setfire.sqs nicht benötigt wird. Auch einen Marker, der die Beschusszone zeigt, und ein Heli-H wird es nicht geben. Variante 1: Man müsste jetzt noch nicht mal östliche Artillerie verwenden, sondern setzt lediglich einen Auslöser mit folgenden Einstellungen auf die Karte: Auslöser: Aktivierung: Achse a/b: bei Aktivierung: Westen Mehrfach Von Osten entdeckt 2000 (den Bereich festlegen!) [thislist] exec “Feindartillerie\Ari.sqs" und ändert die Ari.sqs im Unterordner, wie auf der nächsten Seite erläutert wird, dementsprechend ab. Lediglich die Ari.sqs würde hierbei abgeändert werden. Die Fire.sqs bleibt dabei auf den Geschütztyp M119 eingestellt! Alle Westeinheiten, die nun in diesem Bereich durch Osteinheiten entdeckt werden, werden mit Artillerie beschossen. Dass dies die eigene Artillerie ist, merkt man dabei nicht. Variante 2: Möchte man aber für die Ostseite extra Artillerie anlegen, definiert man das wie folgt: Auslöser: Aktivierung: Achse a/b: bei Aktivierung: 192 Westen Mehrfach Von Osten entdeckt 2000 (den Bereich festlegen!) [thislist] exec “Feindartillerie\Ari.sqs" Die Geschütze: Dieses Beispiel ist mit 6 Geschützen der Seite Ost und dem Geschütztyp D30 definiert. Diese setzt man auf die Karte und benennt sie wie folgt: Namen: E1, E2, E3, E4, E5, E6 Ari.sqs Die Besonderheit dieser Ari.sqs ergibt sich aus der festgelegten Auslösesyntax im Auslöser, welche ja wie folgt definiert wurde: [thislist] exec " ". Das bedeutet, dass jede Westeinheit, die durch die Ostseite entdeckt wird, im Skript die lokale Variable _Ziel zugewiesen bekommt und somit die Zielkoordinate darstellt. Das jeweilige Geschütz und _Ziel würden dann die Fire.sqs im Unterordner Feindartillerie aufrufen. _Ziel = _this select 0; ;Feuer {[_x,_Ziel] exec "Feindartillerie\Feuer.sqs"} foreach [E1,E2,E3,E4,E5,E6] exit; Fire.sqs Dieses Skript wird nun nur noch auf den Ost-Geschütztyp D30 abgestimmt. Dabei muss der Klassenname des Geschützes, hier D30, und der Munitionsname, hier HeatD30, vergeben werden. Man könnte hier als Geschütz also auch einen Panzer o.ä. verwenden. Im Kapitel 3.16 wird erklärt, wie man sich den Waffen- und Munitionstyp ausgeben lässt. Kapitel 6 _K = _this select 0; _Z = _this select 1; _X = getPos _Z select 0; _Y = getPos _Z select 1; _K doWatch [_X,_Y,5000]; _A =_K Ammo "D30"; ~5 _K fire "D30"; @ _A > _K Ammo "D30"; ~3 _N = nearestObject [_K,"HeatD30"]; _X = _X+((random 80)-40); _Y = _Y+((random 80)-40); _H = "HeliHEmpty" createVehicle [_X,_Y] ; _H say "Ari"; ~1 _N setPos [_X,_Y,0]; "SH_125_HE" createVehicle [_X,_Y,0]; deleteVehicle _H; exit; 193 6.8 - Tote Einheiten bzw. Fahrzeuge löschen Gerade im Mehrspielerbereich ist es sehr wichtig, eine gute Performance zu haben, was aber auch im Einzelspielerbereich nicht unbeachtet bleiben sollte. Je mehr Einheiten sich auf der Karte bewegen bzw. dargestellt werden müssen, desto langsamer oder auch manchmal unfunktioneller die Mission. Dieses Skript löscht in einem zuvor festgelegten Auslöserbereich und in variabel definierbarer Zeit tote Einheiten von der Karte. In dieser Auslösesyntax [2] exec "bodydelete.sqs" kann man die Anzahl der toten Einheiten, die maximal auf der Karte liegen bleiben sollen, frei definieren. Statt der 2 gibt man dazu einfach einen höheren Wert an und somit bleiben mehr Leichen liegen. Dieses Skript ist nicht seitenbezogen. Hier kommt es darauf an, wie man den Auslöser einstellt. Dies ist mal ein Einstellungsbeispiel für Osten: Auslöser: Aktivierung: Achse a/b: bei Aktivierung: OSTEN Einfach Vorhanden 2000 (den Bereich festlegen!) [2] exec "Scripts\Bodydelete.sqs" Möchte man, dass alle Einheiten egal welcher Seite gelöscht werden sollen, wählt man bei Aktivierung einfach nur Jeder aus. Möchte man, das nur Westeinheiten gelöscht werden sollen, eben Westen und so weiter. Für dieses Skript wurde im Missionsordner ein Unterordner namens Skripte angelegt. Die Besonderheit an dem Skript ist, dass Soldaten bevor sie gelöscht werden, dank dieser Zeile: (Gravedigger) action ["hidebody",_P] erst im Boden versinken. Dazu braucht man einen Dummy, der im Skript Gravedigger benannt wurde. Dieser macht es dann erst möglich, dass die toten Soldaten zunächst im Boden versinken, bevor sie gelöscht werden. Diesen setzt man einfach irgendwo weit weg vom Geschehen auf eine Insel, damit ihm nichts passiert. Hierbei ist es egal, was es für eine Einheit ist. Er kann jeder Seite angehören. Lediglich der Name muss mit dem im Skript übereinstimmen. Fahrzeuge werden dabei nicht im Boden versinken, sondern direkt gelöscht! Soldatenbezogen: Dieses Skript ist auf die Typenklasse Man (_T="Man") festgelegt. Es löscht also nur Vehikel, die auch diese Typenklasse haben. Gibt man hier Land an, löscht es alle Typenklassen, die Land unterstellt sind. Da sich außer Flugzeuge und Boote alles andere auf Land bewegt, wird somit alles was diese Typenklasse besitzt und nicht mehr lebt, von der Karte gelöscht. 194 Das Skript Bodydelete.sqs sieht dabei wie folgt aus: ? !(local server):exit; _W=_this select 0; _L=[]+thislist; _A=[]; _G=[]; _T="Man"; { if (_T counttype [_x] == 1) then {_G=_G+[_x]} } foreach _L; #Again { if (not alive _x) then {_A=_A+[_x]} } forEach _G; _G=_G-_A; ? count _A > _W :_P=_A select 0;_A=_A-[_P] ; (Gravedigger) action ["Hidebody",_P] ; ~10 deleteVehicle _P; ? count _A == _W and count _G == 0 :exit; goto "Again" In manchen Missionen ist es vorteilhaft die Spielbeschleunigung zu unterdrücken. Zum Beispiel, wenn man nicht möchte, dass der Spieler den Ablauf beschleunigt. Denn dies könnte je nach Situation negative Auswirkungen auf den Missions- und Spielverlauf haben. Wenn man zum Beispiel eine hohe Skriplast oder ähnliches hat, könnte die Spielbeschleunigung gegebenenfalls zu Fehler führen. Da man dies im Editor nicht mit nur einem Befehl lösen kann, regelt man das mit einem kleinen Skript, welches etwa wie folgt aussehen kann: ; Spielbeschleunigung unterdrücken #Check ? not alive Player : exit; setAccTime 1.0; ~0.1 goto "Check" Dieses Skript startet man gleich zu Beginn der Mission direkt aus der Init.sqs oder der Initzeile einer Einheit oder eines Objektes. Es setzt die Zeit immer wieder auf 1. Auch wenn der Spieler die Beschleunigung anklickt, wird sich nichts verändern. 195 Kapitel 6 6.9 - Spielbeschleunigung dauerhaft unterdrücken 6.10 - Der Bullet Mode Hier ein kleines Feature, welches zwar nicht sonderlich realistisch ist, aber trotzdem ein wenig die Möglichkeiten vorn Armed Assault aufzeigen soll. Mit diesem Bullet Mode ist es möglich, während des Spielens auf Zeitlupe umzuschalten, so dass man Kampfszenen in Zeitlupe sehen und mit einem Screenshot festhalten kann. Dies wurde hierbei mit einem Actionmenüeintrag und zwei Skripten realisiert. Natürlich ist das Ganze nur im Singleplayerbereich möglich und für Multiplayer eher unbrauchbar. Zunächst versieht man den Spieler mit einem Actionmenüeintrag: ID=Player AddAction ["Bullet Mode ON", "Bulleton.sqs"]; Das ist der Eintrag, mit dem man den Bullet Mode zunächst startet. Das Skript sieht dabei wie folgt aus: Bulleton.sqs ;Eintrag wird entfernt Player removeAction ID; ;Eintrag wird hinzugefügt IID = Player addAction ["Bullet-Mode OFF ", "bulletoff.sqs"]; ;Zeitlupe wird gesetzt setAccTime 0.0900; exit; Dem Spieler wird nach dem Auslösen des Bulletmodes der Eintrag Bullet-Mode ON entfernt und er bekommt den Eintrag Bullet-Mode OFF hinzugefügt. Alles läuft jetzt, bis der Spieler den Bulletmode wieder ausschaltet, in Zeitlupe ab. Bei folgendem Skript wird das gleiche Verfahren wie oben verwendet, nur eben umgekehrt. Bulletoff.sqs ;Eintrag wird entfernt Player removeAction IID; ;Eintrag wird hinzugefügt ID = Player addAction ["Bullet-Mode ON ", "bulleton.sqs"]; ;Zeitlupe wird zurückgenommen setAccTime 1.0; exit; Ein nettes Zusatzfeature wäre es, wenn man einen Musiktitel mit angibt, der abgespielt wird, wenn der Modus aktiviert und gestoppt wird, wenn der Modus wieder ausgeschaltet wird. 196 6.11 - Das Feindmeldescript Möchte man in einer Mission haben, dass eine befreundete KI irgendwelche Feindeinheiten meldet und diese dann auf der Karte für einen Moment mit einem blinkenden Marker markiert werden sollen, damit man beispielsweise seine Artillerie darauf lenken oder andere Einheiten dorthin schicken kann, kann man das wie im nun folgenden Beispiel realisieren. Im Multiplayer würde man das Skript nur Serverseitig ausführen. Dazu in der ersten Skriptzeile den Zusatz ?(!(local server)):exit mit angeben. Man setzt irgendwo einen Marker auf die Karte und dazu einen Auslöser, der den Bereich festlegt, welche wie folgt eingestellt: Auslöser: Aktivierung: Achse a/b: bei Aktivierung: OSTEN Von Westen entdeckt Mehrfach 5000 thislist exec "Scripts\Signal.sqs" Marker: Name: Farbe: Achse a/b: Symbol: Target1 Red 1 Destroy Kapitel 6 Das Skript dazu sieht dann etwa so aus: _Target = _this select 0; signalcounter = 0; "Target1" setMarkerPos getPos _ Target; "Target1" setMarkerType "Destroy"; #Start ? (signalcounter>=10) OR not alive _Target : goto "Ende"; signalcounter = signalcounter+1; ~0.8 "Target1" setMarkerColor "ColorRed"; ~0.8 "Target1" setMarkerColor "ColorBlack"; goto "Start" #Ende ~1 signalcounter = 0; "Target1" setMarkerType "Empty"; "Target1" setMarkerColor "ColorBlack"; exit; 197 6.12 - Der Airstrike Luftschläge sind auf jedem Schlachtfeld ein taktischer Vorteil. Deshalb wird hier eine Möglichkeit vorgestellt, wie man einen Airstrike umsetzen kann. Diese Version muss gegebenenfalls an die jeweilige Mission angepasst werden. Das heißt, man testet den Airstrike vorher im vorgesehenen Missionsgebiet und verändert gegebenfalls die Flughöhe oder die Zeit bis zum Abwurf. Dabei werden die Treffer zum Teil genauer. Dieses Beispiel ist leider nicht multiplayertauglich, da die Bombe des Harriers das Spiel abstürzen lässt. Um diesen Airstrike in die Mission einzubauen setzt man zunächst folgende Objekte auf die Karte. Unsichtbares Heli-H: Leer/Objekte: H (invisible) Name: ASTarget Funkauslöser: Aktivierung: Text: Achse a/b: bei Aktivierung: Radio Alpha 0-0-1 AIRSTRIKE 0 [] exec "Scripts\Airstrike.sqs" Marker: Name: Farbe: Symbol: Achse a/b: Firedirection rot Destroy 1 Nach dem Aktivieren von Radio Alpha klickt der Spieler auf die Karte und dabei werden das Atarget und der Marker Firedirection auf diese Position gesetzt. Danach wird ein Flugzeug mit Pilot generiert, der dieses Ziel anfliegt. Wenn es in einer gewissen Distanz zum Ziel ist, bekommt es den Bombenabwurfbefehl und wirft die gefährliche Fracht ab. Danach fliegt es weg und wird am Ende wieder gelöscht. 198 Airstrike.sqs Die Logik und den Marker setzt man hierbei irgendwo an den Kartenrand, damit diese für den Spieler nicht zu sehen sind und der Marker und das Ziel später wieder an eine nicht sichtbare Position auf der Karte gebeamt werden können. Jetzt muss man nur noch folgendes Skript anfertigen und es kann losgehen. setfire=true; titleText ["Click on the map to set your firedirection","plain down"]; onMapSingleClick "ASTarget setPos _pos; setfire=false"; @!setfire; "Firedirection" setmarkerpos getPos ASTarget; playSound "Firedirection"; onMapSingleClick ""; titleText ["", "plain down"]; ;=========DEFINE======================= _dropPosition = getpos ASTarget; ~0.5 _dropPosX = _dropPosition select 0; _dropPosY = _dropPosition select 1; _dropPosZ = _dropPosition select 2; ~0.1 _planespawnpos = [_dropPosX + 3000, _dropPosY, _dropPosZ + 1000]; _pilotspawnpos = [_dropPosX + 3000, _dropPosY, _dropPosZ + 1000]; Kapitel 6 ;=========CREATE======================= _PlaneG = creategroup WEST; _plane = createVehicle ["AV8B",_planespawnpos,[], 0, "FLY"]; _plane setPos [(getPos _plane select 0),(getPos _plane select 1),900] ; _pilot = "SoldierWPilot" createUnit [getMarkerPos "Firedirection", _PlaneG, "P1=this"]; _Plane setVelocity [100,0,0] ; ~0.4 P1 moveinDriver _plane; P1 setDamage 0; P1 action ["gear_up", vehicle P1] ; _plane flyinHeight 100; _plane setSpeedMode "full"; #CHECK P1 doMove getPos ASTarget; P1 doTarget ASTarget; P1 doWatch ASTarget; ? (_plane distance ASTarget) < 1500 : goto "DROP" goto "CHECK" Weiter auf der nächsten Seite 199 ;=========FIRE======================= #DROP _i = 0 _plane flyInHeight 100; _plane setPos [(getPos _plane select 0),(getPos _plane select 1),100] ; ~13 #FIRE _i=_i+1 _plane fire "BombLauncher"; ~0.2 ? _i <= 6 : goto "FIRE" ;=========FLY AWAY======================= ASTarget setPos [0,0,0]; "Firedirection" setMarkerPos [0,0]; _plane setSpeedMode “Full” ~4 _plane flyInHeight 300; P1 doMove getPos ASTarget; #Check2 _plane setDamage 0; P1 setDamage 0; ? (_plane distance Player) > 2500 : goto "ENDE"; goto "Check2" ;=========DELETE======================== #ENDE; deleteVehicle _plane; deleteGroup _PlaneG deleteVehicle P1; exit Wenn man die grün markierten Werte bei dem Label #Drop und #Check verändert, wirkt sich das auf die Treffergenauigkeit aus. Je nach geographischer Gegebenheit ist diese besser oder eher schlechter, was ja in der Realität auch so ist. Nachdem der Bomber das Ziel erreicht und seine Bomben abgeworfen hat, bekommt der den Befehl zum versetzten ASTarget zu fliegen um, wenn er ausreichend weit vom Spieler entfernt ist, gelöscht zu werden. Würde man ihn sofort löschen, würde der Sound sofort verschwinden, was ja nicht so realistisch ist. Am Anfang des Skriptes wurde ein Sound (Playsound "Firedirection") gestartet, der natürlich auch vorhanden sein muss und zuvor in der Description.ext definiert werden sollte. 200 6.13 - Der Airvehiclecreator Dieses Skript ermöglicht es dir Luftfahrzeuge in beliebiger Anzahl und beliebigen Typ während des Spielverlaufs zu erstellen. Dabei legt man in der Mission einen Startpunkt, z.B. ein unsichtbares Heli-H, fest und weist der per Skript erstellten Einheit ein Ziel, z.B. eine Einheit oder ein weiteres Heli-H zu. Das Besondere hieran ist der Array, in dem man eine Menge vordefinieren kann. Man hat unter anderem die Möglichkeit den Spieler oder irgendeine andere Einheit im Kampfgebiet als Leader einzutragen oder setzt einfach eine Einheit Namens Dummy auf irgendeine Insel weit weg vom Kampfgeschehen. Im Multiplayer für Leader nie das Wort Player verwenden, sondern den Namen der Einheit. Wichtig: Spiellogik Server setzen! Der Array und die Syntax zum Starten des Skriptes sehen hierbei wie folgt aus: [StartPos, "ParachuteC", "SoldierWB", ZielPos, 100, 0, 0.6, "Combat", Dummy, 10] exec "aircreate.sqs" Dieser sollte natürlich in einer Reihe stehen, was hier nicht möglich ist. Hier ein Objekt auf der Karte mit dem Namen Startpos. Idealerweise ein unsichtbares HeliH, welches man, je nachdem was für ein Luftfahrzeug erstellt werden soll, etwas weiter weg vom Spielgeschehen platzieren sollte. Bei Kampfflugzeugen am besten weit draußen über dem Meer. Die Fhz-Klasse: Hier kommt der Klassenname des Fahrzeugs rein, welches erzeugt werden soll. Oben mit "ParachuteC" festgelegt. Der Einheitstyp: Hier wird der Soldatentyp festgelegt, der das Objekt fliegen soll. Normalerweise ein Pilot. Da aber auch Fallschirmspringer möglich sind, wurde es so ausgelegt, dass man auch andere Einheitstypen angeben kann. Der Leader: Jede Einheit die erstellt wird benötigt einen Leader. Hier kann man jede x-beliebige Einheit auf der Karte festlegen. In diesem Fall wurde ein Dummy definiert. Die Flughöhe: Hier gibt man die Flughöhe in Metern an. Diese wurde oben mit 100 festgelegt. Der Gunner: Da manche Luftfahrzeuge nicht über einen Gunnerplatz verfügen, hat man hier die Möglichkeit diesen auszuschalten. Der Wert 0 steht hierbei für „kein Gunner“ und der Wert 1 für „Gunner“. Der Skill: An dieser Stelle legt man den Skill der Einheit fest. Was oben mit Wert 0.6 definiert wurde, kann auch per Zufall geschehen. Dazu einfach einen Randomwert benutzen (z.B.: random 1). 201 Kapitel 6 Die Startposition: Das Verhalten: Hier wird das Verhalten der Einheit festgelegt. Oben wurde hierbei "Combat" verwendet. Das Ziel: Hier gibt man das Ziel an, welches oben mit ZielPos definiert wurde und ein Objekt auf der Karte ist, welches diesen Namen trägt. Hier könnte man auch Player oder ähnliches angeben. Die Anzahl: Und zu guter letzt die Anzahl der Fahrzeuge, die erstellt werden sollen. Aircreate.sqs ?!(local server):exit; _StartPos = _this select 0; _Airtyp= _this select 1; _Pilottyp = _this select 2; _Target = _this select 3; _Height = _this select 4; _Gunner = _this select 5; _skill = _this select 6; _behaviour = _this select 7; _Leader = _this select 8; _count = _this select 9; _counter = 0; #Start _counter = _counter +1; _Typ = createVehicle [_Airtyp,[(getPos _StartPos select 0)+ random 200,(getPos _StartPos select 1)+ random 200,_Height + random 150], [], 0, "FLY"]; _Typ FlyInHeight _Height; _Typ SetSpeedMode "full"; _Typ setDir getdir _StartPos; _pilot = _Pilottyp createUnit [[(getPos _StartPos select 0),(getPos _StartPos select 1), 2000], _Leader,"Pilot1=this"]; Pilot1 moveInDriver _Typ; Pilot1 setSkill _Skill; Pilot1 doMove getPos _Target; Pilot1 setBehaviour "_behaviour"; ? _gunner == 0 : goto "Next" _gunner = _Pilottyp createUnit [[(getPos _StartPos select 0),(getPos _StartPos select 1), 2000], _Leader,"Gunner1=this"]; Gunner1 moveInGunner _Typ; Gunner1 setSkill _Skill; Gunner1 setBehaviour "_behaviour"; #Next ? _counter >= _count : exit; ~0.5 goto "Start" 202 6.14 - Der Scheinwerfer Da der Scheinwerfer zum Teil nur bewegungslos in die Gegend leuchtet, habe ich dieses Skript dafür entworfen. Hierbei hat man die Möglichkeit in einem Array die äußeren beiden Bewegungsgrenzen frei zu definieren. Das bedeutet, dass die Einheit am Scheinwerfer bis zu ihrem linken im Array festgelegten Punkt leuchtet und dann wieder zurück bis zu ihrem rechten im Array festgelegten Punkt. Der Scheinwerfer bewegt sich dabei langsam von der jeweiligen Richtung in die andere. Jetzt liegt es am Editierer, wie weit die Einheit leuchten darf. Zunächst die Scheinwerfereinheit erstellen und mit einem Namen versehen (z.B.: Wache1) und dann den Array der Syntax dafür festlegen. Hierfür wird folgende Syntax benötigt, um das Skript zu starten: [Name,Linkswert,Rechtswert] exec "Light.sqs" [Wache1,100,180] exec "Light.sqs" Diese Werte werden dann bei dem Aufruf an das Skript Light.sqs übergeben. Light.sqs _Unit = _this select 0; _left = _this select 1; _right = _this select 2; _dir = (getDir _Unit); Kapitel 6 #Start ? !(alive _Unit) : exit; ~0.5 _dir = _dir+1; _Unit setFormDir _dir; ?(_dir > _right) : goto "Next" goto "Start" #Next ? !(alive _Unit) : exit; ~0.5 _dir = _dir -1; _Unit setFormDir _dir; ?(_dir < _left) : goto "Start"; goto "Next" Known Bug Da in Armed Assault vom System her sehr zurückgefahren wird und Objekte, die weiter vom Spieler entfernt sind teilweise quasi abgeschaltet werden, kommt es vor, dass der Scheinwerfer erst anfängt sich zu bewegen, wenn irgendeine Einheit ihren Weg kreuzt. Dazu einfach eine Streife davor entlang laufen lassen oder kurz eine Einheit direkt vorm Scheinwerfer createn und dann wieder löschen (siehe Kapitel 5.45). 203 6.15 - Der Zeitzähler Möchte man seine Mission mit einem Zeitzähler versehen, so kann man dies auf unterschiedliche Art und Weise machen. Hier mal zwei Beispiele. Einmal mit einer Titletext-Einblendung und einmal mit einer Hint-Einblendung. Die Auslösesyntax wird hierbei wie folgt definiert : [60] exec "Time.sqs" Wobei die 60 für den Wert steht. Dieser Wert wird jetzt so lange runtergezählt und auf dem Monitor angezeigt, bis er den Wert 0 erreicht hat und das Skript dann beendet wird. Time.sqs Zunächst die Titletext-Variante, bei welcher die Zahlen am unteren Rand des Bildschirms eingeblendet und langsam runtergezählt werden. _time = _this select 0; #Start ~1 _time = _time -1; Titletext [format["Noch %1 Sekunden", _time],"plain down"]; if (_time >= 1) then {goto "Start"} else {}; Titletext ["","plain down"]; exit; Und hier noch die Hint-Variante, bei welcher die Zahlen oben links am Bildschirmrand eingeblendet und langsam runtergezählt werden. _time = _this select 0; #Start ~1 _time = _time -1; Hint format["Noch %1 Sekunden", _time]; if (_time >= 1) then {goto "Start"} else {}; Titletext ["","plain down"]; exit; Möchte man einen Wert hoch zählen lassen, setzt man die Zeile _time = _time -1 statt dem - ein +, ändert (_time >= 1) auf (_time <= _time) und passt den Text entsprechend an (z.B.: %1 Sekunden). Die Syntax startet man dann mit [0] exec "Time.sqs" 204 6.16 - Das House-Patrol-Script Dieses Skript ermöglicht es Einheiten durch ein Gebäude streifen zu lassen. Dazu muss aber erwähnt werden, dass dies derzeit nur bei dem Hotel wirklich Sinn macht. Man hat dank des wirklich großen Arrays die Möglichkeit, dieses Skript optimal für seine Bedürfnisse zu nutzen. Dieses Skript läuft ohne Weiteres hervorragend im Multiplayer. Dieses wird dabei mit der folgenden, teilweise recht unübersichtlichen Syntax, ausgelöst. Damit man jetzt versteht, wie man diesen Array für seine Bedürfnisse anpassen kann, folgt natürlich gleich eine Erläuterung dazu. Zunächst die Auslösesyntax mit dem Array: [Name, "SAFE", Hotel, 161, 1, 160, 2, 10, 100, 200, 256, 0, 1] exec "housepos.sqs"; Skript Name Verhalten Gebäude _man _behaviour _house Erklärung Name der Einheit Verhalten der Einheit Name des Gebäudes (siehe Kapitel 5.61!) Logik auf das Gebäude setzen und in die Initzeile: Hotel=nearestBuilding this Startposition _startpos Startposition der Einheit im Gebäude Zufall _accident Zufallspositionen (1=an / 0=aus) Hier aktiviert man die Zufallspositionen für zusätzliche Wegpunkte im Gebäude. Ist der Wert 0, werden Zufallspositionzahl und Zufallspositionanzahl überlesen. Zufallspositionzahl _accidentnr Zufallspositionszahl Hier gibt man den Wert an, aus dem eine Zufallsposition ermittelt werden soll. Zum Beispiel wie oben der Wert 160. Es wird jetzt eine Zufallsposition zwischen 0 und 160 ermittelt und als Wegpunkt vergeben. Zufallspositionanzahl _accidentcount Anzahl der Zufallspositionen Wie oft soll eine solche Position generiert werden. Oben sind 2 Abläufe definiert. Pause _rest Pause an Position (oben: 10) Wie lange soll die Einheit an der Position warten, bis sie zur nächsten weiterläuft. Wegpunkt 1 _wp1 Erster Wegpunkt (oben: 100) Wegpunkt 2 _wp2 Zweiter Wegpunkt (oben: 200) Endwegpunkt _ende Endwegpunkt (oben: 250) Statisch/Dynamisch _form Start (Statisch=0/Dynamisch=1) Ist der Wert wie oben 0, dann wird die Einheit an die definierte Startposition im Haus gesetzt. Wiederholen _loop Skript wiederholen.oder Streife beenden. 205 Kapitel 6 Bezeichnung Werte wie Pause oder Start-, Wegpunkt 1, Wegpunkt 2 oder Endwegpunkt kann man hervorragend zusätzlich mit Random belegen und somit noch mehr Dynamik einbringen. Dazu einfach Random vor den Wert im Array schreiben. Dieser Array erfordert ein wenig Konzentration konfigurieren, da dort eine Menge Zahlenwerte hintereinander folgen und man schnell durcheinander kommt. Deshalb muss man hier mal wieder ein wenig gewissenhaft und konzentriert vorgehen. HousePos.sqs ?!(Local Server): exit _man = _this select 0; _behaviour = _this select 1; _house = _this select 2; _startpos = _this select 3; _accident = _this select 4; _accidentnr = _this select 5; _accidentcount = _this select 6; _rest = _this select 7; _wp1 = _this select 8; _wp2 = _this select 9; _ende = _this select 10; _form = _this select 11; _loop = _this select 12; #LOOP _counter = 0; _man setbehaviour _behaviour; ;//Form of employment (Static=0/Dynamic=1) ? _form == 0 : {_x setpos (_house buildingPos _startpos)} foreach units _man; ;//First Waypoint (Enable=Buildingposition;Disable=0) #WP1 ? _wp1 == 0 : goto "WP2" Leader _man move (_house buildingPos _wp1); #WP1Dest ~1 ? Leader _man distance (_house buildingPos _wp1) > 2 : goto "WP1Dest"; ~ _rest ;//Second Waypoint (Enable=Buildingposition;Disable=0) #WP2 ? _wp2 == 0 : goto "AccidentPos"; Leader _man move (_house buildingPos _wp2); Weiter nächste Seite. 206 #WP2Dest ~1 ? Leader _man distance (_house buildingPos _wp2) > 2 : goto "WP2Dest"; ~ _rest ;//Accidenpositions (Enable=1;Disable=0) #AccidentPos ? _accident == 0 : goto "EndP"; #Accident; _counter = _counter +1; _apos = random _accidentnr; ~1 Leader _man move (_house buildingPos _apos); #APosCheck ~1 ? Leader _man distance (_house buildingPos _apos) > 2 : goto "APosCheck" ? _counter >= _accidentcount : goto "EndP" ~ _rest goto "Accident" ;//End Waypoint (Enable=Buildingposition;Disable=0) #EndP ? _ende == 0 : goto "Ende" ~ _rest Leader _man move (_house buildingPos _ende); ;// LOOP (Enable=1;Disable=0) #Ende ? _loop == 1 : goto "Loop" exit; Dieses Skript kann man nun sehr flexibel einsetzen. Als Beispiel mal folgendes: Man möchte, dass Einheiten ein paar Wegpunkte um das Gebäude ablaufen, dann an einem Wegpunkt das Skript aktivieren, diese Positionen ablaufen und danach wieder um das Gebäude laufen. Dazu würde man dynamisch/statisch auf 1, also auf dynamisch setzen. Somit würde die Einheit zunächst den Befehl bekommen den Wegpunkt 1 anzusteuern. Loop setzt man dabei logischerweise auf 0! Generell sollte eine Gruppe nicht mehr als 1-3 Einheiten für eine Streife in dem Gebäude haben. Wobei wohl 1-2 Einheiten realistisch wären. In dem Hotel hat man schon die Möglichkeit mehrere Streifen laufen zu lassen. Zuzüglich fest gesetzter Einheiten in dem Gebäude hat es ein Spieler nicht leicht dort heil oder unbemerkt rein oder herauszukommen. 207 Kapitel 6 #EndPDest ~1 ? Leader _man distance (_house buildingPos _ende) > 2 : goto "EndPDest" 6.17 - Das Minen-Skript Da die Minen nicht wirklich die Funktion einer Mine erfüllen, muss dabei eben nachgeholfen werden. Das löst man hierbei wieder mit einem Skript. Hierbei werden zwei verschiedene Skripte angelegt. Eins für Antipersonenminen und eins für Panzerminen. Der Unterschied besteht dabei nur bei dem Shelltyp, der für die Explosion benötigt wird. Schließlich haben Panzerminen eine größere Sprengkraft als Antipersonenminen. Dazu setzt man zunächst eine Mine auf die Karte und als Ergänzung einen Auslöser, der dann das Skript bei Auslösung aktiviert und die Explosion herbeiführt. Diesen setzt man direkt auf die Mine so dass, wenn eine Einheit in den Bereich der Mine bzw. Auslöser kommt, dieser auslöst. Antipersonenmine Auslöser: Aktivierung: Achse: bei Aktivierung: SEITE Einfach 1/1 thislist exec "apmine.sqs" APmine.sqs ?(!(Local Server)): exit; _Soldier = _this select 0; _Bomb="SH_125_HE" createVehicle position _Soldier exit; Der Vorteil hieran ist, dass man eine Mine mit dem definierten Auslöser mit Copy & Paste in beliebiger Anzahl vervielfältigen kann, ohne noch irgendwas anderes definieren zu müssen. Ein Skript für hunderte von Minen. Panzermine: Für die Panzermine kann man das gleiche Verfahren verwenden, nur dass man eben im Skript einen stärkeren Sprengkörper, also eine andere Shellklasse, verwendet. Diese gibt’s wie gewohnt im Kapitel 3.10. Das Skript benennt man dabei dann eben pzmine.sqs. Für Panzerminen bietet es sich an den Radius des Auslösers ein wenig zu vergrößern. 208 6.18 - Das Vehikeltransportskript Dieses Skript ermöglicht es Fahrzeuge und Objekte an ein Fluggerät zu hängen und an ein Ziel zu transportieren. Hierbei sind zwei Varianten möglich. Zum Ersten die, dass man zwei Objekte (Helikopter(Heli) und Ladung(Veh1)) auf der Karte vordefiniert und mit dessen Namen das VehTrsp-Skript aufruft. Dabei wird die Ladung von dem Startpunkt des Helikopters bis zum definierten Zielpunkt geflogen und dort abgesetzt. Aufgrund der Nichtfunktionalität von Setpos im Multiplayer, läuft dieses Beispiel zur Zeit nur im Singleplayer vernünftig. Das Skript wird mit folgender Syntax aufgerufen: [Heli,Veh1, 70, Player, EndPos] exec "vehtrsp.sqs" Der Array erklärt sich hierbei wie folgt: [Transporter, Ladung, Flughöhe, Absetzpunkt, Endposition] VehTrsp.sqs Kapitel 6 ?!(Local Server): exit _TranspVeh = _this select 0 _Cargo = _this select 1 _Height = _this select 2 _Place = _this select 3 _EndPos = _this select 4 _TranspVeh domove getpos _Place; _TranspVeh flyinheight _Height; ;/////////////////////////////TRANSPORT///////////////////////////////// #Loop _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); ? _TranspVeh distance Player < 100 : goto "Next" ~.01 goto "Loop" ;/////////////////////////////LANDING////////////////////////////////// #Next _TranspVeh flyinheight 13; _TranspVeh setspeedMode "Limited"; _TranspVeh action ["AUTOHOVER", _TranspVeh]; #Loop2 _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); ? (getPos _Cargo select 2) < 1.5 : goto "Loop3" ~.01 goto "Loop2" 209 ##Loop3 _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); ? speed _TranspVeh < 1 : goto "Ende"; ~.01 goto "Loop3" ;/////////////////////////////UNLOADING////////////////////////////////// #Ende _Cargo setpos [(getpos _Cargo select 0),(getpos _Cargo select 1),0] _TranspVeh action ["CANCELACTION", _TranspVeh] _TranspVeh flyinheight _Height _TranspVeh domove getpos _EndPos _TranspVeh setSpeedMode "Normal" exit Spawn-Variante Zum Zweiten gibt es die Variante, mit der beide Vehikel an einem Startpunkt auf der Karte erzeugt werden, der Heli mit der Ladung zu dem Absetzpunkt fliegt, dort die Ladung abgesetzt und dann weiter zum definierten Endpunkt fliegt, wo er dann gelöscht wird. Damit dies auch im Editor übersichtlich gestaltet werden kann, ist das Ganze mit drei unsichtbaren Heli-H´s mit Namen: StartPos Target EndPos realisiert. Diese kann man nun frei auf der Karte platzieren. Das Besondere hieran ist, dass der Heli beim Start in die Blickrichtung des StartPos-Objektes ausgerichtet wird. So kann man durch drehen des StartPos-Objektes schon mal die Flugrichtung des Transporthubschraubers bestimmen. Natürlich hat man hier auch die Möglichkeit als Absetzpunkt den Spieler oder ähnliches anzugeben. Dazu würde man statt Target einfach Player oder den Namen der Einheit dort angeben, bei dem die Ladung abgesetzt werden soll. Als Leader für den zu erstellenden Heli wurde eine Einheit mit Namen Dummy auf der Karte vordefiniert. Dies hat den Grund, dass der Transporthubschrauber dann erfahrungsgemäß besser fliegt und besser landet. Folgend die Syntax, mit der das Skript aufgerufen wird. ["UH60MG", "HMMWVMK", "SoldierWPilot", 70, StartPos, Target, EndPos, Dummy] exec "vehtrspcreate.sqs" Der Array erklärt sich hierbei wie folgt: ["HeliTyp", "Ladungstyp", "Pilottyp", Flughöhe, Startposition, Absetzpunkt, Endposition, Leader] 210 VehTrspCreate.sqs ?!(Local Server): exit _AirVeh = _this select 0 _Vehicle = _this select 1 _Pilottyp = _this select 2 _Height = _this select 3 _StartPos = _this select 4 _Place = _this select 5 _EndPos = _this select 6 _Leader = _this select 7 ;/////////////////////////////CREATE//////////////////////////////////// _TranspVeh = createVehicle [_AirVeh,[(getpos _StartPos select 0),(getpos _StartPos select 1),_Height], [], 0, "FLY"]; _TranspVeh setdir getdir _StartPos _Cargo = _Vehicle createVehicle getpos _TranspVeh _pilot = _Pilottyp createUnit [[(getpos _StartPos select 0),(getpos _StartPos select 1),2000], _Leader,"Pilot1=this"] Pilot1 moveinDriver _TranspVeh _TranspVeh flyinheight _Height Kapitel 6 ;/////////////////////////////TRANSPORT///////////////////////////////// #Loop Pilot1 domove getpos _Place _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); ? _TranspVeh distance _Place < 90 + random 50 : goto "Next" ~.01 goto "Loop" ;/////////////////////////////LANDING/////////////////////////////////// #Next _TranspVeh flyinheight 13; _TranspVeh setSpeedMode "Limited"; _TranspVeh action ["AUTOHOVER", _TranspVeh]; #Loop2 _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); 211 ? (getPos _Cargo select 2) < 1.5 : goto "Loop3" ~.01 goto "Loop2" #Loop3 _xPos = (getPos _TranspVeh) select 0 _yPos = (getPos _TranspVeh) select 1 _zPos = (getPos _TranspVeh) select 2 _Cargo setPos [_xPos, _yPos, _zPos -10]; _Cargo setDir (getDir _TranspVeh); ? speed _TranspVeh < 0.7 : goto "Ende"; ~.01 goto "Loop3" ;/////////////////////////////UNLOADING////////////////////////////////// #Ende _Cargo setpos [(getpos _Cargo select 0),(getpos _Cargo select 1),0] _TranspVeh action ["CANCELACTION", _TranspVeh] _TranspVeh flyinheight _Height _TranspVeh domove getpos _EndPos _TranspVeh setSpeedMode "Full" ;/////////////////////////////DELETE//////////////////////////////////// @ _TranspVeh distance _EndPos < 100 deleteVehicle _TranspVeh deleteVehicle Pilot1 exit 212 6.19 - Das Möwenskript Ein Schwarm Möwen bringt mal wieder eine Menge Atmosphäre ist Spiel. Es fliegt zwar schon so allerlei durch die Lüfte, aber wenn man einen Schwarm gezielt umherfliegen lässt, hat das auch etwas Besonderes. Das Ganze realisiert man mal wieder per Skript. Für dieses Beispiel setzt man zwei Objekte, idealerweise unsichtbare Heli H´s, mit Namen Start und Ziel auf die Map und definiert diese im Auslösearray für das Skript. [Start,Ziel,Anzahl] exec "scripte\bird.sqs" Bird.sqs _spos = _this select 0 _zpos = _this select 1 _count = _this select 2 _i = 0 #Check _x = (random 30) + 10 _y = (random 30) + 10 _z = (random 30) + 10 ? _i >= _count : exit _i = _i + 1 _bird="seagull" camcreate [(getpos _spos select 0) - (sin getdir _spos * _x), (getpos _spos select 1) - (cos getdir _spos * _y), _z] Nach Auslösung des Skriptes werden die Vögel an der Startposition in einem Randombereich (definiert bei: _x,_y,_z) erzeugt, welchen man natürlich jederzeit frei ändern kann. Jeder erstellte Vogel löst dann das zweite Skipt aus und bekommt ein Zufallsziel per Randomwert zugewiesen, den er dann anfliegt. 213 Kapitel 6 [_bird,_spos,_zpos] exec "birdpos.sqs" goto "check" Birdpos.sqs _bird = _this select 0 _spos = _this select 1 _zpos = _this select 2 _x = (random 10) + 10 _y = (random 10) + 10 _z = (random 10) + 10 #Loop _bird camsetpos [(getpos _zpos select 0) - (sin getdir _zpos * _x), (getpos _zpos select 1) - (cos getdir _zpos * _y), _z] ? _bird distance _zpos <= 30 : goto "Loop2" ~1 goto "Loop" #Loop2 _bird camsetpos [(getpos _spos select 0) - (sin getdir _spos * _x), (getpos _spos select 1) - (cos getdir _spos * _y), _z] ? _bird distance _spos <= 30 : goto "Loop" ~1 goto "Loop2" Natürlich lässt sich dieses Beispiel jederzeit noch um weitere Möglichkeiten und Positionen erweitern. Statt der Möwe könnte man hier auch Bienen oder ähnliches angeben. Dazu bitte im Kapitel 3.9 bei den Einheitsklassen nachschauen. Folgend noch ein paar Syntaxbeispiele. deletevehicle _bird _bird camSetPos position Player _bird camsetpos [x,y,z] _bird camCommand "Landed" 214 - Der Vogel wird gelöscht - Der Vogel fliegt zum Spieler - Der Vogel fliegt zu XYZ-Position - Der Vogel landet 6.20 - Das Insektenskript Das Insektenskript gleicht vom Aufbau her dem Möwenskript. Dieses wurde nur ein wenig anders angelegt. Hier sollen Fliegen über einer Leiche erstellt werden, die diese dann umkreisen. Dazu schreibt man lediglich die folgende Syntax in die Initzeile der jeweiligen Einheit. [this,60] exec "skripte\insect.sqs" Statt this kann dort natürlich auch der Name der Einheit stehen. Die 60 steht hierbei für die Anzahl der Fliegen, die die Leiche umkreisen sollen. Alternativ kann man natürlich noch einen Insektensound definieren, der dann im Bereich der Leiche abgespielt wird. Insect.sqs Kapitel 6 ?(!(local server)) : exit _deadman = _this select 0 _count = _this select 1 _i = 0 @not alive _deadman #Check _x = random 1 _y = random 1 _z = random 3 ? _i >= _count : exit _i = _i + 1 _insect="HOUSEFLY" camcreate [(getpos _deadman select 0) + _x, (getpos _deadman select 1) + _y,_z] [_deadman,_insect] exec "insectpos.sqs" goto "check" Insectpos.sqs _deadman = _this select 0 _insect = _this select 1 #Loop _insect camsetpos position _deadman ? _insect distance _deadman <= 0.1 : goto "Loop2" ~2 goto "Loop" #Loop2 _x = (random 3) + 1 _y = (random 3) + 1 _z = (random 3) + 2 _insect camsetpos [(getpos _deadman select 0) + (sin getdir _deadman * _x), (getpos _deadman select 1) + (cos getdir _deadman * _y), _z] ? _insect distance _deadman >= _x : goto "Loop" ~2 goto "Loop2" 215 6.21 - Der Bombenleger Dieser Abschnitt zeigt anhand eines Beispiels, wie man eine KI als Bombenleger einsetzen kann. Diese bewegt sich dann zum Zielpunkt, legt die Bombe und zündet sie, wenn sie weit genug entfernt ist bzw. ihren nächsten Wegpunkt erreicht hat. Dafür nun ein ganz simples Beispiel mit nur drei Wegpunkten. Zunächst muss die Einheit natürlich auch über Sprengsätze verfügen, welche man ihr mit this addMagazine "pipebomb"; zuweisen kann. In diesem Beispiel wird ein Ost-Saboteur verwendet, welcher bereits über Sprengsätze verfügt und von daher nicht extra ausgerüstet werden muss. Zunächst wird die Einheit mit Namen Enemy1 auf die Map gesetzt und ganz normal mit Wegpunkten versehen. Dabei trägt man an jedem Wegpunkt, wo eine Bombe gelegt werden soll Enemy1 fire "PipeBombMuzzle" in die Zeile “bei Aktivierung” ein. Der letzte Wegpunkt wird dann mit dem Auslösebefehl versehen, bei welchem die KI die Sprengsätze zünden soll. Enemy1 action ["TOUCHOFF", Enemy1]; Beipielgrafik Natürlich kann man das Ganze jetzt noch unendlich ausschmücken. Etwa mit weiteren Wegpunkten, Aktionen und so weiter. Die Einstellung der Wegpunkte liegt am Missionsersteller selbst. Dinge wie Verhalten oder Geschwindigkeit sind nicht gerade unwesentlich. Auch die Verwendung der Zeitwerte (Min, Mid, Max) ist sehr interessant und verleiht wieder eine gewisse Dynamik. 216 6.22 - Der Aufklärer Dieses Beispiel zeigt, wie man einen Aufklärer realisieren könnte. Hiermit hat man die Möglichkeit per Funkmenü in die Einheit zu switchen um sich mit eigenem Blick einen Eindruck von der Umgebung zu verschaffen, in der sich der Aufklärer gerade aufhält. Hierbei ist es egal, ob es ein Soldat, ein Panzer oder ein Flugzeug ist. Der Grundbefehl ermöglicht es zunächst in verschiedene Perspektiven der Einheit zu switchen. Hierbei stehen folgende Perspektiven zur Auswahl: "INTERNAL" "EXTERNAL" "GUNNER" "GROUP" - Sicht aus Einheit (1st person) - Sicht aus Rücken der Einheit (3rd person) - Sicht aus Visier der Einheit (Optic) - Gruppenansicht (nur bei Leader) Mit der folgenden Befehl switcht man in die Einheit und die definierte Perspektive: Player switchCamera "Internal" Bei dem nun folgenden Skriptbeispiel, bei welchem die Startsyntax mal wieder frei defniert werden kann, hat der Spieler die Möglichkeit für einen vom Editierer festgelegten Zeitwert in die vom Editierer festgelegte Perspektive des Aufklärers zu switchen. Nach Ablauf der Zeit schaltet die Kamera wieder zurück auf den Spieler. Als Aufklärer könnte in diesem Beispiel jede Einheitsform dienen. Die Auslösesyntax lautet wie nun folgt, wobei man den Spieler, den Scout, die Zeit und die "Perspektive" angibt. Kapitel 6 [Player,Scout,10,"external"] exec "scoutswitch.sqs" Scoutswitch.sqs _leader = _this select 0 _scout = _this select 1 _timeo = _this select 2 _mode = _this select 3 _i = 0 disableuserinput true _scout switchCamera _mode #Loop _i = _i + 1 ? _i >= _timeo : goto "Ende" ~1 goto "Loop" #Ende titlecut [" ", "Black Out"]; titleFadeOut 1 ~0.5 _leader switchCamera "Internal" disableuserinput false titlecut [" ", "Black In"]; titleFadeOut 1 exit 217 6.23 - Einheit ergibt sich Hier mal ein Beispiel, wie man es umsetzen kann, dass sich Einheiten ergeben, wenn bestimmte Bedingungen erfüllt sind. Bedingungen könnten sein, das die Einheit weniger Munition hat als vordefinierter Wert, mehr verletzt ist als vordefinierter Wert oder im Bereich weniger verbündete Einheiten als vordefinierter Wert sind. Diese lassen sich nun bündeln, damit sicht nicht jede Einheit gleich ergibt, obwohl noch genügend Verbündete in der Nähe sind. Es müssen also mehrere Bedingungen erfüllt sein, bevor sich die Einheit ergibt. Als Beispiel: ?!(canStand _enemy) AND (_ammo < _AmmoStat) : goto "PutDown" Hier wäre die Bedingung wenn “Einheit nicht mehr stehen kann” und zusätzlich, wenn “Munitionsstatus kleiner als vorgegebener Wert ist”. Sind beide erfüllt, würde das Skript zum Label PutDown springen und die Einheit sich ergeben. Im Beispielskript wurden unter dem Label Check mehrere gemischte Bedingungszeilen untereinander gesetzt. Trifft eine davon zu, wird sich die Einheit ergeben. Doch jetzt noch was Besonderes. In der Realität ergeben sich Soldaten manchmal und greifen plötzlich doch wieder zur Waffe oder haben gar noch eine Waffe irgendwo in der Tasche. Andere wiederum geben ganz auf. Dieses Skript ermöglicht es dies flexibel zu definieren. Man kann festlegen, dass die Einheit sich wirklich ergibt oder auch, dass die Einheit irgendwann versucht zu fliegen. Es kann zusätzlich sogar noch definiert werden, ob alle Waffen gelöscht werden sollen oder gar noch eine vorhanden bleiben soll. Wenn sich eine Einheit nun ergibt, legt sie ihre Primär- sowie Sekundärwaffe ab und legt die Hände hinter den Kopf. Wurde definiert, dass die Einheit fix stehen bleiben soll, passiert nichts weiter. Wurde definiert, dass die Einheit abhauen soll, kann es passieren dass sie, wenn nicht alle Waffen gelöscht wurden, zurückschießt oder gar eine Handgranate wirft. Es kommt sogar vor, dass sich die Einheit an einer Leiche neu bewaffnet. Die KI wird Dank setCaptive nicht auf kapitulierte Einheiten schießen, außer sie haut ab oder greift wieder zur Waffe, dann sieht das schon ganz anders aus. Verwendet man in dem Auslösearray feste Werte, dann weiß man genau, dass sich eine Einheit ergibt, wenn sie beispielsweise nicht mehr stehen kann und weniger als vordefinierte Munition hat. Versieht man den Auslösearray aber mit Randomwerten, so kann man gar nicht vorhersagen wie die einzelne Einheit reagieren wird. Der Auslösearray Der Auslösearray erklärt sich hierbei wie folgt [Name,Fluchtwert,Munition,Verletzt,Waffenweg,Fix,Freunde,Bereich] Hier ein Beispiel mit der Verwendung fester Werte: [this,0.5,1,0.5,0,0,3,150] Hier ein Beispiel mit der Verwendung einiger variabler Werte: [this,random 0.7,2,random 1,random 1.5,random 2,6+(random3),200] 218 Diese Werte, egal ob fix oder variable, werden dann an das Skirpt übergeben. Natürlich muss dieses noch hinter den Array angegeben werden. Die Auslösesyntax lautet dann: [this,0.5,1,0.5,0,0,3,200] exec "capitulation.sqs"; Arraydefinitionen Name Fluchtwert Munition Verletzt Waffenweg Fix Freunde Einzelne Einheit Möchte man nur eine einzelne Einheit mit dem Skript belegen, so schreibt man die Auslösesyntax in die Initzeile der Einheit und definiert die gewünschten Werte. [this,0.5,1,0.5,0,0,3,200] exec "capitulation.sqs"; Einheiten in einem Bereich Mit folgender Auslösesyntax lösen alle Einheiten eines Auslöserbereiches einzeln das Skript aus. Durch Verwendung der Randomwerte verhält sich nun jede Einheit anders. Auslöser: Aktivierung: Achse a/b: bei Aktivierung: Ost Einfach beliebig {[_x,random 0.7,2,random 1,random 1.5,random 2,6,200] exec "capitulation.sqs"} forEach thislist 219 Kapitel 6 Bereich - Name der Einheit. In der Initzeile auch this möglich. - Fluchtwert der Einheit, welche eine der Bedingungen darstellt. - Mindestwert an Munition der zum Ergeben erreicht sein muss. - Mindestwert der Verletzung der zum Ergeben erreicht sein muss. - Alle Waffen löschen oder nicht. Wert 1 löscht alle. Bis 0.9 erhält die Waffen. Durch Radomwert random 1.5 ungewiss. Ab >=1 sind die Waffen weg. Randomwert sollte nicht größer als 1.5 sein! - Einheit bleibt nach Ergeben definitiv an der Stelle stehen stehen. Werte <= 1 fixiert die Einheit, Werte <=2 gibt Fluchtmöglichkeit. Im Variablebeispiel wurde random 2 definiert. Also Ungewissheit. - Wie viele Verbündete sind mindestens noch im Bereich. Wird der Wert unterschritten, ist die Bedingung erfüllt. Im Beispiel wurde hier der Wert 6+(random3) verwendet. Also mindestens 6 plus Zufallswert. Im Skipt wurden Osteinheiten definiert. Möchte man eine andere Seite anlegen, muss man dort die Soldaten- und Fahrzeugklassen der Seite angeben. - Bereich, welcher geprüft werden soll in Metern. Sind in dem Bereich keine der definierten vorhanden, ist eine weitere Bedingung erfüllt. Dieses Thema lässt sich unendlich ausweiten und auch die Bedingungen bis ins kleinste Detail festlegen, aber irgendwo muss ja mal eine Grenze sein. ?(!(local server)):exit _Enemy = _this select 0 _Fleeing = _this select 1 _AmmoStat = _this select 2 _Injurned = _this select 3 _Removeall = _this select 4 _Standfix = _this select 5 _friendly = _this select 6 _Area = _this select 7 _Enemy allowFleeing _Fleeing #Check ? not alive _enemy : exit _ammo = count magazines _enemy _dammage = getdammage _enemy ;Folgende drei Zeilen stellen eine lange Zeile dar! Klassen bei Bedarf ergänzen. _friends = count nearestObjects [_enemy, ["SoldierEAA","SoldierEAT","SoldierECrew","SoldierEMiner","SoldierEG","SoldierEMG", "SoldierEMedic","SoldierESniper","SquadLeaderE","T72","BMP2","UAZMG","ZSU"], _area] ;Folgende zwei Zweierzeilen stellen je eine lange Zeile dar. Also goto hinter die : ? (_friends < _friendly) AND (_ammo < _AmmoStat) AND (_dammage > _Injurned) : goto "PutDown" ? (_ammo < _AmmoStat) AND (_dammage > _Injurned) AND (_Fleeing > 0.6) : goto "PutDown" ~5 goto "Check" #PutDown _enemy action ["DROPWEAPON", _enemy, primaryWeapon _enemy] ~1 playSound "Dont-shoot" _enemy action ["DROPWEAPON", _enemy, secondaryWeapon _enemy] ~2 ? _Removeall >= 1 : removeallWeapons _enemy _enemy playMove "AmovPercMstpSsurWnonDnon" ~1 ? _standfix <= 1 : goto "Standfix" ? _standfix <= 2 : goto "Fleeing" exit #Standfix _enemy disableAI "ANIM" _enemy setCaptive true #Fleeing _enemy disableAI "ANIM" _enemy setcaptive true ~30 + (random 60) _enemy enableAI "ANIM" _enemy allowFleeing _Fleeing _enemy setCaptive false exit 220 6.24 - Teleport Dieses Skriptbeispiel ist eigentlich nicht als Missionsfeature gedacht, sondern lediglich als eine sehr gute Editierhilfe. Es ermöglicht, dass sich der Missionsauthor per Mapclick an beliebige Stellen der Karte beamen kann, um so Spielabläufe oder ähnliches zu kontrollieren, ohne erst dorthin laufen oder fahren zu müssen. Dies erspart eine Menge Zeit und Nerven. Dieses Beispiel ist für diesem Fall mit einem Funkauslöser kombiniert. Zunächst sollte man im Missionsordner eine Init.sqs anlegen oder die folgende Syntax statt dort in die Initzeile einer Einheit oder eines Objektes schreiben, um das Skript gleich zu Missionsbeginn zu starten. [] exec "teleport.sqs" Mit dem Funkauslöser wird dann später die Variable Teleport auf true gesetzt und das Skript fängt an zu arbeiten. Nachdem der Spieler dann auf die Karte geklickt hat, wird er an die zuvor geklickte Stelle gebeamt und das Skript wird wieder beendet. Dabei wird der Marker PosM an die geklickte Stelle gebeamt, damit er später auf der Karte sieht, wo er sich hingebeamt hat. Funkauslöser: Aktivierung: Marker: Name: Farbe: Symbol: Achse a/b: PosM rot Destroy 1 Kapitel 6 Text: bei Aktivierung: Radio Juliet Mehrfach 0-0-0 Juliet teleport=true Teleport.sqs #start @teleport titletext ["Click on the map to teleport yourself","plain down"] onMapSingleClick "player setpos _pos; teleport=false; ""PosM"" setMarkerPos _pos" @!teleport titletext [" ", "plain down"] ~10 "PosM" setMarkerPos [0,0] goto "start" Eine skriptfreie Alternative ist folgender Eintrag in der Init.sqs, welche dann dauerhaft aktiv ist. Nutzt man in der Mission Skripte mit Mapclick wird auch der Spieler versetzt. onMapSingleClick "Player setPos _pos"; 221 6.25 - Das Verfolgungsskript In folgendem Beispiel wird eine mögliche Variante eines Verfolgungsskriptes näher erläutert. Hierbei bekommt der Verfolger namens Hunter zunächst einmal das richtige Verhalten zugewiesen, bevor er sich auf den Weg zum Spieler macht. Das Skript läuft dabei so lange, bis entweder der Spieler oder die verfolgende Gruppe nicht mehr am Leben ist. Das Ganze wird dabei mit folgender Sytax gestartet: [Hunter, Player] exec "skripte\hunter.sqs"; Hunter.sqs _hunter = _this select 0 _target = _this select 1 _hunter setBehaviour "AWARE" _hunter setCombatMode "RED" _hunter setSpeedMode "Full" _hunter doTarget _target #Loop ?_target distance _hunter >= 10 : {_x doMove getPos _target} foreach units _hunter ~4 ? (count units _hunter) <= 1 : exit ?(!(alive _target)) : exit goto "Loop" Natürlich gibt es auch die Möglichkeit so etwas mit Wegpunkten zu gestalten. Dies ist nur ein Beispiel, wie man so etwas umsetzen könnte. Hierbei soll auch immer gleich die Zusammenarbeit der Befehle gezeigt werden und die eigenen Ideen beflügeln Befehle zu kombinieren und optimal für die individuellen Ideen auszunutzen. 222 Kapitel 7 - Multiplayer In diesem Kapitel werden dir einige grundlegende Bereiche aus dem Bereich Multiplayer erläutert und näher gebracht. Du wirst Dank dieses Kapitels in der Lage sein deine eigene Multiplayermission erfolgreich zu erstellen. Die Multiplayermission Die Respawnpunkte Flexible Respawnpunkte Die MP-Description.ext Die Respawnarten Das Deathmatch Multiplayerbereich festlegen Zeit und Wertung Punkte vergeben bzw. anzeigen lassen Die Zeitanzeige Der Class Header Der Respawndialog Stringtable MP Grundwerte Fahrzeug Respawn Mr-Murray´s Fahrzeug Respawn Flaggen Grundinformationen Capture The Flag Die PublicVariable Allgemeines Die Steuerungsbefehle Die Bewaffnung im Multiplayer Spielerbezogene Textmitteilung Join In Progress (JIP) 224 224 225 226 227 227 228 229 231 232 233 233 234 235 236 238 240 246 247 249 250 251 252 Kapitel 7 7.1 7.2 7.3 7.4 7.5 7.6 7.7 7.8 7.9 7.10 7.11 7.12 7.13 7.14 7.15 7.16 7.17 7.18 7.19 7.20 7.21 7.22 7.23 223 7.1 - Die Multiplayermission Das Erstellen einer Multiplayermission erfordert schon etwas mehr Wissen, was ein weiteres Buch dieses Umfangs füllen würde. Deshalb wird dieser Themenbereich hier nur zum Ansatz behandelt und ein paar grundlegende Bereiche erklärt, die dir das Erstellen einer einfachen Multiplayermission ermöglichen. Grundsätzlich gilt es schon mal eine Logic mit den Namen Server auf jede Multiplayermap zu setzen! Einheiten Zunächst setzt man Einheiten auf die Karte, welche Playable definiert sind. Wird in der Description.ext disabledAI=1 definiert, so werden nur die tatsächlichen Spieler angezeigt. Spielbare Einheiten, die nicht durch einen Spieler belegt sind, werden somit gelöscht und nicht durch KI ersetzt. Anzahl der menschlichen Spieler? Selbstverständlich lässt sich auch dies ausgeben oder als Bedingung verwenden! hint format [ "West: %1\nEast: %2", playersNumber WEST, playersNumber EAST]; oder als Bedingung ? playersNumber > 4 : hint format [“WEST: %1”, playersNumber WEST] 7.2 - Die Respawnpunkte Als feste Respawnpunkte legt man idealerweise Marker mit folgenden Bezeichnungen an: West: East: Respawn_west Respawn_east Widerstand: Zivilisten: Respawn_guerrila Respawn_civilian Ein weiterer Resp-Punkt pro Seite hieße dann Respawn_west_1, Respawn_west_2,... Statt eines Marker hat man natürlich auch die Möglichkeit ein Objekt oder eine Spiellogik als Respawnpunkt zu verwenden. Der Nachteil hierbei ist, dass man dann direkt an dem Punkt gespawnt wird, während man bei einem Marker flexibel im Bereich der Markerfläche gespawnt wird. 224 7.3- Flexible Respawnpunkte Möchte man seine Mission mit flexiblen Respawnpunkten versehen, kann man dies auf unterschiedliche Art und Weise machen. Hier soll als Beispiel mal die Erfüllung eines Missionsziels dienen. Bei jeder Mission fängt man irgendwo auf der Map an und hat ein oder mehrere Ziele. Der Respawnpunkt sitzt zunächst am allgemeinen Startpunkt und soll erst dann versetzt werden, wenn Missionsziel 1 erfüllt ist. Logischerweise sollte er dann auch in den Bereich des ersten Missionsziels versetzt werden, um von dort aus dann, bei Erfüllung des zweiten Missionsziels, auf die Position des zweiten Missionsziels versetzt zu werden. Dazu hat man dann wieder verschiedene Möglichkeiten. Hier ein Beispiel: Respawnmarker Name: Achse a/b: Respawn_West 50/50 Auslöser Typ: Name: Achse a/b: Art der Auslösung: bei Aktivierung: AreaOne Einfach 50 OPFOR Nicht vorhanden "Respawn_West" setMarkerPos getPos AreaOne hint "Gratulation - Ziel 1 ist erfüllt!" 225 Kapitel 7 In diesem Beispiel wurde nun ein Auslöser mit Namen AreaOne gesetzt, der prüft, ob der Bereich feindfrei ist. Ist dies erfolgt, wird der Marker Respawn_West an die Position des Auslösers mit Namen AreaOne versetzt und es erscheint eine Texteinblendung "Gratulation - Ziel 1 ist erfüllt!". Natürlich kann man den Marker auch an eine andere Position des ersten Ziels versetzen. Dies sollte hier lediglich als kleines Beispiel dienen. 7.4 - Die MP-Description.ext In der Description.ext definiert man die Grundsätze für die MP-Mission. Also zum Beispiel die Art oder Zeit bis zum Respawn. Hierzu gehören unter anderem folgende Komponenten: respawn=3; respawnDelay=6; respawnVehicle=3; respawnVehicleDelay=10; disabledAI=1; AIKills=1; - Die Art des Respawn - Die Zeit bis zum Respawn - Die Art des Vehiclerespawn - Die Zeit bis zum Vehiclerespawn - Einheiten, die als spielbar definiert wurden werden als KI nicht dargestellt. - Die Punkte der KI werden auch gewertet Folgend ein Auszug einer Multiplayer-Description.ext in welcher alle wichtigen, für eine Multiplayermission benötigten Komponenten, definiert sind. Description.ext respawn=3; respawnDelay=6; respawnVehicle=3; respawnVehicleDelay=10; disabledAI=0; AIkills=1; respawnDialog = false; class Header { gameType = CTF; minPlayers = 2; maxPlayers = 10; }; titleParam1 = "Time limit:"; valuesParam1[] = {10000, 300, 600, 900, 1200, 1500, 1800, 2100, 3600, 7200}; defValueParam1 = 1800; textsParam1[] = {"Unlimited", "5 min", "10 min", "15 min", "20 min", "25 min", "30 min", "35 min", "60 min", "120 min", }; titleParam2 = "Score to win:"; valuesParam2[] = {10000, 5, 7, 10, 15, 20, 25, 30}; defValueParam2 = 5; textsParam2[] = {"Unlimited", 5, 7, 10, 15, 20, 25, 30}; 226 7.5 - Die Respawnarten In einer Multiplayermission gibt es verschiedene Arten des Respawns. Diese legt man gleich beim Editieren in der Description.ext fest. Dies gilt für Fahrzeuge genauso, wie für Soldaten. Allerdings macht es nicht Sinn für ein Fahrzeug einen Respawn als Möwe festzulegen. Für den Vehiclerespawn verweise ich auf Kapitel 7.14 bzw. 7.15, in welchen sehr umfangreiche Vehiclerespawnarten erläutert sind. Respawnarten: 0 oder "None" 1 oder "Bird" 2 oder "Instant" 3 oder "Base" 4 oder "Group" 5 oder "Side" - Kein Respawn - Respawn als Möwe - Respawn am Todesplatz - Markerrespawn (respawn_west,…) - Gruppenrespawn (Ist keine weitere KI vorhanden, dann Respawn als Möwe!) - Seitenrespawn (Ist keine weitere KI vorhanden, dann Respawn als Möwe!) Bei Vehikeln gelten die Werte 0, 2 und 3 mit den gleichen Respawnarten. 7.6 - Das Deathmatch Möchte man eine Deathmatch Mission erstellen, die ein oder mehr Spieler auch alleine gegeneinander und die KI spielen können, ist es ja notwendig die eigene Seite zu verfeinden, damit sich auch die KI´s Einheiten ihrer Seite beschießen. Kapitel 7 Variante 1 Der Setfriend-Befehl wäre eine Möglichkeit: East setFriend [East,0.1] Hat man mehrere Seiten, muss man eben alle gegeneinander verfeinden. Variante 2 Diese Variante verfeindet die Einheiten egal welcher Seite gegeneinander: this addRating ((- rating this) - 100000) Einheiten die diesen Eintrag nicht haben, werden nicht von Einheiten der eigenen Seite beschossen. Merke Bei Deathmatch-Missionen mit KI ist es notwendig diese mit mindestens 2 Wegpunkten und großem Radius zu versehen, damit diese sich auch bewegt. 227 7.7 - Multiplayerbereich festlegen Da das Areal auf dem gespielt werden kann, mit seinen über 400 Quadratkilometern doch etwas groß ist, gibt es die Möglichkeit einen Spielbereich einzugrenzen. Dies muss man dann auf der Karte, sowie auch direkt in der Landschaft sehen können. Dazu gibt es eine integrierte Funktion, mit welcher man einen solchen Bereich festlegen kann. Dazu bedarf es lediglich eines Objektes auf der Karte, welches den Mittelpunkt dieser Zone darstellt und in dem die Syntax eingetragen wird. Dieses Objekt ist im Idealfall ein unsichtbares Helipad, welches man unter Leer/Objekte finden kann. Dieses setzt man nun in die Mitte des spielbaren Bereiches und gibt in der Initzeile folgende Syntax zum Aufruf der Funktion an: Bereich1 = [this,400,400,100,10] execVM "area.sqf" Beim Start der Mission wird das Objekt, also das Helipad, automatisch Bereich1 genannt und je nach definiertem Bereich erscheinen um diesen Mittelpunkt herum Warnschilder und auf der Karte Marker, die diesen Bereich eingrenzen. Der Array erklärt sich hierbei wie folgt: Name = [Mittelpunkt,X-Wert,Y-Wert,Objektanzahl,Winkel] Alle Werte sind hierbei variabel und können somit frei bestimmt werden. Auf der Karte und in der Mission könnte das später etwa so aussehen: Mit Hilfe dieser Funktion erspart man sich somit eine Menge Arbeit, Zeit und Nerven, die Objekte alle selbst setzen zu müssen. Um das abgesperrte Gelände kann man nun Todesauslöser oder ähnliches setzen, um ein Verlassen des Bereiches durch einen Mitspieler zu vermeiden. 228 7.8 - Zeit und Wertung Die Zeitfestlegung und Wertung sind Multiplayeroptionen, die man mit angeben kann, aber nicht unbedingt muss. Dazu muss man zwei Parameter in der Description.ext definieren, welche wie folgt aussehen und später in der Multiplayerlobby mit angezeigt werden. Zeitlimit titleParam1 valuesParam1[] defValueParam1 textsParam1[] = "Time limit:"; = {10000, 300, 600, 900, 1200, 1500, 1800, 2100, 3600, 7200}; = 1800; = {"Unlimited", "5 min", "10 min", "15 min", "20 min", "25 min", "30 min", "35 min", "60 min", "120 min"}; Alle Werte sind hierbei variabel. Die Zeitwerte können jetzt im Menü als Zeitgrenze ausgewählt werden. Der dazugehörige Text der Zeit ist in der letzten Zeile definiert und kann auch frei beschriftet werden. Punktelimit titleParam2 valuesParam2[] defValueParam2 textsParam2[] = "Score to win:"; = {10000, 5, 7, 10, 15, 20, 25, 30}; = 5; = {"Unlimited", 5, 7, 10, 15, 20, 25, 30}; Auch hier sind die Werte wieder frei änderbar und stellen die zu erreichenden Punktezahlen bis zur Beendung der Mission dar. Somit ist die grobe Konfiguration schon mal fertig. Der Spieler hat nun die Möglichkeit die Punkt- oder Zeitbegrenzung frei nach seinem Interesse einzustellen. Jetzt fehlt nur noch die Konfiguration auf der Map, die dem Spiel sagt, dass die Punkte erreicht sind oder die Zeit um ist. Dazu kommen jetzt die Prüfauslöser. 229 Kapitel 7 Wie man nun auf dem Bild sehen kann, sind die oben definierten Parameter genau so übernommen worden und nun in der Multiplayerlobby frei wählbar. Prüfauslöser Zusätzlich werden nun noch drei Prüfauslöser gebraucht, welche das Vorgehen überwachen. Diese müssen hierbei wie folgt definiert werden: Auslöser 1(Zeitüberwacher): Name: Bedingung: bei Aktivierung: Achse a/b: Zeitende (Param1<10000) and (time>=param1) Ende=true 0/0 Auslöser 2 (Punktüberwacher): Name: Bedingung: bei Aktivierung: Achse a/b: Punktende (Param2 < 10000 and (({score _x >= Param2}) count [S1, S2, S3, S4, S5, S6] > 0)) Ende=true 0/0 Auslöser 3 (Endauslöser): Typ: Achse a/b: Bedingung: Ende 1 0/0 Ende In der Bedingungszeile sind Einheiten mit Namen S1, S2, S3, S4, S5, S6 definiert. Diese können natürlich auch anders benannt werden, sollten aber dann in der Bedingungszeile des Auslösers 2 entsprechend angepasst werden. Damit die Punkte einer KI auch gezählt werden können, muss das in der Description.ext mit AIkills=1 vordefiniert werden. 230 7.9 - Punkte vergeben bzw. anzeigen lassen Es gibt verschiedene Varianten sich die Punkte anzeigen zu lassen. Dies kann erfolgen, wenn jemand eine Fahne erobert bzw. anderweitig gepunktet hat oder ein Missionsziel erfüllt wurde. Je nach Mission eben. Zunächst definiert man die Description.ext, wie in Kapitel 7.8 erläutert. Punktelimit titleParam2 valuesParam2[] defValueParam2 textsParam2[] = "Score to win:"; = {10000,5,7,10,15,20,25,30}; = 5; = {"Unlimited",5,7,10,15,20,25,30}; Jetzt definiert man in der Initzeile einer Einheit oder in der Init.sqs die Punktevariablen, die hier mal mit WestScore = 0 EastScore = 0 definiert werden und gleich zu Missionsbeginn den Wert 0 zugewiesen bekommen. Wird jetzt irgendeine Bedingung erfüllt, also ein Gegner getötet, ein Missionziel erfüllt oder wie auch immer, soll ja die jeweilige Seite Punkte zugewiesen bekommen. Dies würde man dann mit WestScore = Westscore +1 festlegen. Also jedes Mal, wenn die vom Editierer festgelegte Bedingung erfüllt ist, wird der jeweiligen Seite mit der obigen Syntax der Wert 1 (1 Punkt) hinzugefügt. Mit Westscore = Westscore -1 könnte man auch Punkte abziehen. Dazu wird dann in der Regel folgende Syntax verwendet: Titletext [format [localize "STR_MP_STATUS", WestScore, EastScore], "Plain down"] In einem Funkauslöser könnte das dann so aussehen: Wertunganzeiger (Funkauslöser) Aktivierung Achse a/b Text bei Aktivierung Radio Alpha (Mehrfach) 0 @STR_MP_SHOWSCORE Titletext [format [localize "STR_MP_STATUS", WestScore, EastScore], "Plain down"] 231 Kapitel 7 Möchte man diese nun anzeigen lassen, kann man das auch auf unterschiedliche Weise machen. Zum Einen vielleicht mit einem Funkauslöser, welchen ja dann jeder bei Bedarf benutzen kann oder zum Anderen, dass die Punkte angezeigt werden, wenn eine der beiden Seiten wieder gepunktet hat. 7.10 - Die Zeitanzeige In einigen Missionen bietet es sich an, die Zeit ab und dann einblenden zu lassen, um die Mitspieler zu informieren, dass die Mission bald beendet ist und sie somit gleich noch ein bisschen anzuheizen, noch möglichst viele Punkte zu sammeln. Eine bewährte Methode ist die, dass man dafür mehrere Prüfauslöser in die Mission setzt, die nach Ablauf der vom System gezählten Zeit ab Spielbeginn ausgelöst werden. Diese definiert man dann wie nun folgend erläutert. Zunächst muss man aber erst wieder den Parameter in der Description.ext definieren. Zeitlimit titleParam1 valuesParam1[] defValueParam1 textsParam1[] = "Time limit:"; = {10000, 300, 600, 900, 1200, 1500, 1800, 2100, 3600, 7200}; = 1800; = {"Unlimited", "5 min", "10 min", "15 min", "20 min", "25 min", "30 min", "35 min", "60 min", "120 min"}; Die letzten beiden Zeilen stellen eine lange Zeile dar, was hier nicht realisierbar ist. Hier mal ein Prüfauslöser, welcher anzeigt, dass nur noch 1 Stunde bis zum Missionsende Zeit ist, diese erfolgreich zu bewältigen. Zeitanzeiger (Prüfauslöser) Bedingung Achse a/b bei Aktivierung (Param1<10000) and (Param1>=3600) and ((Param1-time) <=3600) 0 Hint localize "STR_MP_07" Jetzt müsste man bei jedem weiteren Prüfauslöser eben den entsprechenden Wert definieren. Als Texteinblendung wurden die Stringtable Grundwerte, welche im Kapitel 7.13 aufgeführt sind, verwendet. Hier mal eine nähere Erläuterung der Bedingung: (Param1<10000) and (Param1>=Wert) and ((Param1-time)<=Wert) Wert ist hierbei der in Parameter1 bei valuesParam1 vergebene Wert (z.B.: 600) (Param1<10000) and (Param1>=600) and ((Param1-time)<=600) Jetzt würde man bei Aktivierung eben den richtigen Stringtablewert dazu angeben, welcher dann angezeigt werden soll. In diesem Fall wäre das: Hint localize "STR_MP_04" - Noch 10 Minuten 232 7.11 - Der Class Header Der Class Header ist eine Definition in der Description.ext und sollte bei jeder MP-Mission dringenst mit angegeben werden. In ihm wird die min- und maximale Spieleranzahl, sowie der Missionstyp definiert, was einem Spieler später bei der Auswahl eines Spielservers (siehe Grafik) mit angezeigt wird. Auf dem Bild wurde beim oberen Server ein Class Header definiert, aber beim unteren nicht. GameType: Hier wird der Missionstyp mit angegeben. Zum Beispiel: SC DM CTF COOP TEAM MinPlayers: MaxPlayers: - Sector Control - Deatmatch - Capture The Flag - Cooperation - Team Angabe der minimalen Spieleranzahl Angabe der maximalen Spieleranzahl In der Description.ext sieht das dann wie folgt aus: class Header { gameType = CTF; minPlayers = 2; maxPlayers = 8; }; Kapitel 7 7.12 - Der Respawndialog Der Respawndialog ist jener, welcher angezeigt wird, wenn man das Zeitliche gesegnet hat und auf seinen Respawn wartet. Diesen kann man in der Description.ext ein- bzw ausschalten. Das macht man mit folgendem Eintrag: respawnDialog = false; Zum Einschalten des Dialogs vergibt man den Wert true. 233 7.13 - Stringtable MP Grundwerte Im Spiel selbst sind diverse Stringtablewerte verankert, welche man aufrufen kann, ohne eine eigene Stringtable.csv im Missionsordner erstellen zu müssen. Folgend nun eine kleine Übersicht einiger Stringtablewerte die zum Multiplayerbereich gehören. STR_MP_POINT_W STR_MP_POINT_E STR_MP_FLAG_TAKEN_W STR_MP_FLAG_TAKEN_E STR_MP_FLAG_BACK_W STR_MP_FLAG_BACK_E STR_MP_SECTOR_ATTACK_W STR_MP_SECTOR_ATTACK_E STR_MP_SECTOR_W STR_MP_SECTOR_E STR_MP_02 STR_MP_03 STR_MP_04 STR_MP_05 STR_MP_06 STR_MP_07 STR_MP_NOLIMIT STR_MP_SCORE STR_MP_SHOWSCORE STR_MP_TIME STR_MP_STATUS STR_MP_GAMEOVER_W STR_MP_GAMEOVER_E STR_MP_GAME_DESC_CTF - USA punktet - SLA punktet - Name hat die Flagge - Name hat die Flagge - Die US Flagge ist wieder da - Die SLA Flagge ist wieder da - Die USA greifen Sector an - Die SLA greifen Sector an - Sektor ist jetzt unter Kontrolle der USA - Sektor ist jetzt unter Kontrolle der SLA - Noch 1 Minuten - Noch 5 Minuten - Noch 10 Minuten - Noch 20 Minuten - Noch 30 Minuten - Noch eine Stunde - Unbegrenzt - Punkte - Punkte zeigen - Zeit - Status – USA: SLA: - Die USA gewinnen - Die SLA gewinnt - 2 Teams, 2 Flaggen, Erobern Sie die feindliche Flagge STR_MP_GAME_DESC_DM - Jeder kämpft für sich, es gibt keine Verbündeten STR_MP_GAME_DESC_SCONTROL - Sammeln Sie Punkte, indem Sie die vorgegebenen Sektoren kontrollieren STR_MP_GAME_DESC_PILOTDOWN - Finden und retten Sie die Piloten STR_MP_GAME_DESC_HOLDCASTLE - USA: Erobern Sie die Festung, SLA: Verteidigen Sie die Festung Zum Aufrufen kann man die verschiedenen Texteinblendsyntaxes verwenden, mit welchen man Text einblenden kann. Siehe die Verwendung im Kapitel 7.17. 234 7.14 - Der Fahrzeug Respawn Für den Vehikelrespawn gibt es verschiedene Möglichkeiten. Zum Einen die Standardvariante und zum Anderen die selbstentwickelte Variante, welche ich im Folgepunkt vorstelle. Hier erst einmal die Standardvariante: Mit folgender Syntax in der Initzeile des jeweiligen Fahrzeugs, legt man für dieses die individuelle Konfiguration fest. Die Syntax hierfür lautet: Fahrzeug1 respawnVehicle [Zeit,Anzahl] Fahrzeug1 respawnVehicle [Zeit] Hat man für dieses Fahrzeug nun einen individuellen Respawnzeitwert vergeben, so wird das Spiel die Zeitvorgabe aus der Description.ext übersehen und die für das Fahrzeug definierte Zeit nutzen. Setzt man die Anzahl der Respawns in der Initzeile auf 0, wird das Fahrzeug unendlich gespawnt. In der Description.ext legt man Standardmäßig folgende Zeilen fest: respawnVehicle=3; - Die Art des Vehiclerespawn respawnVehicleDelay=10; - Die Zeit bis zum Vehiclerespawn Die Respawnarten Bei Fahrzeugen hat man, was die Respawnarten angeht, nur zwei Möglichkeiten. Hierbei stehen der Respawn am Todesplatz (2) oder der Respawn am Seitenrespawnplatz (3) zur Auswahl. Diesen definiert man ganz normal in der Description.ext: - Die Art des Vehikelrespawn 0 oder "None" 2 oder "Instant" 3 oder "Base" - Kein Respawn - Respawn am Todesplatz - Markerrespawn (respawn_west,…) Kapitel 7 respawnVehicle=3; Die Respawnpunkte Die Respawnpunkte für die Vehikel lauten dabei wie folgt: Westen: Respawn_Vehicle_West Widerstand: Respawn_Vehicle_Guerrila Osten: Respawn_Vehicle_East Zivilisten: Respawn_Vehicle_Civilian 235 7.15 - Mr-Murrays Fahrzeug Respawn Da die Standardvariante nicht sonderlich viele Features mit sich bringt, habe ich mich ein wenig damit auseinandergesetzt und die nun folgende, sehr ausführliche Lösung herbeigeführt, welche keinen Description.ext-Eintrag benötigt. Zunächst setzt man ein Fahrzeug auf die Karte, was für den Respawn vorgesehen sein soll. Dieses bekommt den Namen Veh1 und einen festen Respawnpunkt, wofür eine Logik mit dem Namen Veh1Pos gesetzt wird. Jetzt ist ein Fahrzeug mit Spawnpunkt festgelegt. Was nun noch fehlt ist ein Prüfauslöser, welcher prüft, ob das Fahrzeug noch lebt bzw. fahren kann. Jedes Fahrzeug, welches am Ende spawnbar sein soll bekommt hierbei einen eigenen Positionspunkt(Logik) und einen eigenen Prüfauslöser mit dem jeweiligen Namen des Fahrzeugs. Prüfauslöser (Vehikelüberwacher) Name: Bedingung: Bei Aktivierung: Achse a/b: Veh1Guard !Canmove Veh1 [Veh1,"M1Abrams",Veh1Pos,360,2,10,1,0,0] exec "vehicle-respawn.sqs" 0/0 Logik (Positionspunkt) Name: Veh1Pos Der in der Aktivierungszeile des oben aufgeführten Prüfauslösers angegebene Array beinhaltet alle Definitionsmöglichkeiten die wichtig sind. Man muss also nicht mehr in das Skript wechseln und kann alles für jedes Fahrzeug individuell in dem jeweiligen Array konfigurieren. Dieser erklärt sich hierbei wie folgt: [Fahrzeugname, Fahrzeugklasse, Respawnpunkt, Azimut, Respawnzeit, Respawnanzahl, Delete, Statisch, Effekt] exec "vehicle-respawn.sqs" Fahrzeugname Fahrzeugklasse Respawnpunkt Azimut Respawnzeit Respawnanzahl Delete Statisch Effekt 236 - Name des Fahrzeugs - Klasse des Fahrzeugs (siehe Kapitel 3.7) - Respawnpunkt - lickrichtung (Wert der Blickrichtung) - Zeit bis zum nächsten Respawn - Anzahl der Respawns (0=Kein Respawn) - Fahrzeug löschen (0=nein; 1=ja) - Respawn statisch oder flexibel (0=Flexibel; 1=Statisch) - Explosionseffekt beim Löschen (0=Kein Effekt; 1=Effekt) Der eben aufgeführte Array ruft das nun folgende Skript Vehicle-respawn.sqs auf. ?!(Local Server): exit _vehicle = _this select 0 _vehicleClass = _this select 1 _respawnArea = _this select 2 _azimutCode = _this select 3 _respawnDelay = _this select 4 _respawnrate = _this select 5 _deletevehicle = _this select 6 _staticrespawn = _this select 7 _deleteeffect = _this select 8 _counter = 0 #Start ~1 ?(Canmove _Vehicle) : goto "Start" ;// Respawnrate (Number of Respawns) ? (_counter >= _respawnrate) : exit _counter = _counter +1 ;// Staticposition (0=Flexible/1=Static) ? (_staticrespawn == 0) : _respawnArea setpos getpos _vehicle ? (_staticrespawn == 0) : _VehAzimut = getdir _vehicle ~_respawnDelay Kapitel 7 ;// Deletevehicle (0=No Delete/1=Delete) ? (_deletevehicle == 0) : goto "Respawn" deleteVehicle _vehicle ;// Delete effect ? (_deleteeffect == 0) : goto "Respawn" _bomb="M_Javelin_AT" createVehicle [0,0,1000] _bomb setpos getpos _vehicle ;// Respawn #Respawn ~2 _vehicle = _vehicleClass createVehicle getpos _respawnArea _vehicle setdir _azimutCode ? (_staticrespawn == 0) : _vehicle setdir _VehAzimut goto "Start" 237 7.16 - Flaggen Grundinformationen Um Missionen wie Capture the Flag (CTF), Sector Control (SC) oder ähnliches erstellen zu können, benötigt man ein gewisses Grundwissen über die Verwendung der Fahnen, welches nun in diesem Abschnitt erläutert wird. Zunächst gilt zu erwähnen, dass man den Fahnen eine Seite zuweisen kann. Ist einer Fahne eine Seite (z.b West) zugewiesen worden, so ist es der eigenen Seite nicht möglich die Fahne abzunehmen. Alle anderen Seiten können jedoch die Fahne aufnehmen. Die Syntax hierfür lautet: this setFlagSide Seite Diese Syntax wird in der Initzeile der jeweiligen Fahne eingegeben. Jede Fahne wird nun einzeln konfiguriert. Also jede Fahne bekommt nun einen separaten Eintrag in der Initzeile. Folgend eine Definitionsmöglichkeit für eine Fahne: this setFlagSide WEST; this setFlagTexture "Flagge.jpg" Mit diesen beiden Einträgen in der Initzeile ist die Fahne nun fertig definiert. Die Fahne hat nun die Seite West und eine eigene Fahnentextur zugewiesen bekommen. Für die Fahnentexturen verweise ich hier auf Kapitel 5.35 oder die nächste Seite. Zudem muss jede Fahne variabel benannt werden. Also zum Beispiel die Westfahne FlagWest und die Ostfahne FlagEast. Kommt nun ein Ostsoldat an diese Fahne, hat er die Möglichkeit diese aufzunehmen. Dabei wir sie ihm auf die Schulter gesetzt und er trägt sie mit sich. Stirbt er Unterwegs, so wird die Flagge bei seinem Körper liegen bleiben. Kommt ein Mitspieler seiner Seite vorbei, hat dieser die Möglichkeit die Fahne an der Leiche aufzunehmen. Kommt ein Gegenspieler und nimmt die Fahne auf, so wird diese in der Regel wieder an den Fahnenmast zurückgebeamt. Nun gibt es noch verschiedene Befehle, welche dafür benötigt werden: ObjNull Dieser Wert steht für Null, was bedeutet dass, wenn die Fahne an ihrem Mast hängt, genau dieser Zustand besteht. Hat ein Spieler die Fahne, so ist der Zustand nicht mehr ObjNull. Dieser Zustand lässt sich bewusst herstellen oder abfragen. Abfragen eines Zustandes: flagOwner FlagWest == objNull flagOwner FlagWest == EAST Herstellen eines Zustandes: FlagWest setFlagOwner objNull FlagWest setFlagOwner Name 238 FlagOwner FlagOwner ist der Fahnenbesitzer. Dieser Befehl gibt den Besitzer der Fahne zurück. Ist niemand Eigentümer der Fahne wird der Befehl objNull zurück-gegeben. Die Bedingungssyntax hierfür lautet: flagOwner FlagWest flagOwner FlagWest == Name1 SetFlagOwner Mit dieser Syntax wird der Fahnenbesitzer bestimmt. Gibt man statt einem Namen objNull an, wird die Fahne zurück an den Masten gebeamt. Hierfür ist folgende Syntax relevant: Rückgabe an Mast: FlagWest setFlagOwner objNull Vergabe an Spieler: FlagWest setFlagOwner Name1 Flag Mit dem Befehl Flag lässt man sich die Fahne zurückgeben, welche eine Einheit gerade trägt. Es ist also somit eine Prüfung auf Fahnenbesitz. Ist niemand im Besitz der Fahne wird wieder der Wert objNull zurückgegeben. Flag Name1 Beispiel: Prüfung auf Fahnenbesitz: Flag Name1 == FlagWest Und für eine spielinterne Fahne wird der Quellpfand mit angegeben (siehe Kapitel 5.35): this setFlagTexture "\ca\misc\data\usa_vlajka.paa" SetFlagSide Hiermit wird die Seite der Flagge vergeben. Einheiten dieser Seite können die Flagge dann nicht aufnehmen. Die Syntax hierfür lautet: this setFlagSide Seite 239 Kapitel 7 SetFlagTexture Mit setFlagTexture wird die Textur der Fahne bestimmt. Dies ist unter anderem im Kapitel 5.35 erläutert. Die Syntax für eine eigene Fahne, welche im Missionsverzeichnis liegt lautet: this setFlagTexture "Flagge.jpg" 7.17 - Capture The Flag Capture the Flag ist ein Spielverfahren bei dem die eine Seite der anderen die Fahne klaut und zur eigenen Fahne bzw. in den eigenen Bereich bringt und damit punktet. Gewinner ist die Seite, die die vorher im Menü festgelegte Punktzahl zuerst erreicht hat oder in der vorgegebenen Zeit die meisten Punkte erreicht hat. Was sich beim Spielen sehr einfach anhört ist im Editor noch lange nicht so einfach zu bewältigen. Natürlich gibt es auch hier wieder unzählige Möglichkeiten eine solche Mission zu realisieren. Hier wird eine Variante erläutert mit der man für seine CTF-Mission die CTF-Basis festlegen kann. Sprich: wenn man dieses jetzt zeichengenau in die Map übernimmt, ist die Funktion schon mal gewährleistet. Nachdem man die auf den folgenden Seiten erklärten Komponenten auf die Map gesetzt hat, sollte die Map am Ende zunächst wie folgt aussehen: Links ist die Fahne West (FlagWest) mit dazugehörigem Auslöserbereich (ZoneWest), einem grünen Marker (nur markierende Bedeutung) und ganz links die drei dazugehörigen Prüfauslöser zu sehen. East, hier rechts, hat jeweils die gleichen Komponenten, nur mit anderen Werten. Die Fahne Ost heißt hierbei FlagEast und der Auslöserbereich ZoneEast. Dazu noch der rote Marker, der die Position der Fahne auf der Karte zeigt und ganz rechts die drei dazugehörigen Prüfauslöser. Die drei unteren Auslöser unter dem Spieler beinhalten einen Initialisierungsauslöser, einen Zeit- und Punkteüberwachauslöser und den Endauslöser, der die Mission nach Erfüllung der Bedingung Zeit oder Punkte beendet. Dieses Beispiel beinhaltet noch keinen Respawn oder ähnliches. Hier ist nur das reine CTF-Zubehör zu sehen, welches die spätere CTF-Funktionalität sicherstellt. 240 CTF-Komponenten Hier nun die einzelnen Komponenten mit der jeweiligen Konfigurierung. Steht bei Aktivierung, Bedingung oder Init etwas untereinander, so stellt dies trotzdem eine Zeile dar, weil dies hier ja aus Platzgründen nicht anders realisierbar ist. W E S T S E I T E Fahne Westen: Name: Init: FlagWest this setFlagSide WEST; this setFlagTexture "\ca\misc\data\usa_vlajka.paa" Bereich Westen (Auslöserbereich): Name: ZoneWest Achse a/b: 10/10 Erreicht der Eroberer der Ostflagge diesen Auslöserbereich, bekommt die Westseite Punkte zugewiesen, was durch eine Texteinblendung angezeigt wird. Eroberer Ostflagge (Prüfauslöser I): Achse a/b: 0/0 Bedingung: not isNull flagowner FlagEast and flagOwner FlagEast != OwnerEast Aktivierung: OwnerEast = flagOwner FlagEast; titletext[format [localize "STR_MP_FLAG_TAKEN_E", name OwnerEast], "Plain down"]; FlagManW=true Eroberer Ostflagge punktet (Prüfauslöser II): Achse a/b: Bedingung: Aktivierung: 0/0 (OwnerEast in list ZoneWest) and not FlagManE and not Wert1 Kdo=OwnerEast; OwnerEast=objNull; FlagEast setFlagOwner objNull; WestScore=WestScore+1; titletext[format [localize "STR_MP_POINT_W", WestScore, EastScore], "Plain down"]; FlagManW=false; Kdo addScore 5; {_x addScore 5} forEach units Group Kdo 241 Kapitel 7 Dieser Auslöser prüft wer Besitzer der Ostflagge ist. Solange diese am Mast hängt passiert nichts. Sobald ein Westsoldat diese aufnimmt kommt eine Texteinblendung welche angibt, welcher Spieler die Flagge aufgenommen hat. Dieser Auslöser überwacht nun, ob der Eroberer der Ostflagge, also der FlagOwner FlagEast, den Auslöserbereich ZoneWest betreten hat. Ist diese Bedingung erfüllt, bekommt die Westseite einen Punktewert zugewiesen, was wieder durch eine Texteinblendung angezeigt wird. Eroberer Ostflagge verliert Flagge (Prüfauslöser III): Achse a/b: 0/0 Bedingung: (isNull flagowner FlagEast) and FlagManW Aktivierung: FlagManW=false; titletext[localize "STR_MP_FLAG_BACK_E", "Plain down"] Dieser dritte Auslöser überwacht, ob die Fahne noch im Besitz des Eroberers ist. Stirbt dieser und nimmt ein Ostsoldat die Fahne von der Leiche auf, wird die Fahne zurück an den Fahnenmast gebeamt und es kommt eine Texteinblendung, dass die Ostseite ihre Fahne zurück hat. O S T S E I T E Fahne Osten: Name: Initzeile: FlagEast this setFlagSide EAST; this setFlagTexture "\ca\misc\data\ rus_vlajka_co.paa" Bereich Osten (Auslöserbereich): Name: ZoneEast Achse a/b: 10/10 Erreicht der Eroberer der Westflagge diesen Auslöserbereich, bekommt die Ostseite Punkte zugewiesen, was durch eine Texteinblendung angezeigt wird. 242 Eroberer Westflagge (Prüfauslöser I): Achse a/b: 0/0 Bedingung: not isnull flagOwner FlagWest and flagOwner FlagWest != OwnerWest Aktivierung: OwnerWest = flagowner FlagWest; titletext[format [localize "STR_MP_FLAG_TAKEN_W", name OwnerWest], "Plain down"]; FlagManE=true Dieser Auslöser prüft, wer Besitzer der Westflagge ist. Solange diese am Mast hängt, passiert nichts. Sobald ein Ostsoldat diese aufnimmt, kommt eine Texteinblendung welche angibt, welcher Spieler die Flagge aufgenommen hat. Eroberer Westflagge punktet (Prüfauslöser II): Achse a/b: 0/0 Bedingung: (OwnerWest in list ZoneEast) and not FlagManW and not Wert1 Aktivierung: Kdo=OwnerWest; OwnerWest=objNull; FlagWest setFlagOwner objNull; EastScore=EastScore+1; titletext[format [localize "STR_MP_POINT_E", WestScore, EastScore], "Plain down"]; FlagManE=false; {_x addScore 5} forEach units group Kdo Eroberer Westflagge verliert Flagge (Prüfauslöser III): Achse a/b: 0/0 Bedingung: (isnull flagowner FlagWest) and FlagManE Aktivierung: FlagManE=false; titletext[localize "STR_MP_FLAG_BACK_W","Plain down"] Dieser dritte Auslöser überwacht, ob die Fahne noch im Besitz des Eroberers ist. Stirbt dieser und nimmt ein Westsoldat die Fahne von der Leiche auf, wird die Fahne zurück an den Fahnenmast gebeamt und es kommt eine Texteinblendung, dass die Westseite ihre Fahne zurück hat. 243 Kapitel 7 Dieser Auslöser überwacht nun, ob der Eroberer der Westflagge, also der FlagOwner FlagWest, den Auslöserbereich ZoneEast betreten hat. Ist diese Bedingung erfüllt, bekommt die Ostseite einen Punktewert zugewiesen, was wieder durch eine Texteinblendung angezeigt wird. Zusätze: Nachdem nun für jede der Seiten die funktionellen Bereiche festgelegt wurden, fehlen nur noch der Initialisierungsauslöser, der Zeit- und Punkteüberwachauslöser und der Endauslöser, um die Mission auch beenden zu können. CTF-Init (Initialisierungsauslöser): Name: CTF-Init Achse a/b: 0/0 Bedingung: true Aktivierung: Wert1=false; WestScore=0; EastScore=0; OwnerWest= objNull; OwnerEast=objNull; FlagManE=false; FlagManW=false; Zeit=0; Diesen Auslöser kann man alternativ auch weglassen und die Befehle aus der Aktivierungszeile in die Init.sqs schreiben. Aus funktionell sichereren Gründen habe ich diese Variante vorgezogen. Hier werden verschiedene Variablen definiert, welche mit den Auslösern der jeweiligen Seiten zusammenarbeiten. Wertungsprüfer (Prüfauslöser): Name: PunktZeitWache Bedingung: (param1<10000 and ((time >= param1) or (Zeit >= param1))) or (param2<10000 and ((WestScore>=param2) or (EastScore>=param2))) Aktivierung: Zeit=Time; publicVariable "Zeit"; Wert1=true; titletext[format [localize "STR_MP_GAMEOVER_FINAL", WestScore, EastScore], "Plain"]; EndOfGame=true Dieser Auslöser überwacht die Zeit- und Punktevorgaben, die vor dem Spielstart vom Admin eingestellt wurden. Ist die jeweilige Bedingung erfüllt, wird die Mission beendet. Bei diesem Beispiel wird die Mission sofort beendet, da in der Aktivierungszeile EndOfGame=true definiert wurde. Dies könnte man auch weglassen und alternativ ein Outroskript (z.B.: [] exec "outro.sqs") mit einbinden und in diesem dann erst am Ende des Skriptes die Variable EndOfGame auf true setzen. Der Auslöser prüft also, ob der jeweilige Variablenwert (Westscore, Eastscore für die Punkte oder Time für die Zeit) den vorgegebenen Parameterwert (Param1(Punkte), Param2(Zeit)) erreicht oder überschritten hat, womit die Bedingung dann erfüllt ist und der Auslöser auslöst. Hierbei gilt darauf zu achten, dass man in der Description.ext die Zeit- und Punkteparameter definieren muss, wie in Kapitel 7.8 ausführlich beschrieben wurde. Bitte nur den Description.ext-Eintrag vornehmen, weiter nichts. Die Auslöser sind ja bereits definiert. 244 Endauslöser (Prüfauslöser): Name: EndWache Bedingung: EndOfGame Typ Ende 1 Der Endauslöser wird erst ausgelöst, wenn die Variable EndOfGame auf true gesetzt wurde und beendet dann die Mission. Hier ist es Vorteilhaft eine kleine Zeitverzögerung (Min-Mid-Max) anzugeben, damit der Auslöser nicht gleich sofort anspringt, sondern noch ein paar Sekunden wartet. Wertunganzeiger (Funkauslöser): Aktivierung: Radio Alpha (Mehrfach) Achse a/b: 0 Text: @STR_MP_SHOWSCORE Aktivierung: titletext[format [localize "STR_MP_STATUS", WestScore, EastScore], "Plain down"] Alternativ kann dieser Auslöser, welcher auf der Gesamtgrafik nicht zu sehen ist, noch mit eingefügt werden. Er ermöglicht es, dass jeder Spieler jederzeit den aktuellen Punktestand per Funk Alpha aufrufen kann. Punkt- und Zeitdefinition in der Description.ext: Damit die Punkt- und Zeitüberwachung komplett ist, müssen diese noch so in der Description.ext definiert werden, wie es in Kapitel 7.8 erläutert ist. Hier aber trotzdem die Zeilen, die hierfür in der Description.ext erscheinen müssen: = "Time limit:"; = {10000, 300, 600, 900, 1200, 1500, 1800, 2100, 3600, 7200}; = 1800; = {"Unlimited", "5 min", "10 min", "15 min", "20 min", "25 min", "30 min", "35 min", "60 min", "120 min"}; Die letzten beiden Zeilen stellen eine lange Zeile dar, was hier nicht realisierbar ist. Punktelimit: titleParam2 valuesParam2[] defValueParam2 textsParam2[] = "Score to win:"; = {10000, 5, 7, 10, 15, 20, 25, 30}; = 5; = {"Unlimited", 5 , 7, 10, 15, 20, 25, 30}; 245 Kapitel 7 Zeitlimit: titleParam1 valuesParam1[] defValueParam1 textsParam1[] 7.18 - Die Publicvariable Die Publicvariable wird ausschließlich im Multiplayer benötigt, deshalb ist sie auch in diesem Kapitel erläutert und nicht im Scriptingkapitel. Sie ist von der Form her mit der globalen Variable vergleichbar, unterscheidet sich jedoch trotzdem ein wenig von ihr. Mit dem Befehl Publicvariable macht man eine globale Variable publik. Das bedeutet, dass die Information von einem Client an alle übrigen Clients und dem Server oder Host gesendet wird und dort dann die jeweilige Aktion ausgeführt wird. Differenzieren wir noch einmal. Lokale Variable Nur in einem lokalen Bereich gültig. Als Beispiel in einem Skript(SQS) oder einer Funktion (SQF). Zu erkennen ist diese Variable an dem Unterstrich davor. Bsp.: _Variable Globale Variable Die globale Variable gilt, wie der Name schon sagt, global. Also im gesamten Bereich der Mission. Beispiel: Vergibt man einen Namen an eine Einheit, ist das schon eine globale Variable. Spielt man nun im Multiplayer, wird man ja als Client lokal gesehen, was bedeutet, dass also die globale Variable, die in der ganzen Mission und auf der ganzen Karte gilt, so gesehen zu einer lokalen Variable wird. Bei fest vergebenen Namen gibt es kein Problem, da jeder Client die Mission startet und somit die Werte übernimmt. Möchte man nun aber einer Variablen einen Wert zuweisen, also sie auf True oder False setzen, passiert das nur auf dem jeweiligen Client. Diese Information muss also nun an alle anderen gesendet werden, damit die Variable auch auf allen anderen Clients den richtigen Wert bekommt und die jeweilige Aktion auch dort ausgelöst werden kann. Um eine globale Variable publik machen, gibt man das wie folgt an: Ziel1=true; publicVariable "Ziel1" Man setzt also Ziel1 auf True und macht diesen Wert mit dem Zusatz PublicVariable "Ziel1" publik. Diese Information wird nun an alle anderen Clients und dem Server oder Host gesendet. Verwendet man in seiner Mission mehrere Variablen, die später den Wert true oder false bekommen sollen, legt man sie vorher in der Init fest und setzt diese zunächst auf False, damit alle Clients bzw. Host oder Server mit den gleichen Werten starten. Variable1=False Variable2=False publicVariable"Variable1" publicVariable "Variable2" 246 7.19 - Allgemeines In diesem Unterkapitel werden ein paar grundlegende Bereiche erklärt, die unter anderem im Multiplayerediting sehr wichtig sind. Da gerade im Editingbereich wesentliche Unterschiede zwischen Einzelspieler- und Mehrspielermissionen bestehen, ist es wichtig hier kurz zu erläutern, worauf man beim Multiplayerediting so alles achten muss. Dedicated Server Der Dedicated Server ist ein fest zugeordneter(dedizierter) Server, auf welchen alle Clients, auch der Administrator, von extern zugreifen. Dieser ist ausschließlich als Server bestimmt. Es sitzt also kein Spieler an diesem System. Dieser Server kann überall auf der Welt stehen und kann beim jeweiligen Provider angemietet werden. Gesteuert wird dieser ingame dann mit den Steuerungsbefehlen, welche hier im Kapitel 7.20 erläutert sind. Host Ein Host ist ein Spieler, welcher auf seinem Rechner eine Mehrspielermission eröffnet(hostet), auf welche mehrere Mitspieler(Clients) von extern zugreifen. Der Host spielt dann an dem gleichen System. Er ist somit Server und Spieler. Client Ein Mitspieler wird im Multiplayer als Client bezeichnet. Egal ob dabei auf einem Dedicated Server oder auf einem Host gespielt wird. Spielen alle auf einem Dedicated Server, so sind alle Clients. Eröffnet einer ein Spiel auf dem Rechner auf dem er auch spielt, so ist er Host und alle anderen Clients. Kapitel 7 Unterschied Einzelspieler und Mehrspieler Wie sicherlich beim Testen einer Mission im Editor und später im Multiplayer gibt es wesentliche Unterschiede im jeweiligen Bereich. Alles was in der Editorvorschau oder im Einzelspielerbereich funktioniert muss nicht gleich im Multiplayerbereich funktionieren. Deshalb ist es wichtig die jeweiligen Unterkapitel dieses Kapitels zu berücksichtigen und in seiner Multiplayermission zu entsprechend zu definieren. 247 Logik Server bzw. Logik AI Bei Mehrspielermissionen setzt man grundsätzlich eine Logik auf die Karte, die Server heißt. Eine alternative Variante wäre AI, wie BI sie bezeichnet, was aber grundsätzlich keinen Unterschied macht. Also bleibt man dabei, die Logik mit dem Namen Server zu versehen. Diese Logik wird nur vom Server erstellt und taucht auf den Clients nicht auf. Diese gibt an, dass das System Server ist. Mit folgenden Befehlen kann man also nun festlegen, was auf dem Server ausgeführt werden soll und was nicht. ? !(local player) : exit Diese Syntax am Anfang eines Skriptes stellt sicher, dass das Skript nur auf den Clients abläuft. Es wird also geprüft ob das System ein Client ist. Da jeder Spieler beim Verbinden vom System die feste Variable Player zugewiesen bekommt, weiß das System, dass es das Skript ausführen darf. Die Informationen werden hierbei an alle Clients weitergegeben. Ist der Client gleichzeitig Host, wird das Skript auch bei ihm ausgeführt, weil er gleichzeitig Server und Client ist. ? !(local server) : exit Taucht diese Syntax am Anfang eines Skriptes auf, wird das Skript nur auf dem Server ausgeführt. Das System macht hierbei keinen Unterschied zwischen einem Lokal Host und einem Dedicated Server. Das Skript wird nun auf jeden Fall bei beiden Varianten ganz normal ausgeführt. Diese Syntax wird grundsätzlich verwendet. Es wird also serverseitig bzw. global gearbeitet, was ja in der Regel am meisten Sinn macht, da ja die meisten Informationen auch an die Mitspieler weitergegeben werden müssen. Wir arbeiten also grundsätzlich global! Alternativ gibt es noch isServer. Beispiele: ? isServer : hint "Server" oder ?! isServer : hint "Not Server" Spielerbezogenes Skript Möchte man ein Skript nur bei einem Spieler mit einem bestimmten im Editor festgelegten Namen ausführen, legt man das am Anfang des Skriptes fest. Zunächst benennt man die Einheiten natürlich entsprechend im Editor. Ist dies erfolgt, definiert man die Syntax. Das Ganze schaut dann so aus: player != Soldier1 : exit Ist der Spieler also nicht die im Editor benannte Einheit Soldier1, dann wird das Skript beendet. Dies kann man machen, wenn ein Sound nur bei dieser einen Einheit Soldier1 abgespielt werden soll, eine Texteinblendung nur dieser eine Spieler erhalten soll oder ähnliches. Hier nochmal zwei weitere Syntaxbeispiele. Ist Player == Soldier1 dann mach dies oder bei der zweiten Syntax, ist der Name von Spieler == "Mr-Murray", dann mach das (hier: exit) (player == Soldier1) : exit (name vehicle player == "Mr-Murray") : exit 248 7.20 - Die Steuerungsbefehle Dieser Bereich hat zwar nichts mit dem Editing zu tun, aber ist dennoch erwähnenswert, weil ja am Ende doch jeder mal online spielt oder seine Mission testen möchte. Im Multiplayerbereich gibt es verschieden Befehle, mit denen es als Spieler unter anderem möglich ist, einen Administrator zu voten, über den Rausschmiss eines Cheaters abzustimmen und vieles mehr. Dem Admin des Servers stehen hierbei noch weit mehr Befehle zur Verfügung. Diese Befehle sind nahezu identisch zum Vorgänger Operation Flashpoint. Lediglich drei Neue sind hinzugekommen. Folgend nun die Auflistung und Erläuterung der Befehle. Administratorbefehle #login password #logout #vote admin (name or ID) #mission filename #missions #restart #reassign #kick (name or ID) #shutdown #init #monitor (Interval in Sek.) #debug Mitspielerbefehle (Client) #vote missions #vote mission (name) #vote kick (name/ID) #vote restart #vote reassign #userlist Abstimmung zur Missionsauswahl Abstimmung zu bestimmter Mission Abstimmung über Mitspielerkick Abstimmung über Neustart der Mission Neustart und Auswahl einer Rolle Zeigt eine Liste aller connecteten Mitspieler an Die Aufrufe lassen sich mit der Chatmöglichkeit im Spiel starten. Dazu drückt man die “– “ –Taste, auf der auch der Unterstrich “_“ definiert ist, gibt den jeweiligen Befehl ein und bestätigt mit Enter. 249 Kapitel 7 #exec users #exec kick ID #exec ban ID Login als Administrator Logout als Admin Administrator voten (auch für Clients) Auswahl einer Mission mit bekannten Namen Aufruf des Missionsauswahlmenüs Neustart der Mission Neustart und Auswahl einer Rolle Kickt Spieler anhand von Name oder ID Startet den Server neu Lädt die Server Config Datei neu Zeigt Performance Informationen des Servers an (Angabe Zeit in Sekunden. 0 stoppt das Monitoring) Ruft verschiedene Informationen auf (checkfile, console, totalsent, usersent, userinfo, userqueue) Ruft eine Liste aller connecteten Spieler auf Erlaubt einen Spieler vom Server zu kicken. Erlaubt einen Spieler vom Server zu verbannen 7.21 - Die Bewaffnung im Multiplayer Zunächst gibt es bei der Bewaffnung eines Soldaten im Multiplayer keinen Unterschied. Hier wir das gleiche Verfahren verwendet, wie auch schon im Singleplayer. Eben die vorigen Waffen mit dem removeWeapon-Befehl entfernen und die neuen mit dem addWeapon-Befehl hinzufügen. Problematisch wird es nur, wenn der Spieler einmal das Zeitliche gesegnet hat und respawnt wird. Denn dann hat die Einheit die Standardwaffen, die sie hat, wenn man sie uneditiert auf die Map setzt. Dem Problem hilft man sich mir einem Skript ab. Zunächst setzt man einen Prüfauslöser auf die Map, welcher überprüft, ob die Einheit namens Soldat1 noch am Leben ist. Prüfauslöser Typ: Bedingung: Bei Aktivierung: Achse a/b: Mehrfach ! alive Soldat1 [Soldat1] exec "weapon.sqs" 0/0 Wurde Soldat1 nun getötet, löst dieser Auslöser aus und startet das Skript Weapon.sqs. Das Skript pausiert nun am Anfang bei @alive _Unit und wartet, bis Soldat1 wieder respawnt wurde, was ja von der Konfiguration der Description.ext abhängt. Je nachdem welche Delaygröße man dort definiert hat, dauert es eine Weile. Nachdem Soldat1 aber respanwt wurde, läuft das Skript weiter und entfernt erst alle Waffen und fügt dann die Neuen hinzu. Im Skript legt man lediglich man dann die Waffen nach Bedarf fest. _Unit = _this select 0 @alive _Unit removeallWeapons _Unit _Unit addweapon "Binocular"; _Unit addweapon "NVGoggles"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addmagazine "8Rnd_9x18_MakarovSD"; _Unit addweapon "MakarovSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addmagazine "30Rnd_545x39_AKSD"; _Unit addweapon "AKS74UN"; exit; 250 7.22 - Spielerbezogene Textmitteilung Textmitteilungen sind ja normalerweise relativ leicht umzusetzen. Im Muliplayerbereich gibt es aber, je nach Mission, eben das Problem, dass der Text global angezeigt wird. Was also bedeutet das, wenn man einen Hint oder eine andere Texteinblendung machen möchte, die spieler- oder seitenbezogen laufen soll, man etwas anders arbeiten muss. Das Ganze wird hier wieder mit einem kleinen Skript gelöst, bei welchem lediglich die erste Skriptzeile entscheident ist. Hier muss nämlich definiert werden, wer die Mitteilung sehen darf und wer nicht. Hierbei nimmt man sich u.a. folgende Syntaxformen zur Hilfe: Spielerbezogen: ? (player == Name1) : exit ? (player != Name1) : exit ? (name vehicle player != "Mr-Murray") : exit Seitenbezogen: ? side Player == EAST : exit ? side Player != EAST : exit Man kann sich selbst so ziemlich jede Syntaxform selbst stricken, ist nur eine Frage der Parameter. Die obigen Syntaxformen sind lediglich ein paar Beispiele. Anwendungsbeispiele Bei folgendem Beispiel bekommt die Mitteilung jetzt nur der Client, der die Einheit spielt, die im Editor mit S1 benannt wurde. Zum Beispiel der Leader. ? (player != S1) : exit hint format ["%1, Sie haben mit Ihrer Gruppe einen neuen Auftrag", name S1]; exit ? (name vehicle S1 != "Mr-Murray") : exit hint format ["Hallo %1, du spielst die Einheit XY.", name S1]; exit Wie man sich sicher denken kann, ist die Variante der Texteinblendungen völlig egal. Die obigen Beispiele sind mit Hints dargestellt, was aber kein Muss ist. Titletext oder eine Ressourceneinblendung wären hier genauso möglich. titleText [format["%1, Sie haben einen neuen Auftrag", name S1],"Plain Down"] 251 Kapitel 7 Das Ganze kann man natürlich auch anders machen. Zum Beispiel, wenn der Spieler einen bestimmten Spielernamen hat, soll er die Nachricht nicht oder erst recht bekommen. 7.23 - Join In Progress (JIP) Join In Progress ist ein wichtiger Punkt der sehr genau betrachtet und daher schon beim Erstellen einer Multiplayermission voll berücksichtigt werden sollte. Erstellt man eine MPMission, werden immer Spieler connecten oder disconnecten, sofern diese public gehostet ist. Und damit kommt das eigentliche Problem auf! Connectet ein Spieler mitten im Spielverlauf, muss ja auf seinem Rechner der gleiche Status herrschen, wie auf den anderen Clients. Gerade die Missionsziele und die Variablenwerte müssen dann abgeglichen werden. Ist als Beispiel Missionsziel 1 bereits abgehakt und die Variable Start schon true (Start=true), dann müssen diese Werte auf dem gerade connecteten Client angepasst werden. Normalerweise sollte das vom Server her geschehen. Dabei würden Dinge wie Missionszielstatus oder auch Variablenstatus automatisch auf allen Parteien angeglichen. Da dies aber beim derzeitigen Stand von ArmA leider nicht der Fall ist, muss man in diesem Bereich etwas nachhelfen, damit die Mission am Ende auch auf einem Dedicated Server vernünftig läuft. Hierzu lässt man den Server regelmäßig, zum Beispiel, wenn ein Spieler connectet oder ein Missionsziel erfüllt wurde, die Publicvariablen aufrufen. Er macht damit den aktuellen Stand einer Variable publik und sendet ihn an alle Clients. Zunächst mal die Init.sqs, in welcher man den Variablen generell erstmal einen einheitlichen Wert zuweist, damit alle Mitspieler auf einem Stand sind. Init.sqs Var1=FALSE Var2=FALSE Var3=FALSE ? ( ! ( Local Server ) ) : goto "Skip" PublicVariable "Var3"; PublicVariable "Var2"; PublicVariable "Var3"; #Skip onPlayerConnected "Server exec ""scripts\update.sqs"" "; Eine ganz interessante Zeile ist die OnPlayerConnect-Zeile. Connected ein Spieler, so wird der Server aufgefordert das Skript Update.sqs auszuführen, welches hier im selbst angelegten Ordner Scripts hinterlegt wurde. Der Server ruft dann nochmal alle Publicvariablen auf und sychronisiert damit die Variablenstadien auf allen Systemen. 252 Update.sqs Die Update.sqs ist sehr einfach und kurz gehalten. In ihr sind nur die Publicvariablen definiert, welche dann bei Aufruf durch den Server nochmal publik gemacht werden. ? ( ! ( Local Server ) ) : exit publicVariable "Var1"; publicVariable "Var2"; publicVariable "Var3"; exit; Missionsziele Mit Missionszielen verhält sich das Ganze ähnlich. Auch hier sollte bei Join In Progress sychronisiert werden, das es sonst vorkommen kann, dass der gerade connectete Mitspieler noch anstehende Missionsziele hat, die eigentlich schon abgehakt sind. Auch hier bietet es sich an ein Skript oder eine Funktion dafür zu verwenden. Dieses lässt man idealerweise jedes Mal starten, wenn ein Ziel abgehakt wurde oder ein Spieler neu connectet hat. Vom Verfahren her, kann man das Gleiche nutzen, wie auch bei den Publicvariablen. Die Init.sqs bekommt zusätzlich die Zeile: onPlayerConnected "[] exec ""scripts\zielupdate.sqs"" "; Zielupdate.sqs ? ( ! ( Local Server ) ) : goto "Skip" publicVariable "Var1"; publicVariable "Var2"; Kapitel 7 #Skip ~4 ? Var1 : "1" objStatus “DONE” ? Var2 : "2" objStatus “DONE” ?! (alive Name1) : "3" objStatus “DONE” exit; Hier wurden die Variablen als Bedingung zur Erfüllung eines Missionsziels verwendet. Zum Beispiel, wenn eine Gruppe einen Wegpunkt erreicht hat was ein Missionsziel darstellt. Die Variable Var1 würde dann auf true gesetzt und wenn nun das Skript aufgerufen wird und feststellt, dass Var1 true ist, das Missionsziel 1 auf Done gesetzt. Ein weiteres Beispiel wäre Missionsziel 3 welches erreicht ist, wenn Name1 nicht mehr am Leben ist. Generell bietet es sich so also an dieses kleine Skript bei jedem Erfüllen eines Missionszieles oder Connecten eines Mitspielers kurz aufzurufen. 253 Kapitel 8 - Das Camscripting Hier kommen wir zu einem Kapitel, was zwar teilweise sehr arbeitsaufwendig ist, aber die Ergebnisse locker mit Hollywoodfilmen zu vergleichen sind. Kleine Intro´s, Outro´s oder Zwischensequenzen heben eine Mission immer ein wenig hervor und man wird besser in die Rolle des Charakters versetzt. Da man über diese Thematik auch ein eigenes Buch dieses Umfangs schreiben könnte, kommen hier lediglich ein paar Einführungen zum Erstellen eigener Szenen. 8.1 8.2 8.3 8.4 8.5 8.6 8.7 8.8 8.9 254 Die Steuerung Die Kamerakoordinaten Kamera erstellen Die erste Szene Kamera an ein Fahrzeug/Einheit heften Text- und Einblendeffekte Kamera-Effekte Preload - Objekte und Positionen vorladen Kartenanimation ausführen 255 256 257 258 260 261 262 262 263 8.1 - Die Steuerung Die Steuerung einer Kamera hängt von der Tastaturbelegung ab und ist ansonsten ziemlich einfach. Folgend erläuterte Tastaturbelegung ist von der Installation her standardmäßig so vorhanden. Doch bevor man überhaupt eine Kamera steuern kann, so sollte man sie erstmal starten. Name exec "camera.sqs" oder this exec "camera.sqs" Dies sind zunächst die wichtigsten Tasten um Positionen festzulegen, Objekte anzuvisieren und so weiter. Im Tastatureinstellungsmenü hat man natürlich noch eine etwas größere Auswahl an Tasten, die aber jetzt erstmal weniger interessant sind. Diese reichen aus um großartige Sequenzen zu realisieren. - Position speichern - Kamera vor und zurück bewegen - Kamera vorwärts bewegen - Kamera rückwärts bewegen - Kamera nach links bewegen - Kamera nach rechts bewegen - Nach links schwenken - Nach rechts schwenken - Kamera schaut auf - Kamera schaut ab - Ranzoomen - Wegzommen - Kamera anheben - Kamera senken - Fadenkreuz an/aus - Kamera aus - Kamera beschleunigen - Objekt selektieren (siehe Bild) Kapitel 8 Linke Maustaste Maus vor zurück Pfeiltaste auf Pfeiltaste ab Pfeiltaste links Pfeiltaste rechts Numpad 4 Numpad 6 Numpad 8 Numpad 2 Numpad + Numpad Bild auf Bild ab L V Shift links Strg 255 8.2 - Die Kamerakoordinaten Nachdem man seine Kamera nun ausgerichtet hat, klickt man die linke Maustaste. Die Kamerakoordinaten werden nun im Zwischenspeicher gespeichert. Bei Operation Flashpoint drückte man damals die Strg-Taste und es wurde eine Clipport.txt im Hauptverzeichnis erstellt, in der dann alle Kameradaten erfasst wurden. Nachdem man also seine Position nun im Zwischenspeicher gespeichert hat, muss man sie ja irgendwo einfügen. Dazu erstellt man in seinem Missionsordner eine neue Textdatei, welche man dann frei benennen kann. Diese heißt jetzt mal Intro.sqs. In diese fügt man nun die Koordinaten mit Strg-V oder Rechtsklick mit der Maustaste und Einfügen wählen, ein. Das Ganze schaut dann etwa wie folgt aus: ;=== 0:06:18 _camera camPrepareTarget [101880.56,-28486.36,1887.85] _camera camPreparePos [9626.16,10062.31,2.00] _camera camPrepareFOV 0.691 _camera camCommitPrepared 0 @camCommitted _camera Das ist eine gerade festgelegte Kameraposition als Datenblock. Hier sind unter anderem die nun folgend erläuterten Daten enthalten. ;=== 0:06:18 Die Uhrzeit der Festlegung. Diese ist eher unwichtig und kann wegfallen. _camera camPrepareTarget [101880.56,-28486.36,1887.85] Blickrichtung der Kamera, für die auch ein Objekt angegeben werden kann. _camera camPreparePos [9626.16,10062.31,2.00] Kameraposition (X,Y,Z) _camera camPrepareFOV 0.700 Kamerazoom. Je kleiner der Wert, desto größer der Zoom. _camera camCommitPrepared 0 Die Zeit, wie lange die Kamera zu dieser Position braucht. Bei dem Wert 0 ist sie sofort da. Schreibt man aber einen größeren Wert dahin, braucht die Kamera von der alten bis zu dieser neuen Position die jeweils definierte Zeit. @camCommitted _camera Hier pausiert das Skript und warten, bis die Kamera ihre Position erreicht hat. 256 8.3 - Kamera erstellen Wenn man nun einen solchen Koordinatenblock gespeichert hat, muss man das Skript erstmal so definieren, dass die Kamera jetzt auch an dieser Position startet. Dabei kommen folgende Zeilen hinzu: _camera = "camera" camCreate [9626.16,10062.31,2.00] Für die XYZ-Werte kann man nun den _camera camPreparePos-Wert angeben oder auch auf [0,0,0] lassen, wenn die Kamera ohne Zeitverzögerung gleich weitergesetzt wird. _camera camPrepareTarget [101880.56,-28486.36,1887.85] _camera camPrepareFOV 0.691 _camera camCommitPrepared 0 @camCommitted _camera Und der jeweilige Effekt muss jetzt natürlich hiermit noch angegeben werden. _camera cameraEffect ["Internal","back"] Der folgende Befehl schaltet den Cinemarahmen ab und man hat Vollbild. showCinemaBorder false Nachdem die ganzen Daten nun verarbeitet wurden, sieht das Skript so aus: _camera = "camera" camCreate [9626.16,10062.31,6.00] _camera camPrepareTarget [101880.56,-28486.36,1887.85] _camera camPrepareFOV 0.700 _camera camCommitPrepared 0 @camCommitted _camera _camera cameraEffect ["internal","back"] showcinemaborder false 257 Kapitel 8 Dies ist jetzt eher unspektakulär, da die Kamera erzeugt wird und starr in der Luft steht, ohne dass irgendwas passiert (siehe Bild). Dazu sind nun noch mehr Zeilen notwendig. 8.4 - Die erste Szene Dazu wird die erste Kameraposition gleich übernommen, aber für den Targetwert bei _camera camPrepareTarget [101880.56,-28486.36,1887.85] ein Objekt angegeben. Die Kamera wird dann erstellt und schaut genau auf dieses Object, was hier mal Flieger1 heißt. Zudem wurde auch der Zoomwert auf 600, also ranzoomen, verändert. Jetzt braucht man aber einen weiteren Koordinatenblock um die Kamera dorthin wandern zu lassen. Nachdem dem der nun festgelegt wurde, wird er gleich in das Skript integriert und angepasst. Intro.sqs ;Introsequenz titleCut [" ", "BLACK IN"]; titleFadeOut 4 Playmusic "Track1" ;Position 1 Flugzeug _camera = "camera" camCreate [9626.16,10062.31,6.00] _camera camPrepareTarget Flieger1 _camera camPrepareFOV 0.600 _camera camCommitPrepared 0 @camCommitted _camera _camera cameraEffect ["internal","back"] showcinemaborder false ;Position 2 Flugzeug _camera camPrepareTarget Flieger1 _camera camPreparePos [9657.99,10121.22,1.04] _camera camPrepareFOV 0.500 _camera camCommitPrepared 30 @camCommitted _camera Wie man sehen kann wurden hier gleich zwei weitere Zeilen eingefügt: titleCut [" ", "BLACK IN"]; titleFadeOut 4 Blendet schwarz in die Sequenz mit einer Dauer von 4 Sekunden ein. playMusic "Track1" Zeitgleich wird ein eigenes Musikstück gestartet, um die Sequenz soundtechnisch ein wenig zu untermalen. Die Kamera ist nun auf Flieger1 fixiert und braucht 30 Sekunden bis zur nächsten Kameraposition, wobei sie während der Fahrt langsam ranzoomt, aber der Flieger einfach schneller ist und irgendwann am Horizont verschwindet. 258 Position 1 Flugzeug: Position 2 Flugzeug: Nun kann man das natürlich noch ausweiten, aber die Funktion sollte somit verstanden sein. Jetzt muss das Skript natürlich auch beendet werden. Dazu kommen am Ende des Skriptes noch folgende Zeilen hinzu: 6 Fademusic 0 titleCut [" ", "black out"]; titleFadeOut 4 ~6 Kapitel 8 player cameraEffect ["terminate","back"] camDestroy _camera ~1 Playmusic "" 0 Fademusic 1 exit Die Szene blendet nun langsam aus und auch die Musik wird dabei leiser. Nach 6 Sekunden wird die Kamera gelöscht und der Spieler kann seine Mission starten. Nachdem man die Musik mal, wie oben zu sehen, runtergefadet hat, fadet man sie am Ende des Skriptes wieder hoch, damit man später wieder Musiksound hat. 259 8.5 - Kamera an ein Fahrzeug/Einheit heften Man hat auch die Möglichkeit die Kamera an ein Fahrzeug zu hängen, damit diese dann das Fahrzeug verfolgt. Die Kamera lässt sich dabei so gut ausrichten, dass man sie frei an einer Position des Fahrzeugs positionieren kann. Dazu wird zunächst erstmal die Einheit oder das Fahrzeug erstellt, welches hier mal den Namen Auto hat. ;Kamera erzeugen _camera = "camera" camCreate [0,0,0] _camera camSetTarget Auto _camera camSetPos [0,0,0] _camera camSetFOV 0.700 _camera camCommit 0 @camCommitted _camera _camera cameraEffect ["internal","back"] ; Position der Kamera im/am/um das Fahrzeug _car = Auto ;Position der Kamera längs des Fahrzeugs (vorne/hinten/in) _dx = -6 ;Position der Kamera neben dem Fahrzeug (links/rechts/in) _dy = 0 ;Höhe der Kamera (unter/über/in) _dz = 2 #LOOP ;Die folgenden zwei Blöcke sind jeweils eine Zeile, was hier nicht möglich ist. _camera camSetTarget [(10 * sin (getdir _car))+(getpos _ car select 0), 10*cos (getdir _car)+(getpos _car select 1), (getpos _car select 2)] _camera camSetPos [(getpos _ car select 0) + _dx * sin (getdir _car) - _dy * cos (getdir _car), (getpos _car select 1) + _dx * cos (getdir _car) + _dy * sin (getdir _car), (getpos _car select 2)+_dz] _camera camSetFOV 0.900 _camera camCommit 0 @camCommitted _camera ;Um das Skript zu beenden, setzen wir eine Bedingung. Hier: Wenn unser Auto ;näher als 50 Meter an die Einheit (P1) kommt, soll die Szene beendet werden. ?P1 distance Auto < 50 : goto "Ende" goto "LOOP" #Ende P1 cameraEffect ["terminate","back"] camDestroy _camera exit 260 8.6 - Text- und Einblendeffekte Man hat die Möglichkeit verschiedene Arten von Texteinblendungen zu definieren. Dabei verwendet man unter anderem folgende Syntaxformen: titleCut ["Hallo", "Black Out"]; titleFadeOut 6 titleText ["Test", "White In"]; titleFadeOut 6 cutText ["Test", "Black In"]; titleFadeOut 6 Hier eine Übersicht über die einzelnen Varianten: Plain Plain Down Black Black Faded Black In Black Out White In White Out - Text erscheint mitten auf dem Bild - Text erscheint am unteren Bildrand - blendet vom Bild ins Schwarze - blendet vom Bild ins Schwarze - blendet von schwarz ins Bild - blendet Bild ins Schwarze aus - blendet von weiß ins Bild - blendet Bild ins Weiße aus Zeilenumbruch Um einen Zeilenumbruch mit einzusetzen setzt man lediglich ein \n an die jeweilige Position im Text. Setzt man zwei \n\n hintereinander hat man eine Leerzeile und so weiter. titleText ["Paraiso\nOne day later…", "Black In"]; titleFadeOut 4 Ingame schaut das dann später etwa so aus: Und folgend nochmal eine Syntax in Verbindung mit Text aus der Stringtable.csv: hint composeText [localize "STR_RA_M01V03",parsetext format ["<t size='1.2' align='center' color='#ff0000'>%1</t>", name player]]; 261 Kapitel 8 Composetext Neben dem Standardhint gibt es noch den Composetext. Dieser kann farblich und schriftgrößentechnisch völlig frei definiert werden. Die u.a. Syntax stellt eine Zeile dar! hint composeText [parsetext format ["<t size='1.2' align='center' color='#ff0000'>Hallo %1</t>", name player]]; 8.7 - Kamera-Effekte Dieses Unterkapitel zeigt einige Effekte auf, welche man in seinen Sequenzen hier und da ganz gut gebrauchen kann. Diese reichen vom Nachtsichteffekt bis hin zu Soundeffekten. Kinorahmen abschalten Der folgend aufgeführte Befehl schaltet die Kinobalken ab und man Vollbild. showCinemaBorder false Kamera mit Nachtsicht Damit die Kamera die Nachtsichfunktion nutzen kann, benötigt man folgenen Befehl: camUseNVG true Spielgrafik erhellen oder verdunkeln Der folgend aufgeführte Befehl erhellt oder verdunkelt die Spielgrafik. setAperture 1 - hell setAperture 200 - dunkel Kamera etwas sagen lassen Die Kamera wird wie ein Objekt behandelt, daher gilt hierfür der normale Say-Befehl. _camera say "Sound1" Umgebungssound abschalten Wer möchte schon gerne Vogelgezwitscher oder sonstigen Sound neben der Musik in seinem Intro oder seiner Zwischensequenz haben. Hierbei gelten folgende Befehle: enableEnvironment false 3 fadeRadio 0 4 fadeSound 0 2 fadeMusic 0 - Schaltet den Umgebungssound ab - Zeit fadeRadio Funklautstärke - Zeit fadeSound Soundlautstärke - Zeit fadeMusik Musikstärke 8.8 - Preload - Objekte und Positionen vorladen Die äußerst aufwendig gestaltete Umwelt und das ständige Laden und Löschen von Texturen und Objekten kann, bei großen Kamerasprüngen schnell zu fehlerhafter Darstellung der Umgebung und ruckeln führen. Das System und die Engine kommen dabei dem Kamerasprung nicht so schnell nach und somit kommt es zu solchen Fehlern. Um diesem Problem entgegenzuwirken und fehlerhafte Darstellungen und Ruckler zu vermeiden gibt es die Preloadbefehle. Diese laden Objekte, Positionen, Sounds oder was immer man möchte, vor ab in den Arbeitsspeicher. Je nach Befehlsform wird die Kamera erst an die neue Position versetzt, wenn der Bereich oder die Objekte fertig in den Arbeitsspeicher geladen wurden. Folgend nun ein paar Preload-Syntaxbeispiele. preloadObject preloadCamera 262 - Lädt ein Objekt vor (siehe Beispiel) - Lädt Kameraposition vor (siehe Beispiel) preLoadMusic Track1 preloadSound Sound1 preloadTitleRsc ["BIS", "Plain] preloadTitleObj ["BisLogo", "Plain] - Lädt ein Musikstück vor - Lädt einen Sound vor - Lädt eine Ressource vor - Lädt eine Ressource bzw. Objekt vor Hier mal zwei Beispiele der Verwendung von preLoadObject und preLoadCamera. Beim ersten Beispiel werden alle Daten der Umgebung geladen. Das Skript läuft erst weiter, wenn der Ladevorgang abgeschlossen ist und löscht am Ende den lokalen Wert _preload. _preload = [] spawn {waitUntil {preloadCamera position Name}} @scriptDone _preload terminate _preload Gleiches bei preloadObjekt, dort wird das Objekt Name mit Distanz (5) geladen. _preload = [] spawn {waitUntil {5 preloadObject Name}} 8.9 - Kartenanimation ausführen Während eines Briefings ist es sehr interessant eine Kartenanimation ablaufen zu lassen. Dabei kann man die Kamera auf der Karte zu den verschiedenen Markerpositionen wandern lassen, Marker löschen oder verändern und vieles mehr. Folgend ein kurzes Beispiel, wie man so ein Animationsskript gestalten kann. Dabei ist es sinnvoll das Briefing oder auch das Funkgerät auszublenden. Man sollte zudem für jeden angesteuerten Marker 2 Blöcke zu definieren, wie im Beispiel zu sehen ist. Block1=Ranzoomen, Block2=wegzoomen und danach erst weiter zur nächsten Position. forceMap true showPad false disableUserInput true ;// Öffnet die Karte ;// Verbirgt das Briefing ;// Sperrt Spielereingabe Kapitel 8 ;//Marker Pos1 in 3 Sekunden bis auf Wert 0.1 ranzoomen mapAnimAdd [3, 0.1, markerPos "Pos1"] ;// Fügt Animation hinzu [Zeit, Zoom, Position] mapAnimCommit ;// Führt Animation aus @mapAnimDone ;// Wartet bis die Animation beendet ist ~2 ;//Aus Marker Pos1 in 1 Sekunde auf Wert 1 rauszoomen mapAnimAdd [1, 1, markerPos "Pos1"] mapAnimCommit @mapAnimDone ~1 ;//Kartenanimation beenden und Urzustände wiederherstellen forceMap false ;// Schließt die Karte mapAnimClear ;// Löscht Werte von MapAnimAdd showPad true ;// Zeigt das Briefing wieder an disableUserInput false ;// Gibt dem Spieler die Kontrolle zurück exit; 263 Kapitel 9 - Scripting In diesem Kapitel werden dir einige allgemeine Abschnitte aus dem Bereich Scripting näher gebracht. Du wirst Dank dieses Kapitels einige Skripte und Befehle in diesem Buch besser verstehen und bist am Ende sogar in der Lage eigene kleine oder auch größere Skripte zu schreiben und anzuwenden. 9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8 9.9 9.10 9.11 9.12 9.13 264 Die Variable Wahrheitswerte Logische Operatoren Die While-Do-Schleife Der Zähler If-Then-Else Der Delay Random WaitUntil Die Klammer Das Semikolon Der Array Funktionen-Grundwissen 265 266 267 268 268 268 269 269 269 270 271 271 274 9.1 - Die Variable Eine Variable ist ein veränderbarer Wert. Dieser kann dabei ein Wort oder auch eine Zahl sein, dass ist völlig egal. Hierbei gibt es die lokale und die globale Variable. Während eine globale Variable überall gültig ist, ist eine lokale Variable nur für einen Bereich definiert. Hier mal ein Beispiel mit Variablen: Heli1 flyInHeight 120 Der Name Heli1 stellt eine globale Variable dar, während 120 nur ein variabler Wert aber keine Variable in Form eines Namens ist. Man kann eine Zahl nur als Wert verwenden und nicht als Namen vergeben. Verbinden man die Zahl mit einem Buchstaben, wie oben mit Heli1 dargestellt, sieht das schon wieder ganz anders aus. Lokale Variable Eine lokale Variable erkennt man an dem Unterstrich vor der Variable. Diese Variable ist nur in diesem Skript bzw. Bereich gültig. So ist es möglich, die Variable für mehrere Einheiten zu verwenden, ohne das man noch weitere Variablen vergeben muss. Als Beispiel dient hier mal ein Skript, welches so definiert ist, dass zunächst drei Einheiten Name1, Name2 und Name3 eine Animation ausführen sollen. Da es aber irgendwo auf der Karte vielleicht auch noch weitere Einheiten gibt, die auf das Skript zugreifen sollen, verwendet man darin eine lokale Variable. Man muss dafür also nur ein Skript schreiben und vergibt darin eine lokale Variable für eine Vielzahl von Einheiten. Die Namen, die das Skript auslösen sollen, gibt man dabei in einen Array mit an: [Name1,Name2,Name3] exec "skript.sqs" Wird das Skript nun gestartet, wird jedem der drei Beispielsoldaten die lokale Variable _man zugewiesen. Jede der drei Einheiten wird also in dem Skript lokal behandelt und angesprochen. Im Skript sieht das dann etwa so aus: ;Animationsskript ;Einheit bekommt lokalen Wert zugewiesen _man = _this select 0 ;Einheit führt Animation aus _man playMove "Animation"; Diese Einheit, mit dem globalen Namen z.B. Name1, hat nun die lokale Variable _man zugewiesen bekommen und führt den angegebenen Befehl aus. 265 Kapitel 9 ;Skript wird verlassen exit Globale Variable Neben lokalen Variablen gibt es natürlich noch die globalen Variablen. Während eine lokale Variable nur in einem ihr vorbestimmten Bereich gültig ist, wird eine globale Variable, wie der Name schon sagt, für den globalen Bereich festgelegt. Wenn man einem Soldaten einen Namen gibt, so ist das eine globale Variable und diese kann nur einmal vergeben werden. Möchte man einem zweiten Soldaten im Editor den gleichen Namen geben, wird sich das Programm mit einer Fehlermeldung melden. Diese Variable kann man nun von überall, also Skript, Funktion, Auslöser und Wegpunkt ansprechen. Fest vergebene Variablen Einige Werte sind vom Spiel aus schon fest vergeben. Diese lauten wie folgt: Player This Time _time _x _this Pi - Der Spieler - Einheit oder Objekt - Uhrzeit im Spiel - Lokalzeit - Ein Element eines Arrays - Lokale Einheit - 3,14… Variablenzustände Man kann einer Variable Zustände oder Werte zuweisen. Zum Beispiel kann man sie in ihrem Zustand auf true schalten oder ihr einen Textstring zuweisen. Name1= true Name1= 44 Name1= "MeinText" Name1= [Wert1,Wert2] - Variable bekommt den Wert WAHR - Variable bekommt einen Wert - Variable bekommt einen Textstring - Variable bekommt einen Arraywert Variable speichern Variablen lassen sich auch jederzeit speichern und sind im weiteren Verlauf aufrufbar. saveVar "Variablenname" 9.2 - Wahrheitswerte Ein Wahrheitswert ist ein Zustand eines Wertes. Man kann ihn mit einem Ein- oder Ausschalter vergleichen. Setzt man eine Variable auf true, wird die jeweilige Aktion gestartet und setzt man sie auf false wird die Aktion wieder beendet. Für true kann man auch 1 und für false auch 0 schreiben. true false 266 Wird zurückgegeben wenn Bedingung erfüllt ist Wird zurückgegeben wenn Bedingung nicht erfüllt ist 9.3 - Logische Operatoren Hier eine Übersicht einiger allgemein bekannter wichtiger Operatoren. AND OR NOT 267 Kapitel 9 ! ? : If Then Else Exit Do # Goto > < <= >= == ~ ; @ ForEach ThisList Count Random Case Ceil Floor Round - Logisches UND zum Verknüpfen von zwei oder mehreren Variablen - Logisches ODER zur kontrollierten Auswahl zwischen zwei oder mehreren Variablen - Logisches NICHT zur kontrollierten Bestimmung von zwei oder mehreren Variablen - Steht ebenfalls für NOT, also NICHT - WENN - DANN - WENN - DANN - SONST - Stoppt die Ausführung eines Skriptes - Mach (siehe While Do) - Überschrift (Label) - Gehe zu - Größer als - Kleiner - Kleiner oder gleich - Größer oder gleich - Gleich - Zeitverzögerung in Sekunden (~3) - Ist im Kapitel 9.10 näher erläutert - Pausiert und wartet bis die Bedingung dahinter true ist - Für jede Einheit {_x reveal Player} foreach List Bereich1 - Für jede Einheit (Seite) in einem Auslöserbereich - Gibt die Anzahl der vorhandenen Elemente eines Arrays zurück - Bestimmt einen Zufallswert - Falls (Bsp: case 1 : exit (Übersetzt: Ist Fall gleich Wert 1 dann exit) - Rundet Wert auf. (Bsp: ceil 5.25 wäre 6 / ceil -5.25 wäre 5) - Rundet Wert ab. (Bsp: round 5.25 wäre 5 / round -5.55 wäre -6) - Rundet Wert auf/ab. (Bsp: round 5.25 wäre 5 / round 5.55 wäre 6) 9.4 - Die While-Do-Schleife Diese Schleife läuft so lange, bis a größer als b ist. Zu a wird dabei so lange der Wert 1 zu hinzugezählt, bis a größer ist und somit die Schleife beendet wird. Der maximale Wert für Armed Assault liegt derzeit bei 100.000. While {a<b} do {a=a+1} Übersetzt: Solange a kleiner ist als b, zähle zu a den Wert 1 dazu. 9.5 - Der Zähler Möchte man einen Zähler in ein Skript einsetzen, muss man zunächst den Ursprungswert am Skript- oder Missionsstart auf 0 setzen. Der Variable Counter wird somit zunächst der Wert 0 zugewiesen. Danach startet der eigentliche Zähler und zählt zur lokalen Variable _Counter bei jedem Durchlauf den Wert 1 hinzu. Dies passiert aber nur so lange, bis die Variable _Counter >=, also größer gleich, 10 ist und beendet dann das Skript. _counter = 0; #Start; ? (_counter>=10) : exit _counter = _counter+1; goto “Start”; 9.6 - If-Then-Else Diese Syntax heißt übersetzt so viel wie: Wenn – Dann – Sonst. Oder eben so viel wie: WENN Bedingung erfüllt, DANN mach dies, ANSONSTEN mach das. Hier nochmal zwei Syntaxformen dazu: IF (a>b) THEN {c=1} ELSE {c=2} Als Beispiel mal folgendes. Ein Marker soll, solange die Einheit lebt, immer an die aktuelle Position dieser Einheit gesetzt werden. Ist diese Einheit nicht mehr vorhanden, soll das Skript beendet werden. #Start; ~0.5 If(alive Soldat1)Then{"S1-Symbol" setMarkerPos getpos Soldat1} Else{"S1-Symbol" setMarkerType "Empty";exit}; goto “Start”; Wenn (If) Soldat1 lebt dann (Then) setze S1-Symbol auf Soldat1 ansonsten (Else) lösche S1-Symbol und verlasse Skript (Exit). 268 9.7 - Der Delay Ein Delay ist eine Verzögerung und wird in Skripten (SQS) verwendet. In Funktionen nimmt man stattdessen den Befehl Sleep. Diese bekommen dann einen Wert der als Sekunden gewertet wird. Das Skript oder die Funktion zählt dann den gesetzten Wert runter und folgt erst dann dem weiteren Verlauf. ~300 ~random 300 Sleep 300 - Skript pausiert 300 Sekunden bis zur Weiterführung - Generiert einen Zufallswert von 0-300 und pausiert - Funktion „schläft“ 300 Sekunden 9.8 - Random Mit dem Befehl Random hat man die Möglichkeit einen Wert per Zufall generieren zu lassen. So könnte man zum Beispiel eine Variable mit einem Zufallswertwert versehen. Das Ganze schaut dann etwa wie folgt aus: _start = random 4 ? _start < 1 : goto "Start1"; ? _start < 2 : goto "Start2"; ? _start < 3 : goto "Start3"; ? _start < 4 : goto "Ende"; Hier wurde ein Wert bis maximal 4 generiert und das Skript prüft danach wie groß dieser Wert ist und springt zum jeweiligen Label Start oder Ende. Natürlich kann man diesen Operator auch anderweitig benutzen. Zum Beispiel um eine Einheit an eine Zufallsposition in einem Gebäude setzen oder einen Delay mit einem Zufallswert versehen. Das schaut dann etwa so aus: Name1 setPos (nearestBuilding this buildingPos random 10) oder der Delay: ~random Wert 9.9 - Waituntil _Wert = 0; waitUntil {_Wert = _Wert +1; _Wert >= 100}; 269 Kapitel 9 WaitUntil heißt übersetzt warte bis und kann somit als Bedingung für etwas genutzt werden. Es ist also wie ein @ nur eben für Funktionen. Die Funktion wartet dann, bis diese Bedingung erfüllt ist. 9.10 - Die Klammer Beim Skripten werden diverse Klammern verwendet, von denen jede ihre eigene Eigenschaft besitzt. Dabei unterscheidet man zwischen folgenden Varianten: [] {} () "" - Array (im Kapitel 9.12 erläutert) - Code (geschweifte Klammer) - mathematische Operatoren - Textstrings Setzt man eine Klammer, so fasst man etwas zusammen und teilt dem System bzw. ArmA mit, dass dies zusammen ausgeführt werden muss. {} – Code Mit der geschweiften Klammer lässt man Code verarbeiten, also alles, was man in Codeform aufrufen und weiterverarbeiten möchte. Als gutes Beispiel dient hier: {_x moveInCargo Heli1} forEach Units GAlpha Dabei sollen alle Einheiten der Gruppe GAlpha in den Frachtraum des Fahrzeugs Heli1 gesetzt werden. () - Mathematische Operatoren Mit der normalen Klammer () verarbeitet man mathematische Operatoren. Das Ganze läuft wie in der Mathematik, um Punkt-vor-Strich zu umgehen. (a+b)*c Beispiel: In folgendem Beispiel soll eine Einheit an eine Position in einem Gebäude laufen. Dazu sagt man: Einheit gehe zu Haus plus Position Wert. Dabei ist durch die Klammer festgelegt, dass die Position zu dem Haus gehört. Als Syntax, sieht das Ganze so aus: _Man move (_House buildingPos 120) Wären dort keine Klammern definiert, würde ArmA lesen: Einheit gehe zu Haus und zu einer Position 120. Wobei die Engine nicht weiß, dass diese Position zu dem Gebäude gehört und gibt somit Fehlermeldung aus. “Textstrings“ Mit Hilfe der "" legt man Textstrings fest. Alternativ kann man für diese auch einen ' verwenden, welcher auf der Tastatur in der Regel auf der #-Taste zu finden ist. "" können auch geschachtelt werden. Hier mal ein Beispiel der Verwendung anhand eines Mapklicks. onMapSingleClick "Leader Alpha1 move _pos; Player say ""Hallo""" 270 9.11 - Das Semikolon Das Semikolon steht in der Skriptsprache für Trennung bzw. Absatz. Man kann hiermit zwei Befehlszeilen voneinander trennen (siehe Initzeile einer Einheit) oder weitergeben, dass die Zeile zu Ende ist und somit gleich die nächste Zeile gelesen wird. Es sollte also generell jede Skript- oder jede Funktionszeile mit einem Semikolon beendet werden. Des Weiteren gilt zu bemerken, dass in einem Skript oder einer Funktion die Zeichen hinter einem Semikolon nicht gelesen werden. Dies ermöglicht, dass man dahinter einen Vermerk oder ähnliches schreiben kann. Hier mal ein Skriptbeispiel: ;Animationsskript ;Einheit bekommt lokalen Wert zugewiesen _man = _this select 0 playSound "Move"; ;Einheit führt Animation aus _man playmove "Animation"; ;Skript wird verlassen exit Bei der Funktion hat man damit zusätzlich die Möglichkeit Befehle voneinander zu trennen. Hier mal eine Beispielsyntax, welche zwei Semikolon beinhaltet, die den Code darin voneinander trennen. Beispiel = {private["_a","_b"]; _d=[getPos player,_this select 0]; _b = 100}; Achtung! Hat man einen Delay wie z.B. ~10 vergeben oder ein Label # gesetzt, setzt man dahinter kein Semikolon, da das Skript sonst nicht funktionieren wird! 9.12 - Der Array Mit einem Array hat man die Möglichkeit, Werte an ein Skript oder eine Funktion zu übergeben. Er Vorteil daran ist, dass man nun ein Skript sehr flexibel für viele Einheiten oder ähnliches verwenden kann, indem man darin nur lokale Variablen benutzt. Eine Funktion müsste man dann nur einmal schreiben und kann diese dann gleich für sehr viele Aktionen verwenden. Es ist also nicht auf ein spezielles Objekt oder eine spezielle Einheit festgelegt, sondern für viele. Ein Array ist also eine Auflistung von mehreren Werten, die mit Klammern zusammengehalten und dann weitergegeben werden. [Wert1, Wert2, Wert3, Wert4] exec "skript.sqs" 271 Kapitel 9 Array Der Array besteht aus den eckigen Klammern []. Alles was jetzt darin aufgelistet ist, kann dann so an das Skript übergeben werden. Hier mal ein Syntaxbeispiel: Die im Array festgelegten Werte werden jetzt im Skript wie folgt definiert: _Wert1 = _this select 0 _Wert2 = _this select 1 _Wert3 = _this select 2 _Wert4 = _this select 3 Da wir im Skript mit lokalen Werten arbeiten möchten, weist man dem jeweiligen Wert aus dem Array im Skript eine eigene lokale Variable zu. Im nun folgenden Beispiel wird das Ganze sicher deutlicher. Hier soll ein Objekt mit einem Skript erstellt werden. Dies soll hier mal ein leerer BMP2 sein, der an der Position eines unsichtbaren Heli-H´s namens Point1, mit der Ausrichtung 100 und einem Treibstoffwert von 0.5, createt werden soll. Was man jetzt noch alles im weiteren Skriptverlauf definieren könnte, bleibt hier mal freigestellt. Zunächst die Syntax mit dem definierten Array: ["BMP2", Point1, 100, 0.5] exec "skript.sqs" _Object = _this select 0 _StartPos = _this select 1 _Azimut = _this select 2 _Fuel = _this select 3 _Vehicle = "_Object" createVehicle position _StartPos; _Vehicle setDir _Azimut; _Vehicle setFuel _Fuel; exit In diesem Skript bekommen nun die Werte aus dem Array jeweils eine lokale Variable zugewiesen. Dabei wurden diese wie folgt übergeben: "BMP2" Point1 100 0.5 bekommt die lokale Variable Wert _Object bekommt die lokale Variable _StartPos bekommt die lokale Variable _Azimut bekommt die lokale Variable _Fuel Mit diesen vergebenen lokalen Variablen wird nun im Skript weitergearbeitet, wie man im unteren Skriptteil sehr gut erkennen kann. Der Vorteil ist nun, dass man nur ein Script benötigt, welches man beliebig oft verwenden kann. Die folgende Syntax wäre nun genauso darauf anwendbar. Wobei hier mit Random ein Zufallstankfüllwert zwischen 0 und 1 definiert wird und das Objekt, hier ein Heli, nun an der Position des Spielers erstellt wird. ["AH1W", Player, 100, random 1] exec "skript.sqs" 272 Zufallswert aus einem Array beziehen Mit folgender Vorgabe hat man die Möglichkeit sich einen Zufallwert aus einem Array auswählen zu lassen und diesen dann für etwas Bestimmtes zu verwenden. _array = [47,73,78,85,101,103]; _Pos = _array select (random (count _array)-0.5); Als gutes Beispiel dient folgendes. Man möchte die Einheit Soldier1 mit einem im Aufrufarray definierten SetUnitPos-Wert an eine Zufallsposition des Hotels setzen. Dabei sollen aber nur Positionen berücksichtig werden, die auf der ersten Etage sind und vorher im Skriptarray festgelegt wurden. [Soldier1, "Middle", Hotel] exec "skript.sqs" _Unit = _this select 0 _Pos = _this select 1 _House = _this select 2 _array = [47,73,78,85,101,103]; _BPos = _array select (random (count _array)-0.5); _Unit setPos (_House buildingPos _BPos); _Unit setUnitPos _Pos; exit; Hierbei wählt das System einen Wert aus dem Skriptarray aus und setzt die Einheit an diese Position im Hotel. Da hier mit einem Objekt auf der Karte gearbeitet wird, bitte das Kapitel 5.61 beachten, um das Gebäude zu benennen. Kapitel 9 273 9.13 - Funktionen Grundwissen Bereits in OFP Resistance wurden Funktionen eingeführt. Zunächst einmal waren sie an der anderen Dateiendung erkennbar, die nämlich nicht SQS, sondern SQF lautet. Daran hat sich mit und in Armed Assault im Grunde nicht viel geändert. Es gibt immer noch die klassischen Funktionen mit der typischen Dateiendung SQFund es gibt auch noch genau wie bei OFP, Skripte mit der Dateiendung SQS. Wie im Kapitel 2.7 schon erläutert, ist die Funktion(SQF) im Grunde genommen eine Weiterentwicklung der normalen Skript-Syntax(SQS). Jedoch muss erwähnt werden, dass sie keinesfalls das Skript ersetzt. Zumindest nicht in allen Bereichen. Es gibt nach wie vor die SQS-Syntax auf welche die SQF-Syntax nur aufbaut. Für und mit Armed Assault hat BIS auch die Möglichkeiten für Skripte und Funktionen erweitert. So gibt es jetzt eine ganze Reihe neuer Skript-Befehle und Ergänzungen der Control Structures, die bereits in OFP bekannte SQF-Syntax wurde also deutlich erweitert. Und hier beginnt -unnötigerweise- leider auch die Verwirrung. Einige der neuen Befehle erwarten eine bestimmte Syntax, genauso wie einige alte Befehle eine bestimmte Syntax erwarten. Wenn man den Exec-Befehl verwendet, muss man zwangsläufig die OFP Skriptsyntax, also die Sqs-Syntax verwenden. Dort kann man dann auch weiterhin Labels und Goto-Loops anwenden. Man kann das Skript jederzeit mit Exit verlassen. Neu ist allerdings, dass jedes Statement mit einem Semikolon ; beendet werden muss und dass man bei der Verwendung von Code nicht mehr wie bei OFP Anführungszeichen "", sondern geschweifte Klammern {} verwenden muss. Die Anführungszeichen "" werden nun für Strings verwendet. OFP Beispiel: "_x addWeapon ""Binocular"" " foreach units group player ArmA-Beispiel: {_x addWeapon "Binocular"} foreach units group player; Wer sich eine solche Funktion jetzt mal ansieht, wird schnell die Unterschiede zu den normalen OFP-Skripten erkennen. In Funktionen gibt es keine Wartezeiten (Delays), keine Labels # und damit auch keine Goto-Funktionen. Dafür werden in Funktionen häufig While-do- und If-Then-Else-Konstruktionen benutzt. Mit ArmA sind auch neue Befehle wie Switch, Do oder Case hinzugekommen. Diese Befehlskombinationen werden auch Control Structures genannt. Ich verweise hier auf die offizielle Wiki von BI: http://community.bistudio.com/wiki/Control_Structures 274 Eine Funktion hat die Hauptaufgabe eine Lösung kurz und effizient herbeizuführen und besteht daher in der Regel aus einer eher kurzen Befehlsfolge, während ein Skript, je nach Aufgabe, schon mal etwas länger ausfallen kann. Funktionen werden oft aus Skripten aufgerufen, um zum Beispiel einer Variablen einen Wert zuzuweisen, Werte bzw. Daten umzuwandeln oder im weitesten Sinne etwas errechnen zu lassen. Beispiele wären: - die Entfernung zweier Positionen errechnen, - aus einer Anzahl bekannter Einheiten alle Anführer herauszufiltern, - den bekanntesten Feind herausfinden, -einer bestimmten Anzahl von Einheiten bestimmte Waffen zuweisen - Elemente eines Arrays suchen oder zufällig vertauschen und vieles mehr. Oftmals liefert eine Funktion einen Wert zurück an das Skript. Genauer gesagt wurden viele Funktionen gerade dazu geschrieben, einen Wert, den sogenannten Return, an ein Skript zurückzuliefern, was mit einem Skript nicht möglich ist. Funktionen sind im Gegensatz zu Skripten in den allermeisten Fällen Missions- oder Addonunabhängig verwendbar. Wenn sie mit den geeigneten Daten gefüttert werden, liefern sie unbestechlich und unbeirrbar ihr Ergebnis, während viele Skripte auf einen recht speziellen Kontext zugeschnitten sind. Funktionen bieten den Vorteil, dass man diese beim Missionsstart vorladen kann. Sie werden dann in der Engine gespeichert und sind bei Aufruf sofort verfügbar. Sie sind somit schneller verfügbar und werden mit höherer Priorität als ein Skript bearbeitet. Idealerweise lädt man seine Funktionen aus der Init.sqs oder Init.sqf heraus. Möchte man seine Funktion beim Missionsstart vorladen, versieht man sie zunächst mit einem Variablennamen, mit welchem man später die Funktion wieder aufrufen kann. Das System weiß dann: Variablenname = Ergebnis der vorgeladenen SQF Die Syntax zum Laden der Funktion lautet dann: SearchLight = compile preprocessFile "Searchlight.sqf"; 275 Kapitel 9 SearchLight ist die Variable die, wie oben erklärt, beim Aufruf der Funktion vergeben wurde. SearchLight steht jetzt für die Lösung bzw. dem gesamten Inhalt der Funktion. Oder anders... SearchLight ist jetzt die Funktion! Wichtig dabei ist, bei dem Variablennamen (z.B.: SearchLight) darauf zu achten, dass diese Variable keinem Befehl gleichen darf, der in ArmA verwendet wird. Zum Beispiel für eine Positions-Funktion. Position = compile preprocessFile "Position.sqf"; Dies würde jetzt eine Fehlermeldung zur Folge haben, da Position ein ArmA-Befehl ist. Deshalb unbedingt immer Variablennamen wählen, die keinen Befehlen gleichen! Möchte man seine Funktion später im Verlauf der Mission wieder aufrufen, verwendet man dazu grundsätzlich mit dem Call-Befehl! _variable = [Daten] call SearchLight Da diese Funktion vorgeladen bzw. präkompiliert wurde, stehen die Informationen sofort zur Verfügung und die Funktion muss von der Engine nicht mehr zeilenweise interpretiert werden, wie es bei einem Skript der Fall ist. Natürlich kann man manche Aufgabe einer Funktion auch im Skript selbst lösen, auch darin ist es möglich und üblich mit While-Do oder If-Then-Else zu arbeiten. Manchmal ist es aber einfach übersichtlicher, diese Aufgabe einer Funktion zu übergeben und somit gewissermaßen auszulagern. In diesem Fall ruft man die Funktion mit Call auf und kann in der nächsten Zeile des Skriptes schon mit dem Ergebnis der Funktion fortfahren. Wie bereits erwähnt, wurde die SQF-Syntax für ArmA großzügig erweitert und um viele Möglichkeiten reicher. Sie kann jetzt sogar für Skripte verwendet werden, die damit auch die Dateinamenerweiterung SQF bekommen. In den Skripten werden, wie auch sonst überall in ArmA, Code-Blöcke von geschweiften Klammern {} umschlossen und Statements mit einem Semikolon ; abgeschlossen. Natürlich kann man auch in Skripten mit SQF-Syntax Wartezeiten einbauen, dazu wird aber nicht wie bei SQS-Skripten die Tilde ~ benutzt, sondern der Befehl Sleep verwendet. Skripte, die die SQF-Syntax verwenden, müssen mit den Befehlen Spawn oder execVM aufgerufen werden. Wenn ein Skript mehrfach ausgeführt werden soll, empfiehlt es sich das Skript wie eine Funktion vorzuladen, damit es bereits im Speicher bereit liegt und so rascher ausgeführt werden kann. Skript vorladen: BeispielSkript = compile preprocessfile "BeispielSkript.sqf"; Skript aufrufen: [Daten] spawn BeispielSkript; 276 Für Skripte, die nur selten ausgeführt werden sollen, kann man den Befehl execVM verwenden, da hier das Skript nicht vorgeladen werden muss. [Daten] execVM "BeispielSkript.sqf"; Soll ein Skript aus dem Editor aufgerufen werden, ist es leider meistens nötig, den Skriptaufruf etwas zu verändern. Er sieht dann so ähnlich wie ein Funktionsaufruf aus, obwohl das Skript natürlich keinen Wert zurückgibt. Skript aus Editor aufrufen (vorkompiliert): Variable = [Daten] spawn BeispielSkript; oder (nicht vorkompiliert): Variable = [Daten] execVM "BeispielSkript.sqf"; Variable ist nur ein Platzhalter, der momentan lediglich Fehlermeldungen verhindert. Man kann die Variable als Dummy betrachten und auch so bezeichnen oder schlicht und einfach mit d abkürzen. d = [Daten] execVM "BeispielSkript.sqf"; Skripte mit der SQF-Syntax enden einfach, wenn der Interpreter an ihr Ende gelangt, der Exit-Befehl ist nicht nur unnötig, sondern auch ungeeignet, weil es ein SQS-Sytnaxbefehl ist. Sollte es einmal nötig sein, ein SQF-Skript vor dem Dateiende abzubrechen, dann benutzt man folgende Konstruktion: if (Abbruchbedingung) exitWith {}; Man kann in den geschweiften Klammern des exitWith-Befehls natürlich auch noch Code ausführen. Beispielweise: if (Abbruchbedingung) exitWith {Player sidechat "Ende!"}; Kapitel 9 277 Kapitel 10 - Dialoge und Ressourcen In diesem Kapitel werden dir einige grundlegende Bereiche zum Thema Dialoge näher gebracht. Ich habe mich hier wirklich auf ein paar wesentliche Bereiche beschränkt, da mein Wissen im Bereich Dialoge begrenzt ist. Dennoch werde ich dir hier aufzeigen, wie du es schaffst ein Bild, einen Text oder als Highlight sogar ein kleines Video in deine Mission einzubinden. Alle Themen sind selbstverständlich erweiterbar. Dies sind nur ein paar kleine Einleitungen, damit du schon mal ein Basiswissen bekommst, um später auch mal eine Grafik oder ähnliches einbinden zu können. Da Dialoge sehr viel Sorgfalt im Bezug auf Arbeit mit der Description.ext erfordern, muss man auch die notwendige Geduld, Ruhe und das nötige Grundwissen über die Description.ext mitbringen. Das Vergessen eines Semikolons oder einer Klammer führt selbst bei Profis regelmäßig zu CTD´s (Crash to Desktop). Deshalb nicht gleich das Handtuch werfen, sondern ruhig und strukturiert an die Sache herangehen. 10.1 10.2 10.3 10.4 10.5 10.6 10.7 10.8 10.9 10.10 10.11 278 Was sind eigentlich Dialoge Basisdefinitionen(Konstanten) Basisklassen und Subklassen Die Schriftarten Eine Grafik einblenden Einen Text einblenden Visieransichten einblenden Die eigene Lagekarte Einen Button definieren Einen Rahmen definieren Die Videosequenz 279 280 283 286 287 288 289 291 292 294 297 Dialoge sind Bilder, Texte oder Schaltflächen, die sich für eine Mission oder auch für Missionfeatures frei definieren lassen. Man kann so zum Beispiel Grafiken, Texte oder auch Visieransichten während der Mission oder einer Sequenz einblenden lassen. Richtig interessant wird es erst, wenn man Schaltflächen oder Dropdownmenüs definiert und diese etwas ausführen lässt. Als Beispiel dient hier der Editor, der ja fast nur aus Dialogen besteht. Alle Menüs, die sich öffnen lassen sind ebenfalls Dialoge. Ein ebenfalls sehr gutes Beispiel ist die Windowsoberfläche. All das läuft auf Dialogbasis. Folgend mal ein Dialog aus dem Editor zum Gruppen einfügen mit Dropdownmenü In Armed Assault wurden die Möglichkeiten gegenüber Operation Flashpoint um einiges erweitert. Dialoge können jetzt noch viel ansprechender gestaltet und definiert werden. Zum Beispiel mit Farbverläufen, Schatten oder als fliegende Schrift, wie bei den Credits von Armed Assault zu sehen ist. Dialoge sind aber, so schön wie sie sind, dennoch ein Kapitel für sich und teilweise sehr aufwendig umzusetzen. Dieses Kapitel beinhaltet lediglich eine Einführung und gewährt mit der themenabschließenden Videosequenz einen kleinen Blick über den Tellerrand, um zu zeigen, was in diesem Bereich so alles möglich ist. Das Anlegen von Dialogen erfordert eine sehr disziplinierte und sorgfältige Arbeitsweise, da man diese in der Description.ext definieren muss und einen CTD (Crash to Desktop) zur Folge hat, wenn man mal eben etwas übersieht zu definieren. Als bestens Beispiel dienen hier das Vergessen eines Semikolons oder eine falsche Klammersetzung. Auf dem folgenden Bild wurde die Schrift fliegend animiert. 279 Kapitel 10 10.1 - Was sind eigentlich Dialoge 10.2 - Basisdefinitionen (Konstanten) Um Dialoge zu erstellen oder Ressourcen zu nutzen, kommt man meistens nicht darum herum einige Basisdefinitionen vorzunehmen. Hier sind gerade die Defines gemeint, welche eigentlich schon tief in der Engine von Armed Assault verankert sind, aber dennoch auch für den eigenen Bedarf umdefiniert oder neu angelegt werden können. Für einige Bereiche ist es nicht notwendig alle Defines mit in die Description.ext aufzunehmen. Manchmal braucht man sogar gar keine, solange man mit den Basisdefinitionen zufrieden ist. Siehe dazu bei Grafik oder Schrift einblenden, dort wurden gar keine Defines angegeben. Möchte man aber ganz und gar sicher gehen, kann man auch gerne alle mit in die Description.ext aufnehmen und entgeht damit ganz sicher einem CTD (Crash to Desktop) oder einem anderen Fehler. Aber was sind denn jetzt eigentlich diese Defines? Defines sind Platzhalter. Für jedes Define sind von der Engine aus zunächst Werte hinterlegt. Solange diese Werte den eigenen Zweck erfüllen, gibt es keine Notwendigkeit eigene zu definieren. Möchte man aber zum Beispiel für seine Schrift oder was auch immer einen eigenen Define definieren, so ist das durchaus möglich. Als Beispiel mal folgendes. Es gibt ja die Werte True und False für welche man ja auch 1 für True oder 0 für False setzen kann. In der Engine von Armed Assault sollte es von daher folgende Definierung geben: #define false 0 #define true 1 Diese kann man zum Beispiel auch in der entpackten Missions.pbo unter Armory.intro und darin in der rscCommon.hpp sehen. Dort sind für die unterschiedlichsten Dinge die verschiedensten Werte definiert. Define heißt ja am Ende definieren. Man definiert also etwas nach seinen Ansprüchen. Dies könnten hierbei unter anderem Booleans Sounds Elemente Schriften Farben - Aussagewerte wie true oder false - Sounds für Buttons etc. - Rahmen, Flächen, Buttons, Listboxen uvm. - Die Schriftarten - Die Farben sein, oder vieles mehr. Man hat hierbei einen relativ großen Spielraum für eigene Definitionen, wobei es am Ende aber dann doch irgendwann Grenzen geben wird. Einfach gesehen könnte man es ein Wort für einen Wert vergeben bezeichnen, da man sich ein Wort am Ende besser als irgendwelche Zahlen merken kann. Als Beispiel soll hier mal die eigene Definierung von einer eigenen Schriftfarbe dienen. Farben wie scharz oder weiß, sind zahlentechnisch nicht so ganz so schwer zu merken. Hat man aber irgendwelche Zwischenwerte, um ein ganz bestimmtes rot, blau oder was auch immer 280 #define Color_White #define Color_Black {1, 1, 1, 1} {0, 0, 0, 1} Bei einer anderen Farbe sieht es da schon wieder anders aus. Etwa ein blau: #define Mein_Blau {0, 0, 0.7, 1} Exkurs Farben werden aus Werten gemischt. Hierbei gelten alle Werte zwischen 0 und 1. Der letzte Wert gibt dabei die Transparenz an. {rot, grün, blau, Transparenz} Ende des Exkurs! Define-Namen Wie bei dem obigen Define der Farbe blau zu erkennen, wurde dort ein eigener Definename (Mein_Blau) vergeben. Es ist also auch möglich eigene Namen zu vergeben. Generell bietet es sich an, die Standarddefines so zu belassen und zusätzlich eigene anzulegen und später zu vergeben. Damit geht man gegebenfalls einer Menge Ärger aus dem Weg. Folgend mal eine sehr kleine Auflistung einiger Standarddefines mit Namen und Wert: #define CT_STATIC #define CT_BUTTON #define CT_EDIT #define CT_SLIDER #define ST_TITLE_BAR #define ST_PICTURE 0 1 2 3 32 48 Diese Namen zu wählen wäre jetzt nicht besonders sinnvoll. Deshalb sollte man seine Namen so wählen, dass es ganz sicher keine Überschneidung gibt. #define Murray_Title #define Murray_Schrift #define Murray_Sound ST_TITLE_BAR + ST_CENTER "Zeppelin32" {"\ca\ui\data\sound\mouse2", 0.09, 1} Im oberen Beipiel wurde ein eigener Name vergeben und diesem die Werte von ST_Title_Bar und ST_Center zugewiesen, was so auch möglich ist. Hier ist aber jetzt Schluss zum Thema Defines! Man weiß nun, dass es möglich ist eigene Namen und Werte zu vergeben und auch, wie sich die Farben zusammensetzen. Auf der Folgeseite nur noch mal ein Ausschnitt von Standarddefines, welche in vielen der offiziellen Missionen etc. wiederzufinden sind. 281 Kapitel 10 haben zu wollen, ist es doch einfacher, sich diese selbst zu definieren. Die Werte der Farben schwarz und weiß sind also, wie hier zu sehen recht einfach: Standarddefines Folgend eine Auswahl von Standarddefines aus Armed Assault. Generell bietet es sich an, diese aus irgendeiner offiziellen Description.ext einer ArmA-Mission zu kopieren. Hat man sich ein Mal ein Muster, also Template, angelegt, so kann man es immer wieder verwenden. // Control Types // Static Styles #define CT_STATIC #define CT_BUTTON #define CT_EDIT #define CT_SLIDER #define CT_COMBO #define CT_LISTBOX #define CT_TOOLBOX #define CT_CHECKBOXES #define CT_PROGRESS #define CT_HTML #define CT_STATIC_SKEW #define CT_ACTIVETEXT #define CT_TREE #define CT_STRUCTURED_TEXT #define CT_CONTEXT_MENU #define CT_CONTROLS_GROUP #define CT_XKEYDESC #define CT_XBUTTON #define CT_XLISTBOX #define CT_XSLIDER #define CT_XCOMBO #define CT_ANIMATED_TEXTURE #define CT_OBJECT #define CT_OBJECT_ZOOM #define CT_OBJECT_CONTAINER #define CT_OBJECT_CONT_ANIM #define CT_LINEBREAK #define CT_USER #define CT_MAP #define CT_MAP_MAIN #define ST_POS #define ST_HPOS #define ST_VPOS #define ST_LEFT #define ST_RIGHT #define ST_CENTER #define ST_DOWN #define ST_UP #define ST_VCENTER #define ST_TYPE 0x0F 0x03 0x0C 0x00 0x01 0x02 0x04 0x08 0x0c 0xF0 #define ST_SINGLE #define ST_MULTI #define ST_TITLE_BAR #define ST_PICTURE #define ST_FRAME #define ST_BACKGROUND #define ST_GROUP_BOX #define ST_GROUP_BOX2 #define ST_HUD_BACKGROUND #define ST_TILE_PICTURE #define ST_WITH_RECT #define ST_LINE 0 16 32 48 64 80 96 112 128 144 160 176 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 40 41 42 43 44 45 80 81 82 83 98 99 100 101 #define FontM "Zeppelin32" //My Defines #define Murray_Title #define Murray_Font 32 + 64 "TahomaB" Die obigen beiden Fenster stellen eigentlich ein Fenster dar und die Defines sollten daher untereinander stehen, was hier aus Platzgründen leider nicht möglich ist. Deshalb die Aufteilung in zwei Tabellen. Zunächst sind die Control Types und danach die Static Styles nacheinander aufgelistet, wobei die Reihenfolge dabei aber keine Rolle spielt. Wie man erkennen kann ist hierbei eine gewisse Ordnung gegeben. Zum Ende wurde mit FontM eine Schriftart definiert. Eigens angelegte Defines setzt man nun einfach mit unten an, dann sieht man mal abgesehen vom eigenen Definenamen gleich, dass ab dort die Eigenen kommen. 282 Zum Anlegen von Dialogen oder zum Nutzen von Ressourcen benötigt man Basis- und Subklassen. In einer Basisklasse definiert man erstmal grundlegende Dinge und in der Subklasse dann das Klassenspezifische. Als Parallelbeispiel dienen hier mal die normalen Soundklassen, welche man ja auch in der Description.ext definiert. class CfgSounds { sounds[] = { Sound1 }; class Sound1 { name = "Sound1"; sound[] = {"\sounds\sound1.ogg", db+0, 1.0}; titles[] = {}; }; }; Auch hier gibt es die Basis- und die Subklasse. Die Basisklasse CfgSounds legt erstmal fest, dass es sich um einen Sound handelt, während die Subklasse, hier Sound1, die jeweiligen Definitionen zu Sound1 beinhaltet. Genau so sieht es auch bei den Klassen aus, die für Dialoge bzw. Ressourcen benötigt werden. Allerdings gibt es hier weit mehr Definitionsmöglichkeiten, als bei den Sounds. Basisklasse Folgend mal eine Basisklasse, in welcher grundlegende Dinge wie Typ, Style, Hintergrund, Textfarbe, Schriftart und Schriftgröße definiert sind. Diese Basisklasse RscText kann man jetzt grundsätzlich als Basis für alle folgenden Subklassen verwenden. class RscText { type = CT_STATIC; idc = -1; style = ST_CENTER; colorBackground[] = {0, 0, 0, 0}; colorText[] = {0, 0, 0, 0}; font = "TahomaB"; sizeEx = 0.080; }; // Hintergrundfarbe // Textfarbe // Schriftart // Schriftgröße Nachdem man nun eine Basis geschaffen hat, kann man die Subklassen zusätzlich noch individuell anpassen. Als Beispiel könnte man in der Subklasse Schrift1 eine größere und andersfarbige Schrift, als bei der Subklasse Schrift2 oder eben eine andere Position auf dem Monitor definieren. 283 Kapitel 10 10.3 - Basisklassen und Subklassen Subklasse Die Subklasse ansich teilt sich nun auch nochmal auf. Sie hat in dem Sinne auch nochmal eine Subklasse. Diese nennen wir hier jetzt lieber mal Komponente, um Verwechselungen zu vermeiden. In folgendem Beispiel mal eine Gliederung: // Mainklasse class RscText { }; // Subklasse class RscTitles { [Auflistung der Ressourcen] class MeineRessource { [Auflistung der Komponenten] class MeineKomponente { }; }; }; Man achte hierbei auf die Anordnung der geschwungenen Klammern, welche eine gewisse Übersichtlichkeit mitbringen. Man kann so genau erkennen, was zu wem gehört. In folgendem Beispiel aus Kapitel 10.6 in welchem es darum geht eine Schriftressource zu definieren. Hier sieht man die zunächst festgelegt Basisklasse RscText und die darunterliegende Subklasse Schrift1. Description.ext // Basisklasse class RscText { type = CT_STATIC; idc = -1; style = ST_CENTER; h = 0.05; colorBackground[] = {0, 0, 0, 1}; colorText[] = {0, 0, 0, 1}; font = "TahomaB"; sizeEx = 0.040; }; // Weiter auf der Folgeseite! 284 // Hintergrundfarbe // Textfarbe // Schriftart // Schriftgröße Kapitel 10 // Subklasse class RscTitles{Titles[]={"Schrift1"}; // Liste der Ressourcen: “Schrift1, Schrift2,. . .” class Schrift1 { Idd= -1; MovingEnable=False; Duration=10; // Einblenddauer FadeIn=1; // Einblendzeit Name=" Schrift1"; // Name Controls[]={"SchriftButton1"}; // Liste class SchriftButton1 : RscText { ColorText[]={1,1,1,1}; Font="Bitstream"; Text="OPERATION SNAKEBITE"; x = 0.30; y = 0.50; w = 0.50; h = 0.05; }; // Schriftfarbe // Schriftart // Text // X-Achse // Y-Achse // Fensterbreite // Fensterhöhe }; Wie man in der Basisklasse RscText erkennen kann, wurde als Schriftfarbe {0, 0, 0, 1}, also schwarz, definiert. Aber wie auf dem unteren Bild zu sehen ist, ist die Farbe der Schrift weiß. Das liegt daran, dass in der Subklasse SchriftButton1 für Schrift1 die Farbe Weiß {1, 1, 1, 1} definiert wurde. Wie man des Weiteren erkennen kann wurden in der Subklasse zusätzlich noch viel mehr Dinge definiert. Eine ganz wichtige Zeile ist die class SchriftButton1 : RscText Daran erkennt man, dass der Klasse SchriftButton1 die Definitionen von RscText zugewiesen werden. Also alles was in der Basisklasse RscText vordefiniert wurde, wird hier übernommen und könnte in dieser Subklasse ohne weiteres weggelassen werden. Im obigen Beispiel wurde jedoch für SchriftButton1 die Schriftfarbe und Schriftart neu definiert. Deshalb sind diese Zeilen dort mit angegeben. Diese Einblendung wird nun wie folgt aufgerufen: TitleRsc ["Schrift1", "PLAIN"]; 285 10.4 - Die Schriftarten In Armed Assault sind diverse Schriftarten vordefiniert, welche man, je nachdem was man machen möchte, auswählen kann. Man hat die Möglichkeit bei den Defines oder in der jeweiligen Klasse bzw. Subklasse eine dieser Schriftarten zu definieren. Hier eine kleine Auswahl der vorhandenen Schriftarten: Arial Bold Bitstream TahomaB Zeppelin33 Zeppelin33Italic Zeppelin32 Folgend mal zwei Bildbeispiele: TahomaB Zeppelin33Italic Bei folgendem Description.ext-Beispiel wird der Ressource RscText die Schriftart Bitstream mit einer Größe von 0.04 zugewiesen. class RscText { idc = -1; type = CT_STATIC; style = ST_LEFT; colorText[] = {1, 1, 1, 1}; colorBackground[] = {0, 0, 0, 0}; font = Bitstream; sizeEx = 0.04; }; 286 Um eine einfache Grafik einzublenden ist die Definierung von Defines in der Description.ext nicht unbedingt notwendig und kann ohne weiteres weggelassen werden. Für die Grafik muss allerdings eine Klasse in der Description.ext angelegt werden, damit diese auch benutzt werden kann. Als Beispiel könnte hier mal die kurze Einblendung einer Grafik beim Beginn einer Mission oder ähnliches dienen. Dafür wird lediglich eine einfache Klasse für das Bild in der Description.ext definiert. Im unteren Beispiel ist alles definiert, was dazu benötigt wird. Der Aufruf erfolgt hierbei mit: titleRsc ["Bild1","PLAIN"]; Description.ext class RscPicture { idc = -1; type = CT_STATIC; style = ST_PICTURE; colorBackground[] = {0, 0, 0, 0}; colorText[] = {1, 1, 1, 1}; font = Zeppelin32; sizeEx = 0; }; class RscTitles { titles[] ={Bild1}; class Bild1 { idd=-1; movingEnable = true; duration=10; fadein=2; name = "Bild1"; controls[]={Picture}; class Picture : RscPicture { x = 0.30; y = 0.50; w = 0.40; h = 0.05; text = "bilder\bild1.paa"; sizeEx = 0.04; style=48; }; }; // Dauer der Einblendung // Einfadezeit // Name im Editor // X-Achse // Y-Achse // Fensterbreite // Fensterhöhe // Die Grafik mit Pfad }; 287 Kapitel 10 10.5 - Eine Grafik einblenden 10.6 - Einen Text einblenden Das Definieren eines eigenen Textes kann unter anderem schon etwas aufwendiger sein, als das Einblenden einer Grafik. Hierfür definiert man zusätzlich Dinge wie Schriftart, Größe, Farbe, Style und die Position, um mal die Wichtigsten zu nennen. Zunächst definiert man die Basisklasse, in welcher man die Basics festlegt. Danach folgt für jede Texteinblendung bzw. Satz oder wie auch immer eine eigene Subklasse, die man individuell definieren kann. Bei der ersten Subklasse (Schrift1) könnte quasi eine Überschrift mit größerer und farbiger Schrift definiert sein und in der zweiten Subklasse (Schrift2) eine kleinere Schrift in weißer Farbe. Die Einblendung erfolgt wieder mit: titleRsc ["Schrift1","Plain"] Description.ext class RscText { type = 0; idc = -1; style = 0; h = 0.05; colorBackground[] = {0, 0, 0, 0}; colorText[] = {0, 0, 0, 0}; font = TahomaB; sizeEx = 0.080; }; // Hintergrundfarbe // Textfarbe // Schriftart // Schriftgröße class RscTitles{Titles[]={"Schrift1"}; class Schrift1 { Idd=-1; MovingEnable=0; Duration=10; FadeIn=1; Name=" Schrift1"; Controls[]={"Control01"}; class Control01: RscText { ColorText[]={1,1,1,1}; Font="TahomaB"; Size=0; Text="OPERATION SNAKEBITE"; x = 0.30; y = 0.50; w = 0.40; h = 0.1; }; }; 288 // Einblenddauer // Einblendzeit // Name // Schriftfarbe // Schriftart // Text // X-Achse // Y-Achse // Fensterbreite // Fensterhöhe Die normalen Visieransichten der Waffen lassen sich auch für Sequenzen wie Intros, Outros und so weiter verwenden. Das Fernglas lässt sich dabei am unkompliziertesten einblenden. Dazu benötigt man lediglich die folgende Syntax: cutRsc ["Binocular", "PLAIN",0.1] oder titleRsc ["Binocular", "PLAIN",0.1] Alle Anderen muss man zunächst in der Decription.ext definieren. Nach der Definition hat man die Möglichkeit diese Ressource per Auslöser unter Effekte und dort unter Typ und Ressource auswählen oder idealerweise per Skript aufrufen. Folgend eine kleine Auswahl der Visieransichten mit dem jeweiligen Quellenpfad, wobei zu beachten gilt, dass einige Waffen das gleiche Visier nutzen. Von daher wurden hier nicht alle Waffen einzeln aufgeführt, sondern lediglich eine kleine Auswahl. Visiertypen Waffe Quellpfad G36 \ca\Weapons\G36_optics M4SPR M4 \ca\weapons\optika_sniperw \ca\Weapons\optika_ACOG M4GL \ca\Weapons\optika_ACOG SVD \ca\weapons\optika_snpiere Javeline \ca\Weapons\optika_TOW Binocular \ca\weapons\optika_dalekohled Laserdesignator \ca\weapons\optika_SOFLAM NVGoggles \ca\weapons\optika_night M119 \ca\weapons\optika_M119 Stryker Ka50 \ca\Wheeled\optika_stryker_driver \ca\Tracked\optika_stryker_gunner \ca\wheeled\optika_BRDM \ca\air\optika_heli_gunner \ca\air\optika_AH1Z \ca\air\optika_Ka50_rocket.p3d Tankdriver \ca\Tracked\optika_tank_driver Tankgunner \ca\Tracked\optika_tank_gunner M1A1 \ca\Tracked\optika_M1A1_commander ZSU Gunner \ca\Tracked\optika_zsu_gunner ZSUCommander \ca\Tracked\optika_tanke_auxiliary T72Gunner \ca\Tracked\optika_T72_gunner BRDM AH1ZGunner 289 Kapitel 10 10.7 - Visieransichten einblenden Description.ext #define CT_OBJECT 80 class RscObject { type = CT_OBJECT; scale = 1.0; direction[] = {0, 0, 1}; up[] = {0, 1, 0}; }; class RscTitles { titles[] = {SNIPER}; class SNIPER { idd=-1; movingEnable = false; duration=10; name = "SNIPER"; objects[]= {SNIPER}; class SNIPER : RscObject { model= "\ca\weapons\optika_SOFLAM"; idc=-1; position[] = {0,0,0.065}; direction[] = {sin 0, sin 0, cos 180}; up[] = {0, 1, 0}; }; }; Die hier festgelegte Ressource SNIPER wird nun wie folgt aufgerufen. titleRsc ["SNIPER","Plain"] Möchte man diese Ressource später wieder ausblenden geht das, je nach Auswahl, mit: titleRsc ["default","plain",2] oder cutRsc ["default","plain",2] 290 Die Möglichkeit ein Bild einzufügen eröffnet jetzt natürlich diverse neue Möglichkeiten. Statt einem Logo könnte man nun eine eigene Lagekarte bzw. geheime Pläne, ein Fahndungsfoto oder noch viel mehr realisieren. Als Beispiel dient hier mal eine Lagekarte. Wie man diese aufruft soll hierbei mal jedem selbst überlassen bleiben. Funk, Actionmenü oder wie auch immer. Auf jeden Fall sollte die Aufrufsyntax enthalten sein: titleRsc ["Lagekarte","PLAIN"]; Description.ext class RscPicture { type = CT_STATIC; idc = -1; style = ST_PICTURE; colorBackground[] = {0, 0, 0, 0}; colorText[] = {1, 1, 1, 1}; font = Zeppelin32; //Schriftart sizeEx = 0; }; class RscTitles{titles[] ={Lagekarte}; class Lagekarte { idd=-1; movingEnable = true; duration=10; // Dauer der Einblendung fadein=2; // Einfadezeit name = "Lagekarte"; // Name im Editor controls[]={Picture}; class Picture : RscPicture { x = 0.10; // X-Achse y = 0.40; // Y-Achse w = 0.80; // Fensterbreite h = 0.05; // Fensterhöhe text = "bilder\lagekarte.jpg"; // Die Grafik mit Pfad sizeEx = 0.04; style=48; }; }; Wie man erkennen kann, gleicht diese Description.ext genau dem Beispiel aus Kapitel 10.5, nur dass eben einige Werte verändert wurden. 291 Kapitel 10 10.8 - Die eigene Lagekarte 10.9 - Einen Button definieren Einen Button zu definieren ist schon etwas komplexer als das Einfügen eines einfachen Bildes oder Textes. Hierbei müssen auf jeden Fall die Defines verwendet werden und sogar noch einiges mehr, wie man gleich bemerken wird. Man hat hierbei unzählige Möglichkeiten, wobei sich aber dieses Beispiel nur auf ein paar Basics bzw. einen einfachen Standartbutton beschränken wird. Description.ext #define CT_BUTTON #define Color_White #define Color_Black #define Color_Grey #define FontHTML 1 {1, 1, 1, 1} {0, 0, 0, 1} {0.5, 0.5, 0.5, 1} "BitStream" class RscButton { type = CT_BUTTON; style = ST_CENTER; // Text Definitionen font = FontHTML; colorText[] = Color_White; colorDisabled[] = Color_Black; // Hintergrund-Einstellungen colorBackground[] = Color_Black; colorBackgroundDisabled[] = Color_Black; colorBackgroundActive[] = Color_Grey; offsetX = 0.001; offsetY = 0.002; offsetPressedX = 0.003; offsetPressedY = -0.003; colorFocused[] = Color_Black; // Schatten Einstellungen colorShadow[] = Color_Black; // Rahmen-Einstellungen colorBorder[] = Color_White; borderSize = 0.02; // Sounds soundEnter[] = {"\ca\ui\sound\pageopen", 0.1, 1}; soundPush[] = {"\ca\ui\sound\pageclose", 0.1, 1}; soundClick[] = {"\ca\ui\sound\offbutton", 0.1, 1}; soundEscape[] = {"\ca\ui\sound\offbutton", 0.1, 1}; }; Weiter auf der nächsten Seite. Im ersten Teil der Description.ext wurden zunächst die Rahmendaten für den Button definiert. Im zweiten Teil nun der Button selbst. 292 Kapitel 10 class DemoButton { idd = 100; movingEnable = false; controls[] = { MEIN_BUTTON }; class MEIN_BUTTON : RscButton { idc = 100; sizeEx = 0.018; text = "Klick Mich"; // Position x = 0.4; y = 0.4; // Größe w = 0.15; h = 0.04; // Action action = "ctrlSetText [100, ""Danke""]; hint ""TEST"" "; }; }; Hier wurde nun der Button selbst definiert. Er bekommt dabei die Rahmendaten von dem im ersten Description.ext-Teil vordefinierten RscButton zugewiesen. Dieser Button lässt sich nun mit folgender Syntax ganz einfach aufrufen: ok = createDialog "DemoButton" Diese Syntax kann überall ganz frei eingesetzt werden, um den Button aufzurufen. Zum einfachen Testen eignet sich ein Funkauslöser recht gut. Die Actionzeile könnte auch ganz anders aussehen. Hier sollte nur mal gezeigt werden, dass sich der Text eines Buttons beim anklicken auch ändern kann. Ansonsten gibt man darin die Befehle an, die beim anklicken ausgeführt werden sollen. Die Actionzeile könnte beispielsweise auch so aussehen: action = "closeDialog 0; [] exec ""script.sqs"" "; Wie man sieht, lässt sich die Actionzeile recht frei definieren. Man kann hier ganz normal wie bei allen anderen Dingen etwas ausführen lassen oder ähnliches. Wichtig ist dabei die Beachtung der Zeichen wie Klammern, Anführungsstriche etc. Der Befehl closeDialog 0 schließt den Dialog letztendlich. Diesen Butten kann man jetzt noch mit einem Rahmen verzieren oder vieles mehr. Dies sollte lediglich ein schlichtes Beispiel sein, um zu zeigen, wie man einen Button erstellt. 293 10.10 - Einen Rahmen definieren In folgendem Beispiel wird ein ganz normaler Rahmen definiert. Als kleine Besonderheit, hat dieser Rahmen noch einen kleinen Text mit integriert. Zunächst werden im Kopf wieder die Defines festgelegt, welche man dann im restlichen Verlauf zuordnet. Description.ext #define CT_STATIC #define Color_White #define Color_Black #define FontHTML #define ST_FRAME 0 {1, 1, 1, 1} {0, 0, 0, 1} "BitStream" 64 class RscText { Idc = -1; Type = CT_Static; Font = FontHTML; ColorBackground = Color_White; }; class My_Frame : RscText { Style = ST_FRAME; x = 0.22; y = 0.12; w = 0.40; h = 0.20; }; class RscTitles {Titles [] = {"Rahmen1"}; class Rahmen1 { Idd= -1; MovingEnable=False; Duration=10; FadeIn=1; Name="Rahmen1"; // Einblenddauer // Einblendzeit // Name Controls[]={"SchriftRahmen1"}; // Liste class SchriftRahmen1 : MY_Frame { ColorText[]= Color_Black; Text="OPERATION SNAKEBITE"; SizeEx = 0.030; }; }; 294 //Schriftfarbe // Text titleRsc ["Rahmen1", "PLAIN"]; 10.11 - Die Videosequenz Das abschließende Highlight zu diesem Dialogkapitel soll nun die Erstellung einer eigenen Videosequenz darstellen. Eine solche Sequenz wird mit einer Reihe von einzelnen Frames, also vielen einzelnen Bildern und einem kleinen Skript umgesetzt. Natürlich muss, wie bei allen anderen Dialogen auch, erstmal die Description.ext dafür ausgelegt werden. Description.ext class RscPicture { Idc = -1; Type = 0; Style = 48; ColorBackground[] = {0, 0, 0, 0}; ColorText[] = {1, 1, 1, 1}; Font = BitStream; SizeEx = 0; }; class Videodialog { Idd = -1; MovingEnable = true; Controls[] = {Picture_1}; class Picture_1 : RscPicture { idc = 200; x = 0.0; y = 0.0; w = 1.0; h = 1.0; text = "video\frame1.jpg"; size = 0; }; // Die ID // Größe und Position // Dateipfad }; 295 Kapitel 10 Im Spiel sieht das Ganz dann wie folgt aus, wobei man den Rahmen wie folgt aufruft: Nachdem die Description.ext definiert wurde, wird noch ein Skript benötigt, mit welchem die Sequenz aufgerufen und gesteuert wird. Das Skript schaut dabei wie folgt aus: Video.sqs: playMusic "ATrack8" TitleCut [" ", "BLACK IN"]; titleFadeOut 4 _video = createdialog "Videodialog" _x = 1 _delay = 1/24 #Loop ctrlSetText [200, format ["video\frame%1.jpg", _x]] ~ _delay _x = _x + 1 ? _x < 150 : goto "Loop" closedialog 0 TitleCut [" ", "BLACK IN"]; titleFadeOut 4 exit; Wie man erkennen kann, wurden hier gleich einige Effekte mit eingebracht. Die Sequenz blendet Dank dem Titelcut erstmal langsam ein. Dazu wird gleich Musik abgespielt. Etwa gleichzeitig wird der Videodialog erstellt und die Bilder laufen ab. Dazu jetzt aber noch ein paar kurze Erläuterungen. _x - Wird für den eingebauten Zähler verwendet. Solange der Wert kleiner als 150 ist, wird der Loop wiederholt. 150 ist die Anzahl der Bilder, welche im Ordner Video liegen. Dies können natürlich noch weit mehr sein. _delay - Hiemit legt man die Abspielgeschwindigkeit der Bilder fest. Ändert man den Wert zum Beispiel auf 1/12, laufen die Bilder langsamer ab und es entsteht der Zeitlupeneffekt. 1/48 lässt die Bilder noch schneller ablaufen. video\frame%1.jpg - Im Ordner Video sind die einzelnen Bilder hinterlegt, welche als frame1, frame2, ... durchbenannt sind. In diesem Beispiel wurden 150 Bilder verwendet. Möchte man also noch mehr Bilder verwenden, muss man den Wert im Skript einfach anpassen. 296 Dies können, je nach Länge oder eigenem Vorhaben schon eine ganze Menge Bilder werden. Bei dem Beispielskript wurden ganze 150 Bilder verwendet, wobei die Sequenz aber am Ende nur ein paar Sekunden lang ist. Deshalb sollte man sich überlegen, in welcher Form man ein solches Feature anwendet. Es besteht ja auch die Möglichkeit die Bilder zu verkleinern und so anzupassen, dass sie nur einen kleinen Teil des Bildschirms belegen. So eine Art kleines Infovideo, Action Hud oder was auch immer. Möchte man das Video aber über die ganze Bildfläche legen, sollte man die Bilder entsprechend groß speichern. Zum Beispiel 512x512 Pixel. Dabei sollte man aber auch nicht zu große Dateien verwendet. Was die Dateigröße angeht. Da die Mission am Ende vom Gesamtumfang zu groß werden könnte. Ordner Es bietet sich für die einzelnen Bilder an einen extra Ordner anzulegen. Denn diese im Rootverzeichnis der Mission abzulegen wäre etwas unprofessionell. In diesem Beispiel wurde der Ordner Video benannt. Daraus ergibt sich dann der Pfand: video\frame%1.jpg Folgend auch nochmal ein Screen, welcher die nahezu gleichnamigen, aber gleichmäßig durchnummerieren Bilder enthält. Die Engine ersetzt den Wert %1 dann, dank der richtigen Syntax, mit der nächst höheren Zahl. Im Skript schaut diese Syntax wie folgt aus (siehe auch links im Skript): ctrlSetText [200, format ["video\frame%1.jpg", _x]] Im Kapitel 5.66 sind diesbezüglich einige sich selbst erklärende Syntaxarten in speziell dieser Form. Damit sollte sich dieses Verfahren auch von selbst erklären. Jetzt bleibt nur noch... Film ab! 297 Kapitel 10 Die Bilder bzw. Frames Nachdem nun das Gerüst steht, fehlt nur noch der eigentliche Inhalt. Wie schon erwähnt werden dafür einzelne Bilder benötigt. Die länge der Sequenz bestimmt sich also aus der Anzahl der Bilder, die dafür verwendet werden. Dafür gibt es spezielle Freewareprogramme, welche es einem ermöglichen, aus einem Video die einzelnen Bilder zu exportieren. Aus rechtlichen Gründen werde ich diese hier jetzt nicht nennen. Kapitel 11 - Allgemeines In diesem nun letzten Kapitel werden dir noch einige allgemeine Bereiche aus dem Spiel erläutert. Zum Beispiel das Anlegen oder die Verwendung von MOD-Ordnern, die Verwendung von Addons in deiner Mission oder was du beachten solltest, wenn du deine Mission veröffentlichen möchtest. Zum Schluss dann noch das Natoalphabet, welches du als Arma-Soldat auf jeden Fall beherrschen solltest. 11.1 11.2 11.3 11.4 11.5 11.6 11.7 11.8 11.9 11.10 11.11 298 Eigenes Profil Die ArmA Cheats Der MOD-Ordner Die Verwendung von Addons Der Missionsrelease Die ArmA.rpt Das Natoalphabet Die Dienstgradabzeichen Die Squad.xml Die Startparameter Tastenkombinationen, Tipps und Tricks 299 301 302 303 304 305 306 307 308 311 313 11.1 - Eigenes Profil Das eigene Profil, sämtliche gespeicherte Spielstände und die eigenen Editormissionen sind ja von Haus aus unter zu finden. Natürlich ist dies nicht weiter schlimm, aber wenn man sehr viele Missionen editiert und der Ordner immer größer wird, ist die Systemfestplatte C:\ irgendwann voll. Man sollte seine Systemfestplatte, im Normalfall C:\, generell nur für sein System und die Programme nutzen. Alle weiteren Daten sollten auf einer anderen Festplatte oder Partition gespeichert bzw. hinterlegt werden. Armed Assault legt von Haus aber den Ordner nun unter Eigene Dateien an, was nicht sehr sinnvoll ist. Müsste man nun sein Windows aus Virengründen oder was auch immer neu installieren, wären alle Daten weg. Gerade bei selbsteditierten Missionen, in welche man eine Menge Zeit investiert hat, ist das sehr ärgerlich. Zudem läuft Windows mit der Zeit immer schlechter, wenn man dauernd irgendwelche Daten auf der C-Festplatte hin und her kopiert. Hat man sein Armed Assault nun also auf einer anderen Festplatte bzw. Partition installiert, hat man auch die Möglichkeit sein Profil im Armed Assault Verzeichnis anzulegen. Dazu muss man zunächst eine Verknüpfung zur Arma.exe erstellen. Dann klickt man per Rechtsklick darauf und wählt Eigenschaften. Danach ändert man einfach nur noch den vorhandenen Pfad in: D:\ArmA\arma.exe -profiles=D:\ArmA\ -name=Username Natürlich muss man den Pfad entsprechend anpassen. Je nachdem, wo ArmA halt installiert ist. Zusätzlich könnte man noch folgende Parameter mit angeben: -window -nosplash - hat zur Folge das ArmA im Fenstermodus läuft - startet ArmA ohne Vorabscreens (Schnellstart) In einer Zeile würde das dann etwa so aussehen: C:\ArmA\arma.exe -nosplash -window -profiles=D:\ArmA\ -name=Username Mit der obigen Zeile würde also das Profil im ArmA-Ordner angesprochen und das Spiel im Fenstermodus(Window) und ohne Vorabscreens gestartet. Tipp: Möchte gerade man nur editieren, lohnt es sich ArmA im Fenstermodus laufen zu lassen, da man so viel schneller zwischen Skripten und Spiel switchen kann. 299 Kapitel 11 C:\EigeneDateien\ArmA\Benutzer\Missions Username.ArmAProfile Im Profilordner findet sich eine Datei namens Username.ArmAProfile, in welcher alle Konfigurationen des Users gespeichert bzw. hinterlegt sind. Hierzu gehören unter anderem, nur um mal die wichtigsten zu nennen: - Grafikeinstellungen(Helligkeit,Gamma,Schatten,Shading,etc.) - Soundeinstellungen - Tastenkonfiguration - Mauseinstellungen - zuletzt gespielte SP-Mission - zuletzt gespielte MP-Mission - zuletzt gespielte Kampagnen-Mission - ausgewählte Kampagne - Multiplayereinstellungen (Filter, etc.) - Schwierigkeitsgrad - benutzerdefinierter Schwierigkeitsgrad - eigene Indetität (wie etwa in Description.ext) - aktive Missionskeys - aktive Vehikelkeys (Waffenkammer) - Blut (ein/aus) Diese Datei kann man ganz normal mit dem Texteditor öffnen. Man hat somit also auch die Möglichkeit, die Einstellungen direkt darin vorzunehmen. ArmA.cfg Eine weitere wichtige Datei im Profilordner ist die ArmA.cfg. In dieser finden sich direkte Systemeinstellungen zum Spiel. Also Dinge wie Grafikauflösung, RAM usw. winX=0; winY=5; winW=1024; winH=746; winDefW=1028; winDefH=746; FSAA=2; HDRPrecision=8; lastDeviceId="4318,661,107156578"; localVRAM=527429632; nonlocalVRAM=260046847; 300 - Bildposition X-Achse - Bildposition Y-Achse - Auflösung X-Achse - Auflösung Y-Achse - relative Auflösung X-Achse - relative Auflösung Y-Achse - AntiAliasing - HDR - Gesamtschlüssel der Informationen - Grafikkartenspeicher - Vom MB zugewiesener Shaderspeicher 11.2 - Die ArmA-Cheats Alle nun folgend erklärten Cheats erfordern folgende Vorgehensweise. Dazu hält man die linke Shift-Taste gedrückt und klickt kurz die Minus-Taste (-) auf dem Nummernblock. Dann den angegebenen Code mit gedrückter Shif-Taste eingeben. War dies erfolgreich, erscheint oben links am Bildschirmrand eine kurze Einblendung des zuvor eingegebenen Codes als Bestätigung. Wichtig zu wissen ist, dass für die Eingabe des Codes keine Eingabezeile erscheint. Man gibt diesen also blind ein und bekommt dann eben die Bestätigung durch die Einblendung. CAMPAIGN - Schaltet die Kampagne komplett frei, ohne dass man diese durchspielen muss. Dazu muss man zunächst auf die Kampagnen übersicht wechseln und gibt dann den Code ein. MISSIONS - Schaltet die Missionen komplett frei, ohne dass man zunächst eine andere gespielt haben muss, damit die nächste freigeschaltet wird. Dazu wechselt zunächst in die Missionsübersicht und gibt dann den Code ein. ENDMISSION - Gibt man diesen Code während einer Mission an, wird diese beendet. SAVEGAME - Speichert den aktuellen Spielstand beim Spielen einer SP-Mission. TOPOGRAPHY - Generiert eine Map im EMF-Vektor-Format und hinterlegt diese im Verzeichnis C:\. Die Datei wird generiert, wenn man nach der Eingabe das nächste Mal auf die Map wechselt. Vorsicht bei verstellter Tastatur! Dann wird das als Z gesehen. Dazu dann TOPOGRAPHZ eingeben. FLUSH - Löscht unnötige Dateien, Texturen und Objekte aus RAM-Speicher Einzelspielermissionen freischalten Die Einzelspielermissionen lassen sich auch auf andere Art und Weise freischalten. Dies erfordert die Editierung des eigenen ArmA-Profiles. Dazu wechselt man zunächst in den eigenen Profilordner, öffnet anschließend die Datei Username.ArmAProfile mit dem Texteditor und trägt dort die noch nicht vorhandenen aktive Keys mit ein. Das Ganze muss am Ende dann etwa so aussehen: activeKeys[]= { "M00", "M01", "M02", "M03", "M04", "M05", "M06", "M07", "M08", "M09", "M10", "TT01", "TT02", "TT03", "TT04", "TT05", "TT06" }; Nach dem Speichern der Änderung, wird diese sofort wirksam und bleibt bestehen. 301 Kapitel 11 Die nun folgend aufgeführten Cheats für Armed Assault sind in dem Sinne eigentlich gar keine Cheats. Zumindest verschaffen sie dem Spieler beim Spielen, mal abgesehen von dem Cheat Savegame, nicht unbedingt einen Vorteil. Dennoch sind sie in gewisser Hinsicht nette Features, welche ab und dann von Nutzen sein können. 11.3 -Der MOD-Ordner Die Verwendung von MOD-Ordnern gewährleistet eine bessere Übersicht bei der Benutzung von MOD´s und Addons. Zudem hat man dann die Wahl, welche Addons man mitladen möchte und welche nicht. Viele Addons aus der Community beinhalten fehlerhafte Configs, welche sich dann mit in die Mission.sqm eintragen, ohne dass man das Addon überhaupt darin verwendet hat. Hinzu kommt, dass sich die Ladzeit des Spiels unnötig in die Länge zieht, wenn man jedes Mal alle Addons mitladen muss, obwohl man sie gerade nicht benötigt. Deshalb verwendet der schlaue Arma-Spieler MOD-Ordner! MOD-Ordner kann man unterschiedlich benutzen. Hier mal eine Anregung: Missionsbezogen Themenbezogen MOD-bezogen @MeineMission @IIWeltkrieg @ECP-MOD Die Namen der Ordner sind dabei variabel benennbar. Außer bei MOD´s, die ja vorgegeben sind, kann man jeden Namen frei vergeben. Bei den oberen Anregungen ist zum Beispiel ein Ordner Namens @MeineMission. In diesen kommen nun alle Addons, die man in seiner Mission verwendet hat. Der Vorteil ist nun, dass man diesen jetzt mit zum Download anbieten kann, damit sich die Spieler der Mission nicht erst alle Addons mühevoll zusammensuchen müssen. Der Spieler hat jetzt beim Spielstart die Wahl, ob er die Addons mitlädt oder nicht. Möchte er die Mission gerade nicht spielen, braucht er auch die Addons nicht zu laden und spart somit Zeit und Performance. Das Anlegen eines MOD-Ordners Einen MOD-Ordner legt man direkt im Spielverzeichnis von ArmA an und gibt ihm einen passenden Namen. Jetzt öffnet man seinen MOD-Ordner und erstellt darin einen Ordner namens Addons. In diesen Unterordner kommen nun alle Addons, die man für seine Mission, oder was auch immer, benötigt. 302 Das Laden eines MOD-Ordners Möchte man einen MOD-Ordner laden, kann man dies durch das Hinzufügen eines Parameters in einer eigens dafür erstellten Verknüpfung zur ArmA.exe realisieren oder man nutzt einen ArmA-Launcher, welchen es im Internet zum Download gibt. Zweiteres ist natürlich die elegantere Lösung. Hier jedoch der Parameter, mit welchem man die Verknüpfung ergänzt. Um diesen nun in die Verknüpfung mit einzufügen klickt man mit der rechten Maustaste auf die Verknüpfung und passt diese entsprechend an: D:\ArmA\arma.exe -mod=@MAPFACT Diese Verknüpfung könnte man jetzt ArmA-Mapfact oder ähnlich benennen. 11.4 - Die Verwendung von Addons Addons sind eine nette Sache, erweitern ArmA ungemein und gestalten es auf lange Sicht gesehen wesentlich interessanter. Ganz klar, dass diese natürlich auch in einer Mission nicht fehlen sollten. Doch dabei gibt es einiges zu beachten, was nun hier erläutert wird. Möchte man Addons in seiner Mission verwenden, sollte man darauf achten, dass diese nicht zu performanceunfreundlich sind. Viele Addonbastler vergessen gerade die Performance nur zu gerne. Es werden oft Unmengen an Polygonen und unnötig große Texturen für Dinge verwendet, die meistens eher unwesentlich sind. Größtenteils lässt sich all das meistens viel performancefreundlicher, also somit mit weniger Polygonen und kleineren Texturen umsetzen. Hat man sich nun das richtige Addon rausgesucht steht dem Editing nichts mehr im Weg. Jetzt sollte man nur noch darauf achten, dass man nicht zu viele Mods und Addons für nur eine Mission verwendet. Die Spieler müssen sich dann oft die Addons zusammensuchen und ewig runterladen. Nach all der Mühe folgt dann oft die Enttäuschung, dass die Mission schlecht umgesetzt ist oder so gut wie gar nicht spielbar ist, weil eben zu viele Addons verwendet wurden, die nicht gut zusammenarbeiten. Also immer daran denken… weniger ist mehr! Nicht die Anzahl der verwendeten Addons in einer Mission ist wichtig, sondern viel mehr die Umsetzung, Funktionalität, Story und vor allem die Spielbarkeit! 303 Kapitel 11 Vor den Namen Mapfact wurde ein @ gesetzt, damit der MOD-Ordner im ArmAVerzeichnis gleich ganz oben mit angezeigt wird. Benennt man nun alle Ordner zuerst mit dem @, werden alle entsprechend sortiert angezeigt und man sieht gleich, was ein MOD-Ordner ist und was nicht. Natürlich kann man auch ein anderes Zeichen oder was auch immer benutzen. Dies ist lediglich eine Anregung. 11.5 - Der Missionsrelease Hat man seine Mission nach einigen Nervenzusammenbrüchen und etwas mehr oder weniger investierter Zeit nun endlich fertig gestellt, steht die Veröffentlichung dieser vor der Tür. Endlich will man sein Werk der Öffentlichkeit präsentieren und für seine Arbeit ein anständiges Feedback bekommen. Doch auch hierbei gibt es einige nicht gerade unwesentliche Dinge zu beachten. Es ist unwichtig, ob die Mission heute oder morgen kommt. Lieber einen Tag länger testen und ein vernünftiges Ergebnis abliefern, als eine halbfertige Mission. Testen, testen, testen Die Mission sollte bis ins Detail auf Funktionalität und Spielbarkeit von dir und deinen Freunden oder Bekannten getestet werden. Story und Ablauf Die Mission sollte eine gute Story und einen schlüssigen Ablauf haben. Der oder die Spieler müssen immer wissen, was als nächstes ansteht und sollten durch die Story und die Spannung ein wenig in den Bann gezogen werden. Die Readme Bei deiner Mission sollte mindestens eine Readme enthalten sein. Darin sollte stehen, von wem die Mission ist, vielleicht eine Kontaktemailadresse, die verwendeten Addons mit Downloadlink, einige Hinweise zur Mission und ggf. eine Aufführung aller bekannten Bugs, die man einfach nicht gefixt bekommen hat. Verwendete Addons Idealerweise bietet man mit der Mission einen MODOrdner zu seiner Mission mit an. Dieser sollte dann alle kleineren Addons enthalten, die in der Mission verwendet wurden. Für größere Mods oder ähnliches kann man gerne einen Downloadlink angeben. Das Paket Am Ende sollte das Ganze als Rar- oder Zip-Datei gepackt werden und mindestens folgendes beinhalten: die Mission.pbo, eine Readme und den Modordner Wenn du die zuvor erwähnten Punkte einigermaßen befolgt hast, sollte deinem Release und dem Erfolg deiner Mission jetzt nichts mehr im Wege stehen. Also dann viel Erfolg für deinen ersten Missionsrelease! 304 11.6 - Die ArmA.rpt In dieser Datei werden unter anderem Fehler von: - Missionen - Skripten - Funktionen - Addons hinterlegt. Dies könnten fehlende Zeichen, Texturen, Modelle, Materialien oder auch Configfehler sein. Die ArmA.rpt ist aber nicht nur eine Fehlerreportdatei. Sie kann auch als Log-Datei gesehen werden. Unter anderem sind hier auch - Statusänderungen von Einheiten und Objekten - Statusänderungen Spieler - Multiplayeraktivitäten und vieles mehr zu finden. Sie ist somit der optimale Wegweiser bei Fehlern und so weiter. Möchte man also seine Mission oder sein Addon veröffentlichen, lohnt sich zuvor immer nochmal ein Blick in die Rpt. Denn dort kann man sehen, ob es eventuell noch Fehler gibt, die sich nicht unmittelbar und sichtbar bemerkbar machen. Es empfielt sich, diese Datei ab und dann zu leeren oder ganz zu löschen. ArmA wird diese dann wieder neu anlegen. Diese Datei lässt sich dabei ganz normal mit dem Texteditor öffnen. Folgend mal ein kleiner Auschnitt: No more slot to add connection at De61 (6952.9,8228.9) Client: Object 8:57 (type UpdatePositionVehicle) not found. *** Remote: Identity Mr-Murray transferred from 8:98 to 8:120 File update_v1\RscDefine.hpp, line 0: '.100': Missing ';' at the end of line File update_v1\RscDefine.hpp, line 0: '.120': Missing ';' at the end of line Updating base class ->Helicopter, by ca\air\config.bin/CfgVehicles/UH60MG/ Die ArmA.rpt findet sich, wenn man mit -profile, wie im Kapitel 11.1 erläutert,arbeitet, normalerweise im ArmA-Root-Verzeichnis. Ansonsten unter: C:\Dokumente und Einstellungen\User\Anwendungsdaten\ArmA 305 Kapitel 11 Die ArmA.rpt ist die Fehlerreportdatei von Armed Assault. Die Engine hinterlegt hier wichtige Informationen. Wenn ArmA beispielsweise mal wieder einen CTD (Crash To Desktop) herbeigeführt hat, kann man darin nachsehen, wo der Fehler gelegen hat. Als Beispiel dient hier die Description.ext, mit der wohl die meisten Editierer ab und dann wieder auf dem Desktop landen und sich dann fragen, was denn nun falsch sein könnte. Ein Blick in die ArmA.rpt verweist dann auf den Fehler. 11.7 - Das Natoalphabet 306 A Alpha B Bravo C Charlie D Delta E Echo F Foxtrott G Golf H Hotel I India J Juliett K Kilo L Lima M Mike N November O Oskar P Papa Q Quebec R Romeo S Sierra T Tango U Uniform V Viktor W Whisky X X-Ray Y Yankee Z Zulu 11.8 - Die Dienstgradabzeichen Folgend nun die Dienstgradabzeichen verschiedener NATO-Länder. Natürlich gibt es in dem ein oder anderen Land noch diverse andere Dienstgrade, aber das würde hier jetzt den Rahmen sprengen. Mannschaften Gefreiter Obergefreiter Hauptgefreiter Stabsgefreiter Oberstabsgefreiter Unteroffiziere Unteroffizier Stabsunteroffizier Feldwebel Oberfeldwebel Hauptfeldwebel Stabsfeldwebel Oberstabsfeldwebel Fahnenjunker Fähnrich Oberfähnrich Offiziere Leutnant Oberleutnat Hauptmann Major Oberstleutnant Oberst Brigadegeneral Generalmajor Generalleutnant General Kapitel 11 Deutschland USA Großbritanien Frankreich Private --Private First Class ----- Private --Lance Corporal ----- Premiére Classe Caporal Caporal Chef ----- Corporal --Sergeant Staff Sergeant Sergeant First Class Master Sergeant Sergeant Major --Cadet --- Corporal --Sergeant Staff Sergeant --Warrant Officer Class 2 Warrant Officer Class 1 --Officer Cadet --- Sergent Sergent Chef Adjudant --Adjudant Chef Major ----Aspirant --- Second Lieutnant First Lieutenant Captain Major Lieutenant Colonel Colonel Brigadier General Major General Lieutenant General General/Field Marshal Second Lieutnant Lieutenant Captain Major Lieutenant Colonel Colonel Brigadier Major General Lieutenant General General/General of Army Sous Lieutenant Lieutenant Capitaine Commandant Lieutenant Colonel --Général de Brigande Général de Division Général de Corps d´Armee Général d´Armee 307 11.9 - Die Squad.xml Die Squad.xml eignet sich hervorragend um auf dem Schlachtfeld eine Zuordnung für verschiedene Clans zu schaffen. Hiermit ist es möglich jedem Spieler eines Clans ein Logo zuzuweisen. Dazu macht es natürlich Sinn, wenn jedes Teammitglied das gleiche Logo benutzt. Natürlich kann man auch als einzelner Spieler, wenn man nicht Mitlied eines Clans ist, ein eigenes Logo verwenden. Das Logo wird später dann ingame auf Fahrzeugen etc. angezeigt (siehe Bild). Das Benutzen einer Squad.xml erfordert ein paar Voraussetzungen. Man benötigt dafür einen Server, auf dem die nun folgend aufgeführten Dateien abgelegt werden können. Dazu legt man auf seinem Server ein neues Verzeichnis an und legt die zugehörigen Dateien dort ab, welche man vorher seinen Bedürfnissen angepasst hat, was dann als nächstes erklärt wird. Abzulegende Dateien Abzulegende Dateien sind hierbei: squad.xml squad.css squad.dtd squad.xsl squadpic.paa Hierbei merkt man sich die URL, welche man später etwa so aussehen könnte: http://www.meinserver.de/armaxml/squad.xml 308 Diese gibt man dann später, wie auf dem folgenden Bild zu sehen, bei Squad URL an. Kapitel 11 Player ID Eine weiterer wichtiger Punkt ist die Player ID, welche unten rechts im Bild zu sehen ist. Jeder Spieler hat eine eigene ID, welche in der Squad.xml definiert werden muss. Die Konfiguration Die einzigsten Dateien, welche hierbei bearbeitet werden müssen sind die Squad.xml und die Squadpic.paa. Die anderen sind dabei eher unwichtig, aber müssen der Funktionalität halber auf dem Server liegen. Squad.xml In ihr wird die eigentliche Konfiguration vorgenommen. Hierbei wird im oberen Abschnitt die Squad definiert und im unteren Abschnitt die einzelnen Spieler. <Squad Nick> <Name> <EMail> <Web> <Picture> <Title> - Squadabkürzung (Clan-Tag) - Squadname - Squadkontakt - Squadwebseite - Bild (Squadpic.paa) - Squadname Diese Datei keinesfalls mit Excel, sondern mit dem Texteditor bearbeiten! 309 Im unteren Abschnitt wird der Spieler definiert: <Member ID> <Nick> <Name> <EMail> <ICQ> <Remark> - Player ID (siehe Profilbild) - Nickname (Profilname) - Name - Spielerkontakt - IM-Kontakt - Bemerkung In einer fertigen Datei sieht das Ganze dann etwa so aus: <?xml version="1.0" encoding="ISO-8859-1" ?> <!DOCTYPE squad SYSTEM "squad.dtd"> <?xml-stylesheet href="squad.xsl?" type="text/xsl"?> <squad nick="MAP"> <name>Mr-Murray</name> <email>[email protected]</email> <web>www.mr-murray.de.vu</web> <picture>squadpic.paa</picture> <title>Mr-Murray</title> <member id="12345678" nick="Mr-Murray"> <name>Mr-Murray</name> <email>[email protected]</email> <icq>N/A</icq> <remark></remark> </member> </squad> Squadpic.paa Die Squadpic.paa ist das Logo, welches hinterher im Profil angezeigt wird. Dieses ist aber nicht zwingend vorgeschrieben und man kann es also auch weglassen. Wenn man es aber haben möchte, muss es auf jeden Fall im gleichen Ordner liegen, wie die Squad.xml! Squadpic ist hierbei wieder ein variabler Name. Benennt man die Datei anders, muss man das logischerweise auch in der Squad.xml anpassen. Möchte man nun ein eigenes Squadlogo erstellen, macht man das mit einem Grafikprogramm. Dazu erstellt man zunächst ein neues Bild im TGA-Format und legt die Maße fest, welche wie folgt lauten können: 16/16, 32/32, 64/64, 128/128, 256/256 Anschließend gestaltet man sein Logo den eigenen Wünschen entsprechend und speichert das Ergebnis ab. Mit dem Programm TexView läd man sein Logo dann und speichert es anschließend als PAA-Datei. 310 Ergebnis Drückt man nun später ingame in einer Mehrspielermission egal ob Hostet oder Dedicated die P-Taste, wird folgendes Ergebnis angezeigt: Kapitel 11 Template Ein downloadbares Template findet man auf www.mr-murray.de.vu Dieses muss man dann, wie zuvor erklärt, lediglich seinen Bedürfnissen anpassen. 11.10 - Die Startparameter Für Armed Assault gibt es zahlreiche Startparameter, die sich an die ArmA.exe oder eine entsprechende Verknüpfung zur ArmA.exe anhängen lassen. Mit diesen Parameten hat man nun eine Menge Vorteile. Ein Vorteil, der wohl mit am beliebtesten ist, ist der, ArmA im Fenstermodus starten zu lassen oder die Voreinblendungen abzuschalten. Folgend nun eine kleine Übersicht der wichtigsten Parameter. Weitere finden sich in der BIS-Wiki. Bildschirm Optionen -window -nosplash -x=Wert -y=Wert - Startet ArmA im Fenstermodus - Startet Arma ohne Voreinblendungen - Auflösungsbreite - Auflösungshöhe 311 Verschiedene Optionen -nomap -noland - buldozer -init= -profiles= -name=Username -noPause -maxMem=Wert -world=Sara Οrdner -mod=@Ο Netzwerk Optionen -port= -password= -host -server -connect= -netlog -cfg= - Startet ArmA nur mit benötigten Addons - Startet ArmA ohne Insel - Startet ArmA im Buldozer Mode - -init=playMission[,'M04Saboteur.Sara'] - Bestimmt den Userordner (-profiles=F:\ArmA\) - Lädt das jeweilige Benutzerprofil - Spiel läuft auch im Hintergrund weiter - Maximale Speichermenge (MB) - Lädt die angegebene Insel (Sara=Sahrani, Intro=Rahmadi, Empty=keine) - Lädt den angegebenen MOD-Ordner mit - Port zum Server (Local Host bzw. Dedicated Server) - Passwort zum Dedicated Server - Startet einen Host-Server - Server einen Dedicated Server - Server zu dem verbunden werden soll - Aktivert das Protokolieren der Netzwerkaktivität - Auswahl einer Cfg-Datei Einbindung eines Parameters Einen Parameter hängt man an die ArmA.exe bzw. einer extra dafür angelegten Verknüpfung. Dazu klickt man mit der rechten Maustaste auf die Exe und wählt die Egenschaften aus. Jetzt öffnet sich ein solches Fenster, wie rechts zu sehen ist. Bei Ziel gibt man dann die jeweiligen Parameter an und Speichert das Ganze. Hier mal ein Beispielparameter: C:\ArmA\arma.exe -nosplash -nomap Man hat auch die Möglichkeit verschiedene Verknüpfungen anlegen, die man dann individuell konfigurieren kann. Jedoch sparen Community-Tools, wie etwa ein Arma-Launcher, eine Menge Arbeit, da man damit noch viel übersichtlicher Arbeiten kann. 312 11.11 - Tastenkombinationen, Tipps und Tricks Wie auch in jedem anderen Programm, gibt es auch im Armed Assault Editor diverse Tastenkombinationen, Kniffe und Tricks, die ein schnelleres Editieren ermöglichen. Kapitel 11 Tastenkombinationen [STR] und [C] [STR] und [X] [STR] und [V] [Entfernen] [Shift] und [Entfernen] [Shift] und [linke Maustaste] - Kopieren einer Einheit/Objekt - Ausschneiden einer Einheit/Objekt - Einfügen einer Einheit/Objekt - Löscht markierte Einheit/Objekt - Löscht alle markierten Einheiten/Objekte - Einheiten drehen (Tasten gedrückt halten und Maus bewegen) [Shift] und [linke Maustaste] - Einheit mit Wegpunkt bearbeiten (F1 wählen, Shift gedrückt halten und linke Maus drücken) [Linke Maustaste] - Einheit/Objekt verschieben /Bereich markieren (Tasten gedrückt halten und Maus bewegen) [Linke] und [rechte Maustaste] - Karte Bewegen (Tasten gedrückt halten und Maus bewegen) [Mausrad] - Karte ran- oder wegzoomen Templates Generell lohnt es sich für gewisse Missionsinhalte so genannte Templates zu erstellen. Wenn man zum Beispiel eine Stellung oder ähnliches gebaut hat, muss das ja nicht unweigerlich heißen, dass diese nur für die eine Mission zu gebrauchen ist. Oder andere Dinge wie Zufallspositionen etc. Erstellt man sich für jedes Missionsfeature ein rohes Template, hat man so die Möglichkeit es jederzeit schnell in seine aktuelle Mission zu importieren und zu verwenden. Man spart sich damit definitiv eine Menge Zeit, welche man dann sinnvoller nutzen kann. Dazu erstellt man sich einfach eine simple Mission mit dem jeweiligen Inhalt, etwa der Stellung und speichert sie zum Beispiel als Editormission mit Namen _Temp_Bunker ab. Templates II Hat man eine große und komplexe Mission geschaffen, kommt es oft vor, dass man plötzlich noch eine tolle Idee hat, die unbedingt mit implementiert werden soll. Zum Beispiel eine neue Basis oder wie auch immer. Also etwas, wo man wieder ein wenig bauen, verschieben und in die Vorschau wechseln muss. Bei der Mission wäre es dann so, dass beim Start ja alles gestartet wird, was man zuvor darin definiert hat. Dafür lohnt es sich eine neue Map (Template) zu erstellen, auf der man diese Basis nun ohne ablenkendes Drumherum bauen kann, nach der Fertigstellung speichert man diese einfach als Editormission, wechselt zu seiner Hauptmission und nutzt die Importfunktion „Zusammenführen“, um das Template in seine Mission zu importieren. 313 Stichwortverzeichnis A Bezeichnung Kapitel Seite Abgefeuerter Typ ausgeben lassen Actionbefehl Actionmenüeintrag Airstrike Airvehiclecreator Alarm Allgemeines MP Animationsbefehl Arma.rpt Array Artillerie Aufklärer Auslöser und Wegpunkte synchronisieren Auslöser einfügen Auslöser erzeugen Auslöserbereich prüfen Auslöserbereiche addieren 3.16 5.55 6.3 6.12 6.13 5.32 7.19 5.56 11.6 9.12 6.7 6.22 1.6 1.4 5.69 5.26 5.26 92 136 181 198 201 119 247 139 305 271 189 217 35 27 160 115 115 Bezeichnung Kapitel Seite Bedingung Tod Beendigung einer Mission Befreundete Parteien Bekanntheitsgrad einer Einheit Bereich prüfen Bewaffnung im MP Bombe erzeugen Bombenleger Briefing Briefingzubehör Bullet Mode 5.33 4.6 5.31 5.29 5.26 7.21 5.46 6.21 2.13 4.3 6.10 120 101 118 117 115 250 126 216 59 98 196 Bezeichnung Kapitel Seite Camskripting Capture The Flag Cheats Class Header 8.1 7.17 11.2 7.11 255 240 301 233 B C 314 D Kapitel Seite Datum und Uhrzeit einstellen Deathmatch Delay Description.ext Dialoge Dienstgrad vergeben Dienstgradabzeichen Distanz zweier Einheiten oder Objekte 5.43 7.6 9.7 2.3 10.1 5.76 11.8 5.34 123 227 269 48 279 171 307 120 Bezeichnung Kapitel Seite Editoroberfläche Eigenes Profil Einheiten/Fahrzeuge einfügen Einheiten/Fahrzeuge erzeugen Einheiten bewaffnen und ausrüsten Einheiten und Objekte drehen Einheiten verbinden Einheit begibt sich in Gebäude Einheit bleibt stehen Einheit bewegt sich zu Bestimmungsort Einheit ergibt sich Einheit hat Waffe Einheit mit Wegpunkten bearbeiten Einheitsklassen Einheit in Fahrzeug Einheiten starten bzw. stoppen Einheiten zu Missionsbeginn im Fahrzeug Ein- und aussteigen lassen Einheit verlässt Gruppe und tritt anderer bei Einheit wählt Waffe Einheit wendet sich anderer Einheit zu Einheit ein Ziel zuweisen Einheiten in einem Bereich ansprechen Einheitsstatus speichern oder laden Einheit begibt sich zu Gebäudeposition Eventhandler Explosionen , Rauch und Flares erzeugen 1.1 11.1 1.2 5.45 3.3 5.15 1.9 5.19 5.10 5.12 6.23 3.17 1.10 3.9 5.4 5.11 5.6 5.7 5.20 5.23 5.22 5.21 5.27 5.28 5.63 5.65 5.46 16 299 20 124 70 111 39 112 109 110 218 92 40 77 107 111 108 108 113 114 114 113 115 116 153 155 126 Stichwortverzeichnis Bezeichnung E 315 F Bezeichnung Kapitel Seite Fahne vergeben Fahrzeugklassen Fahrzeugwaffen Fahrzeuge be- und entladen Fahrer/Beifahrer eines Fahrzeugs Fahrzeugverbot für Einheit Fahrzeug fährt erst, wenn Einheit eingestiegen ist Fallschirmspringer Fahrzeug Respawn Fahrzeug Respawn (Mr-Murray) Fehlerreportdatei / Arma.rpt) Feindmeldeskript Fernglasbenutzung durch Einheit Feuer (brennend/erloschen) Feuer erzeugen (Skriptversion) Flexible Respawnpunkte Freundlicher Feind Flaggen Grundinformationen MP Flares, Rauch und Explosionen erzeugen Fluchtverhalten einer Einheit oder Gruppe Flughöhe einer Einheit Funkmenu verändern Funkspruch abgeben Funktionen Grundwissen (SQF) 5.35 3.7 3.8 3.5 5.2 5.3 5.6 6.1 7.14 7.15 11.6 6.11 5.77 5.36 5.75 7.3 5.30 7.16 5.46 5.14 5.17 5.48 5.50 9.13 120 73 76 71 106 106 108 179 235 236 305 197 172 121 169 225 117 238 126 110 112 127 129 274 Bezeichnung Kapitel Seite Gebäudepositionen Geschwindigkeit einer Einheit/Fahrzeug Geschwindigkeit ausgeben lassen GPS-System Grafikformate (Paa/Pac) Gruppen erzeugen Gruppe zu Missionsbeginn im Fahrzeug 5.62 5.8 5.9 6.2 2.8 5.45 5.6 148 108 108 180 55 124 108 G 316 H Bezeichnung Kapitel Seite Helikopterlandung Höhenversetzung eines Objektes House-Patrol-Skript 5.64 5.16 6.16 153 111 205 Bezeichnung Kapitel Seite Identität festlegen ID´s verwenden If-Then-Else Informationstext Init.sqs Insektenskript 5.53 5.59 9.6 5.59 2.5 6.20 134 144 268 144 53 215 Bezeichnung Kapitel Seite Jahreszahl, Datum festlegen 5.43 123 Bezeichnung Kapitel Seite Kameraeffekte Kamerasteuerung Kamerakoordinaten Kamera erstellen Kamera an Fahrzeug oder Einheit heften Kartenanimation KI abschalten Klammereigenschaften Karte auf den Monitor erzwingen 8.7 8.1 8.2 8.3 8.5 8.9 5.57 9.10 5.40 262 255 256 257 260 263 144 270 121 Bezeichnung Kapitel Seite Laternen abschalten Leeres Fahrzeug Leerer Scheinwerfer mit Licht Lichtquellen erzeugen (Skriptversion) Liegen, knien und stehen Lip-Dateien Löschen von Einheiten und Objekten Logische Operatoren 5.61 5.1 5.86 5.72 5.60 2.11 5.45 9.3 145 106 177 167 144 57 124 267 I Stichwortverzeichnis J K L 317 M Bezeichnung Kapitel Seite Mapclick Marker einfügen Marker erzeugen Marker mit Einheiten verbinden Minen-Skript Mimiken Missionsordner Mission.sqm Missionsname Missionsstart Missionszubehör Missionswertung Missionsziele Mission beenden Mission speichern Missionsrelease MOD-Ordner Möwen-Skript Munitionskiste Multiplayer-Allgemeines Multiplayer-Bewaffnung Multiplayer-Description.ext Multiplayerbereich festlegen Musik oder Sound einbinden 6.6 1.7 5.70 1.9 6.17 5.54 2.1 2.2 4.1 4.2 4.3 4.4 4.5 4.6 4.7 11.5 11.3 6.19 3.4 7.19 7.21 7.4 7.7 5.52 187 36 162 39 208 135 42 43 97 97 98 99 99 101 103 287 302 213 71 247 250 226 228 130 Bezeichnung Kapitel Seite Natoalphabet Nachladen verbieten 11.7 3.19 306 93 Bezeichnung Kapitel Seite Objekt- und Gebäudeklassen Objekte Versetzen oder höher setzen Overview 3.11 5.16 2.12 81 111 58 N O 318 P Kapitel Seite Patrouille laufen, fahren oder fliegen PBO-Datei Pflanzenklassen Profileigenschaften Positionen (xyz) auslesen Publicvariable Punktvergabe MP Punkte vergeben bzw. anzeigen lassen MP 5.13 2.9 3.12 11.1 5.64 7.18 7.8 7.9 110 56 88 299 153 246 229 231 Kapitel Seite Bezeichnung Kapitel Seite Random Rauch erzeugen (Skriptversion) Rauch, Flares und Explosionen erzeugen Respawnpunkte Respawnarten Respawndialog Rufzeichen vergeben Rund ums Vehikel Rucksack 9.8 5.74 5.46 7.2 7.5 7.12 5.49 5.71 6.4 269 168 126 224 227 233 128 165 181 Bezeichnung Kapitel Seite Schadenwert vergeben Scheinwerfer Schilderklassen Seiten verfeinden Sekundär- oder Primärwaffe Semikolon Setvelocity Shellklassen Sichtweite ändern Skript (.sqs) Staub erzeugen 5.24 6.14 3.14 5.31 3.18 9.11 5.58 3.10 5.41 2.6 5.73 114 203 91 118 93 81 144 80 122 54 167 Stichwortverzeichnis Bezeichnung Q Bezeichnung R S 319 Sound erstellen Sound oder Musik einbinden Spielerseite auslesen Spielereingabe unterdrücken Speichern Spielbeschleunigung unterdrücken Spielerbezogene Textmitteilung Spielbare Einheit hinzufügen Squad.xml Startparameter Staub erzeugen Stehen, knien und liegen Steinklassen Streifen laufen, fahren oder fliegen Stringtable.csv Stringtable Grundwerte Stringtable Grundwerte MP Sychronisieren 5.51 5.52 5.38 5.39 4.7 6.9 7.22 5.37 11.9 11.10 5.73 5.60 3.13 5.13 2.4 5.67 7.13 1.6 129 130 121 121 103 181 251 121 308 311 167 144 90 110 51 158 234 35 Bezeichnung Kapitel Seite Tote Einheiten/Fahrzeuge löschen Todeszone erstellen Texteinblendarten Text- und Einblendeffekte 6.8 5.25 5.66 8.6 194 115 157 261 Bezeichnung Kapitel Seite Unzerstörbares Objekt Umgebungssound abschalten 5.61 8.7 145 262 Bezeichnung Kapitel Seite Variable Vehikeltransport-Skript Verschlossenes Fahrzeug Versetzen von Objekten, Auslösern und Markern Verwendung von Addons 9.1 6.18 5.1 5.15 11.4 265 209 106 111 303 T U V 320 W Kapitel Seite Waffen und Magazine erzeugen Waffen und statische Waffen Waffenwahl einer Einheit Waffenauswahl im Briefing Waffen der Fahrzeuge Waffen- und Magazintypen ausgeben lassen Waffenbezeichnungsliste Waffen und Munitionskiste Wahrheitswerte WaitUntil Wegpunkte einfügen Wegpunkte erzeugen Wegpunkte und Auslöser synchronisieren Wetter einstellen While-Do-Schleife 3.21 3.1 5.23 3.6 3.8 3.15 3.2 3.4 9.2 9.9 1.5 5.68 1.6 5.42 9.4 94 64 114 72 76 92 68 71 266 269 30 159 35 122 268 Bezeichnung Kapitel Seite XYZ-Positionen auslesen 5.64 155 Kapitel Seite Bezeichnung Kapitel Seite Zähler Zeitanzeige im Multiplayer Zeitlupe oder Zeitsprint Zeitzähler Zielzuweisung für eine Einheit Zufallsanimation Zufallsmusik Zufallspositionen Zufallspositionen Zufallswetter Zuwendung einer Einheit 9.5 7.8 5.44 6.15 5.21 5.56 5.52 1.9 6.5 5.42 5.22 268 229 123 204 113 139 130 39 185 122 114 Stichwortverzeichnis Bezeichnung X Y Bezeichnung Z 321 Syntaxverzeichnis A Bezeichnung Kapitel Seite Active Action AddAction AddEventhandler AddRating AddSwitchableUnit AddWeapon AddMagazine AddWeaponCargo AddWaypoint AddMagazineCargo AIKills Alive AllowGetin AllowFleeing And Animate AnimationState AssignAsCargo AssignAsCommander AssignAsDriver AssignAsGunner AssignTeam AssignToAirport AssignedVehicle AssignedVehicleRole AVGScore 4.5 5.55 6.3 5.65 4.4 5.37 3.3 3.3 3.4 5.68 3.4 7.4 5.71 5.3 5.14 9.3 5.61 5.56 5.78 5.78 5.78 5.78 5.79 5.82 5.78 5.78 4.4 99 136 181 155 99 121 70 70 71 159 71 226 165 106 110 267 145 139 172 172 172 172 173 175 172 172 99 Bezeichnung Kapitel Seite BuildingPos 5.62 148 Bezeichnung Kapitel Seite Call CamUseNVG CanMove CanFire CanStand 9.13 8.7 5.81 5.81 5.81 274 262 174 174 174 B C 322 9.3 9.3 3.4 3.4 10.9 5.21 5.80 5.80 5.80 5.80 9.13 8.6 9.3 10.9 5.45 5.70 3.20 5.51 5.69 5.45 5.45 5.45 5.71 10.7 8.6 267 267 71 71 292 113 174 174 174 174 274 261 267 292 124 162 93 129 160 124 124 124 165 289 261 Bezeichnung Kapitel Seite Damage Default DefValueParam DeleteMarker DeleteStatus DeleteVehicle DeleteWaypoint Driver Done DoFire DoGetOut DoMove DoStop 5.24 1.2 7.8 5.70 5.28 5.47 5.68 5.71 4.5 5.21 5.47 5.12 5.10 114 20 229 162 116 127 159 165 99 113 127 110 109 Syntaxverzeichnis Case Ceil ClearWeaponCargo ClearMagazineCargo CloseDialog CommandTarget CommandFire CommandMove CommandStop CommandTarget Compile ComposeText Count CreateDialog CreateGroup CreateMarker CreateMine CreateSoundSource CreateTrigger CreateVehicle CreateVehicleLocal CreateUnit Crew CutRsc CutText D 323 DoTarget DoWatch DisableAI DisableUserInput DissolveTeam Distance 5.21 5.22 5.57 5.39 5.79 5.34 113 114 144 121 173 120 Bezeichnung Kapitel Seite EnableAI EnableEnvironment EnableRadio EnableReload Enemy ExecVM ExitWith 5.57 8.7 5.50 3.19 5.31 9.13 9.13 144 262 129 93 118 274 274 Bezeichnung Kapitel Seite FadeMusic FadeRadio FadeSound Failed Fire False Flag FlagOwner Floor FlyInHeight Format ForEach ForceMap ForceSpeed Fuel 5.52 5.52 5.52 4.5 5.21 9.2 7.16 7.16 9.3 5.17 5.66 9.3 5.40 5.71 5.71 129 129 129 99 113 266 238 238 267 112 157 267 121 165 165 Bezeichnung Kapitel Seite GameType GetDammage GetDir 7.11 5.24 5.22 233 114 114 E F G 324 GetMarkerPos GetPos GetPosASL GetSpeed GlaceAt GlobalChat Goto Group GroupChat GrpNull Gunner 36 114 153 108 114 129 267 108 129 113 165 Bezeichnung Kapitel Seite HandsHit HasWeapon Hidden Hint, HintC, HintCadet 5.81 3.17 4.5 5.59 174 92 99 144 Bezeichnung Kapitel Seite If then else In InFlame IsEngineOn IsNull IsServer 9.6 5.71 5.36 5.71 5.71 7.19 268 165 121 165 165 247 Bezeichnung Kapitel Seite Join 5.20 113 Bezeichnung Kapitel Seite KnowsAbout 5.29 117 Bezeichnung Kapitel Seite Land LandAt 5.18 5.82 112 175 Syntaxverzeichnis 1.7 5.22 5.64 5.8 5.22 5.50 9.3 5.6 5.50 5.20 5.71 H I J K L 325 Leader LimitSpeed List Localize Local Player Local Server Lock, Locked LookAt LoadIdentity LoadStatus 5.79 5.71 9.3 5.66 7.19 7.19 5.1 5.22 5.53 5.28 173 165 267 157 247 247 106 114 134 116 Bezeichnung Kapitel Seite Magazines MapAnimAdd MapAnimClear MapAnimCommit MapAnimDone MaxPlayers MaxScore MinPlayers MinScore ModelToWorld Move MoveInCargo MoveInCommander MoveInDriverMoveInGunner MoveInTurret 3.15 8.9 8.9 8.9 8.9 7.11 4.4 7.11 4.4 5.15 5.12 5.2 5.2 5.2 5.2 92 263 263 263 263 233 99 233 99 111 110 106 106 106 106 Bezeichnung Kapitel Seite NearestBuilding NearestObject Not 5.61 5.61 9.3 145 145 267 Bezeichnung Kapitel Seite ObjNull ObjStatus OnLoadIntro 5.21 4.5 4.2 113 99 97 M N O 326 OnLoadIntroTime OnLoadMission OnLoadMissionTime OnPlayerConnected OnMapSingleClick OrderGetIn 4.2 4.2 4.2 7.22 6.6 5.78 97 97 97 252 187 172 Bezeichnung Kapitel Seite Player PlayMove PlayMusic PlaySound Position PreLoadCamera PreLoadMusic PreLoadObject PreLoadSound PreLoadTitleRsc PreLoadTitleText PreProcessFile PrimaryWeapon PublicVariable 9.1 5.56 5.52 5.52 5.64 8.8 8.8 8.8 5.52 8.8 8.8 9.13 3.18 7.18 265 139 130 130 153 262 263 262 130 263 263 274 93 246 Kapitel Seite Bezeichnung Kapitel Seite Random Rank Rating RemoveAction RemoveEventhandler RemoveWeapon RemoveAllWeapons RemoveMagazine RemoveSwitchabeUnit Respawn 9.8 5.76 4.4 6.3 5.65 3.3 3.3 3.3 5.37 7.4 269 171 99 181 155 70 70 70 121 226 P Syntaxverzeichnis Q Bezeichnung R 327 RespawnDelay RespawnDialog RespawnVehicle RespawnVehicleDelay Reveal 7.4 7.12 7.14 7.14 5.29 226 233 235 235 117 Bezeichnung Kapitel Seite Saving SaveGame SaveIdentity SaveStatus SaveVar Say ScriptDone SecondaryWeapon SelectLeader SelectPlayer SelectWeapon Server SetAccTime SetAirportSide SetAmmoCargo SetAperture SetBehaviour SetCaptive SetCombatMode SetDamage, SetDammage SetDate SetDir SetFace SetFace Animation SetFlagOwner SetFlagSide SetFlagTexture SetFog SetFormation SetFormDir SetFriend SetFuel SetFuelCargo 4.7 4.7 5.53 5.28 9.1 5.51 8.8 3.18 5.37 5.37 5.23 7.19 5.44 5.82 1.2 8.7 1.5 5.30 1.4 5.24 5.43 1.2 5.53 5.53 7.16 7.16 5.35 5.42 1.5 1.2 5.31 5.71 5.71 103 103 134 116 265 129 263 93 121 121 114 247 123 175 20 262 30 117 27 114 123 16 134 134 238 238 120 122 30 20 118 165 165 S 328 5.49 5.53 5.73 5.73 5.73 5.70 5.70 5.70 1.7 5.70 5.70 5.70 5.70 5.69 5.54 5.42 5.15 5.48 5.42 5.76 1.2 1.2 5.69 5.8 1.2 5.83 5.69 5.69 5.69 5.69 5.69 5.69 1.2 5.60 3.3 5.24 1.2 5.15 5.58 5.41 5.68 128 134 167 167 167 162 162 162 36 162 162 162 162 160 135 122 111 127 122 171 20 20 160 108 20 176 160 160 160 160 160 160 20 144 70 114 20 111 144 122 159 Syntaxverzeichnis SetGroupID SetIdentity SetLightAmbient SetLightBrightness SetlightColor SetMarkerBrush SetMarkerColor SetMarkerDir SetMarkerPos SetMarkerShape SetMarkerSize SetMarkerText SetMarkerType SetMusicEffect SetMimic SetOverCast SetPos SetRadioMessage SetRain SetRank SetRepairCargo SetSkill SetSoundEffect SetSpeedMode SetTargetAge SetTerrainGrid SetTriggerActivation SetTriggerArea SetTriggerStatements SetTriggerText SetTriggerTimeOut SetTriggerType SetUnitAbility SetUnitPos SetVehicleAmmo SetVehicleArmor SetVehicleInit SetVehiclePosition SetVeloCity SetViewDistance SetWaypointType 329 SetWaypointBehaviour SetWaypointCombatMode SetWaypointDescription SetWaypointFormation SetWaypointHousePosition SetWaypointPosition SetWaypointScript SetWaypointSpeed SetWaypointStatements SetWaypointTimeOut SetWaypointType ShowCinemaBorder ShowCompass ShowDebriefing ShowGPS ShowMap ShowNotePad ShowRadio ShowWatch ShowWaypoint Side SideChat SkipTime Sleep SomeAmmo Spawn SpeedIsNull Stop SwitchLight SwitchMove SwitchCamera 5.68 5.68 5.68 5.68 5.68 5.68 5.68 5.68 5.68 5.68 5.68 8.4 4.3 4.3 4.3 4.3 4.3 4.3 4.3 5.68 5.38 5.50 5.43 9.7 3.19 9.13 5.71 5.11 5.61 5.56 6.22 159 159 159 159 159 159 159 159 159 159 159 260 98 98 98 98 98 98 98 159 121 129 123 269 93 274 165 109 145 139 217 Bezeichnung Kapitel Seite This ThisList Terminate TextParam Time TitleCut TitleFadeOut 9.1 9.3 8.8 7.8 9.1 8.6 8.6 265 267 263 229 265 261 261 T 330 TitleText TitleParam TitleRsc True TypeOf 5.66 7.8 10.3 9.2 5.71 157 229 283 266 165 Bezeichnung Kapitel Seite UnAssignTeam UnAssignVehicle Unlocked Unit, Units 5.79 5.7 1.2 5.6 173 108 20 108 Bezeichnung Kapitel Seite ValuesParam Variable Vehicle VehicleChat Visible 7.8 9.1 5.71 5.50 4.5 229 265 165 129 99 Bezeichnung Kapitel Seite WaitUntil Weapons WeaponDirection WeaponHolder While do 9.9 3.15 3.22 3.21 9.4 269 92 95 94 268 Kapitel Seite Kapitel Seite Kapitel Seite U Syntaxverzeichnis V W X Bezeichnung Y Bezeichnung Z Bezeichnung 331 IMPRESSUM Autor: Webseite: Sascha “Mr-Murray” Hoffmann www.mr-murray.de.vu Text, Layout und Design: Grafik und Coverdesign: Lektorat: Englische Übersetzung: Sascha Hoffmann Sascha Hoffmann Sascha Hoffmann, Daniel Schönyan, Dan Bolan Daniel "Memphisbelle" Schönyan Stephen "Steevo" White Englisches Lektorat: Dan "Metal0130" Bolan and Matt Rochelle Publisher: Mr-Murray Spielentwickler: Bohemia Interactive (www.bistudio.com) Credits: Memphisbelle, Metal0130, Parvus, Wolle, Blackland, Woody, Placebo, Maruk, Suma, Ivan, Pete, Shadow, Jan Hlavatý, Dslyecxi, Hoz, Jahve, Planck, RichUK, Q, Raedor, Rastavovich, Vilem, Jerry Hopper, Deadeye, Matt Rochelle, M-E, Foxhound, C930, Marco-Polo-IV, MCPXXL, Silola, Chneemann, Lester, Swat, Pit, Sgt Ace, SNKMan, Legislator, Imutep, Crowe, Wolf der Kleine, Berghoff, Al Simmons, Pitti, Sniping-Jack, JörgF, BadAss, Unterfeld, OneManGang, Flashpoint_K, Kriegerdaemon, Wüstenfuchs, LockheedMartin$ch, Burns, Simba, LordOfTheFlames, Spinor, OFPEC-Team, Deadeye, Luemmel, Zenshin, Moses, Hardrock, TheArmALord, Bolek, Flimmi, Lima, NoFu, Tajin, John Silver,T_D , Redfish, Buliwyf, Big X, Teufelsklaue, Clausewitz, Vektorboson Cervo,Mandoble,Vienna,NeoArmageddon,Mondkalb,ColonelKlink Credits Screenshotcontest: Marcus-Ergalla, Burns, Stoned Boy, Laggingape, Swat, Xsive, Woody, Evil Ash, Legislator, Arctic, AlexXx, Blechreiz, Churchill, Switcher83, Blacktiger Spielversion: Dieses Buch basiert auf Spieleversion 1.15 Copyrighthinweis ©2008 Sascha “Mr-Murray” Hoffmann. Alle Rechte vorbehalten. Die in diesem Medium verwendeten Firmennamen, Namen, Logos, Grafiken, Warenzeichen und Produktbezeichnungen dienen nur Identifikationszwecken. Sie verbleiben im alleinigen Eigentum der jeweiligen Rechteinhaber. Das Cover-Artwork ist Eigentum von Bohemia Interactive (BIS) 2008 und wurde mit freundlicher Genehmigung von BIS zur Verfügung gestellt. ©2008 Bohemia Interactive. Alle Rechte vorbehalten. 332 333