Hallo und wilkommen in die Einführung für Skripten im G.E.C.K.
Erst einmal vorab: Wozu braucht man eigentlich Skripte?
Skripte sind im G.E.C.K. kleine Hilfswerkzeuge, die uns eine ganze Reihe weiterer Möglichkeiten offenbaren und für viele Ereignisse "hinter den Kulissen" verantwortlich sind. Sie sind es, die meist die Quests steuern und es zum Beispiel ermöglichen, dass das Betätigen eines Schalters die verlinkte Tür öffnet. Sie sind es, die bei Aktivieren eines Gegenstands Dialogboxen erscheinen lassen oder einfach nur die Erfüllung einer bestimmten Voraussetzung überprüfen.
Die Skripte sind also recht mächtige Werkzeuge, mit denen sich viele interessante Dinge anstellen lassen.
Generell ist es von Nutzen, wenn ihr bereits Kenntnisse mit Programmiersprachen verschiedener mitbringt, da somit der Einstieg in die verschiedenen Kontrollstrukturen wegfällt. Dieses Tutorial soll sich aber auch an die Einsteiger richten, die noch nie mit einer Programmier- oder ähnlichen Sprache gearbeitet haben.
Der Einsatz von Skripten
Bevor wir mit der Syntax beginnen, sehen wir uns zuerst noch einmal an, wo Skripte überhaupt angewandt werden.
Skripte können in verschiedenen Formen angewandt werden. So unterscheiden sich diese in 3 Typen: Quest-Skripte, Object-Skripte und Effect-Skripte.
Quest-Skripte werden, wie schon der Name verrät, bei Quests angewendet und steuern diese. Die Object-Skripte können auf die meisten interagierbaren Objekte angewandt werden, wie etwa NPCs, Doors, Items, Activators und viele weitere. Die Effect-Skripte sind für die sogenannten Game Effects, also diverse Zustände und Enchantments, die Kreaturen oder Characters betreffen, zuständig.
Die Syntax
Der Skriptname
Jedes Skript beginnt zunächst mit einer einfachen Kennzeichnung, die sich aus folgendem Code zusammensetzt:
Groß- und Kleinschreibung spielt hier keine Rolle, es kann als genauso "SCN" oder auch "scriptname" geschrieben werden. Wie man sieht, bieten Funktionen meist sowohl eine Kurzschreibweise, als auch eine lange Schreibweise an. Welche davon angewandt wird, bleibt jedem selbst überlassen.
Die Kommentare
Der mit dem ;-Zeichen gekennzeichnete Eintrag ist ein Kommentar. Kommentare können mit einem ";" begonnen werden und gelten dann für die fortlaufende Zeile. Sie sind dazu da, das geschriebene Skript durch Erklärungen lesbarer zu machen, also damit man auch später noch weiß, was das Skript nun eigentlich machen soll.
Die Variablenzuweisung
Unter dem Skriptnamen folgen die Variablenzuweisungen. Variablen sind ganz einfach kleine Datenspeicher, die mit einem Wert (hier sind nur numerische Zahlen als Werte möglich) ausgestattet und modifiziert werden können. Im G.E.C.K.-Scripting gibt es 4 Variablentypen: short, long, float und ref.
Die short-Variable kann Zahlen von -32768 bis 32767 speichern, während long und float höhere Grenzwerte besitzen. Da wir jedoch im G.E.C.K.-Scripting meist in einem sehr niedrigen Zahlenbereich arbeiten und wir wohl nie über größere Zahlenwerte hinauskommen werden, ist nur die short-Variable relevant.
Die ref-Variable ist eine Referenzvariable. Sie speichert statt Zahlenwerten eine Objektreferenz. Mit diesen können wir also richtige Objektreferenzen aus der Spielwelt ansprechen.
Der Beginblock
Nach den Variablendeklarationen folgt immer der Begin-Block. Dieser sorget dafür, dass der weiterstehende Code nur dann ausgeführt wird, wenn die Begin-Bedingung erfüllt wurde. Der Begin-Block "Begin OnActivate" wird beispielsweise nur dann ausgeführt, wenn das betreffende Objekt, auf dem das Skript liegt, vom Spieler aktiviert wird. Begin-Blöcke MÜSSEN nach ihrem darin enthaltenen Code mit "End" abgeschlossen werden.
Eine Auflistung aller im G.E.C.K. möglichen Begin-Bedingungen, sowie deren Erklärung, findet ihr im Offiziellen GECK-Wiki: Begin - GECK.
Anmerkung: Die Einrückung des im Begin-Block stehenden Codes ist nicht zwingend erforderlich. Es gehört jedoch zum guten Ton, in Blöcken stehend Codesegmente mit dem Tabulator einzurücken, was auch die Lesbarkeit von umfassenderen Skripten deutlich vereinfacht.
Variablen modifizieren
Wird eine Variable neu deklariert, ist ihr Anfangswert zunächst "0". Eine Wertzuweisung geschieht mit der Set-Funktion:
Hier wird also der zuvor auf 0 deklarierten Variable der Wert 1 zugewiesen. Variablenname können natürlich auch einfach inkrementiert werden:
Die if-Bedingungen
Die if-Bedingungen sind WENN-Bedingungen, welche für gewöhnlich einen Wert auf ZUTREFFEND oder NICHT ZUTREFFEND abprüfen und nach diesem entscheiden, ob der Code im ersten Block (falls zutreffend), oder der zweite im else-Block (ANDERNFALLS) stehende Code (falls nicht zutreffend), ausgeführt werden soll.
if-Bedingungen verwenden für Überprüfen verschiedene Operatoren. Diese wären:
--- if i == 1
Prüft ab, ob die zu überprüfenden Elemente die selben Werte besitzen.
if i > 1
Prüft ab, ob das linke Element größer als das rechte ist.
if i < 1
Prüft ab, ob das linke Element kleiner als das rechte ist.
if i != 1
Prüft ab, ob die zu überprüfenden Elemente nicht die selben Werte besitzen.
if i >= 1
Prüft ab, ob das linke Element größer oder gleich das rechte ist.
if i <= 1
Prüft ab, ob das linke Element kleiner oder gleich das rechte ist.
---
Außerdem lassen sich noch mehrere if-Bedingungen miteinander verknüpfen. Bei if-Bedingungen, die mit dem logischen Operator && (UND) verknüpft sind, müssen beide Bedingungen zutreffen. Bei if-Bedingungen, die mit dem logischen Operator || (ODER) verknüpft sind, muss mindestens eine der beiden Bedingungen zutreffen.
Ein if-Block muss mit einem endif abgeschlossen werden. else-Zweige sind möglich, müssen jedoch nicht unbedingt angewandt werden. Um auf einen else-Block direkt eine weitere if-Bedingung folgen zu lassen, kann dieser auch mit endif geschrieben und daraufhin wie ein gewöhnliches if behandelt werden.
Erläutern wir das durch ein Beispiel:
Die Funktionen
Funktionen sind Programmroutinen, die eine bestimmte Aufgabe ausführen und daraufhin einen Wert zurücklierfern, der den Status des Ergebnisses ausgibt. Der Funktion vorangestellt wird eine Referenz, an der diese angewendet werden soll. Referenz und Funktion werden durch einen Punkt getrennt, also: referenz.Funktion
- Als Beispiel: Die Funktion "myRef.GetDead" überprüft, ob unsere angegebene Referenz (bei der es sich in diesem Fall um einen NPC handelt) noch lebt. Ist der NPC tot, wird der Wert "1" zurückgegeben. Lebt sie hingegen noch, wird der Wert "0" zurückgegeben.
Funktionen lassen sich selbstverständlich auch in if-Bedingungen anwenden. So ist z.B. folgendes Skript möglich, um den Tod eines NPC's festzustellen:
Mit diesem Skript lässt sich ohne weiteres feststellen, ob der NPC tot ist, oder noch lebt, um entsprechend darauf zu reagieren. Anstatt des "GetReference" können wir auch ohne weiteres einen Referenznamen wählen, den wir zuvor einer NPC-Referenz zugewiesen haben.
Es gibt irrsinnig viele Funktionen, die alle ihren eigenen Zweck haben. Hier alle aufzuzählen wäre nicht möglich, ohne das Thema hier zu sprengen.
Eine ausführliche Auflistung alle Funktionen und deren Zweck finden sich im Offiziellen GECK-Wiki.
Schlusssatz
Das war es auch bereits mit unserer "Einführung" in das Skripten. Ich wünsche euch gutes Gelingen mit euren ersten Skripten und hoffentlich hat dieses Tutorial euch weitergeholfen.
Also, wenn ich das richtig verstanden habe, ist das skript Global, wenn ich es mit "Begin GameMode" Anweisung laufen lasse? Einmal Aktiviert, läuft es immer? Gibt es eine möglich keit ein skript zu starten ohne das es an einem Objekt oder einem Activator Bereich in der 3d Welt zugewiesen ist? Beispielsweise wenn ein Spiel gestartet wird?
wenn ich gewollt hätte, das du dich nur mit den scripten auseinandersetzt, hätte ich direkt die skriptseite aufgeschlagen.
ich wollte eigendlich dsa du von selbst dahinterkommst, aber mal ein kleiner ansatz, dann weisst du auch wo im wiki du fündig wirst um dein prob zu lösen.
topics werden durch quests oder AI´s aktiviert/ausgelösst/abgespielt.
--
Wir sagen euch die Wahrheit, auch wenn sie weh tut.
Vielleicht sollte ich etwas konkreter werden. Im Gespräch mit einen Npc wird ein Zufallsgenerator ausgelöst (der funktioniert auch), und ja nadem wie er ausfällt soll das Gespräch eine andere Wendenung nehmen.
Ich schreibe das Script in gekürzter Form mal hierein.
if GetRandomPercent >= 48.6486486
-> HIER SOLL DAS GESPRÄCH MIT DEM TOPIC ABC FORTFAHREN
else -> HIER SOLL DAS GESPRÄCH MIT DEM TOPIC XYZ FORTFAHREN
endif
Ist das möglich? Ansonsten mache ich das über "ShowMessage", aber die Lösung über das Gespräch gefällt mir besser.
Du kannst auch 2 Queststages machen und bei deinem Percentwert eben auf diese Queststage setzen die da sein soll, und bei dieser Queststage soll der Actor den Player mit dem Topic aktivieren. Hoffe du verstehst das xD
--
If you're not too great at construction - don't worry! You can place a variety of characters in silly positions. Ihr glaubts mir nicht? Klick
Du kannst auch 2 Queststages machen und bei deinem Percentwert eben auf diese Queststage setzen die da sein soll, und bei dieser Queststage soll der Actor den Player mit dem Topic aktivieren. Hoffe du verstehst das xD
uff....
Pass auf
Bei deinem NPC machst du nun bei der AI ein Find Packages auf den Player.
Die Condition ist GetStage QuestID == 50.
Und bei der Quest machst du jetz dein Topic und als Condition beim Topic auch GetStage QuestID 50 und natürlich GetIsID NpcREF.
Und eben dasselbe nochmal mit Percentwert == 60 oda so.
--
If you're not too great at construction - don't worry! You can place a variety of characters in silly positions. Ihr glaubts mir nicht? Klick
ref light ;der name "light" hat der eine bedeutung oder ist er frei erfunden?
Begin OnActivate
if light == 0 ;wenn die Variable light 0 ist? was ist damit gemeint, unten steht doch schon enable oder disable, ist das der Anfangswert? also wenn das Licht = 0? dann ensteht erst der Bezug zu dem Lichteffekt?
set light to GetLinkedRef
endif
if light.GetDisabled ;also, wenn das light ausgeschaltet wird (ist "light" immer noch die Variable?), dann wird das "light" eingeschaltet, sonst wird es ausgeschaltet?
light.Enable
else
light.Disable
endif
Activate
End
es Funktioniert nicht, Die Objekte sind Lichter keine Lampen
ScriptName LightSwitchVTCT01
ref light
Begin OnActivate
if light == 0
set light to [VTCTMaHaLi01]GetLinkedRef
set light to [VTCTMaHaLi02]GetLinkedRef
set light to [VTCTMaHaLi03]GetLinkedRef
set light to [VTCTMaHaLi04]GetLinkedRef
set light to [VTCTMaHaLi05]GetLinkedRef
set light to [VTCTMaHaLi06]GetLinkedRef
endif
if light.GetDisabled
light.Enable
else
light.Disable
endif
Activate
End
Und was genau möchtest du jetzt? o_O
Und btw:
Du kannst einer Ref nicht mehr als 1 Funktion oder ähnliches zuweisen.
Du müsstest also 6 Refs machen in deinem fall.
--
If you're not too great at construction - don't worry! You can place a variety of characters in silly positions. Ihr glaubts mir nicht? Klick
Ich möchte mit einem Schalter/Activator 6 Lichter in einem Raum deaktivieren.
Nachdem ich die Klammern vor und hinter den Referencen zu den Lichtern gelöscht und eben einen Punkt zwischen reference und getlinkedref gesetzt hab passiert jetzt auch was. Mein Schalter verschwindet nachdem ich ihn aktiviere
Begin OnActivate
if light == 0
set light to VTCTMaHaLi01.GetLinkedRef
endif
if light.GetDisabled
light.Enable
else
light.Disable
endif
Activate
End
Begin OnActivate
if light == 0
set light to VTCTMaHaLi02.GetLinkedRef
endif
if light.GetDisabled
light.Enable
else
light.Disable
endif
Activate
End