Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Autor X-Freak Cartman Datum 15.08.2007, 14:53 Aufrufe 3262
Beschreibung Prioritäten, Tasks, Interrupts, globale Scripts
Kategorie X3R MSCI Befehlsreferenz Typ

Prioritäten, Signals und

...

Tasks 

 

Prioritäten


Eine Priorität ist in MSCI-Scripts eine Zahl von -2.147.483.647 bis 2.147.483.647, die jedem laufenden Script zugewiesen wird, und die regelt, welche Signals und Interrupts auf das Script wirken.
Logischerweise gilt für Prioritäten:
Je höher die Priorität, desto wichtiger ist der Script. Unterbricht man ein Script, so wird der unterbrechende Script nur gestartet, wenn seine Priorität gr��er größer als die des laufenden Scripts ist.
Deshalb sollte man die Priorit�t Priorität nicht zu hoch setzen, damit alle Signals aktiv sind und es keine Komplikationen mit anderen Scripts gibt, die die Aktivit�t Aktivität eines Schiffes unterbrechen. Normalerweise benutzt man die Priorit�t Priorität 0. Negative Priorit�ten Prioritäten sind nicht �blichüblich, aber auch m�glichmöglich. Generell sollte man sich gut �berlegenüberlegen, ob man die Priorit�t gr��er Priorität größer als 199 setzt, da hier nicht registriert wird, ob ein neuer Leader vorliegt. Auf keinen Fall sollte man jedoch bei NPCs �ber über 299 gehen (Fehler bei Kaperungen) oder generell bei allen Schiffen �ber über 9.999, da hier SIGNAL_KILLED nicht mehr greifen w�rdewürde.
Man kann die Priorit�t folgenderma�en Priorität folgendermaßen auslesen lassen:
<RetVar> == get script priority
Gibt die Priorit�t Priorität des aktuellen Scripts zur�ck zurück
<RetVar> is script with prio <Var/Number> on stack
Pr�ft Prüft, ob einer der laufenden Scripts auf dem momentanen Task des momentanen Objektes genau die gegebene Priorit�t Priorität <Var/Number> hat
Doch wie Scripter nun mal so sind, wollen sie alles beherrschen, also gibt es nat�rlich natürlich auch Befehle, mit denen sich die Priorit�t Priorität festlegen l�sstlässt:set script priority to <Var/Number>
Dieser Befehl setzt die Script-Priorit�t Priorität in einem laufenden Script. Somit kann man beispielsweise gezielt einzelne Signals oder Unterbrechungen deaktivieren oder die Priorit�t Priorität herabsetzen, damit eben diese Signals gestartet werden k�nnenkönnen.
Es ist der einzige Befehl, mit dem ein Script seine eigene Priorit�t �ndern Priorität ändern kann. Alle anderen Befehle legen nur die Priorit�t Priorität mein Start eines Scripts fest:
global script map: set: key=<Object Command/Signal>, class=<Var/Class>, race=<Var/Race>, script=<ScriptName>, prio=<Var/Number>
Setzt die Priorit�t Priorität eines Scripts beim Start desselben per Kommando <Object Command> �ber über die Kommandokonsole oder per Befehl START <RefObj> command <Object Command>: arg1=<Value>, arg2=<Value>, arg3=<Value>, arg4=<Value> zu <Var/Number>.
<RefObj> connect ship command/signal <Object Command/Signal> to script <Script Name> with prio <Var/Number>
Wie vorheriger Befehl, nur auf einzelne Schiffe bezogen, nicht auf Schiffsklassen/-typen
<RefObj> verbinde Fl�gelmann Flügelmann Kommando/Signal <Object Command/Signal> mit Script <ScriptName> mit Priorit�t Priorität <Var/Number>
Setzt Priorit�t f�r Priorität für ein Fl�gelmannFlügelmann-Kommando (Aufruf per Hotkey)
<RefObj> -> start task <Var/Number> with script <Script Name> and prio <Var/Number>: arg1=<value> arg2=<value> arg3=<value> arg4=<value> arg5=<value>
Startet einen Script auf einem Task mit der angegebenen Priorit�tPriorität.
<RefObj> -> interrupt task <Var/Number> with script <Script Name> and prio <Var/Number>: arg1=<value> arg2=<value> arg3=<value> arg4=<value>
<RefObj> -> interrupt task <Var> with script <Script> and prio <Var>: arg1=<value> arg2=<value> arg3=<value> arg4=<value>
<RefObj> interrupt with script <ScriptName> and prio <Var/Number>
Diese drei Kommandos unterbrechen ein laufendes Script und starten ein anderes Script mit der festgelegten Priorit�tPriorität.
Die Unterbrechung findet an einem unterbrechbaren Befehl (Ein Befehl mit einem @ davor) statt, und verlangt, dass die Priorit�t Priorität des unterbrechenden Scripts gr��er größer als die des zu unterbrechenden Scripts ist. Hier als Priorit�t Priorität null anzugeben, h�tte hätte also denselben Effekt, wie in Argon Prime eine weitere Argon Collossus patrouillieren zu lassen: Die Performance geht runter, aber es bringt Nichts.

