Scripting:Basic course

From STNE Wiki

Revision as of 20:09, 20 March 2011 by Cs.temp.mail (Talk | contribs)
Jump to: navigation, search

This page needs translation. You can help to complete the translation.



Main | Syntax | Operators | Interfaces | FAQ | Contents | API Reference | Index

This is a beginners course for the STNE engine script. It is not complete and probably not 100% correct. I have basically taught myself to use the STNE engine through trail and error, bad translation, good examples, and the benevolence of others. My spelling sucks. I'm sorry. If you see a mistake please fix it.

Contents

Vorwort

Much like the German version this course is aimed primarily at those who have never programmed and would like to start scripting in STNE. Please realize it is not easy and it will take a little while before you realize results. Be patient and keep at it! Like all good things it takes effort but it should be worth the time you put into it. I wish you the best of luck.

Chapter 1 - Strings

In programming a String is a series of characters. The chapter title would be a String as would this text. The famous line "Hello World!" is also a String and it is this String you will be working with.

"Hello World!"

We don't really know where it started but when first embarking on learning a programming language the first program you tend to write will be "Hello World!" In the STNE engine this is very easy. First launch the script editor under: Database -> Script Editor -> Create a new script -> Custom script without input wizard Then you will click "Edit source code". In the text field provided type:

WriteLine('Hello World!');

Now click Save&Run. Did it work? If not double check your input. Are the capital letters capital? Are there opening and closing quote marks and parentheses? Does it end with a semicolon? When it works you should see the line:

Hello World!
Congratulations you are now programming. Try making a program that says:
Hello World!
Live long and prosper!

Your code should look like this:

WriteLine('Hello World!');
WriteLine('Live long and prosper!');

Note every line of code ends with a semicolon. But what if you want to write everything on one line:

Hello World! Live long and prosper!

This is done by use of the & symbol:

WriteLine('Hello World!'&' Live long and prosper!');

The & symbol allows you to combine two Strings. It literately sticks them right next to each other which is why ' Live long and prosper!' has the preceding space. See what happens when you remove it!

"But wait!" You say. "I could simple code:
WriteLine('Hello World! Live long and prosper!');
and never have to deal with the & symbol!"

True, and as a programmer you will have many choices of different ways to do things. But the '&' is important as you will find out in the next chapter.

Summary: Strings

  • A String is a sequence of several characters.
  • A String is output, or printed, using the command WriteLine();.
  • You may use the character & to combine one String with another within the parameters, or parentheses, of WriteLine();.

Chapter 2 - Variables

Basic types

Think of a variable as a reference that you can use again and again and again. They can be a word, a number, or true/false. These are all called Data Types and, of course, each has a special name:

  • String - a series of characters
  • Integer - a whole number
  • Boolean - decision (True/False)

Variables

Imagine you have a gigantic project with hundreds of lines of code. Dozens upon dozens of times your code will output the lines:

Captains log Stardate:

You could code:

WriteLine('Captains log Stardate:');

every single time and maybe misspell it. Or you could use a variable. Before a variable can be used, or called, it must be created. You do this with the word "Var" followed by the name followed by "As" followed by the type of variable it is followed by "=" followed by the data to be stored.

Sound complicated? Bear with us.

In keeping with the above example let us declare a String variable that contains the line: 'Captains log Stardate:'

Var CL As String = 'Captains Log Stardate:';

the name can be anything you choose it to be. In this example we used the letters CL because they are an acronym for Captains Log but you could as easily use LC or X or foo. Choose something that makes sense to you because you will use it through your code. No two variables can have the same name though.

Lets create a number, or integer, variable:

Var SD As Integer = 234121;

Notice that because this is a number the type is Integer and because this is not a String we DO NOT put quotes around the assignment (what follows the equal sign). When you run this program, though, it doesn't seem to do much. That is because everything is happening behind the curtain and trust us you don't want to look back there! But if we add an output statement:

WriteLine(CL & SD);

Things start to happen. Cool huh? Just in case your having trouble your code should look like this:

Var CL As String = 'Captains Log Stardate:';
Var SD As Integer = 234121;
WriteLine(CL & SD);

Remember that variable assignments always have to come before variable calls. Your code is executed one line at a time and it needs to know what CL is before it can WriteLine CL. Also note the clever use of the & symbol. It stuck the integer and the string together! The output looks like:

Captains Log Stardate:234121

See if you can find a way to get a space between the colon and the number...

Captains Log Stardate: 234121

Converting One Data Type to Another

In many programming languages including an older version of the STNE engine you often need to convert variables from one type to another. For instance if you had a variable:

Var number As Integer = 12345;

You couldn't use it in certain functions like

