Difference between revisions of "De:Chapter 1"
(→CHARDEF: Uebersetzung und kleine Tippfehlerkorrektur) |
m (→Beispiele) |
||
(4 intermediate revisions by the same user not shown) | |||
Line 553: | Line 553: | ||
− | random_food 1 | + | random_food 1<br> |
0 3 | 0 3 | ||
− | Addiert man die | + | Addiert man die zweite Zahl in den beiden Zeilen, erhält man 4. Das sagt Sphere "OK, 1 von 4 Mal, will ich random_food und 3 von 4 Mal wähle ich 0." Man kann auch Zufallsauswahlen verschachteln, aber das wird dann verwirrend. |
Line 630: | Line 630: | ||
ITEM=random_reagent, {5 12}<br /> | ITEM=random_reagent, {5 12}<br /> | ||
ITEM=random_necro_reagent, {5 12}<br /></font></tt> | ITEM=random_necro_reagent, {5 12}<br /></font></tt> | ||
− | |||
==Beispiele== | ==Beispiele== | ||
Line 690: | Line 689: | ||
Der beste Weg diese Art von Skripten zu lernen, liegt darin, dass man die Skripte in den Dateien wie beispielsweise sphereitem_colorarm.scp und sphereitem_beers.scp liest. | Der beste Weg diese Art von Skripten zu lernen, liegt darin, dass man die Skripte in den Dateien wie beispielsweise sphereitem_colorarm.scp und sphereitem_beers.scp liest. | ||
+ | |||
+ | [[De:Chapter 2|Kapitel 2]] | ||
[[Category:Tutorials]] | [[Category:Tutorials]] |
Latest revision as of 07:59, 10 March 2011
Zahlen
Als erstes wird die verschiedenartige Art und Weise zur Verwendung von Zahlen innerhalb der Sphere Skripte behandelt. Da Zahlen naturgemäß sehr wichtig für einen Sphereskripter sind, ist dies der erste Abschnitt überhaupt. Am Ende dieser Einheit wird hoffentlich jeder über ein allgemeines Verständnis über hexadezimale, dezimale und binäre Zahlensysteme und die Verwendung in Sphere Skripten besitzen. Zudem wird noch vermittelt, wie einerseits Zufallszahlen innerhalb eines Zahlenbereichs oder aus einer Liste von Zahlen generiert werden können.
Es muss zunächst verstanden werden: wie wir zählen ist nicht die einzige Art zu zählen. Unser Zahlensystem enthält zehn Ziffern (0, 1, 2, 3, 4, 5, 6, 7, 8, und 9). Ab der zehnten Zahl wird eine weitere Ziffer angehängt und die letzte Stelle auf 0 gesetzt (1, 2, 3, 4, 5, 6, 7, 8, 9, 10). Deshalb funktioniert unser Zahlensystem wie es funktioniert.
Im Dezimalsystem, ohne dass wir davon Notiz nehmen, schreiben wir diese Zahlen immer als Zehnerpotenzen. Beispielsweise die beliebige Zahl 17282 aufgeteilt in Zehnerpotenzen:
Zehnerpotenz | 4 | 3 | 2 | 1 | 0 |
10 hoch Zehnerpotenz | 10000 | 1000 | 100 | 10 | 1 |
Ziffer | 1 | 7 | 2 | 8 | 2 |
Um zur Zahl 17282 zu gelangen, wird immer 10 hoch Zehnerpotenz mal der Ziffer in der untersten Zeile berechnet und am Ende alle Ergebnisse addiert. Das Ergebnis: 10000 + 7000 + 200 + 80 + 2. Offensichtlich ist das sehr einfach und jeder tut das ständig ohne davon Notiz zu nehmen. Du fragst dich sicherlich jetzt "Richtig, warum schrieb Taran das alles?" Die Sache ist die, dass unser Zahlensystem nicht das einzige ist.
Computer zählen beispielsweise komplett anders. Sie kennen nur zwei Ziffern (1 und 0) und das wird dann Binärsystem genannt. Binäre Zahlen sehen beispielsweise so aus: 101011101101. Oftmals tauchen sie in der Werbung für Computer auf. Ziffern im Binärsystem werden Bit genannt (kurz für BInary digiT). Binärzahlen im Kopf zu Dezimalzahlen zu berechnen ist meist nicht ohne weiteres möglich, hierfür braucht es ein wenig Mathematik.
Binärsysteme funktionieren wie Dezimalsysteme, es wird eine Potenz einer Zahl addiert. Da Binarzählen nur aus zwei Ziffern bestehen, handelt es sich hierbei um Zweierpotenzen. Manchen wird die folgende Tabelle sicher bekannt vorkommen:
Zweierpotenz | Binärzahl | Dezimalzahl |
0 | 1 | 1 |
1 | 10 | 2 |
2 | 100 | 4 |
3 | 1000 | 8 |
4 | 10000 | 16 |
5 | 100000 | 32 |
6 | 1000000 | 64 |
7 | 10000000 | 128 |
8 | 100000000 | 256 |
9 | 1000000000 | 512 |
10 | 10000000000 | 1024 |
Spannend oder? :)
Wir brauchen ein besseres System! Der Grund, dass seltsame Ergebnisse auftreten, liegt daran, dasss 10 keine Potenz von 2 ist. Wir brauchen deshalb ein System, das eine Zweierpotenz als Basis hat. Das am meisten genutzte System ist ein 16er System, auch hexadezimal genannt. Im Sphere-Forum sieht man das Wort hex sicherlich an der ein oder andren Stelle, das ist kein Fluch und auch kein böser Zauber. Es ist eine Kurzform für "hexadecimal".
Binär | Dezimal | Hexadezimal |
1 | 1 | 1 |
10 | 2 | 2 |
11 | 3 | 3 |
100 | 4 | 4 |
101 | 5 | 5 |
110 | 6 | 6 |
111 | 7 | 7 |
1000 | 8 | 8 |
1001 | 9 | 9 |
1010 | 10 | A |
1011 | 11 | B |
1100 | 12 | C |
1101 | 13 | D |
1110 | 14 | E |
1111 | 15 | F |
10000 | 16 | 10 |
Ersichtlich, wie das funktioniert? Es gibt sechs Ziffern, die zusätzlich am Ende des Systems herangezogen werden müssen, es werden üblicherweise hierfür die ersten 6 Buchstaben des Alphabets verwendet.
Innerhalb von Sphere Skripten wird beinahe NIE mit Binärzahlen gearbeitet, die KEINE Potenz von zwei sind und wenn, dann kann jeder herkömmliche Taschenrechner benutzt werden, um sie umzurechnen. Mit Hexadezimalzahlen ist das um einiges einfacher.
(This is the last table, I promise!!)
Binär | Hexadezimal |
000000001 (1) | 01 |
000000010 (2) | 02 |
000000100 (3) | 04 |
000001000 (4) | 08 |
000010000 (5) | 010 |
000100000 (6) | 020 |
001000000 (7) | 040 |
010000000 (8) | 080 |
100000000 (9) | 0100 |
Wie in der Tabelle ersichtlich gibt es ein Muster in der Hexadezimalspalte. Man könnte meinen, dass da ein Muster in den Zahlen 1, 2, 4 und 8 auftritt. Das stimmt auch. Ein weiteres Detail sind die führenden 0en für Hexadezimalzahlen (0100 statt nur 100). In Sphere bedeutet eine solche führende 0: "Diese Zahl ist eine Hexadezimalzahl!" und dementsprechend sind 100 und 0100 völlig verschiedene Zahlen.
Angenommen in einem Sphere Skript wird das 13. bit in einer Zahl benötigt (FLAGS beispielsweise), dann würde so etwas verwendet werden:
SRC.FLAGS |= 8192
Allerdings: merkt man sich wirklich, dass 8192 das Ergebnis von 2 hoch 13 ist? Das tut man nicht, es ist viel einfacher diese Liste durch zu gehen, bis man zur 13. Zahl kommt (wichtig: Zählen beginnt immer bei 0!).
01 | 02 | 04 | 08 | 010 | 020 | 040 | 080 | 0100 | 0200 | 0400 | 0800 | 01000 | 02000 |
2^0 | 2^1 | 2^2 | 2^3 | 2^4 | 2^5 | 2^6 | 2^7 | 2^8 | 2^9 | 2^10 | 2^11 | 2^12 | 2^13 |
Und hier sind sie: die ersten 14 Zweierpotenzen in Hexadezimal.
SRC.FLAGS |= 02000
Diese Zeile ist identisch zur obigen, nur dass 8192 (dezimal) GLEICH 02000 (hexadezimal) ist.
8192 = 02000
Nun könnte man sagen "Wie weiß ich, dass das nicht frei erfunden ist?". Nunja, schon der windowseigene Microsofttaschenrechner beherrscht die Umrechnung zwischen Binär-, Hexadezimal-, Dezimal und Oktalzahlen (ein weiteres, aber in Sphere nutzloses Zahlensystem). Der Taschenrechner von Windows befindet sich im Startmenü unter Programme im Zubehör. Im Taschenrechner wird im Menü Ansicht auf Wissenschaftlich umgestellt. Die Oberfläche des Taschenrechners verändert sich dann ziemlich. Um damit eine Zahl zwischen den Systemen umzurechnen, muss nur die originale Zahl eingegeben werden und dann kann zwischen den verschiedenen Zahlensystemen (Hex, Dez, Okt, Bin) umgeschaltet werden. Eine 0 vorne an eine Hexadezimalzahl gehängt und Sphere interpretiert sie als auch als eine hexadezimale Zahl.
Das war vermutlich das schwierigste in allen Sphere Skripten. Glücklicherweise, wegen des nächsten Abschnitts, muss sich ab jetzt niemand mehr mit angsteinflössenden Zahlen beschäftigen. Wenn du nach dieser Einheit noch dabei bist, wird sicher alles gut!
Weiter gehts mit: Skripten für Sphere!
Defnames
Hier eine Liste angsteinflössender Zahlen, die man innerhalb von Sphere Skripten antrifft:
angsteinflössende Zahl | Was sie bedeutet |
0eed | ID einer Goldmünze |
0dda | ID eines roten Moongates |
1650,1440 | Koordinaten von Britain |
021 | Farbcode für die Farbe "rot" |
04000 | Farbcode für unsichtbar |
04000efad | Eindeutige serielle Nummer eines Gegestands |
4 | Das PLEVEL eines GMs |
2048 (oder 0800) | Flag für den Unsichtbarkeitszauber |
010 (oder 16) | Memory type für Aggressoren |
Offensichtlich will solche Zahlen niemand auswendig kennen. Aber in frühesten Versionen, weit vor Sphere und TUS (vor .50 Sphere) und tief im Nebel von Grayworld (vor .41 TUS), musste jeder Skripter diese Zahlen kennen. Ich kenne diese Zahlen (ausser die serielle Nummer, die frei erfunden ist) und noch ein paar weitere, allesamt in- und auswändig. Glücklicherweise hat sich für jeden, der nicht gern Zahlen auswendig lernen will, Sphere dazu entwickelt, dass Namen statt Zahlen verwendet werden können.
Zwar wird alles mögliche immer noch mit Zahlen verknüpft, aber diese Zahlen sind mittlerweile mit Namen verknpft worden.
Gib im Spiel .add 0eed ein und drücke die Returntaste. Ein Zielcursor taucht auf und es kann eine Goldmünze erschaffen werden.
Nun gib .add i_gold ein und drücke Return. Es passiert genau das selbe.
Natürlich kann man sich i_gold leichter als 0eed merken. Aber wie funktioniert das? Dazu muss die Skriptdefinition von einer Goldmünze angesehen werden. Dieses Skript muss an dieser Stelle noch nicht verstanden werden, Itemskripte werden später genauer behandelt. Dieser Skriptausschnitt findet sich in der Datei sphere_item_resources.scp.
[ITEMDEF 0eed]
//gold coin
DEFNAME=i_gold
TYPE=T_GOLD
VALUE=1
CATEGORY=Provisions - Miscellaneous
SUBSECTION=Coins
DESCRIPTION=Gold Coin
DUPELIST=0eee,0eef
Die rot markierte Zeile ist für diese Lektion von Belang. Ansonsten ist noch die erste Zeile, die 0eed enthält, interessant, aber der Rest kann getrost ignoriert werden vorerst. Die 0eed ist die Nummer des Items, diese Nummern werden im nächsten Abschnitt behandelt.
Wirklich interessant ist allerdings DEFNAME=i_gold. Diese Zeile legt im Server fest: "Ab jetzt wird 0eed mit i_gold identifiziert". Wird vor dieser Zeile irgendwo innerhalb eines Skripts i_gold verwendet, wird der Server einen Fehler melden (siehe Kapitel 2 über die Reihenfolge von Skripten), aber jetzt ist ihm bekannt, worauf i_gold verweist und es kann in Skripten oder im Spiel frei verwendet werden.
Es sollte IMMER ein solcher Name mit DEFNAME erstellt werden, wenn ein Item geskriptet wird. Normalerweise wird dieser defname in [ITEMDEF] selbst festgelegt (mehr darüber später), aber wenn unbedingt Zahlen verwendet werden sollen, sollte zudem noch ein einfach zu zu merkender Name verwendet werden (bspw nicht goldenes_gulasch für ein Schwert). Es macht das Leben einfacher, als Zahlen zu benutzen.
Eine zweite Möglichkeit, DEFNAME zu nutzen, ist die Nutzung eines [DEFNAME]-Abschnitts. Hier ein Beispiel dafür:
[DEFNAME colors]
color_blue 02
color_red 021
color_green 041
Ein ähnliches Skript steht in spheredefs.scp, eine weitere Datei, die ganz am Anfang geladen werden sollte.
Hier eine Aufschlüsselung dieses Skripts, Zeile für Zeile:
Zeile 1: Hier wird der Typ des Skripts festgelegt und der Name dafür (Colors in diesem Fall). Hier wird dem Server vermittelt, dass von dieser Zeile bis zum nächsten Identifier (das sind die Zeilen die von eckigen Klammern eingerahmt sind) eine bestimmte Art von Skript enthalten ist. Alle Identifier haben dieses Format. Der erste Parameter legt dabei den Skripttyp fest und davon gibt es mehrere, die in den weiteren Kapiteln abgehandelt werden. Der zweite Parameter ist entweder eine Zahl als ID oder ein Defname. In den meisten Fällen wird in selbst geschriebenen Skripten wird hier ein Defname stehen. Die einzige Ausnahme besteht dann, wenn neue Items in die Clientdateien eingefügt werden.
Zeilen 2-4: Diese Zeilen enthalten individuelle Teile. Es wird festgelegt, dass color_blue gleich 02, color_red gleich 021 und color_green gleich 041 ist. Zwischen dem Namen und dem Wert können beliebig viele Leerzeichen enthalten sein. Die Definitionen in spheredefs.scp sind so ziemlich die nützlichsten auf die man treffen kann, da sie es unnötig machen, viele angsteinflössende Zahlen zu verwenden. In spheredefs.scp werden deshalb Namen für Flags, für Attribute von Items, für verschiedene Töne und Klänge, für Memory Types und viele andere Dinge festgelegt. Einen Blick in diese Datei zu werfen ist sicherlich zuweilen ganz ratsam.
Das wars mit DEFNAMES. Weiteres taucht später in allen möglichen Skripten auf.
Jetzt werden Items abgehandelt.
ITEMDEF
Oder: wie macht man aus einem Maulwurfshügel einen Berg auf Sphere-Art.
Die meisten machen sich Itemskripte schwieriger, als es nötig ist. Für die Zwecke dieses Tutorials, da es noch ein weit fortgeschritteneres später gibt, werden hier nur einfach die Grundlagen eines ITEM Skripts behandelt, Zeile für Zeile. Wir werden das Goldskript vom vorherigen Absatz verwenden, vorausgesetzt ich finde es ...
Ok, hier ist es, mit Farbe unterlegt, damit es schöner anzusehen ist!
[ITEMDEF 0eed] //gold coin DEFNAME=i_gold TYPE=T_GOLD VALUE=1 CATEGORY=Provisions - Miscellaneous SUBSECTION=Coins DESCRIPTION=Gold Coin DUPELIST=0eee,0eef
Das ist das einfachste aller Itemskripts, da es kein weiteres Verhalten hat und nichts anderes macht ausser einfach nur zu existieren. Es wird nun jede Zeile erklärt und was es damit auf sich hat:
Zeile 1: [ITEMDEF 0eed]
Die erste Zeile eines Itemskripts ist die wichtigste. Grundsätzlich bedeutet diese Zeile für den Server "Hey, das ist ein Item und es soll 0eed heißen!". Der Server sieht sich dann die Clientdateien an (vor allem art.idx), und gleicht ab, ob das Item eins der eingebauten ist. Ich glaube, alle Items mit Nummern unter 04500 gelten als eingebaut, deshalb sollte nie ein neues Item mit einer Zahl definiert werden, die darunter liegt. Bei Eingabe dieser Zeile, wird der Server wissen, dass ein Itemskript folgt. Außerdem wird 0eed als gültiges Item festgelegt, was später nützlich ist, wenn die Spieler Gold brauchen!
Zeile 2: // gold coin
Das ist die Sphereversion eines Kommentars. C-Programmierer kennen das Format (Anmerkung des Übersetzers: eigentlich kennt man das erst ab C++). Jede Zeile, die mit // beginnt ist eine Kommentarzeile und alles, was in einer Kommentarzeile enthalten ist, wird nicht vom Server interpretiert oder gelesen. Diese Kommentare können aber auch an beliebiger Stelle innerhalb einer Zeile beginnen um am Ende einer Zeile eine Erklärung einzufügen. Auf jeden Fall sind Kommentare nicht für die Funktion des Skriptes relevant, sondern können sie unter Umständen verständlicher machen.
Zeile 3: DEFNAME=i_gold
Du solltest jetzt wissen, was diese Zeile bedeutet. Wenn nicht, dann sollte die vorherige Einheit nochmal wiederholt werden. Es legt im Server fest, dass i_gold und 0eed das selbe sind. In Itemskripten sind alle alle Parameter nach diesem Format spezifiziert:
variable=wert
Später, wenn es um Skripte geht, wird ersichtlicher, dass dieses Format sehr hilfreich ist. Items haben einige Variablen, die belegt werden können, unter anderem:
- DEFNAME
- ID
- TYPE
- VALUE
- RESOURCES
Andere Variablen sind wiederum vom Wert von TYPE abhängig.
Zeile 4: TYPE=t_gold
"Was ist t_gold?" Auch das ist nur ein DEFNAME. Also eine Zahl, in diesem Fall 72. In spheredefs.scp steht diese Zahl, also hätte TYPE=72 den selben Effekt.
Momentan gibt es 183 eingebaute Itemtypen. Sie sind hardcoded (=fest in Sphere implementiert) und enthalten vordefinierte Verwendungszwecke für einen Gegenstand. Hat ein Gegenstand keinen Typ, dann erhält man eine "You cannot think of a way to use that item"-Nachricht, wenn man im Spiel das Item anklickt. Es gibt eine vollständige Liste von Itemtypen und wie sie genutzt werden. Der Typ t_gold hat nur einen Effekt: der Gegenstand wird behandelt wie eine Goldmünze (d.h: es können damit Dinge gekauft werden!). Andere Gegenstände den Typ t_gold zu geben würde den Server dazu veranlassen auch diese Dinge als Währung heran zu ziehen. Ich habe das nie versucht, aber es könnte eine interessanter Weg sein einzigartige Währungen zu haben ...
Zeile 5: VALUE=1
Diese Zeile legt fest, wie viel ein Item wert ist, wenn es gekauft wird - in Gold. Natürlich ist eine Goldmünze eine Goldmünze wert, deshalb wird der Wert hier auf 1 gesetzt.
Zeilen 6-8: CATEGORY, SUBSECTION, DESCRIPTION
Diese Zeilen werden nur von Spheres GM-Tool, Axis, benutzt, das es unnötig macht, im Spiel ".add i_gold" einzugeben. Wichtiger noch, es übernimmt solche Aufgaben auch für Items, die keinen DEFNAME haben, sondern nur eine Nummer.
Zeile 9: DUPEITEM
Es wäre viel Arbeit für das Sphereteam alle 8000 Items im Spiel zu definieren, vor allem, wenn viele eigentlich ein und das selbe sind. (Beispielsweise kann eine Tür mit dem Befehl .xflip gedreht werden. Dieser Befehl läuft durch alle DUPEITEMS, die für ein Item angegeben sind.) Die Liste von Nummern sind Itemnummern, die vielleicht noch nicht definiert wurden. Hier wäre das Skript für 0eee:
[ITEMDEF 0eee] //gold coins DUPEITEM=0eed CATEGORY=Provisions - Miscellaneous SUBSECTION=Coins DESCRIPTION=Gold Coins
In diesem Skript gibt es nur einen Parameter für das Item. Es verweist den Server auf das DUPEITEM, das unter 0eed (oder i_gold) angelegt wurde, um die Informationen von dort, wie TYPE und VALUE zu verwenden. DUPEITEM spart Tipparbeit, wahrscheinlich wird es selten benutzt.
CHARDEF
Oder was es braucht, einen nackten Mann zu machen, der rumstehen und "Huh?" sagen kann.
NPCs machen die Welt lebendig. Sie sind das, was UO zu einem einzigartigen Multiplayer Spiel macht. Die Monster und NPCs die du skriptest machen den Server einzigartig im Vergleich zu jedem anderen. Dieser Abschnitt des ersten Kapitels wird beinhalten, wie ein einfacher nackter Mann geskriptet wird, der herumwandern und ein wenig mehr als "Huh?" (oder "Halt Dieb!", wenn man so will) sagen kann.
Als erstens sehen wir uns das SKript eines einfachen nackten Mannes an. Es befindet sich in spherechar_human.scp.
[CHARDEF 0190] DEFNAME=c_man Name=Man ICON=i_pet_MAN CAN=MT_EQUIP|MT_WALK|MT_RUN|MT_USEHANDS RESOURCES=i_flesh_head, i_flesh_torso, i_flesh_right_arm, i_flesh_left_arm FOODTYPE=15 t_food, t_fruit DESIRES=i_gold,e_notoriety AVERSIONS=t_TRAP,t_eerie_stuff SHELTER=r_house BLOODCOLOR=0 TSPEECH=spk_human_prime TSPEECH=spk_human_default TEVENTS=e_Human_HearUnk DESCRIPTION=Man SUBSECTION=Miscellaneous CATEGORY=Civilized
Wie ersichtlich sieht es sehr viel anders aus als die Skripte der vorherigen Abschnitte. Es werden eine ganze Menge an Variablen gesetzt, die gleich sind wie der DEFNAME, DESCRIPTION und die anderen Axis Variablen.
Aber es gibt auch eine Menge neuer Dinge hier, die der Reihe nach und Zeile für Zeile betrachtet werden! Und es ist länger diesmal! Let the good times roll! (Entschuldigung an alle Nichtamerikaner, alle amerikanischen Cliches sind vermutlich irritierend!)
Zeile 1: [CHARDEF 0190]
Überraschung! Ein Identifier, der dem Server mitteilt, dass hier ein Charakter bis zum zum nächsten Identifier definiert wird. Und zudem wird für diesen Charakter bzw. NPC die ID 0190 gesetzt. Der Server kennt diese ID, da es eine eingebaute ist. In der Tat gehört diese ID zum nackten Mann. Des weiteren steht 0190 als hexadezimale Zahl natürlich für 400, nicht wahr? :) Warum weißt du das nicht? OK, nur ein Witz, das muss man natürlich nicht wissen.
Zeile 2: DEFNAME=c_man
Nichts neues. c_man entspricht hiermit 0190. Die meisten DEFNAMES für Charaktere beginnen mit c und dann folgt ein _ wie oben.
Zeile 3: Name=Man
Hier ist etwas neues. Items haben einen vorgegebenen Namen, der im Server bekannt ist. Charaktere nicht. Deshalb muss ein Name zugewiesen werden. Es kann im Grunde jeder Name zugewiesen werden, den man hier haben möchte, aber da das kein spezifischer Mann ist, heißt er einfach nur Man.
Zeile 4: ICON=i_pet_man
Ich brauchte eine Weile, um das herauszufinden. ICON legt ein kleines Bildchen fest, das man bei benutzung des Tracking Skills sieht und diese kleinen ICONs tauchen im Menü dort auf. Eigentlich sind diese Bildchen Items. Um herauszufinden, wie dieses Bildchen aussieht, kann der Mann einfach im Spiel mit .addnpc c_man erstellt werden und dann der .shrink Befehl auf ihn angewendet werden. Die ID dieses Items wird dann zum i_pet Item.
Zeile 5: CAN=mt_*
(Falls * nicht bekannt ist: * heisst "alles mögliche" für diejenigen, die Linux nutzen.)
Das ist eine der wichtigsten Zeilen im Character Skript, neben der ID die in der ersten Zeile vergeben wird. Sie lässt uns festlegen, was ein NPC tun kann und was nicht. Es gibt nur ein paar wenige Möglichkeiten für mt_*, die alle in der spheredefs.scp definiert sind. Für unsere Zwecke sind sie hier hin kopiert worden.
MT_NONMOVER 0 // Kann ueberhaupt nicht laufen MT_GHOST 01 // Kann wie ein Geist durch Tueren und aehnliches laufen MT_SWIM 02 // Ich kann schwimmen! (Wasser Elementare, Delphine, etc) MT_WALK 04 // Ich kann laufen! Setze dies wenn deine Kreatur laufen koennen soll. MT_FLY 010 // Laeuft durch Baeume (soll das darueber Fliegen darstellen) MT_FIRE_IMMUNE 020 // Ist gegen Feuer Immun. Das sollte man nicht auf einen Spieler setzen. :) MT_EQUIP 00100 // Kann Sachen anlegen (equip). MT_USEHANDS 00200 // Kann seine Haende benutzen um Sachen zu tragen (oder Tueren zu oeffnen) MT_MALE 0 // Ist maennlich MT_FEMALE 00800 // Ist weiblich MT_NONHUM 01000 // Kein Mensch. Ich bin mir nicht sicher was es genau bewirkt. MT_RUN 02000 // Kann wirklich schnell laufen!
Nach dieser Tabelle wird klar, dass ein NPC ohne CAN Flags ein MT_Male und MT_NONMOVER (zweimal 0) ist. Die Flags können durch ein | (Alt Gr + <) getrennt in einer Liste angegeben werden, so dass ein NPC mehrere solcher Flags erhalten kann. In diesem Fall erlauben wir unserem Mann, dass er etwas ausrüsten (oder anziehen), gehen, rennen und seine Hände benutzen kann. (Interessant ist, dass sogar Kreaturen ohne Hände ihre Hände nutzen können und damit bspw. Lichtquellen tragen können. Feuerelementare tun das beispielsweise, deshalb leuchten sie.)
Zeile 6: RESOURCES
Die Resources sind etwas morbide als Bezeichnung. Vor allem für Personen, denn sie enthalten die Items, die herauskommen, wenn man im Spiel eine Leiche aufschneidet. Gruslig, hm?
Zeile 7-10: FOODTYPE, DESIRES, AVERSIONS
FOODTYPE: Legt fest, welche Art von Essen der NPC essen würde und wenn NPC_AI_FOOD aktiviert ist, sucht der NPC nach so einem Essen wenn er hungrig wird.
DESIRES: Legt fest, welche Art von Items ihn interessieren und wenn NPC_AI_EXTRA aktiviert ist, dann wird ein NPC aus Spielerleichen diese Gegenstände holen oder, falls diese Gegenstände am Boden liegen, zu ihnen hingehen.
AVERSIONS: Das ist nicht ganz klar. Ich nehme an, dass diese Option angibt, was der NPC am liebsten angreift. Beispielsweise: Ich habe ein Pferd mit dem Event e_horse und einen Imp mit AVERSIONS=e_horse, dann würde im Falle eines Kampfs der IMP wohl vorziehen gegen das Pferd zu kämpfen.
Zeile 11: BLOODCOLOR
Jemals vorgehabt den Spielern grünes Blut zu verpassen? Das geht hiermit. Eine Nummer für eine Farbe oder ein DEFNAME funktioniert hier. (Für Farben sollte man versuchen die Zahlen zu lernen, das macht es einfacher.)
Der Rest: TSPEECH and TEVENTS
Diese beiden Zeilen erhalten eigene Kapitel. Sie sind sehr komplex und mitunter die komplexesten Dinge beim Skripten! (Wie oft ich das wohl sagen werde, bis das wirklich wahr ist?)
Einige andere Dinge:
Auf 56B gibt es weitere Variablen wie MOVERATE, RESLEVEL, RESDISPDNID and RESDISPDNHUE. Sie klingen schwierig und seltsam, aber das sind sie nicht. Hier ist eine Erklärung:
MOVERATE: Diese Einstellung (die nur innerhalb eines CHARDEF Blocks sein kann) legt fest, wie schnell sich ein NPC bewegt. Je kleiner der Wert, desto schneller ist ein NPC. Beispielsweise für ein Pferd mit vorgegebener MOVERATE von 100, wäre ein anderer NPC mit MOVERATE von 60 schneller als das Pferd. Das ist ganz gut, um schwierige Monster zu skripten, die nur schwer zu erlegen sind.
RESLEVEL: Das sagt Sphere aus welcher Version von UO das Monster abstammt, Beispielsweise hat ein "Wanderer of the Void" RESLEVEL=3 (3 ist AOS) (siehe spheredefs.scp für eine Liste), so dass nur Accounts mit RESDISP 3 oder größer das Monster so sehen, wie es wirklich aussieht.
NOTE: Setzt man einen zu niedrigen Wert für RESLEVEL und der Spieler hat die passende Animation nicht, führt das zum Absturz seines Clients.
RESDISPDNID: Wie wahrscheinlich bemerkt, sagte ich oft nun "wie er wirklich" ist, genau wegen dieser Einstellung. Das legt fest, wie ein Monster für einen Spieler aussieht, hat er die Animation nicht. Beispielsweise wird der Wanderer of the Void für jeden mit ACCOUNT.RESDISP=3 oder großer auch wie ein Wanderer of the Void aussehen, aber für alle anderen sieht er wie ein c_spectre aus (wenn es so eingestellt wurde).
RESDISPDNHUE: Das legt fest, welche Farbe für den Spieler das Monster hat, wenn die RESDISPDNID angezeigt wird (und sein account.resdisp kleiner als reslevel dieses Charakters ist).
Hier ist ein Beispiel für diese neuen Einstellungen:
[CHARDEF 310] DEFNAME=c_Wailing_Banshee NAME=Wailing Banshee SOUND=snd_monster_zombie1 ICON=i_pet_wailingbanshee DAM=11,16 RESDISPDNID=c_spectre RESLEVEL=3 RESDISPDNHUE=01 ARMOR=20 CAN=MT_WALK|MT_FLY DESIRES=i_gold,e_notoriety,e_horses,c_man,c_woman,t_corpse CATEGORY=New Monsters SUBSECTION=AOS DESCRIPTION=Wailing Banshee ON=@Create NPC = brain_monster FAME = {100 3000} KARMA = {-5000 -6999} STR = {126 166} INT = {86 115} DEX = {41 75} MAGICRESISTANCE = {75.0 95.0} TACTICS = {45.0 75.0} WRESTLING = {50.0 70.0} ON=@NpcRestock ITEM = i_gold, {50 100} ITEM = i_reag_daemon_bone, {2 6}
Und das wars. Einfache Charakterskripte und ein paar neue Dinge. Es gibt dazu noch ein spezielles Kapitel nur über das Skripten von NPCs später.
TEMPLATE
Oder wie man eine große Menge serverbelastender Items in einen nichtserverbelastenden Container packt.
Jeder hat sie schon gesehen. Die Shards, die keine TEMPLATEs benutzen. Wird beispielsweise ein Drache auf diesen Shards erlegt und lootet man ihn dann, dann findet man statt schön abgepackte Behälter ein paar 100 Tränke im Lootfenster verteilt. Nicht nur das, alle magischen Gegenstände sind auch noch darunter vergraben!
Wie wird das Problem gelöst? Sphere hat ein sehr handhabbares Werkzeug: die TEMPLATES. Sie erlauben, dass Container Items definiert werden und die Items in diesen Containern ebenfalls und zwar gleichzeitig. Das ist doch toll? I dachte es mir, als ich heraus fand, was sie sind. Deshalb wieder eine Zeile für Zeile Aufschlüsselung, diesmal mit einem TEMPLATE aus spheretemp_loot.scp.
[TEMPLATE 101505]
DEFNAME=backpack_poor
CATEGORY=Item Templates
SUBSECTION=Loot Templates
DESCRIPTION=Poor Backpack
CONTAINER=i_backpack
ITEM={ random_food 1 0 3 },{ 1 3 }
ITEM={ random_bottle 1 0 8 }
ITEM={ random_light 1 0 8 }
ITEM={ random_male_tops 1 0 4 }
COLOR=colors_all
ITEM={ random_male_pants 1 0 4 }
COLOR=colors_all
ITEM=POOR_GOLD_PILE
Sieht verwirrend aus. Aber kein Problem, das wird schon alles klar werden, was das bedeutet!
[TEMPLATE 101505]: Als erstes wird die Kopfzeile des templates betrachtet. Interessant an Templates ist, dass der Itemname kein DEFNAME sein kann, sondern eine sehr hohe Zahl sein muss.
DEFNAME=backpack_poor: Natürlich sind die Sphere Entwickler nicht bösartig und haben deshalb hier noch die Möglichkeit eines DEFNAMEs eingeführt.
CATEGORY, SUBSECTION, DESCRIPTION: Der übliche Axiskram. Optional natürlich. In den vorherigen Abschnitten wird das genauer erklärt.
CONTAINER=i_backpack: Ok, nun gehts runter bis aufs Eingemachte. Das ist der Container, der benutzt wird und alle anderen Items landen in diesem. Wenn der Container im Spiel erstellt wird, dann sieht man ihn. In diesem Fall ist das ein Rucksack. Ganz einfach. Hier kann nur ein gültiger Container vom Typ t_container oder t_container_locked angegeben werden.
ITEM={ random_food 1 0 3},{1 3} Das sieht ziemlich kryptisch aus. Deshalb wird diese Zeile ein wenig eingehender beleuchtet.
Als erstes muss ZUFALLSAUSWAHL behandelt werden! Klingt nach Spaß, nicht? Nun ja, klingt auch für mich nicht danach, aber es ist unbedingt notwendig, um einen guten Shard zu bauen.
Sie sind einfache grundlegende Mechanismen, um mit einem Befehl eine zufällige Zahl zu erhalten. Was wäre das schon für ein Shard, auf dem jeder getötete Drache auch eine Platemail of Magic Stuff und ein Super Duper Sword of Power liefern würde? Jeder würde damit herumlaufen, deshalb braucht es etwas Variabilität.
Es gibt zwei Arten von Zufallsauswahlen: gewichtete und bereichsweise Auswahl. Gewichtete Auswahlen funktionieren so: "OK, 1 mal von 10 nimm Nummer A, 3 mal von 10 nimm Nummer B und 6 mal von 10 nimm Nummer C". Bereichsweise Auswahlen funktionieren so: "Wähle eine zufällige Zahl zwischen zwei Zahlen, die ich festlege".
Unser Beispiel nutzt beides - sowohl bereichsweisen als auch gewichteten Zufall. Der Reihe nach:
{ random_food 1 0 3}
Das ist eine gewichtete Auswahl. Um das richtig zu verstehen, wird der Ausdruck zwischen den Klammern in zwei Teile zerlegt:
random_food 1
0 3
Addiert man die zweite Zahl in den beiden Zeilen, erhält man 4. Das sagt Sphere "OK, 1 von 4 Mal, will ich random_food und 3 von 4 Mal wähle ich 0." Man kann auch Zufallsauswahlen verschachteln, aber das wird dann verwirrend.
{ { random_food 1 0 3} 1 random_clothing 1}
Klar, was das heisst?
random_clothing 1
{ random_food 1 0 3} 1
2 ist hier die magische Zahl. Einmal von 2 nimmt Sphere random_clothing und einmal von 2 nimmt Sphere den vorherigen Auswähler, der dann aus seinen eigenen Optionen eins auswählt. Wenn du jetzt schon verwirrt bist, keine Sorge. Das ist sehr selten, aber es wird sich zeigen, wie TEMPLATES diese Probleme lösen können.
Ich habe erwähnt, dass es noch einen weiteren Zufallswähler gibt. Und dieser ist hier:
{1 3}
Anmerkung: Leerzeichen sind hier wichtig. Hier dürfen keine Leerzeichen zwischen { und der ersten Zahl oder } und der letzten Zahl sein. Ansonsten kommt seltsames Verhalten dabei heraus.
Das weist Sphere an "Nimm eine beliebige Zahl zwischen 1 und 3, inklusive". Inklusive heißt, dass Sphere auch 1 und 3 wählen kann oder eben jede Zahl dazwischen. In diesem Fall ist der Bereich sehr beschränkt. Sphere wird eine 1, 2 oder eine 3 liefern. Bereichsweise Auswähler werden oftmals in gewichteten Auswählern benutzt.
{ {1 3} 3 {4 9} 1}
"Einmal aus 4, nimm eine Zahl zwischen 4 und 9. Dreimal von 4, nimm eine Zahl zwischen 1 und 3."
Nachdem wir das nun hinter uns haben, sehen wir uns die Zeile des Skripts von oben an. Der Teil mit ITEM=
Das legt im Skript fest "Ok, wir werden jetzt ein Item zum Container hinzufügen". Alles nach dem = legt fest, was genau das ist und in welcher Menge. Es kann natürlich geskriptete werden ITEM=i_platemail_chest oder sonst was ohne die mysteriösen { } Auswähler, aber der Grund, warum TEMPLATES so interessant sind, ist die große Variabilität, die sie bringen.
{ random_food 1 0 3}
Das ist das Item, das erstellt wird. Aus der Einheit über gewichtete Zufallsauswahlen, 1 von 4 Mal, wird das random_food sein und 3 von 4 Mal, wird das 0 sein. Wenn ein Item 0 ist, dann wird nichts erstellt. Das bedeutet: "Hier gibt es eine 1 zu 4 Chance, dass random_food im Container auftaucht." Was random_food ist? Das ist ein weiteres TEMPLATE, das in spheretemplate.scp definiert wurde ... glaube ich.
{1 3} Ist die Menge des Items, die erstellt wird. Das ist eine zufällige Bereichsauswhl. Sphere nimmt eine Zahl zwischen 1 und 3 und setzt dann die Menge im Container. Natürlich: ist das Item zuvor 0 geworden, dann wird auch die Menge daran nichts ändern, denn 3 mal 0 ist weiterhin 0.
Das war grundlegend das Template Skript. Hier können noch so viele Items eingefügt werden, wie man Lust hat. Ausserdem ist noch folgendes Konstrukt dann interessant:
ITEM=i_sword_long,R11
Das ist eine Kurzform von:
ITEM={ i_sword_long 1 0 10 }
R11 bedeutet: "1 zu 11 Chance, dass das Item gefunden wird". Und zusätzlich kann noch eine Mengenauswahl hinten angehängt werden, was es ziemlich seltsam aussehen lässt:
ITEM=i_sword_long,R11,{4 5}
Aber warum würde man 4 oder 5 Langschwerter haben wollen? Das wäre noch seltsamer. :)
Das wars von Templates. Gratulation, das erste Kapitel ist hiermit durch. Jetzt sollten die Beispiele im nächsten Abschnitt nicht schwierig zu verstehen sein. Du könntest auch einige fragen haben, die hier allerdings ohnehin nicht beantwortet werden. Einfach weiterlesen, es wird noch vieles in den folgenden Kapiteln abgehandelt.
(Ein Template Beispiel von Belgar)
[TEMPLATE tm_necromancer]
CONTAINER=i_bag
ITEM=random_necro_scroll
ITEM=random_necro_scroll
ITEM=random_necro_reagent, {5 12}
ITEM=random_reagent, {5 12}
ITEM=random_necro_reagent, {5 12}
Beispiele
Oder ... naja, glaub es gibt kein anderes Wort für "Beispiele".
Das soll mein Versuch sein, einfachste simpelste Items zu erstellen. Du wirst hier einige DInge in diesen Beispielen sehen, die in den Tutorials nicht behandelt wurden. Hauptsächlich gibts hier ein ON=@create das im 2. Kapitel abgehandelt wird. Für die Beispiele ist nur wichtig, dass die Farbe der Dinge im Spiel geändert werden kann und dass das unter on=@create passieren muss.
Beispiel 1: Ein rotes Schwert
[ITEMDEF i_sword_red]
ID=i_sword_viking
TYPE=t_weapon_sword
NAME=Das rote Schwert
CATEGORY=Weapons
SUBSECTION=New Swords
DESCRIPTION=Red Sword
ON=@Create
- COLOR=colors_red // Das ist ein Kommentar. Kommentare werden von Sphere ignoriert.
Moment ... was heisst das // an dieser Stelle? Das ist ein Kommentar, er wird gänzlich von Sphere ignoriert, deshalb kann hier alles stehen, solange es hinter den // steht. Es gibt in Sphere keine mehrzeiligen Kommentare, solange man nicht jede Zeile mit // beginnen lässt. Deshalb sollte man das gar nicht versuchen, sonst wird Sphere viele Fehler ausgeben und man darf sie suchen.
Beispiel 2: Ein blauer Ettin
[CHARDEF c_ettin_blue]
ID=02 // Hier kann auch c_ettin benutzt werden natürlich.
NAME=Mein blauer Ettin
ON=@Create
- COLOR=02 // Das ist dunkelblau. Wird oft für Counselorroben benutzt. Merken.
Beispiel 3: Ein Template aus einer der Dateien, weil ich zu faul bin eins selbst zu schreiben
[TEMPLATE 101521]
DEFNAME=goodie_meager_1
CATEGORY=Item Templates
SUBSECTION=Loot Templates
DESCRIPTION=Meager Goodie 1
ITEM={ meager_gold_pile 1 backpack_meager 1 pouch_meager 1 }
ITEM={ random_boots 1 0 4 }
ITEM={ random_gorget 1 0 4 }
ITEM={ random_staff 1 0 4 }
ITEM={ random_necklace 1 0 4 }
ITEM={ i_cape 1 0 9 }
COLOR=colors_all
Bemerkenswert ist hier etwas neues (das speziell in rot hervorgehoben ist) und ja, das kann man so schreiben. Alle Zeilen zwischen ITEM= Zeilen betreffen das zuvor erstelle Item. COLOR= bezieht sich also auf die Zeile
ITEM={ i_cape 1 0 9 }
Der beste Weg diese Art von Skripten zu lernen, liegt darin, dass man die Skripte in den Dateien wie beispielsweise sphereitem_colorarm.scp und sphereitem_beers.scp liest.