Der Stack
Der Stack ist theoretisch ein Stapel, auf dem alle Scripts liegen, die unterbrochen wurden und auf ihre weitere Ausf�hrung Ausführung warten. Eine Unterbrechung kann entweder durch einen Script Call, einen Interrupt oder durch ein Signal hervorgerufen werden. Der unterbrochene Script wird dann an der Unterbrechungsstelle gestoppt und l�uft läuft erst nach Beendigung des unterbrechenden Scripts weiter.
Durch diese Unterbrechungen ergibt sich der Stapel von Scripts, der Script Stack.
Es gibt nur zwei M�glichkeitenMöglichkeiten, Sachen aus dem Stack abzurufen:
Entweder per <RetVar> is script with prio <Var/Number> on stack, das nach einem Script mit der entsprechenden Priorit�t Priorität sucht, oder per <RetVar/IF> <RefObj> is script <ScriptName> on stack of task=<Var/Number>.
Letzteres ist die einzige M�glichkeitMöglichkeit, den Script Stack eines Objektes von einem anderen Task oder Objekt aus auf Vorhandensein eines bestimmten Scripts zu pr�fenprüfen.
Signals
Signals sind von der Spielengine gestartete Kommandos, die bei einem bestimmten Fall eintreten. Einfachstes Beispiel ist SIGNAL_ATTACKED: Es wird gestartet, wenn ein Schiff angegriffen wird. SIGNAL_KILLED hingegen wird nur gestartet, wenn ein Schiff zerst�rt zerstört wurde.
Einige Signals k�nnen können auch unter bestimmten Umst�nden Umständen mit <RefObj> send signal <Object Signal> gestartet werden. Die genauen Umst�nde Umstände stehen in der Befehlsbeschreibung.
Signals arbeiten wie Interrupts: Sie unterbrechen den momentanen Script und starten einen Neuen. Wenn kein Script auf dem momentanen Objekt l�uftläuft, wird das Signal auch nicht gestartet.
Signals haben den Vorteil, dass sie nur bei einem bestimmten eintretenden Fall gesendet werden und nach dem Ablauf des Signal-Scripts den vorherigen Script weiter laufen lassen. Da es sich um Interrupts handelt, haben Signals nat�rlich natürlich auch eine Priorit�tPriorität:
Code:
20 - !ship.signal.leaderjumps
40 - SIGNAL_REQUESTUNDOCK
50 - SIGNAL_ATTACKED - Fluchtreaktion
99 - SIGNAL_RESPONDTOHELPREQUEST - Angriff
99 - SIGNAL_ATTACKED - Gegenangriff
100 - SIGNAL_ATTACKED
150 - SIGNAL_LEADERNEEDSHELP
150 - SIGNAL_FOLLOWERNEEDSHELP
150 - SIGNAL_RESPONDTOHELPREQUEST
200 - SIGNAL_FORMATIONLEADERCHANGED
300 - SIGNAL_CAPTURED
10.000 - SIGNAL_KILLED

Bedeutung einzelner Signals (im originalen Spiel)
!ship.signal.leaderjumps
Es ist kein richtiges Signal an sich, sondern wird vom Script !move.jump per Interrupt auf den Followern von [THIS] gestartet.
Es sorgt daf�rdafür, dass die Formationsschiffe nach einer kurzen Zeit ebenfalls den Sprungantrieb starten und dem Leader hinterherspringen.
SIGNAL_REQUESTUNDOCK
Versucht ein Schiff, an einer Station anzudocken, an der bereits alle Andockklammern besetzt sind, so wird dieses Signal an das Schiff geschickt, das bereits am l�ngsten längsten angedockt ist. Es startet dann von der Station, wartet ein bisschen im All und dockt wieder an der Station an.
SIGNAL_ATTACKED
Dieses Signal ist f�r für den Realismus des Spiels das wohl wichtigste Signal, da es gestartet wird, wenn ein Schiff angegriffen wird, sodass es ausweichen und zur�ckschlagen zurückschlagen kann. Den Ablauf des Script k�nnte könnte man wie folgt zusammenfassen:
------
Ausweichen (defensive move) (nur, falls H�lle Hülle oder Schild angeschlagen und Schiff kein GKS oder TS)
Starte Kampfdrohnen (falls TS)
Greife Attacker an, falls Waffen vorhanden (setze Priorit�t Priorität 99), ansonsten: Fliehe zu Station (setze Priorit�t Priorität 50)
------
Im Gro�en Großen und Ganzen ist dieser Script also dazu da, dass Schiffe einen Gegenangriff starten oder fliehen.
Es ist �brigens übrigens auch das einzige Signal, das man auf Stationen starten kann. Normalerweise gibt es nur bei Spielerstationen einen Script, der mit diesem Signal auf Stationen verbunden ist. Es startet gelandete, kommandolose Spielerschiffe, die dann die Station verteidigen und wieder andocken.
SIGNAL_LEADERNEEDSHELP
Schiff ist in einer Formation, deren Leader angegriffen wurde.
Der Angreifer wird als attacker der Formationsschiffe gesetzt...
Eigentlich sollten die Formationsschiffe den Angreifer attackieren, jedoch wurden diese Zeilen auskommentiert, sodass dieser Script nur den attacker setzt sowie laufende Bewegungs-Befehle unterbricht.
Es ist zu vermuten, dass der Sinn dieses Signals im Zusammenhang mit Formationsbezogenen Kampfbefehlen erst richtig greift, da diese den attacker des Schiffes abfragen und es attackieren. Wird der Leader nicht nur attackiert, sondern get�tetgetötet, so wird der Killer des Leaders angegriffen, obwohl der Leader schon tot ist.
SIGNAL_FOLLOWERNEEDSHELP
Schiff ist Formationsanf�hrer Formationsanführer und eines der Formationsschiffe wird angegriffen
Der Script ist, abgesehen von zwei auskommentierten Zeilen, mit dem Script von SIGNAL_LEADERNEEDSHELP identisch: Der attacker wird gesetzt.
Der Unterschied ist hier, dass hier SIGNAL_ATTACKED mit dem Angreifer des Formationsschiffes als Argument gestartet wird. Dadurch greift der Leader den Angreifer an oder flieht zu einer Station.
SIGNAL_RESPONDTOHELPREQUEST
Die Bedingungen zum Start dieses Signals sind unbekannt, jedoch ist seine Funktionsweise eindeutig:
Falls das Schiff zum Kampf geeignet ist (kein Transportschiff, Laser installiert, keine andere wichtige Besch�ftigungBeschäftigung), kommt es einem angegriffenen Schiff zur Hilfe und zerst�rt zerstört die Angreifer. Daf�r Dafür setzt es, um einen Mehrfachaufruf dieses Signals zu verhindern, die Priorit�t Priorität auf 90.
Da dieses Signal erst seit X3 vorhanden ist, wird angenommen, dass dieses Signal f�r Milit�rschiffe für Militärschiffe und andere NPC-Jobs g�ltig gültig ist, damit diese rechtzeitig auf den Hilferuf eines anderen V�lkerschiffes Völkerschiffes reagieren k�nnenkönnen, und nicht nur pr�ventiv präventiv das Universum nach Feinden durchsuchen.
Dieses Signal ist auf keinen Fall f�r für Spielerschiffe, sondern ausschlie�lich f�r ausschließlich für NPCs g�ltiggültig.
SIGNAL_FORMATIONLEADERCHANGED
Formationsanf�hrer Formationsanführer hat sich ge�ndert geändert (beispielsweise bei Tod des bisherigen Leaders, Leader einer Formation kann ausschlie�lich ausschließlich per <RefObj> give formation leadership to <Var/Ship> ge�ndert geändert werden).
In diesem Fall wird einfach nur das laufende unterbrechbare Kommando unterbrochen (Bewegungskommando, beispielsweise "escort ship"), sodass die Formationsschiffe dem neuen Leader unverz�glich unverzüglich folgen.
SIGNAL_CAPTURED
SIGNAL_KILLED
Diese beiden Kommandos sind ziemlich identisch: Das erste wird bei Kaperung eines Schiffes (Ausstieg des Piloten) gestartet, das zweite bei Zerst�rung Zerstörung des Schiffes.
Diese Kommandos legen einfach nur einen neuen Formationsanf�hrer Formationsanführer fest und starten SIGNAL_ATTACKED auf dem neuen Formationsanf�hrerFormationsanführer, damit dieser den Angreifer des alten Anf�hrers bek�mpftAnführers bekämpft.
Einige Scripts nutzen das SIGNAL_KILLED, um beispielsweise eine Schockwelle auszul�sen auszulösen (XTM) oder Kopfgeld auszuzahlen (GAIUS).

Wie man sehen kann, regeln Signals eigentlich ausnahmslos den Kampfablauf. Es gibt zwei unbenutzte Signals: SIGNAL_ABORTED und SIGNAL_COLLISONWARN. �ber über Ersteres ist nur der Name selbst bekannt, Letzteres sollte urspr�nglich ursprünglich das Schiff davor bewahren, mit einer Station oder einem sonstigen Objekt �fter öfter als n�tig nötig zu kollidieren.
Tasks
Da oft mehrere Scripts auf einem Schiff laufen sollen, muss eine Regelung her, mit der man verschiedene Scripts eindeutig voneinander unterscheiden kann. Daf�r Dafür sind die Tasks zust�ndigzuständig. Ein Task ist eine Art Scriptslot eines Objektes, auf dem jeweils nur ein Script gestartet werden kann. Tasks werden per Zahlen zugeordnet, die man per <RetVar/IF> get task ID auslesen kann. Es sind jeweils nur Task IDs von 0 bis 2.147.483.647 m�glichmöglich.
Im normalen Spiel werden die Tasks wie folgt benutzt:
Code:
Schiffe Stationen
0 Hauptkommando Haupttask
1 Kanzel 1
2 Kanzel 2
3 Kanzel 3
4 Kanzel 4
5 Kanzel 5
6 Kanzel 6
10 zus�tzliches zusätzliches Schiffskom. 1 Stationskommando 1
11 zus�tzliches zusätzliches Schiffskom. 2 Stationskommando 2
12-19 Stationskommando 3-10

Startet man also per Kommandokonsole eines Schiffes ein Kommando, so wird es auf Task 0 gestartet.
Die Tasks f�r für Kanzeln entsprechen der jeweiligen Turret ID, sodass man bei einem Turret-Script zur Identifizierung der zu steuernden Kanzel einfach nur die Task ID abfragen muss.
Die Zus�tzlichen Zusätzlichen Schiffskommandos 1 und 2 belegen dann noch Task 10 und 11.
Bei Stationen ist die ganze Sache etwas anders: Wird eine Station gebaut, so wird ein idle-Script auf Task 0 gestartet:
Code:
Script !station.cmd.idle.pl
001 while [TRUE]
002 @ = wait 999999 ms
003 end
004 return null
Dieser Script ist ausschlie�lich ausschließlich dazu da, bei SIGNAL_ATTACKED unterbrochen zu werden.
Die eigentlichen Stationskommandos 1 bis 10 sind dann auf den Tasks 10 bis 19 gestartet.
Alle anderen Tasks kann der Spieler nicht �ber über die Kommandokonsole einsehen, sodass sie unsichtbar auf dem Objekt laufen.
Wie auch bei den t-files und Kommandos gibt es einen f�r für Egosoft reservierten Bereich. Dieser reicht von 0 bis 39. Der Bereich ab 20 ist f�r für das Bonuspaket reserviert, Task 33 wird von den Kanzelscripts zum automatischen Waffenwechsel verwendet (im normalen Spiel blo� bloß von NPCs genutzt)
Es ist also zu empfehlen, nur Task IDs zu w�hlenwählen, die gr��er größer als 40 sind. Aus pers�nlichem persönlichem Anlass bitte ich darum, Task IDs ab 65 zu w�hlenwählen, da der Bereich zwischen 50 und 60 haupts�chlich hauptsächlich von meinen Projekten eingenommen ist.
Im Egoforum gibt es eine �bersicht �ber Übersicht über verwendete feste Tasks, sodass es keine Konflikte mit anderen Scripts bez�glich bezüglich der Tasks gibt.
Sind die auf dem Task zu startenden Scripte tempor�r temporär und laufen nur wenige Millisekunden anstatt in Dauerschleife, so empfiehlt es sich, einen beweglichen Task zu verwenden. Der Script daf�r dafür sieht dann wie folgt aus:
Code:
$Task = 65
while <RefObj> -> is task $Task in use
inc $Task =
end
<RefObj> -> start task $Task with script <Script Name> and prio <Var/Number>: arg1=<value> arg2=<value> arg3=<value> arg4=<value> arg5=<value>
Somit wird eine Task ID gesucht, die gr��er größer oder gleich 65 ist und zur Zeit nicht benutzt wird. Somit ist sicher gestellt, dass kein anderer Script gestoppt wird.
Globale Scripts
Globale Scripts werden gestartet, wenn man versucht, ein Script auf dem Objekt null zu starten. Dies kann auch aus Versehen passieren, wenn ein Objekt zerst�rt zerstört wurde, SIGNAL_KILLED durchgelaufen ist und der Interruptpunkt ein Start-Script Call war.
Da dann ein Objekt-Script global l�uftläuft, ist es empfehlenswert, in jedem Objekt-Script am Anfang die folgende Pr�fung Prüfung einzubauen:
Code:
skip if [THIS]
return null
Dadurch wird verhindert, dass ein Script ungewollt global l�uftläuft.
Laufende globale Scripts kann man im ScriptEditor unter "Global Script Tasks" einsehen (direkt unter dem Script Debugging Menu). Normalerweise l�uft läuft hier nur plugin.autotrade.lockmaster, der f�r Universumsh�ndler für Universumshändler regelt, an welcher Station sie andocken d�rfendürfen. Besonders in der XTendedMod kommen weitere globale Scripts hinzu, doch auch einzelne Projekte k�nnen können Globale Scripts starten.
Globale Scripts sind generell hilfreich, wenn sich der Script nicht eindeutig auf ein Objekt bezieht, sondern stattdessen mehrere Objekte pr�ft prüft oder den Wechsel des Spielerschiffs vernachl�ssigen vernachlässigen soll und keine AL-Option verf�gbar verfügbar sein soll.
Bei Globalen Scripts sollte man immer zuerst pr�fenprüfen, ob schon ein derartiger Script l�uftläuft. Daf�r Dafür empfiehlt sich folgender Code am Anfang und am Ende des Scripts:
Code f�r für einen Globalen Script, der nur ein einziges Mal durchlaufen und sich dann beenden soll
Code:
Script globaler.script
001 $GlobVarName.Active = <eindeutiger GV-Name, der nur von diesem Script genutzt wird>
002 skip if not get global variable: name=$GlobVarName.Active
003 return null
004 set global variable: name=$GlobVarName.Active value=[TRUE]
<eigentlicher Script Code>
050 set global variable: name=$GlobVarName.Active value=null
051 return null
L�uft Läuft der Script noch nicht, ist die GlobVar null. Somit wird Zeile 003 �bersprungen übersprungen und die Globale Variable auf [TRUE] gesetzt.
Versucht jetzt ein Script erneut, den globalen Script zu starten, so wird dieser in Zeile 003 beendet.
Ist der erste Script schlie�lich schließich fertig mit seiner Arbeit, so wird die Globale Variable wieder zur�ckgesetzt zurückgesetzt und beim n�chsten nächsten Start dieses Scripts beginnt das Ganze wieder von vorn.
Aber es gibt nat�rlich natürlich auch Scripts, die in Endlosschleife laufen sollen. Daf�r Dafür empfehle ich folgenden Code, der dem f�r für einmaligen Ablauf �hnlich ähnlich ist:
Code:
Script globaler.script
001 $GlobVarName.Active = <eindeutiger GV-Name, der nur von diesem Script genutzt wird>
002 skip if not get global variable: name=$GlobVarName.Active
003 return null
004 set global variable: name=$GlobVarName.Active value=[TRUE]
<eigentlicher Script Code>
050 set global variable: name=$GlobVarName.Active value=null
051 $null = null
052 @ START $null -> call script 'globaler.script' :
053
054 return null
Hier wird ebenfalls �berpr�ftüberprüft, jedoch startet sich das Script in Zeile 52 als neuer globaler Script neu.
W�rde Würde man einfach eine while-Schleife benutzen, so m�sste müsste man f�r für eine Aktualisierung des Scripts eine Sonderfunktion einbauen, die den Script neu startet, wenn eine neue Version verf�gbar verfügbar ist. Bei dieser Variante regelt sich das Ganze automatisch, da sich der Script unabh�ngig unabhängig von seiner Version regelm��ig regelmäßig selbst neu startet.
Dieser Script muss nur ein einziges Mal im Setup-Script des Scriptpakets gestartet werden, danach l�uft läuft er unendlich lang weiter, bis er aus dem scripts-Ordner entfernt wird. Nat�rlich Natürlich kann man auch f�r für eine Deinstallation eine Sonderroutine einbauen, das bleibt jedoch dem Scripter �berlassenüberlassen.
btw: AL-Scripts und BBS-Scripts werden ebenfalls global gestartet. Bei der XTendedMod gab es ein Problem mit einem AL-Script, das bei jedem Laden des Speicherstands neu gestartet wird. Speichert und l�dt lädt man regelm��igregelmäßig, so erh�ht erhöht sich die Anzahl der Instanzen je ein mal, bis die Performance schlie�lich schließlich im Keller ist. Es handelte sich um den Script al..XTM.St.Xtra, der besonders lange l�uft läuft (bis zu mehreren Minuten). Benutzt ihr die Mod schon seit 0.7.1, so k�nnt könnt ihr in ihn sicher mehrfach unter euren Global Script Tasks finden.
Damit so ein peinlicher Fehler bei euren Scripts nicht auftritt, empfehle ich, immer zu pr�fenprüfen, ob ein globaler Script bereits l�uftläuft, vor Allem, wenn er in Dauerschleife agiert.

 

...

Dieser Artikel wurde ursprünglich von X-Freak Cartman geschrieben und war bis zu deren Deaktivierung auf www.madxhawk.com zu finden. X2