WriteLine(number);

Because the parameters for WriteLine() would only accept Strings and the variable 'number' is an Integer.

In that case you would use another function CStr() to convert it to a String:

CStr(number)

You could even place that inside the parameters of WriteLine():

WriteLine(CStr(number));

Likewise you could covert a String to it's integer value with CInt();

But lucky for us the language is much smarter now and this has become a problem of such little significance that we can not even think up a satisfactory example.

Rules for Naming Variables

There are some rules for naming your variables

  • Do not duplicate names. Each script you make must only use a name once. Capitalization is significant though so while FOO and foo are different variables we would not recommend you use them because you might get confused.
  • Do not use spaces. Use capital letters to signify different words.
  • Do not use reserved names. Certain names are needed by the complier and by the STNE system and should be avoided. This names include dates, commands for system-defined functions, and features.
  • For clear coding consider starting your variable name with a three digits representing the variable type. For example:
intDeutNeeded
  • Remember always attempt to make your code as easy to understand as possible. Someday you will come back to it and try to understand what you were attempting.

Summary: Variables

  • A variable takes the place of "hard coded" data.
  • To create a variable use 'VAR Name AS Datentype;
  • To assign data to a variable you use Name = Inhalt;
  • To output a variable use WriteLine(Name); This can be very important when debugging.
  • The & symbol connects variables withing a function callWriteLine();

Kapitel 3 - Kontrollstrukturen

Da wir uns in Kapitel 2 mit Variablen beschäftigt haben, können wir uns nun dem eigentlichen Aufwand beim Programmieren zuwenden: den Kontrollstrukturen. Diese Wort klingt ersteinmal sehr hochtrabend, an und für sich ist es jedoch sehr einfach.

If - then - Else

Es werden 2 Variablen miteinander verglichen oder überprüft, ob eine Variable einem Wert entspricht und dann wird darauf reagiert.

VAR var1 AS Integer = 42;
if (var1 = 42)
{
  WriteLine('var1 ist 42');
}
else
{
  WriteLine('var1 ist nicht 42');
}

Dies ist ersteinmal sehr einfach und wirkt auf den ersten Blick sinnlos, was es auch ist. Aber es zeigt auf einfache Art, wie man 2 Werte miteinander vergleicht, dies kann man zum Beispiel dafür nutzen, um zu prüfen wieviel Lageraum ein Schiff noch hat. Dazu aber irgendwann später mehr. Bleiben wir bei dem Code und schauen ihn uns einmal genauer an: In der ersten Zeile wird die Variable var1 definiert, dies sollte aus Kapitel 2 bekannt sein.

If (var1 = 42)

Hier wird der Vergleich durgeführt, in diesem Fall wir geschaut ob der Wert von Zahl1 42 ist. Man könnte an dieser Stelle genausogut prüfen ob der Wert größer oder kleiner ist, als ein anderer. Hierfür nutzt man dann nicht "=" sondern "<",">","<=",">=" Innerhalb der { } folgt dann der Code, welcher ausgeführt werden soll, wenn die Bedigung stimmt, also in diesem Fall, wenn var1 gleich 42 ist.

Das folgende Else mit den Klammern gibt, welche Aktionen ausgeführt werden sollen, wenn die Bedingung nicht stimmt.

Zu guter letzt gibt es noch Elseif dies ist dafür gedacht wenn man mehr als eine Alternative hat. Beispiel

VAR var1 AS Integer = 42;
if (var1 < 42)
{
  WriteLine('var1 ist kleiner als 42');
}
elseif (var1 > 42)
{
  WriteLine('var1 ist größer als 42');
}
else
{
  WriteLine('var1 ist weder größer noch kleiner als 42');
}

Dies ist nicht auf ein elseif beschränkt, es können beliebig viele sein.

Schleifen

Die soeben kennen gelernten Strukturen helfen uns Fallunterscheidungen zu machen. Aber was machen wir wenn wir eine ganze Liste (zum Beispiel Schiffe) haben und die abarbeiten wollen? Dafür gibt es Schleifen, hier unterscheid man in drei Arten: Kopf-, Fuss- und Zählergesteuert.

while

While Schleifen sind Kopfgesteuert, dass heißt, solange die Bedingung zutrifft, wird der Inhalt der Schleife ausgeführt. Es gelten die selben Operatoren wie bei Abfragen mit if: =,<,>,>=,<=,<>

VAR i AS Integer;
i = 0;
WriteLine('Ich zähle jetzt bis Zehn');
while ( i <= 10)
{
  WriteLine(CStr(i));
  i = i + 1;
}

Solange i kleiner oder gleich 10 ist, wird i ausgegeben und dann einen hochgezählt. Bei Whileschleifen ist zu beachten, dass wenn die Bedingung zu Anfang bereits nicht erfüllt ist, dass sie dann nicht durchläuft. Soll sie mindestens einmal durchlaufen muss man Fussgesteuerte Schleifen wählen.

Do

Do-Schleifen sind Fussgesteuert. Sie funktionieren wie While-Schleifen nur das sie mindestens einmal durchlaufen.

VAR i AS Integer;
i = 10;
WriteLine('Ich zähle jetzt bis Null');
Do
{
  WriteLine(CStr(i));
  i = i -1;
}
While (i >= 0);

Gebe i solange aus und zähle einen runter, solange i größer gleich null ist. Aus der Beschreibung wird deutlich wo der unterschied zwischen While- und Do-Schleifen liegt.

In beiden Schleifen wird deutlich das ich jedes mal die Variable i runter bzw. hochzählen muss, um dies zu umgehen gibt es die möglichkeit Zählergesteuerte Schleifen zu verwenden.

For

For-Schleifen sind genau dies.

VAR i AS Integer;
For ( i = 0 To 10)
{
  WriteLine(CStr(i));
}

auf diese Weise kann man sich ein wenig Arbeit abnehmen, da die Schleife einem das Zählen abnimmt. So kann man auch Endlosschleifen vermeiden, die auftreten wenn man vergisst, die Schleifenvariable (in diesen Fällen immer i) runter- bzw. hochzuzählen.

For-Schleifen bieten noch eine weitere Möglichkeit: Es kann angegeben werden in welchen Schritten die Schleife zählt.

VAR i AS Integer;
For ( i = 0 To 100 Step 10)
{
  WriteLine(CStr(i));
}

Der Code ist der bis auf das Step identisch. Die Zahl die hinter Step steht kann sowohl positiv als auch negativ sein.

Kapitel 4 - Der Shipmanager - Einführung

Nachdem wir nun über ein paar Grundlagen verfügen, wollen wir uns den wirklich interessanten Dingen zuwenden, der Steuerung von Spielinhalten durch Scripte.

Um mit Schiffen zu interagieren gibt es eine Sammlung von Methoden, welche im Shipmanager zu finden sind. Hierzu müssen wir dem Shipmanager als erstes Mitteilen, welches bzw. welche Flotte er verwenden soll.

Hierführ gibt es die Befehle:

ShipManager.BenutzeSchiff(NCC-Nummer des Schiffes);

bzw.

ShipManager.BenutzeFlotte(ID der Flotte);

Damit weiß der ShipManager schonmal welches Schiff, bzw. welche Flotte die Aktionen ausführen soll.

Mit dem Shipmanager können folgende Aktionen ausgeführt werden:

  • An- und Abdocken
  • Alarm Stufe ändern
  • Aus Flotten austreten
  • Aus Orbit einfliegen austreten
  • Benennen(Name As String)
  • Deuterium sammeln (Nur mit FP)
  • Erz sammeln (Nur mit FP)
  • Fliegen
  • Sensoren aktivieren / deaktivieren
  • Reparieren
  • Batterien entladen
  • Schilde aktivieren/deaktiviere/aufladen
  • Reservebatterie aufladen
  • Traktorstrahl ein- / ausschalten
  • Beamen
  • Verstecken
  • Replikator aktivieren/deaktivieren
  • Waren über Bord werfen
  • Warpkern aktiveren/deaktivieren
  • Wrackextraktoren

Eine vollständige Auflistung aller Funktionen findet sich im Objekt-Explorer.

Im folgenden wollen wir uns einige Funktionen genauer anschauen:

Beamen

Syntaxe:

ShipManager.TransferiereZuSchiff(Schiffid, Menge, EBeamRessource.Ware);

Hier musst du nun nurnoch den kursiven Text mit deinen Angaben ersetzten. Hier ein Beispiele:

ShipManager.BenutzteSchiff(1);
ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);

Natürlich kann man auch eine ganze Flotte beamen lassen, dazu ersetzt du ShipManager.BenutzteSchiff(1); durch ShipManager.BenutzteFlotte(1); Dann sieht das Script folgendermasen aus:

ShipManager.BenutzteFlotte(1);
ShipManager.TransferiereZuSchiff(2, 20, EBeamRessource.Nahrung);

Fliegen

Bei der Syntaxe gibt es 2 Möglichkeiten, die eine für Spieler unter Level 8 oder mit Feature-Pack, also mit Autopilot, und die andere für die Leute über Level 8 und ohne Feature-Pack, die Variante ohne Autopilot.

Fliegen mit dem Autopiloten

