<text>Ab CR Build 265 ist es m<>glich, Spieler auch per Script beitreten zu lassen. Solche Spieler verhalten sich wie normale Spieler. Sie besitzen eine Crew, ein Konto, Heimatbasismaterial, ein Team, Baupl<70>ne, etc. Einziger Unterschied ist, dass sie von keinem Spieler gesteuert werden und auf keinem Rechner ein Sichtfenster f<>r diese Spieler ge<67>ffnet wird.</text>
<text>Scriptspieler sind n<>tzlich, um zum Beispiel KI-Gegner zu realisieren.</text>
<hid="Runtime">Beitritt zur Laufzeit</h>
<text>F<EFBFBD>rs Erstellen einer KI zur Laufzeit - zum Beispiel als Gegner im Deathmatch - dient <funclink>CreateScriptPlayer</funclink>. Daraufhin erfolgt (unter Umst<73>nden verz<72>gert, weil es sich um einen Spielerbeitritt handelt!) ein InitializePlayer-Aufruf f<>r diesen Scriptspieler. Da der Aufruf verz<72>gert ist, sollte die eigentliche KI-Initialisierung in diesem Aufruf passieren.</text>
<text>Dazu ein Beispiel:</text>
<code>/* Script einer aktivierten Spielregel namens "KI Erzeugen" */
#strict
public func Activate(int iPlr)
{
// Der Spieler iPlr hat die Spielregel ausgew<65>hlt. Erzeuge einen KI-Gegner!
<text>Dieses Beispielscript f<>r ein Regelobjekt erlaubt dem Spieler, zur Laufzeit KI-Gegner zu erstellen. Au<41>erdem sorgt es daf<61>r, dass alle Clonks dieses KI-Gegners angreifen. Achtung: Das Beispiel <20>bernimmt die Kontrolle nur f<>r alle Clonks, die der Spieler zu Spielbeginn nach Szenarienvorgaben erhalten hat. Wenn ein Szenarienscript zum Beispiel noch andere Clonks erstellen w<>rde, w<>rden diese nicht gesteuert.</text>
<text>F<EFBFBD>r Internetspiele kann man auch MaxScriptPlayers in der <emlinkhref="scenario/Teams.html">Teams.txt</emlink> auf einen Wert >0 setzen. Dann bekommt man in der Lobby die Option, Scriptspieler zu aktivieren. Diese Spieler treten auch wie gew<65>hnliche Spieler bei, und man sollte auch hier in InitializePlayer entsprechend das KI-Kontrollobjekt erstellen. Das obige Beispiel w<>rde also auch sofort mit in der Lobby aktivierten KI-Spielern funktionieren.</text>
<hid="Preset">Beitritt als Vorgabe</h>
<text>Wenn ein Szenario schon von Anfang an einen Scriptspieler beinhalten soll - zum Beispiel weil Objekte in der Objects.txt in dessen Besitz sein sollen, oder weil in Initialize Objekte f<>r diesen Spieler erzeugt werden, dann sollte man diesen wie in einem Savegame definieren. Also eine SavePlayerInfos.txt wie diese anlegen:</text>
<code>[PlayerInfoList]
LastPlayerID=1
[Client]
ID=0
Flags=Initial
[Player]
Name="Aliens"
Flags=Joined
ID=1
Type=Script
Team=2
Color=65535
GameNumber=1
GameJoinFrame=0
</code>
<text>Dies f<>hrt eine Spieler-Wiederherstellung durch, analog zur Wiederherstellung nach einem Savegame. Es wird also kein InitializePlayer f<>r diesen Spieler aufgerufen. Das Szenarienscript sollte in der Initialisierung die Crew f<>r diesen Spieler erstellen, oder es sollte eine entsprechende Crew in der Objects.txt vorhanden sein. Ansonsten wird der Scriptspieler sofort zum Spielbeginn eliminiert.</text>
<text>Scriptspieler werden im Gegensatz zu regul<75>ren Spielern ebenfalls gespeichert, wenn man in der Konsole "Speichern als Szenario" w<>hlt. Auf diese Weise kann man sich die richtige SavePlayerInfos.txt automatisch anlegen lassen. Dazu sollte einfach im Entwicklermodus manuell <funclink>CreateScriptPlayer</funclink> aufgerufen und dann Clonks f<>r diesen Scriptspieler verteilt werden. Speichert man dann als Szenario, wird der Scriptspieler mitgespeichert und steht beim Starten wieder zur Verf<72>gung.</text>
<hid="Specialized">Spezialisierte Spieler</h>
<text>Manchmal kann es sinnvoll sein, einen Scriptspieler erst zur Laufzeit zu erstellen aber trotzdem eine spezielle Initialisierung durchzuf<75>hren. Zum Beispiel sollte ein spezieller Alien-Gegner in einem Hazard-Deathmatch keine Hazardclonks erhalten.</text>
<text>Mit einem Parameter an <funclink>CreateScriptPlayer</funclink> lassen sich die szenarienspezifische Initialisierung, das hei<65>t das Erzeugen des Startmaterials, das Setzen der Startparameter nach Vorgaben und auch alle InitializePlayer-Aufrufe unterbinden. Stattdessen erfolgt nur ein InitializeScriptPlayer-Definitionsaufruf in der angegebenen Definition. Dazu ein Beispiel:</text>
<code>/* Script einer aktivierten Spielregel namens "Aliens erzeugen" */
#strict
public func Activate(int iPlr)
{
// Der Spieler iPlr hat die Spielregel ausgew<65>hlt. Erzeuge einen Alien-Gegner!