Den Roboter mit einem Script Programmieren



Die Programmiersprache 'script' wird verwendet um den Roboter zu programmieren;
dafür müssen Sie eine Datei SCRIPT.TXT wie das folgende Beispiel
in den Ordner vom Roboter kopieren.

--------------------------------------------------------------------------------

// Hier ein einfacher script der Hallo zu allen reinkommenden Leuten sagt

proc event (session_key, userid$, sex$, has_photo, age, is_away,
            admin, cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{
  if (action == 128)   // action 128 zeigt einen reinkommenden chatter an
  {
    // mit dem Kommando print kann man eine Zeile auf dem chat schreiben
    print ("Willkommen im Raum " + userid$ + " :p");
  }
}

--------------------------------------------------------------------------------

notiz:
1 - wenn Sie ihren script ändern, drücken Sie die F5 Taste um ihn neu zu laden.
2 - sie können mehrere script dateien mit der endung "SCRIPT.TXT"
    in den Roboter Ordner tun (z.b: SCRAB-SCRIPT.TXT, ROBOT-SCRIPT.TXT),
    alle scripts werden dann in alphabetischer reihenfolge ausgeführt.


Auf diesem script beispiel sehen sie eine prozedur "event" die bei jeder
aktion im raum ausgeführt wird.

Diese prozedur "event" bekommt die folgenden Informationen über den
Chatter der mit der Aktion zu tun hat :


session_key: nummer die mit der ankunft des chatters im raum zusammenhängt
             und die ihn begleiten wird bis er den raum verlässt;
             der session_key wird unter anderem benutzt um den chatter
             zu wählen der rausgeworfen wird.
userid$    : name des chatters
sex$       : geschlecht des chatters ("M", "F" oder "C")
has_photo  : zeigt an ob der chatter ein foto im profiel hat (0=nein, 1=ja)
age        : alter des chatters
is_away    : zeigt an ob er in Tasse ist (0=nein, 1=ja)
admin      : zeigt an ob er gerade seinen Hammer genommen hat (0=kein hammer, 1=braunen, 2=goldenen)
cam_on     : zeigt an ob seine webcam an ist (0=nein, 1=ja, 2=ja und cam wurde von einem Anim überprüft)
is_bot     : zeigt an ob er ein roboter ist (0=nein, 1=ja)
toc_capab  : zeigt an ob er in der Lage ist einen Hammer zu nemen (0=nein, 1=braunen, 2=goldenen)
signature$ : Unterschrift des chatters, z.b. "1234567890ABCDEF"
suffix$    : Unterschrift Suffix (nach dem Doppelpunkt), z.B: "FAB2"
profile_life : Anzahl Tage seit das Profil angelegt wurde
action     : Aktion-Typ, siehe Liste unten
is_myself  : zeigt an ob der chatter dieser Roboter ist (also sich selber) (0=nein, 1=ja)
line$      : zeigt die Text Zeile an die von chatter geschrieben wurde, siehe unten


Mögliche Aktionen
-----------------
Hier ist eine Liste aller Aktionen, mit deren Nummer :

   Nr   Aktion
------  ------
    0   Chatter schreibt eine normale Textzeile
    1   Chatter schreibt eine Gedankenzeile (mit dem Ballon Ikon)
    2   Chatter geht weg (in Tasse) oder kommt zurück
   16   Chatter nimmt Hammer oder legt ihn nieder
  127   Chatter war schon im Raum vor diesem Roboter
  128   ein neuer Chatter betritt den Raum
  129   Chatter verlässt den Raum in einer normalen weise / oder wird in einen anderen Raum teleportiert
  130   Chatter wurde von Server getrennt
  200   Chatter flüstert dem Roboter (pv)
  204   Das Flüstern vom Chatter wurde mit dem durchgestrichenen Telefon blockiert (line$ enthält den Pseudo vom Blockierer)
  240   Manager gibt provisorischen Toc (line$ enthält die 10-Ziffern session_key und userid des Empfängers)
  241   dasselbe als 240 aber um den Toc zurück zu nemen
  256   Chatter wurde aus dem Raum geworfen
  300   Chatter hat auf Text Zone geklickt - siehe chr$(3,a,b,c) unten
  400   Chatter hat eine neue Nachricht in der Gruppe hinterlassen
             (mit Pannel Nr (9 Ziffern), Nachricht Nr (9 Ziffern), und Thema in line$)
  512   Chatter spricht am Mikrophon
  550   Chatter schaltet seine Webcam an oder aus
  601-609 Chatter klick auf einen chat menu button (siehe Befehle um einen Button einzufügen)
  912   Chatteur klickt auf 3D Actor (line$ enthält Actor's session_key in 10 Ziffern)
  915   Chatter hat auf ein clickbares 3D Objekt geklickt (line$ enthält die Nr des 3D-Objektes in 1-bis-6 Ziffern)


Text Zeile line$
----------------
Die Text Zeile line$ enthält druckbare Zeichen (ascii codes 32 bis 255)
aber sie enthält auch spezielle 4- oder 8-zeichen sequenzen die mit
einem zeichen zwischen chr$(0) und chr$(9) beginnen, zum beispiel :

chr$(0,n%256,n/256,0)    : emoticon N
chr$(1,rot,grün,blau)    : farbe (rot, grün und blau sind Werte zwischen 0 und 255)
chr$(2,schrift,styl,0)   : schriftart oder styl (siehe Kapitel macros)
chr$(3,a,b,c)            : Text Zone Markierung - chr$(3,0,0,0) ist die End-Markierung
chr$(4,a,b,c)            : (wird noch nicht verwendet)
chr$(5,a,b,c)            : (wird noch nicht verwendet)
chr$(6,a,b,c,d,e,f,g)    : Bild (jpeg/gif/bmp/png)
chr$(7,a,b,c,d,e,f,g)    : Ton (wav)
chr$(8,a,b,c,d,e,f,g)    : (wird noch nicht verwendet)
chr$(9,a,b,c,d,e,f,g)    : (wird noch nicht verwendet)


Z.b, wenn Sie "Hello" auf dem chat schreiben, könnten userid$ und line$ die folgenden Werte haben :

userid$=[0,11,1,0,6,16,156,56,39,33,252,127,65,0,4,0,0]
line$=[0,50,0,0,0,11,1,0,6,16,156,56,39,33,252,127,65,0,4,0,0,32,58,32,1,12,94,254,2,2,0,0,72,101,108,108,111]


Die elemente von line$ sind :

0 50 0 0                  : emoticon 50  ":M"
0 11 1 0                  : emoticon 267 (11 + 1*256) "$nr"
6 16 156 56 39 33 252 127 : Bild (banner vom chatter)
65                        : buchstabe A
0 4 0 0                   : emoticon 4 ";)"
32                        : leerzeichen
58                        : zeichen ':' zwischen pseudo und text zeile
32                        : leerzeichen
1 12 94 254               : ein farb-code (rot=12,grün=94,blau=254)
2 2 0 0                   : ein schrift code (2=Arial)
72 101 108 108 111        : "Hello" in ascii


Wenn action==0, dann hat line$ immer die folgende Struktur :

- ein emoticon (oder ein Bild falls der Raum-Eigentümer seine eigenen Ikone gezeichnet hat)
- der Inhalt von userid$, also das pseudo vom chatter, das mehrere Text, Ikon oder Bild-Sequenzen
  beinhalten kann,
- die folge : leerzeichen, zeichen ':', leerzeichen
- dann die text Zeile, die irgend welche folgen von text, schrift oder Farb-Sequenzen beinhalten kann.


Der folgende Test Script erlaubt es ihnen tests zu machen um den Inhalt von line$ besser zu verstehen :


proc event (session_key, userid$, sex$, has_photo, age, is_away,
            admin, cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{
  var i, s$, u$;
  if (!is_myself)
  {
    for (i=1; i<=len(line$); i++)
    {
      if (i > 1)
        s$ = s$ + ",";
      s$ = s$ + str$(asc(line$,i));
    }
    for (i=1; i<=len(userid$); i++)
    {
      if (i > 1)
        u$ = u$ + ",";
      u$ = u$ + str$(asc(userid$,i));
    }
    print ("action=" + str$(action) + " userid$=[" + u$ + "] line$=[" + s$ + "]");
  }
}



Elemente der Script Sprache
===========================

Daten
=====

Die Script Sprache verarbeitet zwei arten von Daten :

1) ganzzahlige Nummern :

        9  -62  136  0xFFD2

Alle Werte müssen zwischen -2147483647 und +2147483647 liegen.
Die nummer 0xFFD2 ist in hexadecimal (basis 16 anstatt der gebräuchlichen basis 10).


2) zeichenfolgen :

       ""    "Guten Tag"   "Ja:p"

die erste zeichenfolge hier oben ist leer (enthält null zeichen).
die maximale länge einer zeichenfolge ist 8192 zeichen.


Variablen
=========

Eine variable ist eine Speicherzelle vom PC die einen Namen erhalten hat;
diese Speicherzelle kann einen Daten-Wert speichern der sich ändert während das Programm läuft.

Es gibt zwei arten von variablen :

- die die eine ganzzahligen Nummer enthalten (z.b: count, i, player)

- die die eine zeichenfolge enthalten (z.b: fruit$, user$)
  (diese variablen enden immer mit einem dollar zeichen '$')


Bevor Sie eine variable benutzen müssen Sie sie erst 'deklarieren',
d.h. speicherplatz für ihren Wert reservieren, mit dem Kommando 'var'.

beispiel:

  var count;       // wird einen Zähler enthalten
  var user$, t$;   // zwei zeichenfolgen variablen
  var fruit$[3];   // eine Tabelle mit 3 zeichenfolgen : fruit$[1], fruit$[2] and fruit$[3]

Variablen können an zwei Plätzen deklariert werden,
- entweder am Anfang des scriptes,
- oder am Anfang einer Funktion oder Prozedur.

Wenn Sie am Anfang des scriptes deklariert werden, dann behalten sie ihren Wert
von einer Aktion zur nächsten; andernfalls werden sie jedes mal gelöscht.

Am Anfang enthalten numerische variablen den Wert null,
und zeichenfolge variablen enthalten eine leere zeichenfolge.



Prozeduren und Funktionen
=========================

Eine Prozedur ist ein Kommando das Parameter bekommen kann, z.b. 'print'
kann die zeichenfolge "Welcome !" bekommen, das schreibt sich so :

  print ("Welcome !");

Eine Funktion sieht wie eine Prozedur aus, sie rechnet aber zusäztlich einen Ergebnis-Wert aus,
z.b. die Funktion 'len' die die länge einer zeichenfolge errechnet :

  laenge = len ("abc");


Die folgenden standard Prozedures/Funktionen existieren :

Robot Befehle
-------------
print ("Willkommen !");          // bot sendet eine text zeile auf den chat
bubble ("thinks he's right :p"); // bot sendet einen gedanken (mit blasen Ikon)
away ();                         // bot geht weg (in tasse) oder kommt wieder
toc ();                          // bot nimmt seinen Hammer oder legt ihn nieder
kick (session_key, "geh zu bett");// bot wirft den chatter raus mit der angegebenen session_key nummer


Befehle um einen Button einzufügen
----------------------------------
Um einen Button (Knopf) im chat menü einzufügen der eine Action 601 bis 609
generieren wird wenn man drauf klickt :

  create_button (session_key, 601, "{lock01}");  // mit Ikon
  create_button (session_key, 602, ":)");        // mit smiley
  create_button (session_key, 603, "T");         // mit Text

Die Action 601 bis 609 wird in line$ den session_key vom chatter der klickt enthalten (in 10 ziffern),
gefolgt von dem Text der auf der Chat Zeile getippt wurde.

Um den Button zu löschen :

  delete_button (session_key, 601);


Teleportations Befehle
----------------------
Um einen Chatter in einen anderen Raum zu teleportieren (der bot muss einen Toc haben) :

    teleport (session_key, x, y, z, dir);            // um einfach die 3D Koordinaten zu ändern
    teleport (session_key, x, y, z, dir, port);      // IP nicht nötig falls selber router oder PC
    teleport (session_key, x, y, z, dir, port, ip$);


Kalendar
--------
d$ = now$ ();           // funktion die das heutige datum berechnet
                        // beispiel: now$() == "2007/01/17 12:23:12"

d  = weekday (d$);      // berechnet den wochentag (1=montag, 7=sonntag) des angegebenen datums
                        // beispiel: weekday("2007/01/17 12:23:12") == 2

d$ = add_date$ (d$,n);  // berechnet ein datum das um n sekunden älter gemacht wurde
                        // beispiel: add_date$("2007/01/17 12:23:12", 3600) == "2007/01/17 13:23:12"

n = nb_days_since_1901 (d$);  // berechnet die anzahl Tage zwischen dem 1/1/1901 und das angegebene Datum,
                              // was benutzt werden kann um die anzahl Tage zwischen zwei Datum zu berechnen:
                              // nb_days_since_1901 (date2$) - nb_days_since_1901 (date1$)

Numerisch
---------
n = random (a,b);       // berechnet eine zufallszahl zwischen a und b
                        // beispiel: random(1,50) == 12

n = abs (n);            // berechnet den absoluten wert von n
                        // beispiel: abs(-2) == 2

n = sin (angle, M);     // berechnet den sinus(angle), multipliziert mit M

n = cos (angle, M);     // berechnet den cosinus(angle), multipliziert mit M

angle = atan2 (Y, X);   // berechnet den Winkel : arctangent von (Y / X)

n = sqrt (n, M);        // berechnet die Quadrat Wurzel von n, multipliziert mit M


Zeichenfolge
------------
n  = len(s$);           // berechnet die länge der zeichenfolge s$
                        // beispiel: len("abc") == 3

s$ = dup$(s$,N);        // berechnet die zeichenfolge s$ N-mal dupliziert (mit N >= 0)
                        // beispiel: dup$("ab",3) == "ababab"

s$ = chr$(N1,N2,N3,..); // berechnet eine zeichenfolge die aus den ascii zeichen N1,N2,.. besteht
                        // example: chr$(65,66,67) == "ABC"

c  = asc(s$[,N]);       // berechnet die ascii nummer des Nten zeichen der zeichenfolge s$ (N=1 wenn nicht angegeben)
                        // beispiel: asc("A") == 65
                        // beispiel: asc("ABC",2) == 66

s$ = str$(N);           // berechnet eine zeichenfolge die der nummer N als zeichenfolge entspricht
                        // beispiel: str$(23) == "23"

n  = val(s$);           // berechnet die nummer die der zeichenfolge s$ entspricht (das umgekehrte von str$)
                        // beispiel: val("23") == 23

s$ = left$(s$,N);       // berechnet die N linken zeichen von s$
                        // beispiel: left$("ABCD",2) == "AB"

s$ = right$(s$,N);      // berechnet die N rechten zeichen von s$
                        // beispiel: right$("ABCD",2) == "CD"

s$ = mid$(s$,a,N);      // berechnet N zeichen von s$ ab dem 'a'ten zeichen
                        // beispiel: mid$("ABCDEF",2,3) == "BCD"

i  = pos(s1$,s2$);      // berechnet die position von s2$ in s1$, oder 0 falls nicht gefunden
                        // beispiel: pos("ABCDEF","CD") == 3
                        // beispiel: pos("ABCDEF","X") == 0

Eingabe/Ausgabe
---------------
n = count_lines ("quizz.txt");     // berechnet die anzahl von zeilen in der datei im Roboter ordner
                                   // beispiel: count_lines ("quizz.txt") == 120

l$ = read_line$ ("quizz.txt", i);  // berechnet die i'te zeile der Datei
                                   // beispiel: read_line$ ("quizz.txt", 3) == "Frage 3 : now ..."

i$ = image$("a.jpg");              // berechnet das Bild oder den Ton in einer datei im Roboter ordner
i$ = sound$("a.wav");              // beispiel: print ("eine kuh : " + image$("images/kuh.jpg"));

s = selected_user_session_key();   // berechnet die session_key des chatters der in der rechten Liste
                                   // auf dem Bot-Schirm selektiert wurde, oder null whenn kein chatter selektiert ist.


Datenbank
---------
store (schublade$, wert$);  // speichert den wert$ in der schublade$ der datenbank chat.db
                            // beispiel: store ("GAME-1", "1 35 16 32 89 12");
                            // die länge von tiroir$ muss 100 nicht überschreiten.

a$ = fetch$ (schublade$);   // berechnet den wert der in der schublade schublade$ der datenbank ist
                            // beispiel: fetch$ ("GAME-1") == "1 35 16 32 89 12"

Timer
-----
set_timer (n);     // ruft die Prozedur timer() in n sekunden auf (oder nie wenn n==0)



Zusäzlich zu den existierenden Prozeduren und Funktionen die hier oben beschrieben wurden
können Sie neue definieren; hier sind drei Beispiele :

// eine Funktion die den Wert n verdoppelt
func double (n)
{
  var result;
  result = n * 2;
  return result;
}

// eine Funktion die eine zeichenfolge von N minus zeichen baut
func tiret$ (n)
{
  return dup$("-", n);
}

// eine Prozedure die N minus zeichen auf dem chat anzeigt
proc print_tiret (n)
{
  print (tiret$(n));
}


Operatoren
==========

Operatoren werden benutzt um berechnungen durchzuführen, z.b:

    2 + 3 * 4

Jeder operator hat eine priorität, z.b * hat eine höhere priorität als
+, folglich ist die Formel oben gleich mit dieser Formel :

    2 + (3 * 4)

und nicht gleich zu :

    (2 + 3) * 4

Wenn die letzte berechnung gewünscht ist, muss man klammern benutzen.


Hier sind die verfügbaren operatoren, in reihenfolge absteigender priorität :

numerische operatoren
---------------------
 !     logisches NICHT
 *     multipliziert mit
 /     geteilt durch
 %     rest der teilung
 &     bitweises UND
 |     bitweises ODER
 +     addieren
 -     subtrahieren
 <=    kleiner als, oder gleich
 >=    grösser als, oder gleich
 ==    gleich zu
 !=    nicht gleich zu
 <     kleiner als
 >     grösser als
 &&    logisches UND
 ||    logisches ODER

zeichenfolge operatoren
-----------------------
 +     zwei zeichenfolgen zusammenschmieden (eine hinter der anderen)
 <=    kleiner als, oder gleich (lexicographische reihenfolge = wörterbuch)
 >=    grösser als, oder gleich
 ==    gleich zu
 !=    nicht gleich zu
 <     kleiner als
 >     grösser als


beispiel:

  if ("ab" < "abc")
    print ("ab kommt vor abc im Wörterbuch");



Instruktionen
=============

assignation
-----------
Die assignation instruktion wird verwendet um eine berechnung durchzuführen (rechts)
und das resultat in die variable (links) zu speichern.

  result = a * b + c;          // berechne '(a * b) + c' und speicher das ergebnis in der variable 'result'
  line$ = "Hello" + userid$;   // schmiede beide folgen "Hello" und userid$ zusammen, und speicher in line$
  fruit$[2] = "apfel";         // speicher die zeichenfolge "apfel" in der zelle 2 der tabelle fruit$
  ligne$ = "i enthält den wert " + str$(i);
  length = len(s$) + 1;

Assignation mit incrementation erlaubt es eine Wert zu der linken variable
zu addieren oder von ihr zu subtrahieren.

  i += 72;             // addiere 72 zu i
  j -= (b + c);

Einfache incrementation erlaubt es 1 zu addieren oder zu subtrahieren :

  i++;       // addiere 1 to i
  j--;       // subtrahiere 1 von i



If instruktion
--------------

Die IF instruktion erlaubt es eine gruppe von instruktionen
nur auszufüllen wenn eine bedingung erfüllt ist.


  // if mit einfacher instruktion

  if (i < 10)
    print ("i zu klein");   // print nur ausführen wenn i kleiner als 10 ist



  // if mit mehreren instruktionen
  // notiz: { } sind obligatorisch im falle mehrerer instruktionen

  if (i < 10)
  {
    print ("i zu klein");
    print ("probier nochmal");
  }



  // "if" mit "else" klausel

  if (i < 10)     // wenn i kleiner als 10 ist
  {
    print ("i zu klein");
    print ("probier nochmal");
  }
  else           // sonst
  {
    print ("i grösser als oder gleich zu 10 !");
  }



  // "if" mit mehreren teilen

  if (i < 10)     // wenn i kleiner als 10 ist
  {
    print ("i zu klein");
    print ("probier nochmal");
  }
  else if (i == 10)          // sonst wenn i gleich 10 ist
  {
    print ("i ist gleich 10 !");
  }
  else                       // sonst (i grösser als 10)
  {
    print ("i grösser als 10 !");
  }



  // if mit komplexer berechnung

  if (i < 10 && j == 3 && a$ == "hello")    // if i < 10 UND j == 3 UND a$ == "Hello"
    print ("ja");

  if (i < 10 || j == 3 || a$ == "hello")    // if i < 10 ODER j == 3 ODER a$ == "Hello"
    print ("ja");



  // if mit leerer instruktion

  if (i < 10)
    ;          // mache nichts
  else
  {
    print ("ja");
  }



FOR instruktion
---------------

Die FOR instruktion erlaubt es eine gruppe von instruktionen
zwischen { } zu wiederholen, indem der Wert einer Variable bei jeder ausführung erhöht wird.

beispiele:


  // um die nummern von 1 bis 5 auszudrucken :

  for (i=1; i<=5; i++)
  {
    print (str$(i));
  }

  druckt:
    1
    2
    3
    4
    5


  // um die nummern von 5 bis 1 auszudrucken :

  for (i=5; i>=1; i--)
  {
    print (str$(i));
  }

  druckt:
    5
    4
    3
    2
    1


WHILE instruktion
-----------------

Die WHILE instruktion erlaubt es eine gruppe von instruktionen zu wiederholen
solange eine bedingung wahr ist.

  // solange i <= 10,
  // wiederhole die instruktionen zwischen { }

  i = 1;
  while (i <= 10)
  {
    print ("Hallo");
    i++;
  }


  // laufe auf tabelle tab[]
  // bis ein wert 6 gefunden ist

  var tab[512];

  .......

  i = 0;
  while (i <= 512 && tab[i] != 6)   // solange i <= 512 und tab[i] nicht gleich 6, erhöhe i um 1.
  {
    i++;
  }



break und continue
------------------

  // die 'break' instruktion endet die wiederholung sofort

  for (i=1; i<=6; i++)
  {
    if (i == 3)
      break;
    print (str$(i));
  }

  druckt:
    1
    2



  // die 'continue' instruktion geht zu nächsten wiederholung über

  for (i=1; i<=6; i++)
  {
    if (i == 3 || i == 5)   // wenn i gleich 3 oder 5, geh zum nächsten i
      continue;
    print (str$(i));
  }

  druckt:
    1
    2
    4
    6



timer Prozedur
==============

Wenn Sie eine "timer" Prozedur in ihren script zufügen,
wird diese einmal ausgeführt wenn sie den Raum betreten.

Danach können sie mit der Prozedur set_timer(N) eine nochmalige Ausführung
nach N sekunden verlangen. Wenn N == 0, dann wird eine nochmalige Ausführung annuliert.

Beispiel
--------

proc timer ()
{
  print ("diese Meldung wird jede 30 Sekunden wiederholt");

  if (mid$(now$(),12,5) == "12:00")
    print ("es ist 12 uhr !");

  if (mid$(now$(),12,5) == "13:00")
    print ("es ist 13 uhr !");

  set_timer (30);   // timer() nochmal in 30 Sekunden ausführen
}



Die Ikone CAM neben dem Raum-Namen anzeigen
===========================================

Die Ikone CAM erscheint automatisch neben dem Raum-Namen wenn
sich im Raum ein bot befindet der mit bot.txt so eingestellt ist
dass webcams obligatorisch sind.

Wenn Sie ihren eigenen script haben um webcams obligatorisch zu machen,
können Sie die Ikone CAM manuell erscheinen lassen, indem Sie das folgende
Kommando in chatserv.ini zufügen :

  [settings]
  cams = oblig   ; cams obligatorisch



Eine Text-Zone clickbar machen
==============================

Indem Sie eine Text-Zone markieren können Sie sie clickbar machen,
d.h. wenn ein Chatter mit der Maus auf die Text-Zone klickt
wird dem Bot eine Action 300 gesendet bei der line$ den markierungs-code
enthält.

Eine markierung beginnt immer mit dem code 3. End-Markierungen sind immer chr$(3,0,0,0).

Markierung chr$(3,255,a,b) is reserviert für das mine Spiel vom Bot.

Beispiele:

  print (chr$(3,0,0,1) + image$("logo.gif") + chr$(3,0,0,0));

  print (chr$(3,0,0,1) + image$("logo1.gif") +
         chr$(3,0,0,2) + image$("logo2.gif") +
         chr$(3,0,0,0));

  print ("Logo 1 : " + chr$(3,0,0,1) + image$("logo1.gif") + chr$(3,0,0,0) +
         "Logo 2 : " + chr$(3,0,0,2) + image$("logo2.gif") + chr$(3,0,0,0) +
         "Logo 3 : " + chr$(3,0,0,3) + image$("logo3.gif") + chr$(3,0,0,0));

...

  if (action == 300)
    print ("sie haben auf das logo " + str$(asc(line$,4)) + " geklickt");




Fehler
======

Die folgenden Fehler können während der Ausführung eines scriptes auftreten :

  1 "array index out of range"   : index der tabelle [] ist ausser limit
  2 "division by zero"           : teilung durch null ist nicht erlaubt
  3 "string too long"            : zeichenfolge zu lang - kann 8192 zeichen nicht überschreiten
  4 "out of string space"        : zu viele zeichenfolgen, der speicher ist voll
  5 "bad argument"               : schlechter wert für standard funktion
  6 "application hangs"          : der script hat schon 100 million instruktionen ausgeführt
                                   und scheint im kreis zu laufen
  7 "missing return in function" : funktion ohne "return" instruktion
  8 "expression too complex"     : zu viele parameter oder aufrufe
  9 "callstack full"             : zu viele parameter oder aufrufe

Die Fehler 10 bis 15 signalisieren ein problem innerhalb der chat software :

 10 "arithmetic stack empty"
 11 "unknown pcode",
 12 "outside code range"
 13 "outside var range"
 14 "ret outside range"
 15 "astack corrupt"



Beispiel Scripts
================


////////////////////////////////////////////////////////////////////////////////


//  Beispiel 1 : Uhr

proc event (session_key, userid$, sex$, has_photo, age, is_away,
            admin, cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{
  var heure, phrase$, phrase2$;

  if (action == 128)
  {
    heure = val (mid$(now$(),12,2));

    if (heure >= 12 && heure <= 13)
      phrase$ = "Guten Appetit$mi ";
    else if (heure >= 0 && heure <= 4)
      phrase$ = "Gute Nacht(s) ";
    else if (heure >= 6 && heure <= 19)
      phrase$ = "Guten Tag:) ";
    else
      phrase$ = "Guten Abend;) ";

    if (sex$ == "F")
      phrase2$ = " (f)";
    else
      phrase2$ = " (y)";


    print (phrase$ + userid$ + phrase2$
            + ", es ist " + right$(now$(),8)  + "(o)");
  }
}


////////////////////////////////////////////////////////////////////////////////


//  Beispiel 2 : Spiel "Vier Gewinnt"

var jeu;         // 1 = spiel actiev
var tab[35];     // 5 lignes de 7 colonnes
var joueur;


proc effacer_table ()
{
  var i;
  for (i=0; i<35; i++)
    tab[i] = 0;
}


proc afficher_table ()
{
  var line, col, line$, i;

  i = 0;

  for (line=0; line<5; line++)
  {
    line$ = "   ";

    for (col=0; col<7; col++)
    {
      if (tab[i] == 0)
        line$ = line$ + chr$(1,0,0,0) + ".";
      else if (tab[i] == 1)
        line$ = line$ + chr$(1,0,0,255) + "X";
      else
        line$ = line$ + chr$(1,255,0,0) + "O";
      i++;
    }

    print (chr$(2,5,4,0) + line$);  // courier new + gras
  }

  print (chr$(2,5,4,0) + chr$(1,0,0,0) + "  >" + "1234567<");
}


func score (col, line)
{
  var x, y, c, i, j, count;

  // 4 cases consecutives horizontales

  j     = 0;
  count = 0;

  for (x=0; x<7; x++)
  {
    c = tab[x+line*7];

    if (c == 0 || c != j)
    {
      count = 1;
      j = c;
    }
    else
    {
      count++;
      if (count == 4)
        return j;
    }
  }


  // 4 cases consecutives verticales

  j     = 0;
  count = 0;

  for (y=0; y<5; y++)
  {
    c = tab[col+y*7];

    if (c == 0 || c != j)
    {
      count = 1;
      j = c;
    }
    else
    {
      count++;
      if (count == 4)
        return j;
    }
  }


  // 4 cases consecutives obliques \

  j     = tab[col+line*7];
  count = 1;

  for (i=1; i<=3; i++)
  {
    if (col-i < 0 || line-i < 0 || tab[col-i + (line-i)*7] != j)
      break;
    count++;
  }

  for (i=1; i<=3; i++)
  {
    if (col+i >= 7 || line+i >= 5 || tab[col+i + (line+i)*7] != j)
      break;
    count++;
  }

  if (count >= 4)
    return j;


  // 4 cases consecutives obliques /

  j     = tab[col+line*7];
  count = 1;

  for (i=1; i<=3; i++)
  {
    if (col-i < 0 || line+i >= 5 || tab[col-i + (line+i)*7] != j)
      break;
    count++;
  }

  for (i=1; i<=3; i++)
  {
    if (col+i >= 7 || line-i < 0 || tab[col+i + (line-i)*7] != j)
      break;
    count++;
  }

  if (count >= 4)
    return j;

  return 0;
}


// col de 1 a 7
// joueur 1 ou 2

func ajouter (col, joueur)
{
  var line;

  col--;

  if (col < 0 || col >= 7)
    return -1;

  if (tab[col] != 0)
    return -1;

  for (line=0; line<4; line++)
  {
    if (tab[col+line*7+7] != 0)
      break;
  }

  tab[col+line*7] = joueur;

  return score (col, line);
}


proc event (session_key, userid$, sex$, has_photo, age, is_away, admin,
            cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{
  var c$, col, r;

  if (action == 128)
  {
    print ("Willkommen im Raum, tippe !p4 um Vier Gewinnt zu spielen.");
  }

  if (action == 0)
  {
    if (len(line$) >= 3 && right$(line$,3) == "!p4")
    {
      jeu = 1;
      afficher_table();
    }
    else if (jeu == 1)
    {
      if (len(line$) >= 1)
      {
        c$ = right$(line$, 1);
        if (c$ >= "1" && c$ <= "7")
        {
          col = val (c$);

          if (joueur == 1)
            joueur = 2;
          else
            joueur = 1;

          r = ajouter (col, joueur);

          if (r >= 0)
          {
            afficher_table();

            if (r > 0)
            {
              if (r == 1)
              {
                print (chr$(1,0,0,0) + "Bravo ! " + chr$(1,0,0,255) + "X"
                        + chr$(1,0,0,0) + " hat gewonnen");
              }
              else if (r == 2)
              {
                print (chr$(1,0,0,0) + "Bravo ! " + chr$(1,255,0,0) + "O"
                        + chr$(1,0,0,0) + " hat gewonnen");
              }

              effacer_table ();
              jeu = 0;
            }
          }
        }
      }
    }
  }
}


////////////////////////////////////////////////////////////////////////////////


// Beispiel 3 : tassen nach 30 sekunden rauswerfen

var session[256];     // speichert die session_key der chatteurs in tasse
var expire$[256];     // datum und uhrzeit wann die chatter rausgeworfen werden
var nb_session;       // anzahl elemente in der Tabelle


// eine session_key in beiden tabellen zufügen

proc ajouter_dans_table (session_key)
{
  var i;

  for (i=0; i < nb_session; i++)
  {
    if (session_key == session[i])    // gefunden
      break;
  }

  if (i == nb_session)   // nicht gefunden, also tabelle vergrössern
    nb_session++;

  session[i] = session_key;
  expire$[i] = add_date$ (now$(), 30);
}


proc supprimer_de_table (session_key)
{
  var i;

  for (i=0; i < nb_session; i++)
  {
    if (session_key == session[i])   // gefunden
      break;
  }

  if (i < nb_session)   // gefunden
  {
    session[i] = session[nb_session-1];
    expire$[i] = expire$[nb_session-1];
    nb_session--;
  }
}


proc timer ()
{
  var i;

  for (i=0; i < nb_session; i++)
  {
    if (now$() > expire$[i])   // ist erloschen
    {
      kick (session[i], "hier ist kein parking !");
      supprimer_de_table (session[i]);
    }
  }

  set_timer (1);    // timer() einmal pro sekunde aufrufen
}


proc event (session_key, userid$, sex$, has_photo, age, is_away,
            admin, cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{

  if (!is_myself)  // nicht ichselbst
  {
    if (action == 2)
    {
      if (is_away)   // chatteur geht in tasse
      {
        print ("Vorsicht " + userid$ + " : do wirst nach 30 sekunden in tasse rausgeworfen !");
        ajouter_dans_table (session_key);
      }
      else           // reviens de tasse
      {
        supprimer_de_table (session_key);
      }
    }

    if (action == 129 || action == 130 || action == 256)
    {
      supprimer_de_table (session_key);
    }
  }

}

////////////////////////////////////////////////////////////////////////////////
 
// Beispiel 4 : multi-functionaler Roboter

var nombre;              // nombre a deviner (pour le jeu devine)
var jeu_score[50], jeu_pseudo$[50];

var nombre_de_lignes;    // compte le nombre de lignes reçues

var fruit$[3];           // tableau de 3 fruits


func fq$ ()    // changer la couleur et le style d'écriture
{
  return chr$(1,0,0,128)  // couleur bleue claire (voir chapitre macros)
       + chr$(2,5,4,0);   // font "Courier New", style gras
}

func red$ ()
{
  return chr$(1,255,0,0);   // couleur rouge
}

func green$ ()
{
  return chr$(1,0,255,0);
}

func blue$ ()
{
  return chr$(1,0,0,255);
}


proc demarre_devine ()
{
  print ("rate eine nummer von 1 bis 99");
  nombre = random (1,99);
}


// punkte in der tabelle jeu_score[] addieren

proc ajoute_points (userid$)
{
  var i, j, u$;

  // suche den userid$ in der tabelle jeu_pseudo$[]
  // oder suche eine leere zelle in der tabelle

  for (i=0; i<50; i++)
  {
    if (jeu_pseudo$[i] == userid$ || jeu_pseudo$[i] == "")
      break;
  }


  // die zelle fühlen und die punkte addieren

  jeu_pseudo$[i] = userid$;
  jeu_score[i]++;            // einen Punkt geben


  // den Spieler in der Tabelle zeile hochbringen falls er
  // mehr Punkte hat als der Spieler ober ihm

  while (i > 0 && jeu_score[i] > jeu_score[i-1])
  {
    j = jeu_score[i];
    jeu_score[i] = jeu_score[i-1];
    jeu_score[i-1] = j;

    u$ = jeu_pseudo$[i];
    jeu_pseudo$[i] = jeu_pseudo$[i-1];
    jeu_pseudo$[i-1] = u$;

    i--;
  }
}


// die ersten 9 zeilen der tabelle ausdrucken
// sowie den userid$ wenn er nach den 9 ersten ist

proc affiche_scores (userid$)
{
  var i, score$;

  print (fq$() + "PUNKTE");
  print (fq$() + "======");

  for (i=0; i<50; i++)
  {
    if (jeu_pseudo$[i] == "")
      break;
    if (i < 9 || userid$ == jeu_pseudo$[i])
    {
      score$ = str$(jeu_score[i]);
      if (len(score$) < 4)
        score$ = dup$(" ",4-len(score$)) + score$;
      print (fq$() + str$(i+1) + ". " + score$ + "  " + jeu_pseudo$[i]);
    }
  }
  print("");
}


proc joue_devine (word$,userid$)
{
  var last, first, n;

  // enlève les blancs à la fin
  last = len(word$);
  while (last >= 1 && asc(word$,last) == 32)
    last--;

  // collecte tous les chiffres à la fin
  first = last;
  while (first >= 1 && asc(word$,first) >= 48 && asc(word$,first) <= 57)
    first--;

  if (first == last)   // pas de chiffres
    return;

  n = val (mid$(word$,first+1,last-first));

  if (n < nombre)
    print ("nein, zu klein !");
  else if (n > nombre)
    print ("nein, zu gross !");
  else
  {
    print ("Bravo, ja ! es war " + str$(nombre));
    ajoute_points (userid$);
    affiche_scores (userid$);
    nombre = 0;
  }
}


proc print_fruits ()
{
  if (fruit$[1] == "")   // tableau pas encore rempli
  {
    fruit$[1] = "Apfel";
    fruit$[2] = "Birnen";
    fruit$[3] = "Bananen";
  }
  print ("Halloooooooo :d  magst Du " + fruit$[random(1,3)] + " ? ");
}



// die zeile line$ saubermachen : alle ikone durch leerzeichen ersetzen,
// alle buchstaben in kleinbuchstaben,
// and alle wörter mit leerzeichen trennen.

func clean$ (line$)
{
  var last, r$, i, c;

  i = 1;
  last = len(line$);

  while (i <= last)
  {
    c = asc (line$,i);
    if (c <= 9)  // séquence spéciale
    {
      i += 4;    // passer 4 caractères
      if (c > 5)
        i += 4;
      c = 32;  // remplacer par un blanc
    }
    else   // caractère normal
    {
      if (c >= 65 && c <= 90)  // si entre A et Z
        c += 32;    // convertir en minuscules
      i++;
    }
    r$ = r$ + chr$(c);
  }

  return r$ + " ";
}



proc timer ()
{
  if (mid$(now$(),12,5) == "12:00")
    print ("es ist 12 uhr !");

  if (mid$(now$(),12,5) == "13:00")
    print ("es ist 13 uhr !");

  set_timer (55);  // alle 55 sekunden aufrufen, also garantiert jede Minute
}



proc event (session_key, userid$, sex$, has_photo, age, is_away,
            admin, cam_on, is_bot, toc_capab, signature$, suffix$, profile_life,
            action, is_myself, line$)
{
  var word$, w$, heure, i;

  word$ = clean$(line$);   // macht die zeile sauber um darin wörter suchen zu können

  if (action == 127)   // die leute anzeigen die schon im raum sind
  {
    print ("Schon im Raum : " + userid$ + "  (session_key=" + str$(session_key) + ")");
  }

  if (action == 128)   // im raum ankommen
  {
    if (is_myself)    // ich bin es
      toc();          // ich nehme den Hammer !

    w$ = blue$();

    heure = val (mid$(now$(),12,2));

    if (heure >= 12 && heure <= 13)
      w$ = w$ + "Guten Appetit$mi ";
    else if (heure >= 0 && heure <= 4)
      w$ = "Gute Nacht(s) ";
    else if (heure >= 6 && heure <= 19)
      w$ = w$ + "Guten Tag:) ";
    else
      w$ = w$ + "Guten Abend;) ";

    w$ = w$ + userid$;

    if (sex$ == "F")
      w$ = w$ + " (f)";
    else
      w$ = w$ + " (y)";

    w$ = w$ + ", es ist " + right$(now$(),8)  + "(o)";

    print (w$);

//    print ("Ihre Unterschrift ist : " + signature$);

    print (blue$() + "tippe " + red$() + "!devine" + blue$() + " für das Frage-Spiel");
  }

  if (action == 0)    // ligne de texte normale
  {
    if (!is_myself)    // ce n'est pas moi-même
    {
      if (pos (word$, " !devine "))    // enthält !devine (mit leerzeichen vor und nach, vorsicht !)
        demarre_devine ();

      if (nombre > 0)  // le jeu devine est actif
        joue_devine (word$, userid$);


      // kicker quelqu'un s'il dit cochon

      if (pos (word$, " schwein "))
        kick (session_key, userid$ + ":@ unverschämt !!");


      // Afficher l'heure

      if (pos (word$, " uhr "))
        print ("Uhrzeit : " + now$());


      // die willkommenst Datei anzeigen, zeile für zeile

      if (pos (word$, " guten "))
      {
        for (i=1; i<=count_lines("willkommen.txt"); i++)
          print (read_line$("willkommen.txt", i));
      }


      // ein Tür-Bild anzeigen

      if (pos (word$, " tür ") > 0)
        print ("-> " + image$("kitchen02.jpg") + "welche Tür ? :p");


      // einen Satz behalten idem man ihn in der Datenbank speichert chat.db

      if (pos (word$, " behalte ") > 0)
      {
        store ("Behalte " + signature$, line$);
        print ("Satz behalten, sag 'was' um ihn wiederzusehen !");
      }

      // den satz wieder sagen

      if (pos (word$, " was ") > 0)
      {
        print ("dein Satz war : "+ fetch$("Behalte " + signature$));
      }


      nombre_de_lignes++;    // anzahl Zeilen erhöhen


      // alle 200 zeilen, die anzahl zeilen sagen

      if ((nombre_de_lignes % 200) == 0)
        print ("Schon " + str$(nombre_de_lignes) + " zeilen auf diesem chat gesprochen :p");


      // alle 100 zeilen, fragen ob man eine frucht möchte

      if ((nombre_de_lignes % 100) == 0)
        print_fruits ();
    }
  }


  if (action == 2 && is_away)   // weg gehen
  {
    print ("Hallo da " + userid$ + " ?  versteckt man sich ?");
  }

  if (action == 2 && !is_away)  // zurück von tasse
  {
    print ("Na gut das Du zurückkommst " + userid$ + " $si");
  }

  if (action == 1)       // text zeile mit der wolke
  {
    print ("Na, traumst Du " + userid$ + " :d");
  }
}

////////////////////////////////////////////////////////////////////////////////

zurück zur vorherigen Seite