Silbermonds Scripting Crash Kurs

Dieses Tutorial bietet einen Einstieg in das Scripten für Morrowind

Schlagworte:
  1. Silbermond
    (bei Fragen ein email an silbermond@onlinehome.de)

    Eine Auflistung von den wichtigsten Befehlen nach Themen sortiert (allerdings auf englisch) gibt es im Construction Set unter Help->Contents->Gameplay->Scripting->Functions.


    Globales Script, um Dinge und NPCs am Anfang verschwinden zu lassen.

    Am Anfang macht man am besten ein globales Script, womit man alle Personen und Gegenstände, die am Anfang nicht sichtbar sein sollen, erstmal unsichtbar macht.

    Bei Gegenständen muss dafür immer das Kästchen „references persist“ markiert sein.

    Mit Gameplay->Edit Startscripts kann man dann das Script am Anfang des Plugins aktivieren.

    Bei den Scriptnamen sollte man am Anfang immer eine Buchstaben- oder Zahlenkombination voranstellen, damit man sie besser wiederfindet und um Doppeltbenennungen mit Scripten aus anderen Plugins zu vermeiden.

    Jedes Script beginnt mit begin + Scriptname und endet mit dem Wort end.

    Alles, was hinter einem Semikolon steht, dient zur Erklärung und hat keine Bedeutung für ein Script

    Code:
    
    begin caff_disablescript
    
       ;Am Anfang des Scripts werden Variablen deklariert. Die Deklaration der Variablen beginnt immer mit dem Wort "short" + Name der Variablen, den man sich selber ausdenken kann. Je nach Umfang des Scripts müssen eventuell mehrere Variablen deklariert werden. Bei den einfachen Scripts, wo nur eine bestimmte Abfolge von Ereignissen eintreten soll, reicht meist eine Variable. Die Variablen haben am Anfang immer den Wert 0.
    
    Short status
    
       ;Dann werden die Bedingungen aufgezählt, die erfüllt sein müssen, damit die Ereignisse eintreten. Diese Bedingung bedeutet: "Wenn die Variable status den Wert 0 hat" - also beim Start des Scripts...
       ;Die Bedingung wird immer durch das Wort "if" eingeleitet. Zwischen der Klammer und dem Wort dahinter muss immer ein Leerzeichen sein.
       ;Es können mehrere Bedingungen aufgezählt werden. Aber für das Script, bei dem die Dinge am Anfang unsichtbar gemacht werden, reicht diese Bedingung.
    
    If ( status == 0 )
    
       ;Dann werden die Ereignisse aufgezählt, die ausgelöst werden, sobald die Bedingungen erfüllt sind: Hierdurch wird Objekt 1 und NPC1 unsichtbar gemacht
    
    Objekt1->disable
    NPC1->disable
    
       ;Dann wird die Variable einen Wert heraufgesetzt, damit sich das Script nicht tausendmal wiederholt und unter Umständen nicht richtig ausgeführt wird.
    
    Set status to 1
    
       ;Dadurch ist ja die Bedingung status == 0 nicht mehr erfüllt, nachdem alle Gegenstände und NPCs unsichtbar gemacht wurden und das Script hat seinen Zweck erfüllt und wird nicht weiter ausgeführt.
    
       ;Jede mit if begonnene Bedingung muss mit endif wieder geschlossen werden. Da nur eine Bedingung da ist, braucht man hier auch nur ein endif.
    
    endif
    
       ;Mit end muss jedes Script beendet werden.
    
    end
    So, das war schon mal das einfachste Script ;-)

    Jetzt folgt ein Beispielscript, mit dem ein NPC erscheint, sobald man sich ihm (der durch das Startscript unsichtbar gemacht wurde) nähert und den Spieler anspricht und dann zu einem bestimmten Punkt geht, um eine Rüstung anzuziehen und den Spieler angreift.


    Script für eine Folge von Ereignissen

    An den NPC kannst Du dann folgendes Script hängen:
    Code:
    
    Begin caff_kampfscript
    
    Short status
    
    If ( status == 0 )
    If ( getdistance player < 512 )
    
       ;Bedingungen: Wenn die Variable status den Wert null hat und der Spieler 512 Einheiten von dem unsichtbaren NPC entfernt ist treten folgende Ereignisse ein:
    
    NPC1->enable      ;Der NPC wird sichtbar.
    Forcegreeting     ;Der NPC spricht dich an.
    
    Set status to 1   ;Wenn der Wert nicht heraufgesetzt würde, würdest du eine endlose Ansprache vom dem NPC kriegen und das Spiel würde crashen, denn dann würde der NPC dich unendlich oft grüßen.
    
    Endif             ;Die Bedingung getdistance player wird hiermit geschlossen und es geht zum nächsten Ereignis. Jetzt soll der NPC ja an einen anderen Ort gehen.
    
    elseif ( status == 1 )
                      ;Die Variable status hat inzwischen den Wert 1, da die Variable schon einmal vorgekommen ist, muss sie jetzt mit elseif angegeben werden
    
    if ( getjournalindex caff_journal == 10 )
                      ;Wenn die Bedingung erfüllt ist, dass der Tagebucheintrag caff_journal auf der Indexnummer 10 ist (wurde ja durch das Gespräch ausgelöst) treten folgende Ereignisse ein (man kann auch < kleiner als und > größer als oder != für ungleich einsetzen, aber für diesen Fall muss man == nehmen):
    
    aitravel x, y, z
                      ;Der NPC bewegt sich zu den x y z Koordinaten in der Zelle.
    
    set status to 2
                      ;Die Variable muss wieder hochgesetzt werden, weil sonst das Script pausenlos den Bewegungsbefehl auslösen würde, und der NPC sich dadurch gar nicht bewegen würde.
    
    endif             ;Dadurch wird wieder die getjournal caff_journal Bedingung geschlossen.
    
    elseif (status == 2)
                      ;Die Variable hat inzwischen den Wert 2
    
    if ( getAiPackageDone == 1 )
                      ;Wenn die zuletzt ausgeführte Bewegung beendet ist, also wenn der NPC seinen Zielpunkt erreicht hat, treten folgende Ereignisse ein (wenn die Ereignisse eintreten sollen, wenn er den Zielpunkt noch nicht erreicht hat, müsste man bei 1 eine 0 hinschreiben.
    
    NPCName->additem "Name der Rüstung" 1
                      ;In sein Inventar wird eine Rüstung eingefügt, normalerweise zieht er sie dann auch sofort an, wenn er mehr Rüstungen haben soll, müsste man die 1 entsprechend verändern.
    
    Setfight 100      ;Sein Aggressionswert wird auf 100 gesetzt, so dass er jetzt angreift. Der Wert bei Fight muss vorher natürlich auf 0 sein (einzustellen unter dem Button AI bei dem NPC).
    
    Startcombat player
                      ;Er greift sofort den Spieler an und nicht irgendjemanden anderen, der da gerade so herumsteht.
    
    Endif             ;Hiermit wird die Bedingung if getaipackage done wieder geschlossen.
    
    Endif             ;Hiermit wird die Bedingung if status == ... wieder geschlossen.
    
    
       ;Hiermit endet jedes Script.
    
    end
    Jetzt kannst Du z.B. beim Dialogfeld des NPCS im Feld "result" schreiben:
    Code:
    Journal caff_journal 10
    Dafür müsstest du unter journal einen Tagebucheintrag mit dem Namen caff_journal und der Indexnummer 10 erstellt haben, der dann durch das Gespräch mit dem NPC aktiviert würde.

    Wenn der NPC nicht kämpfen soll, sondern wenn du möchtest, dass er teleportiert wird, kannst Du statt dem SetFight und StartCombat eingeben:
    Code:
    NPC->positioncell x,y,z,rotation "Name der Zelle"
    Oder du kannst ihn mit NPC1->disable auch wieder verschwinden lassen und ihn an einer anderen Stelle auftauchen lassen, wenn Du vorher einen anderen gleichaussehenden NPC an eine andere bestimmte Stelle gestellt hast, den du vorher in dem globalen Script mit NCP_neu->disable hast verschwinden lassen.

    Mit NPC_neu->enable kannst Du den neuen NPC zu den von dir gewünschten Bedingungen dann mit einem Script wieder auftauchen lassen.


    Gerüst eines Scripts für eine Folge von Ereignissen

    Also das Gerüst eines Scripts, mit dem man mehrere Ereignisse hintereinander auslösen kann, sieht so aus (am besten, du schreibst es auch so versetzt, dann kannst du immer sehen wo noch ein endif fehlt):
    Code:
    
    Begin Scriptname
    
    
    Short status
    
    
    If ( status == 0 )
    
       if (Bedingung 2 )
    
          if ( Bedingung 3 )
    
    
             Ereignis 1
    
             Ereignis 2.....
    
             Set status to 1
    
          Endif
    
       Endif
    
    
    Elseif ( status == 1 )
    
       Ereignis 3
    
       Ereignis 4
    
       Set status to 2
    
    Elseif ( status == 2 )
    
    
       Ereignis 5
    
       Set status to 3
    Endif
    
    End
    Wichtig ist, dass in jedem Block immer nur die mit if begonnenen Bedingungen mit endif geschlossen werden müssen, nicht die mit elseif.

    Die Bedingung, die am Anfang mit if ( status == 0 ) begonnen wurde, wird erst am Schluss geschlossen, nach dem letzten elseif ( status == xx ).

    Hier noch eine etwas verfeinerte Variante, womit du noch bestimmen kannst, wie viel Sekunden zwischen den einzelnen Ereignissen verstreichen sollen. Hiermit könnte man z.B. eine Filmsequenz, d.h. eine Abfolge von Ereignissen, auslösen, die von dem Spieler beobachtet wird, aber sie ist auch für andere Sachen sehr nützlich.
    Code:
    
    Begin zeitscript
    
    
    Short status
    
    Float timer
    
       ;Diese Variable muss du am Anfang deklarieren, um den zeitlichen Ablauf bestimmen zu können.
    
    
    If ( status == 0 )
    
    Disableplayercontrols   ;Diesen Befehl eingeben, wenn der Spieler nur beobachten und nicht eingreifen soll, durch diesen Befehl wird er unbeweglich und kann nur beobachten. Ansonsten einfach weglassen.
    
    Set timer to ( timer + getsecondspassed )
    
       ;Hiermit wird die Variable timer auf die Anzahl der verstrichenen Sekunden gesetzt.
    
    if timer > 5
    
       ;Wenn 5 Sekunden verstrichen sind.
    
    Ereignis 1
    
    Ereignis 2
    
    Set timer to 0
    Set status to 1
    
       ;Die Variable timer muss wieder auf 0 gesetzt werden, sonst funktioniert das weitere Zählen nicht und status wieder eine Einheit höher, damit das nächste Ereignis ausgelöst werden kann.
    
    
    endif
    
       ;Die Bedingung if timer > 5 wird hiermit geschlossen.
    
    
    elseif ( status == 1 )
    
    Ereignis 3
    
    Ereignis 4
    
    Enableplayercontrols   ;Dadurch kann sich der Spieler wieder bewegen, wenn er bisher nur beobachten sollte.
    
    
    Endif
    
       ;Die Bedingung ( status == xx ) wird wieder hiermit geschlossen.
    
    end
  1. Diese Seite verwendet Cookies, um Inhalte zu personalisieren, diese deiner Erfahrung anzupassen und dich nach der Registrierung angemeldet zu halten.
    Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden