Auszug aus einem IRC-Log in dem auf das Questsystem, im speziellen auf die Quest-XMLs, eingegangen wird. Achtung! Die Angaben im Log sind möglicherweise veraltet.

<bKtHeG> <quest ...>...</quest>
<bKtHeG> in diesem tag muss grundsätzlich alles stehen
<bKtHeG> bei quests gibt es zudem die attribute "id" und "name"
<bKtHeG> <answer ...>....</answer>
<bKtHeG> gibt eine antwort an
<bKtHeG> antworten sind grundsätzlich von dialogen getrennt
<bKtHeG> ein und die selbe antwort kann somit in verschiedenen quests bei verschiedenen dialogen verwendet werden
<bKtHeG> attribute: id
<bKtHeG> <dialog ...>....</dialog>
<bKtHeG> ein dialogtext (steht immer über den antworten - vgl. video ds2)
<bKtHeG> dialoge können bbcode enthalten (die tags aus dem comnet)
<bKtHeG> und sie können sich über mehrere zeilen erstrecken
<bKtHeG> attribute: id, picture (das gesicht neben dem dialog) und comment (muss da sein - ist aber im moment sinnfrei)
<bKtHeG> <script ...> .. </script>
<bKtHeG> die scripte - das herzstück
<bKtHeG> attribute: id
<bKtHeG> <require .... />
<bKtHeG> bindet eine andere xml-datei (nicht install-datei!) ein
<bKtHeG> dadurch stehen alle dialoge, antworten usw dieser datei (und aller von ihr eingebundenen) zur verfügung
<bKtHeG> attribute: file (gibt die datei an)
<bKtHeG> <inject ... />
<bKtHeG> gültig nur in <script ... > (möglicherweise funktioniert es auch bei <part...> - habs aber nie getestet)
<bKtHeG> an inject-stellen können andere "quests" eigenen code platzieren
<bKtHeG> so können z.B. quests sich in gtu-posten eintragen
<bKtHeG> zweck des ganzen ist folgendes: eine datei pro quest
<bKtHeG> und nicht eine datei für ganz ds 2
<bKtHeG> dadurch werden die entsprechenden scripte sehr viel übersichtlicher (installiert werden die nämlich extrem groß)
<GabrielAngel> k
<bKtHeG> nun eine generelle sache zu ids (wichtig für <answerid /> <scriptid /> <questid /> <dialogid /> und <injectscript />)
<bKtHeG> wenn dialoge, antworten usw aus der selben datei angegeben werden, reicht einfach nur die id (wie sie bei id="..." angegeben wurde)
<bKtHeG> wenn aber welche aus anderen (via require eingebundener) dateien verwendet werden sollen ist das format: dateiname:id
<bKtHeG> wobei der dateiname ohne dateiendung ist
<GabrielAngel> k
<bKtHeG> <injectscript ...>... </injectscript>
<bKtHeG> kennzeichnet einen bereich, in dem (in <part>-anweisungen)code drinne steht, der in ein anderes script eingefügt werden soll (an die durch <inject /> markierten stellen)
<bKtHeG> die id gibt hierbei die id des zielscripts an
<bKtHeG> <part ...> ... </part>
<bKtHeG> nur gültig in <injectscript>
<bKtHeG> fügt code an die durch "id" angegebene stelle im zielscript ein
<bKtHeG> (die ids sind die in <inject> angegebenen)
<bKtHeG> <anwerid ... />
<bKtHeG> fügt an die stelle die db-id für die antwort mit der entsprechenden id ein
<bKtHeG> attribute: id
<bKtHeG> gleiches gilt für <questid /> <scriptid /> und <dialogid />
<bKtHeG> wichtig ist, dass diese dinger verwendet werden und nicht direkt irgendwelche db-ids
<GabrielAngel> k
<bKtHeG> sonst geht jedes bissel übersichtlichkeit verloren, wenn 5 ids hintereinander stehen *g*
<bKtHeG> zumal die ids unterschiedlich sein können von system zu system
<bKtHeG> (system meint computersystem)
<bKtHeG> bei allen tags gilt grundsätzlich: sie sollten nur an der für sie vorgesehenen stelle stehen - zwar meckert der installer nicht, aber die ergebnisse können unvorhersehbar sein
<GabrielAngel> k
<bKtHeG> (alles ist halt ziemlich work-in-progress)
<GabrielAngel> kk
<bKtHeG> außerdem müssen alle xml-dateien in utf-8 geschrieben sein
<bKtHeG> also kein ascii oder iso-zeichensatz
<GabrielAngel> 'k
<bKtHeG> kurz noch das allerwichtigste zu den scripten:
<bKtHeG> ! -> so beginnt ein befehl
<bKtHeG> # -> das ist ein "register"
<bKtHeG> $ -> ein string
<bKtHeG> § -> eine generelle anweisung an den scriptparser
<bKtHeG> : -> eine sprungmarke
<bKtHeG> immer nur eine sache pro zeile
<GabrielAngel> k
<bKtHeG> wenn ein string deklariert wird, dann zuerst $ dann den stringnamen und dann einfach hintereinander weg den string (ohne " oder ähnliches)
<bKtHeG> § -> hier gibt es im moment nur "parameter"
<bKtHeG> parameter gibt an welche sprungmarken beim staren eines scripts sofort angesprungen werden dürfen
<bKtHeG> alle anderen kann das script selbst nur (intern) anspringen
<bKtHeG> die :0 sprungmarke bildet hier eine ausnahme
<bKtHeG> diese wird von aussen im normalfall angesprungen
<bKtHeG> wenn halt nichts anderes angegeben wurde beim starten des scripts
<bKtHeG> oder wenn die angegebene marke illegal war
<bKtHeG> befehle haben die struktur name_des_befehls parameter 1 parameter 2 parameter 3 usw
<GabrielAngel> k
<bKtHeG> wobei der nicht meckert, wenn da zu viele parameter sind


##################################################################################


<bKtHeG> darin dürften die meisten sachen eher weniger interessant sein - wichtig sind eigendlich nur die beiden einträge unter "Quests"
<GabrielAngel> k
<bKtHeG> btw: wenn du nen eintrag im admin siehst und nicht sofort klar ist, was er bedeutet - nicht anklicken!
<GabrielAngel> ko
<GabrielAngel> ok
<bKtHeG> manche teile laufen unter ds 2 nämlich leicht amock
<GabrielAngel> 'k
<bKtHeG> mit dem handler-teil kannst du ereignis-handler bearbeiten
<GabrielAngel> k
<bKtHeG> wobei die hälfte von denen sowieso über INSTALLHANDLER gesetzt wird
<GabrielAngel> kk
<bKtHeG> Quest XMLs ist da schon wichtiger
<bKtHeG> dort kannst du quests installieren
<bKtHeG> sowie neue questxmls hochladen
<GabrielAngel> k
<bKtHeG> und alte löschen (generell aber nicht zu empfehlen)
<GabrielAngel> 'k
<bKtHeG> beim installieren immer den namen der xml-datei mit samt erweiterung angeben
<bKtHeG> also z.B. "gtu 1" wäre ungültig
<GabrielAngel> kk
<bKtHeG> gtu 1.xml aber gültig
<GabrielAngel> k
<bKtHeG> das piraten-quest hast du dir ja bereits angesehen
<GabrielAngel> jup
<bKtHeG> nur steht da halt nicht drin wie es überhaupt aufgerufen wird *g*
<bKtHeG> dazu musst du z.B. unter handler gehen
<bKtHeG> und dort siehst du bei onenter einen eintrag
<GabrielAngel> hab
<bKtHeG> nur hat der etwas seltsame koordinaten
<bKtHeG> -1 heißt nämlich sowas wie *
<bKtHeG> also alle möglichen koordinaten
<GabrielAngel> kk
<bKtHeG> geht aber nur für x und y
<bKtHeG> wenn du nun auf den eintrag klickst kommst du zum eigendlichen handler
<GabrielAngel> hab
<bKtHeG> *:5:0:%2:n
<GabrielAngel> jup
<bKtHeG> das ist genau ein eintrag
<bKtHeG> verschiedene einträge werden durch ; getrennt
<GabrielAngel> k
<bKtHeG> in diesem fall aber unnötig
<bKtHeG> verschiedene teile eines eintrags werden wiederum durch ein : getrennt
<bKtHeG> die ersten beiden teile müssen immer angegeben sein
<GabrielAngel> k
<bKtHeG> die anderen sind optional
<bKtHeG> der erste ist immer der user (id), den es betrifft (* für alle user)
<GabrielAngel> k
<bKtHeG> wenn mehrere einträge existieren, hat grundsätzlich eine userid eine höhere priorität als ein *
<GabrielAngel> kk
<bKtHeG> der zweite teil gibt das script an
<bKtHeG> um genau zu sein die scriptid
<bKtHeG> 5 ist in diesem fall die id des piraten-scripts
<GabrielAngel> k
<bKtHeG> (zu sehen in der install-file)
<bKtHeG> als drittes steht die id des quests
<bKtHeG> 0 steht in diesem fall für kein quest
<GabrielAngel> k
<bKtHeG> wobei quests grundsätzlich auch innerhalb von scripten erzeugt werden können
<bKtHeG> wenn du irgendwo einen solchen eintrag mit r beginnen siehst ist es ziemlich sicher ein gerade laufendes quest
<GabrielAngel> 'k
<bKtHeG> der dritte parameter ist aber wie gesagt normalerweise optional
<bKtHeG> er muss in diesem fall nur angegeben werden, weil es noch zwei weitere einträge gibt
<bKtHeG> die reihenfolge der letzten beiden einträge ist egal
<bKtHeG> sie müssen auch nicht da stehen
<bKtHeG> % kennzeichnet grundsätzlich einen eintag mit wahrscheinlichkeit
<GabrielAngel> 'k
<bKtHeG> in diesem fall eine 2%ige wahrscheinlichkeit, dass das script ausgelöst wird
<bKtHeG> (wir wollen ja nicht immer einen piratenüberfall)
<GabrielAngel> hehe
<bKtHeG> n gibt an, dass unter allen umständen ein neues quest gestartet werden muss
<GabrielAngel> 'k
<bKtHeG> sonst sucht sich das scriptsystem auch schonmal ein laufendes quest aus
<bKtHeG> was probleme gibt, da ja schiffe "gelockt" werden
<bKtHeG> und die wollen wieder freigegeben werden
<GabrielAngel> hm...
<GabrielAngel> k
<bKtHeG> gelockte schiffe sind sozusagen vor dem zugriff anderer geschützt
<bKtHeG> sie können nicht weiterfliegen
<bKtHeG> sie können nicht angegriffen werden
<bKtHeG> usw
<GabrielAngel> kk
<bKtHeG> sonst könnte ja der spieler einfach aus dem sektor rausfliegen und vor den piraten verschwinden
<GabrielAngel> jup.
<bKtHeG> umgekehrt soll der user auch nicht einfach die piraten angreifen bevor er nicht auf ihre frage(n) geantwortet hat
<GabrielAngel> kk
<bKtHeG> daher müssen die schiffe gelockt werden
<GabrielAngel> k
<bKtHeG> zudem gilt bei onenter-ereignissen noch, dass dialoge mit antworten nur richtig funktionieren, wenn das eigene schiff auch gelockt ist
<GabrielAngel> 'k
<bKtHeG> ging leider nicht anders - sonst hätte es einige exploits gegeben
<GabrielAngel> k
<bKtHeG> zurück zu den handlern
<GabrielAngel> 'k
<bKtHeG> direkt im adminmenü wirst du vermutlich nur oncommunicate, onenter und onmove berarbeiten
<bKtHeG> die beiden anderen werden zu 99% von scripten gesetzt
<bKtHeG> wobei onmove vermutlich in den meisten fällen auch automatisch gesetzt wird
<bKtHeG> noch eine sache zu onmove: ich hab das teil nie getestet
<GabrielAngel> oh...
<GabrielAngel> 'k
<bKtHeG> hab erst gedacht ich brauche es für nen quest und hab das quest dann doch anders gebaut
<bKtHeG> nun zu den scripten
<bKtHeG> ich erläutere mal ein paar grundfunktionen
<bKtHeG> COMPARE
<bKtHeG> vergleicht zwei werte miteinander
<bKtHeG> es können sowohl direkt werte, alsauch register und strings angegeben werden
<GabrielAngel> wie "a=b" oder eher "If a=b Then"
<bKtHeG> das ganze arbeitet mit subtraktion
<bKtHeG> $wert 1 - $wert 2
<bKtHeG> das ergebnis steht hinterher in #cmp
<GabrielAngel> #k
<bKtHeG> das #cmp-register ist eines der speziellen register
<GabrielAngel> 'k
<bKtHeG> es wird z.B. automatisch von !J... befehlen verwendet
<bKtHeG> es gibt insgesamt folgende jump-befehle: JE, JL, JG, JNE, JLE, JGE sowie JUMP
<GabrielAngel> k
<bKtHeG> die bedeutung sollte soweit klar sein denke ich
<bKtHeG> als parameter schlucken sie die sprungmarke
<GabrielAngel> jo
<bKtHeG> allerdings nur ohne das :
<GabrielAngel> hm...
<bKtHeG> COPY
<GabrielAngel> k
<bKtHeG> kopiert einen wert/ein register/einen string in ein anderes register
<GabrielAngel> kk
<bKtHeG> das ziel steht als erster parameter
<bKtHeG> ADD
<bKtHeG> addiert zwei werte
<bKtHeG> das ergebnis steht in #MATH
<GabrielAngel> k
<bKtHeG> gültig sind werte und register
<bKtHeG> gleiches gilt für SUBSTRACT
<GabrielAngel> kk
<bKtHeG> nur das hier $wert 1-wert 2 gerechnet wird
<bKtHeG> MULTIPLY
<bKtHeG> im prinzip genauso wie bei den beiden vorherigen befehlen
<GabrielAngel> kk
<bKtHeG> das ergebnis steht wieder in #MATH
<bKtHeG> ARRAYRESET
<bKtHeG> im prinzip das selbe wie reset() in php
<GabrielAngel> kk
<bKtHeG> setzt solche dinge wie den internen pointer im array auf den anfang
<bKtHeG> einfach vor jedem durchlauf eines arrays ausführen
<GabrielAngel> ok
<bKtHeG> akzeptieren tut das dingen nur register
<bKtHeG> ARRAYNEXT
<bKtHeG> gibt das nächste array-element in einem gewünsten register zurück
<bKtHeG> das ziel steht als erstes - das array als zweites
<bKtHeG> akzeptieren tut es nur register
<bKtHeG> sollte der interne pointer überings auf den anfang zeigen wird das erste element zurückgegeben und nicht das zweite
<GabrielAngel> k
<bKtHeG> zusätzlich setzt die funktion noch das #cmp-register
<bKtHeG> wenn kein element mehr existiert steht es auf -1 - wenn eines existiert auf 0
<GabrielAngel> kk
<bKtHeG> INITQUEST
<bKtHeG> erzeugt ein laufendes quest
<bKtHeG> das bedeutet, dass ein script, welches in diesem quest-kontext läuft auf alle register zugreifen kann, auf die auch du im diesem moment zugriff hast
<bKtHeG> als erstes wird die questid angegeben
<bKtHeG> danach (optional) noch ein parameter, der dafür sorgt, dass unbedingt ein neues quest erstellt wird
<GabrielAngel> k
<bKtHeG> sonst schaut nämlich initquest zuerst nach ob schon ein passendes laufendes quest existiert und verwendet dieses
<bKtHeG> gültig sind werte und register
<bKtHeG> ENDQUEST
<bKtHeG> beendet ein laufendes quest
<GabrielAngel> kk
<bKtHeG> LOCKSHIP
<GabrielAngel> ui
<bKtHeG> lockt ein schiff
<bKtHeG> als ersten parameter schluckt es die id des schiffes
<bKtHeG> möglich sind normale werte und register
<bKtHeG> als zweiten (optionalen) wert ein ereigniss, dass noch ausgeführt werden darf
<bKtHeG> wichtig ist das nur, wenn du das schiff eines spielers lockst, mit dem das script ausgelöst wurde
<bKtHeG> im normalfall sollte es auch einfach das ereigniss sein, dass das script ausgelöst hat
<bKtHeG> (im fall der piraten - onenter)
<GabrielAngel> auch ontick?
<bKtHeG> bei den locks ist noch wichtig zu erwähnen, dass diese, wenn sie in einem questkontext ausgeführt werden, sich beim ende eines quests automatisch wieder "deinstallieren"
<bKtHeG> hrm
<bKtHeG> bei ontick bringt das glaube ich nichts
<GabrielAngel> ok
<bKtHeG> habs im wesendlichen nur für onenter und das piratenquest eingeabut
<bKtHeG> wobei es theoretisch fälle gibt wo das nötig sein würde - ka ob das scriptingsystem das aber bereits unterstützt
<bKtHeG> locks haben nämlich noch eine nette eigenschaft
<bKtHeG> die ausgabe kann gespeichert werden und wird dem spieler solange vorgehalten bis er sich endlich für eine antwort entscheidet
<GabrielAngel> ui...
<bKtHeG> damit die antwort verarbeitet werden kann muss das für die verarbeitung zuständige ereigniss bei lockship angegeben sein
<bKtHeG> das speichern übernimmt SAVEOUTPUT
<bKtHeG> funktioniert aber nur im questkontext
<bKtHeG> um genau zu sein wird die ausgabe nämlich in einem speziellen register gespeichert
<GabrielAngel> k
<bKtHeG> und die register sind halt nur dauerhaft da, wenn das nen laufendes quest ist
<GabrielAngel> kk
<bKtHeG> locks wirken sich überings auch auf flotten und auf gedockte schiffe aus
<GabrielAngel> k
<bKtHeG> UNLOCKSHIP
<bKtHeG> das ist das gegenstück
<GabrielAngel> kk
<bKtHeG> hat auch die selben parameter
<bKtHeG> wobei der zweite parameter wirklich absolut optional ist
<bKtHeG> einfach nur aus freundlichkeit zum scriptsystem ein schiff möglichst mit dem selben ereignis unlocken mit dem du es auch gelockt hast
<bKtHeG> (dann kann es nämlich den uninstall-befehl wieder entfernen)
<GabrielAngel> kk
<bKtHeG> ist aber auch nicht schlimm wenn du es nicht machst
<bKtHeG> LOADDIALOG
<bKtHeG> lädt einen dialog
<bKtHeG> ein dialog muss grundsätzlich in zwei schritten verarbeitet werden
<bKtHeG> zuerst das laden aus der db
<bKtHeG> dann kann er bearbeitet werden
<bKtHeG> antworten können hinzugefügt werden usw
<bKtHeG> im zweiten schritt muss er dann via INITDIALOG angezeigt werden
<bKtHeG> grundsätzlich kann immer nur ein dialog gleichzeitg bearbeitet werden
<GabrielAngel> kk
<bKtHeG> als parameter schuckt loaddialog die id
<bKtHeG> (soweit ich mich errinnern kann gehen keine register/strings)
<bKtHeG> ADDANSWER
<bKtHeG> fügt eine antwort hinzu
<bKtHeG> die antwort steht als erster parameter
<bKtHeG> register/strings gehen nicht
<GabrielAngel> k
<bKtHeG> als zweite steht sowas wie eine id innerhalb des scripts
<bKtHeG> damit wird die antwort innerhalb der dialogbearbeitungsphase identifiziert
<bKtHeG> gleichzeitig ist es die sprungmarke, zu der gesprungen wird, wenn die antwort angeklickt werden sollte
<GabrielAngel> k
<bKtHeG> SETANSWERURL
<bKtHeG> wenn du auf eine andere seite verlinken willst kannst du hiermit eine url einer antwort zuordnen
<bKtHeG> als ersten parameter schluckt die funktion die antwort-id (die id innerhalb des scripts)
<bKtHeG> als zweites einen string mit der url
<GabrielAngel> kk
<bKtHeG> SETDIALOGTEXTVAR
<bKtHeG> ersetzt eine variable in einem dialog mit einem wert
<bKtHeG> variablen stehen grundsätzlich in {}
<bKtHeG> (innerhalb des dialogtexts und nicht im script natürlich)
<GabrielAngel> k
<bKtHeG> die variable steht als erstes - keine register oder strings sind möglich
<bKtHeG> als zweites der wert durch den sie ersetzt werden soll (z.B. der schiffsname)
<bKtHeG> hier gehen normale werte, register und strings
<bKtHeG> COPYVAR
<bKtHeG> das ist ne etwas schwierigere funktion
<bKtHeG> ich gehe ersteinmal nur auf die allerwichtigsten aspekte ein
<bKtHeG> als erstes steht das zielregister
<bKtHeG> als zweites der zu kopierende wert
<GabrielAngel> k
<bKtHeG> möglich sind z.B. shipsource.id
<bKtHeG> das wäre in diesem fall die id des schiffes, das das script ausgelöst hat
<bKtHeG> oder shipsource.cargo -> das wäre der cargo dieses schiffes (als cargo-objekt - also nicht versuchen das ausgebene)
<bKtHeG> shipsource.e -> energie
<bKtHeG> shipsource.crew -> die crew
<bKtHeG> shipsource.s -> die antriebsüberhitzung
<bKtHeG> shipsource.offizier -> die _id_ des offiziers an bord des schiffes
<bKtHeG> der dritte parameter ist optional