Nur für Spieler mit Feature-Pack oder unter Kolonisationslevel 8 möglich!

Der Befehl:

ShipManager.FliegeZu(xxx|yyy);

Auch hier Gilt es wieder das kursive durch die eigenen Angaben zu ersetzten. Wie in folgendem Beispiel:

ShipManager.BenutzteSchiff(1);
ShipManager.FliegeZu('123|465');

oder mit dem Flottenbefehl:

ShipManager.BenutzteFlotte(1);
ShipManager.FliegeZu('123|465');

Mit deisem Befehl fliegt das Schiff zu einer belibigen Position, NPC-Gebiete ausgenommen, und umgeht dabei wie der Autopilot Energie-intensive Hindernisse, sowie solche die das Schiff oder die Crew Gefährden.

Fliegen ohne Autopilot

Der Befehl hierzu sieht wie folgt aus:

ShipManager.Fliege(Strecke, EShipRichtung.Richtung);

Auch hier ersetzt du die kursiven Worte mit deinen Angaben, ein Beispiel folgt:

ShipManager.BenutzteSchiff(1);
ShipManager.Fliege(5, EShipRichtung.Hoch);
ShipManager.Fliege(8, EshipRichtung.Links);

oder wenn es eine ganze Flotte ist:

ShipManager.BenutzteFlotte(1);
ShipManager.Fliege(5, EShipRichtung.Hoch);
ShipManager.Fliege(8, EshipRichtung.Links);

Schiffsystem nutzen

kommt noch

Alternative zum Schiffsmanager: Schiffsaktion

Für Objekte des Typ's CMyFlotte und CMyShip kann über die Eigenschaft Aktion direkt auf die Funktionen des Schiffsmanagers zugegriffen werden.

VAR Schiff AS CMyShip = new CMyShip( 4711 )
Schiff.Aktion.Abdocken()
VAR Flotte AS CMyFlotte = new CMyFlotte( 4711 )
Flotte.Aktion.Abdocken()

Enumeration ist Alles

kommt noch

Methoden

Öfters wiederkehrende Aufgaben können in Methoden zusammengefasst werden:

Function ShowKoords(x As Integer, y As Integer)
{
  WriteLine(CStr(x) + '|' + CStr(y));
}

Die Methode ShowKoords kann dann im Script folgendermaßen aufgerufen werden:

ShowKoords(3, 4);
ShowKoords(ship.MapPosition.X,ship.MapPosition.Y);

Wenn berechnete Werte von der Methode zurückgegeben werden sollen:

Function Distanz(x1 As Integer, y1 As Integer, x2 As Integer, y2 As Integer) As Integer
{
  Var distanz As Integer;
  
  distanz = Math.Abs(x1 - x2) + Math.Abs(y1 - y2);
  Return distanz ;
}

WriteLine(Distanz(1, 1, 5, 5));

Einfache Typen werden immer 'ByVal' übergeben, d.h. die Werte werden als Kopie an die Methode übergeben und die entsprechenden Variablen im Script nicht verändert. 'ByRef' ist zwar in der Scriptengine vorgesehen und kann angegeben werden, ist aber derzeit ohne Funktion. Objekte werden immer ByRef übergeben.

Klassen

In Klassen können Daten und Methoden in einem Objekt gekapselt werden:

Class CKoords
{
  Var x As Integer;
  Var y As Integer;
  
  Function New(x As Integer, y As Integer)
  {
    This.x = x;
    This.y = y;
  }
  
  Function ToString() As String
  {
    Return (CStr(x) + '|' + CStr(y);
  }
  
  Function Distanz(koord As CKoords) As Integer
  {
    Return Math.Abs(x - koord.x) + Math.Abs(y - koord.y);
  }
}

Var ko1 As New CKoords(3, 5);
Var ko2 As CKoords;


ko2 = New CKoords(8, 9);
WriteLine('Distanz von ' + ko1.ToString() + ' nach ' + ko2.ToString() + ': ' + CStr(ko1.Distanz(ko2)));

Wichtig: Klassen brauchen immer eine Methode New(), sonst kann kein neues Objekt der Klasse generiert werden!

Autoren

(hier dürfen sich diejenigen verewigen die hier min. ein Kapitel geschrieben haben [sonst kommt noch einer daher nur weil er nen Rechtschreibfehler verbessert hat ;)])

Nickname IG-id Kapitel
WiZz4Rd 16475 Kapitel 1, Kapitel 2, Kapitel 4
Stryke 28885 Vorwort, Kapitel 3, Kapitel 4
Xenon 10127 Korrektur & Überarbeitung Kapitel 1
Fling 54865 Kapitel 7, Kapitel 8


Anfängerkurs

Personal tools