Besonderheiten in Cleo

  1. CLEO OPCODES

  2. Die extra Cleo-opcodes findet man in der Sannybuilder-HILFE unter
  3. CLEO 3 Code Library >> CLEO 3: opcodes


  4. Zwei bedeutende codes, um Scripte zu starten, sind jene die für die main schon existieren und für Cleo neu erstellt wurden,:
  5. 1.) 004F: create_thread @SAVEGAME startet in der Main.scm die gewöhnlichen Scripte, Thread genannt
    Wenn man so ein gewöhnliches Script als Cleoscript kompilieret, bedarf es diesen code nicht, da es vom Cleo-Programm gestartet wird.
    Um ein weiteres Cleoscript aus einem anderen Cleoscript zu starten, ist folgender Cleo-opcode anzuwenden:
    0A92: create_custom_thread "New_Test_thread.cs"
    Der Name, der zu startenden Datei mit Punkt und Dateityp wird zwischen die Anführungszeichen eingetragen.
  6. Die Cleo-Scriptdatei erhält dann als Dateiformat die Endung, die in der Cleo-Direktive am Scriptanfang einzutragen ist
  7. {$CLEO .cs} = Cleo-Direktive, wird zu *.cs kompiliert
    Als New_Test_thread.txt gespeichert und zu New_Test_thread.cs kompiliert
  8. Das Script wird dann 2 mal gestartet, einmal vom anderen Script heraus und einmal vom Cleo-Programm
    Man muss eine Abfrage an den Scriptanfang stellen, die dafür sorgt,
    daß es beendet wird sobald es vom Cleo-Programm gestartet wurde.
  9. Eine andere Möglichkeit ist, das zu startende Script als .S zu erstellen
    0A92: create_custom_thread "New_Test_thread.s" wäre das dann
    Die zu startende Cleo-Scriptdatei erhält dann als Dateiformat die selbe Endung, {$CLEO .cs}
    Man muss dann den Datei-Typ manuell von .CS in .S ändern
    In diesem Fall wird das zu startende Script "New_Test_thread.s" nur ausgeführt, wenn es mit 0A92: create_custom_thread
    von einer anderen Scriptdatei aufgerufen wird.
  10. Der create_thread code mit Parametern:
    Der create_custom_thread -Code kann auch mit Informationen gefüttert werden
    Zum Beispiel
    0A92: create_custom_thread "PimpmyCarFULL2A1.cs" 1 2 0 3@ 4@ 5@ 6@ 29@ 8@ 9@ 10@
    Das zu startende Script empfängt die Werte aus den Parametern der create_thread-Zeile
    und setzt dann 0@ geleich mit dem Wert des ersten Parameters, 1@ mit dem zweiten, usw.
    0@ entspricht 1.Parameter
    1@ entspricht 2.Parameter
    2@ entspricht 3.Parameter
    3@ entspricht 4.Parameter
    4@ entspricht 5.Parameter
    usw.
    Es können integere Werte sowie Locale Variable in den Parametern eingetragen werden
    Ich empfehle, nur integere Werte zu transportieren.
    Man muss nicht 2 Cleodateien erstellen um einen create_thread aufzurufen,
    Man kann auch viele threads in ein Cleo.cs packen, die aus ihrer eigenen Cleo.cs heraus
    aufgerufen werden und in der selbigen laufen.
    Aber man muss eine Abfrage an den Scriptanfang stellen, die dafür sorgt,
    daß es is in den Hauptthread geleitet wird sobald es vom Cleo-Programm gestartet wurde.
  11. 2.) 0417: start_mission 3 startet ein Missionsscript der main.scm.
    Angegeben wird eine Nummer, die die Missionen in der Missionsauflistung in der main.scm haben
  12. Bei Cleo gibts keine Liste. Aber ein Cleo-Missionsscript erfordert immer ein Cleo-Missions-STARTER-script,
    mit folgem Cleo-Opcode:
    0A94: start_custom_mission "DriftMission"
    Der Name, der zu startenden Missionsdatei ohne Dateityp wird zwischen die Anführungszeichen eingetragen.
  13. Die Cleo-Scriptdatei erhält dann als Dateiformat die Endung, die in der Cleo-Direktive am Scriptanfang einzutragen ist
  14. {$CLEO .cm} = Cleo-Direktive, wird zu *.cm kompiliert
    Als DriftMission.txt gespeichert und zu DriftMission.cm kompiliert
  15. Die Missionsdatei kann auch in einem anderen Ordner, z.B. in einem Unterordner des Cleo-Ordners gespeichert werden
    0A94: start_custom_mission "RaceMissions\DriftMission" startet dieses mission script: GTASA\CLEO\RaceMissions\DriftMission.cm
    Script-Vorlage siehe unten


  16. 0A93: end_custom_thread beendet das Script, es ist dann inaktiv
    Die Originalversion des Codes, die in der main.scm genutzt wird, ist 004E: end_thread
    Und diese Originalversion wird in Cleo-Missions-scripten benutzt
    004E: end_thread
  17. Also:
  18. 0A93: end_custom_thread bei gewöhnlichen Cleo-Scripten, die zu einer *.cs kompiliert werden
  19. {$CLEO .cs}
    0A93: end_custom_thread
  20. 004E: end_thread bei Cleo-Missions-scripten, die zu einer *.cm kompiliert werden
  21. {$CLEO .cm}
    004E: end_thread


    Cleo erstellt beim Speichern zusätzliche Speicherdateien, die unter CLEO\Cleo_save abgelegt werden.

    Beim Speicherstand-Laden ist darauf zu achten, daß die Präsenz der Scripte im Cleo-Ordner dem Status entspricht, wie er gespeichert wurde
    besondere Aufmerksamkeit gilt dabei Scripten, die den Cleo-opcode, um den Script Status zu registrieren, enthalten


    Script Status registrieren

    Die Cleo-Scripte mit Endung .CS werden beim Spiel laden immer neu ausgeführt, egal ob Savegame geladen wurde oder Neus Spiel gestartet.
    Werden im Script, parked_car_generators ausgeführt und man speichert dann und lädt dieses Savegame, wirds nochmal ausgeführt.
    Es entsteht eine Doublette, eine weitere Instanz des parked cars, wenn man das mehrmals macht, hat man mehrmals das selbe parked_car.
    Das gilt auch für Objekte, die platziert werden sowie für Pickups

    Um das zu verhindern gibts ein Cleo-opcode,
    oder um den Scriptstatus mittels "Cleo-Variable" zu bestimmen, muss der Scriptstatus gespeichert werden.
    Dazu trägt man zu Scriptbeginn folgenden code ein:

    0A95: enable_thread_saving

    Damit wird Cleo angewiesen den Scriptstatus beim Speichern zu erfassen


    spezielle globale "Cleo-Variable"

    Die Dinge im Spiel brauchen eine IDentität, unter dem sie im Spiel registriert werden,
    ein Name mit dem wir der Engine anweisen im Spiel auszuführen. Z.B. für die Definition eines parked-car-generators.
    Sie sind variable einsetzbar

    Das Charackter-Zeichen @ bildet zusammen mit einer Zahl, eine Lokale Variable
    Beispiel: 1@

    Das Charackter-Zeichen $ bildet zusammen mit Buchstaben oder Zahlen, auch Unterstrich ist möglich, eine Globale Variable
    Beispiel: $ONMISSION oder $PLAYER_CHAR oder $10440

     

    Lokale oder Globale Variable hat folgende Bedeutung:

    Lokale Variable gelten nur innerhalb des jeweiligen Scriptes, in denen sie eingesetzt werden

    Globale Variable gelten global. Sie können in einem Script einen Wert an die Engine übertragen,
    der von anderen Scripten, die die gleichnamige Globale Variable in Ausführung bringen, registriert wird.

    Die dekompilierte main.scm enthält viele Scripte, wie gewöhnliche "Threads" im Hauptteil, Missions-Scripte,
    Extern Scripte die zur externen Script.img kompiliert werden und diverse Sub-Scripte.

    In der main.scm werden Globale Variable dazu benutzt, um Werte oder Spiel-Inhalte scriptübergreifend zu verstehen.
    So wird zum Beispiel der Wert einer Globale Variable zum Registrieren einer abgeschlossenen Mission im Missions-Script verändert
    Das Script zum Starten des Missions-Scriptes versteht die Wertänderung und schaltet die nächste Mission frei.

    In Cleoscripten sollen aber keine Globalen Variablen benutzt werden, weil das zu Fehlern führen kann


    Einzig diese 3 Globale Variable hat Seemann für das Cleo-Programm registriert:
    $PLAYER_CHAR
    $PLAYER_ACTOR
    $ONMISSION

    Trotzdem funktionieren Scripte, die Globale Variable enthalten, aber nicht zuverlässig. Besonders beim Spielen von Story-Missionen,
    während ein Cleo-Script Globale Variable ausführt, kann dies zu schweren Bugs oder Abstürtzen führen

    Als Ersatz für die scriptübergreifende Funktion Globaler Variablen
    hat Seemann die spezielle globale "Cleo-Variable" erstellt


    Sie kann nur mit den extra dafür vorgesehenen CLEO OPCODES benutzt werden:

    0AB3: var 0 = 10
    und
    0AB4: 0@= var 0

    Anstatt eines Charackter-Zeichens bildet der Ausdruck var zusammen mit einer Zahl die spezielle globale "Cleo-Variable"
    Da die Variable in anderen codes nicht benutzt werden kann, muss erst ihr Wert an eine Lokale Variable weitergegeben werden:

    0AB4: 13@ = var 44
    if
    0039:   13@ ==  1  // integer values
    004D: jump_if_false @weiter

    Die Einträge im CLEO OPCODE 0AB3 können variabel gestaltet werden
    0AB3: var 44 = 10// var 44 wird sofort mit einem integeren Wert gleichgesetzt, nämlich 10
    0AB3: var 44 = 1@// var 44 wird mit einer Localen Variable gleichgesetzt, und erhält deren Wert


    Script-Vorlage zum Starten eines Cleo-Missions-Script

    In diesem Starter-Script wird eine Bedingung abgefragt, die man erfüllen muss, um die Mission zu starten
    if
    00FE: actor $PLAYER_ACTOR 1 (in-sphere)near_point 2480.1343 -1665.475 13.3348 radius 3.5 3.5 5.5
    man muss in die rote Markierung bei x= 2480.1 , y= -1665.4 , z= 13.3 , das ist in San Fierro/Carlton Heights nähe Speicher-Arpatement
    oder einfach die eigenen Koordinaten eingeben

    {$CLEO .cs}
    :Test_M_Start_1
    03A4: name_thread 'TSTM'
    
    :Test_M_Start_2
    0001: wait  0 ms
    00D6: if  0
    0256:   player $PLAYER_CHAR defined
    004D: jump_if_false @Test_M_Start_2
    00D6: if  0
    0038:   $ONMISSION ==  0  // integer values
    004D: jump_if_false @Test_M_Start_2
    
    :Test_M_Start_6
    00D6: if  0
    00FE:   actor $PLAYER_ACTOR  1 (in-sphere)near_point 2480.1343 -1665.475 13.3348 radius  3.5  3.5  5.5
    004D: jump_if_false @Test_M_Start_2
    00BA: text_styled 'STAD_02'  1000 ms  2
    0004: $ONMISSION =  1  // integer values
    0A94: start_custom_mission "TestMission"  //
    0002: jump @Test_M_Start_2

    Das Missions-Starter-Script enthält den Cleo-Opcode
    0A94: start_custom_mission "TestMission"
    Der Name, der zu startenden Missionsdatei ohne Dateityp wird zwischen die Anführungszeichen eingetragen.

    Die Cleo-Missions-Datei erhält dann als Dateiformat die Endung, die in der Cleo-Direktive am Missions-Scriptanfang einzutragen ist
    {$CLEO .cm} = Cleo-Direktive, wird zu *.cm kompiliert
    Als TestMission.txt gespeichert und zu TestMission.cm kompiliert
    Name der Cleo-Missions-Datei und Eintrag im start_custom_mission -opcode müssen übereinstimmen

    {$CLEO .cm}
    :TestMiss_1
    03A4: name_thread "TESTM"  
    0050: gosub @TestMiss_main_1 
    00D6: if  0
    0112:   wasted_or_busted
    004D: jump_if_false @TestMiss_end_1
    0050: gosub @TestMiss_fail_1                    
    
    :TestMiss_end_1
    0050: gosub @TestMiss_clep_1
    004E: end_thread
    
    :TestMiss_main_1
    0317: increment_mission_attempts//here starts the missionscript
    0004: $ONMISSION =  1
    054C: use_GXT_table 'MENU2P'
    00BC: text_highpriority 'MENU_18'  5000 ms  1
    
    :TestMiss_11
    0001: wait 0 ms
    if and
    02D8:   actor $PLAYER_ACTOR currentweapon == 0 
    00E1:   key_pressed 0 17 
    004D: jump_if_false @TestMiss_11
    
    :TestMiss_pass_1
    00BA: text_styled 'M_PASS'  5000 ms  1
    0051: return
    
    :TestMiss_fail_1
    00BA: text_styled 'M_FAIL'  5000 ms  1
    0051: return
    
    :TestMiss_clep_1
    0004: $ONMISSION =  0
    00D8: mission_cleanup
    0051: return
  22. wenn die Mission gestartet wurde, einfach bei aufgeschalteter nackter Faust, die [FEUERN]-Taste drücken, um die Mission zu beenden
nothing
nothing