Benutzer:Schnobs/Skripte: Unterschied zwischen den Versionen

Aus X-Lexikon
Zur Navigation springenZur Suche springen
Keine Bearbeitungszusammenfassung
 
(4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt)
Zeile 1: Zeile 1:
Jawoll, ich will's versuchen. Mal sehen, was dabei rauskommt. Als erstes Projekt habe ich mir ein Skript vorgenommen, daß automatisch Satelliten aufstellt (und zerstörte Satelliten ersetzt).
Hier ein paar Skripte, die ich mir so im Laufe der Zeit geschrieben habe. Bei Interesse findet ihr in den Wiki-Menüs am linken Rand die Funktion "Email an diesen Benutzer".
==Kleine Helferlein==


Hier der Plan. Kommentare sind herzlich willkommen.
===Geschützturmbefehl für den Bergbau===


Im Standard-Skript "Greife mein Ziel an" (!turret.attacktarget.std) findet sich folgendes:


==Funktionsumfang==
012      if not [THIS] -> is $victim a enemy
013        $victim = null
 
Damit soll verhindert werden, daß die Kanzel das Feuer auf neutrale und befreundete Schiffe und Stationen eröffnet. Eigentlich ist das ja ganz sinnvoll. Nur sind Asteroiden prinzipiell neutral und ändern ihre Meinung auch nicht, wenn man sie beschießt. Eine kleine Änderung am Skript prüft zusätzlich, ob das Ziel ein Asteroid und die Waffe ein Mobiles Bohrsystem ist.
 
Nun kann sich der Bergbauingeneur ganz auf die Steuerung des Schiffes konzentrieren, und muß nicht länger in die Heckkanzel umsteigen.
 
===Landecomputer für die KI===
 
Alle mit Landecomputer ausgestatteten Schiffe benutzen ihn auch.
 
===Mehr Fairness beim Völkerrang===
 
Die Flotten der Völker sind offensichtlich überfordert und schaffen es nicht, die Sicherheit in ihren Sektoren zu gewährleisten. Da ist der Spieler gefragt... und mit den Patroullienkommandos aus dem Bonuspack ist das ja durchaus zu schaffen. Nur: wo bleibt der Dank?
 
Wenn eines meiner Schiffe Völkerbesitz beschädigt, werde ich dafür persönlich zur Rechenschaft gezogen. Das gleichzeitig zahlreiche Patroullien in meinem Namen und auf meine Rechnung für Sicherheit sorgen, wird hingegen von niemandem gewürdigt. Das hat mir dermaßen Gestunken, daß ich da was unternommen habe.
 
Jetzt bekomme ich den vollen Völkerrang für Abschüsse durch eigenes Personal. Die Prämie muß ich mir mit dem Piloten teilen, schließlich hat er seinen Kopf hingehalten.
 
 
==Autom. Satellitenverteiler==
===Funktionsumfang===
oder<br>
oder<br>
'''Was geht und was nicht geht'''
'''Was geht und was nicht geht'''
Zeile 10: Zeile 33:
Dies ist ein sehr schlichtes Skript, um in einem bestimmten Bereich Satelliten aufzustellen. Das Schiff plaziert Satelliten in allen Sektoren des Einsatzgebietes, und ersetzt verloren gegangene. Die erforderlichen Satelliten werden (ebenfalls innerhalb des Einsatzgebietes) günstigst eingekauft.
Dies ist ein sehr schlichtes Skript, um in einem bestimmten Bereich Satelliten aufzustellen. Das Schiff plaziert Satelliten in allen Sektoren des Einsatzgebietes, und ersetzt verloren gegangene. Die erforderlichen Satelliten werden (ebenfalls innerhalb des Einsatzgebietes) günstigst eingekauft.


Dieses Skript richtet sich an den aufstrebenden Jungunternehmer: der Funktionsumfang ist bescheiden, mit Problemen kann es nicht umgehen. Dafür entstehen auch keine weiteren Kosten, keine Gebühr pro aufgestelltem Satellit oder sowas. Die Satelliten und das Schiff sind schon teuer genug.
Dieses Skript richtet sich an den aufstrebenden Jungunternehmer: der Funktionsumfang ist bescheiden, mit Problemen kann es nicht umgehen. Dafür entstehen auch keine weiteren Kosten, keine Gebühr pro aufgestelltem Satellit oder sowas. Ständig Satelliten zu ersetzen verursacht schon genug laufende Kosten.
 


Bedienung:<br>
Bedienung:<br>
Zeile 18: Zeile 40:
Weiterhin wird man gefragt, welche Art von Satellit man verteilen will: E = Erweitert, alle anderen Eingaben = Navigationssatellit.
Weiterhin wird man gefragt, welche Art von Satellit man verteilen will: E = Erweitert, alle anderen Eingaben = Navigationssatellit.


Zu guter letzt soll man noch eine Sprungweite angeben. Der Ausgangspunkt ist der Sektor, in dem sich das Basislager befindet. Das Einsatzgebiet wird aus der Sprungweite in Verbindung mit den Freund/Feind-Einstellungen berechnet. Beispiel: Basislager ist die Handelsstation in Argon Prime, Sprungweite ist 7, alle außer den Argonen sind Feinde. Ergebins: das Einsatzgebiet sind die sog. "Argonischen Kernsektoren".
Zu guter letzt soll man noch eine Sprungweite angeben. Der Ausgangspunkt ist der Sektor, in dem sich das Basislager befindet. Das Einsatzgebiet wird aus der Sprungweite in Verbindung mit den Freund/Feind-Einstellungen berechnet, dadurch kann man das Einsatzgebiet sinnvoll abgrenzen. Beispiel: Basislager ist die Handelsstation in Argon Prime, Sprungweite ist 7, alle außer den Argonen sind Feinde. Ergebnis: das Einsatzgebiet sind die sog. "Argonischen Kernsektoren".


Die Einbeziehung der Freund/Feind-Einstellungen ermöglicht eine recht sinnvolle Abgrenzung des Einsatzgebietes. Es wird einmal berechnet und dann als Liste gespeichert; es ließe sich also mit relativ wenig Aufwand ein Skript basteln, das einzelne Sektoren zur Liste hinzufügt oder daraus entfernt. Wenn man die F/F-Einstellungen später ändert, hat das KEINE Auswirkungen auf den Einsatzbereich!
:''VORSICHT: Die Rassen haben ja mehr als ein Gebiet. Wenn man die Sprungweite zu hoch einstellt, landen Sektoren aus mehreren Gebieten in der Liste. Das kann erwünscht sein, aber auf jeden Fall sind die Wege lang und u.U. führen Sie durch einen Xenonsektor oder dergleichen...''
 
Die Liste der Sektoren wird bei Programmstart berechnet und dann gespeichert; es ließe sich also mit relativ wenig Aufwand ein Skript basteln, das einzelne Sektoren zur Liste hinzufügt oder daraus entfernt. Wenn man die F/F-Einstellungen später ändert, hat das KEINE Auswirkungen auf den Einsatzbereich!


Was geschieht:<br>
Was geschieht:<br>
Zeile 28: Zeile 52:


Also, nochmal zum mitschreiben: das Skript ist schlau genug, ohne Satelliten gar nicht erst zu starten. Und das ist die einzige Intelligenz, die es hat. Andere Probleme werden nicht einmal erkannt.
Also, nochmal zum mitschreiben: das Skript ist schlau genug, ohne Satelliten gar nicht erst zu starten. Und das ist die einzige Intelligenz, die es hat. Andere Probleme werden nicht einmal erkannt.
==Ablauf (hier brauche ich Hilfe)==
===setup.plugin.satdrop===
001  $textID = 1312
002  $pageID = 1002
003  load text: id=$textID
004 
005  * link command to equipment
006  set script command upgrade: command=COMMAND_DEPLOY_SATELLITE  upgrade=Spezialsoftware MK1
007 
008  * link command to actual script
009  global script map: set: key=COMMAND_DEPLOY_SATELLITE, class=Light Fighter M5, race=Player, script='plugin.satdrop.start', prio=0
010 
011  set global variable: name=$pageID.satdrop value=$pageID
012  set global variable: name=$textID.satdrop value=$textID
013  return null




===plugin.satdrop.start===
==Der (fast) perfekte Händler==


Funktion: übernimmt die Benutzereingabe.
...funktioniert (von außen gesehen) ähnlich wie die Handelssoftware Mk3, nur viel besser. Denn dieser Händler Vergleicht systematisch alle Handelsgelegenheiten und entscheidet sich für den besten Auftrag, unter Berücksichtigung von Laderaum und Spielerkonto. Bezahlt wird er in CPU-Zyklen.
Klappert alle Sektoren ab und schreibt sie in ein array
Schickt das Schiff zum Basislager
exportiert die notwendigen variablen
startet das eigentliche Skript


Arguments
Anders als die Uni-Händler (oder Fabrikfrachter) kann dieser Händler nur die Preise der Sektoren abfragen, die der Spieler auch "sehen" kann. Er macht also nichts, was man nicht auch selbst tun könnte, und ist in dieser Hinsicht ausgesprochen fair. Geschrieben habe ich dieses Skript als ich (mal wieder) ein neues Spiel angefangen habe, des ständigen Preisvergleichs aber schnell überdrüssig wurde.  
    * 1: Camp , Var/Station , 'Select Base Camp'
    * 2: SatType , Var/Number , '0 NavSat, alles andere Erw.Sat'
    * 3: Range , Var/Number , 'max. Jump Range'
Source Text
001  $textID = get global variable: name=$textID.satdrop
002  $PageID = get global variable: name=$pageID.satdrop
003  load text: id=$textID


An dieser Stelle gibt es ein Problem: $PageID bekommt den Wert 1312 (=$textID), obwohl ich oben 1002 gesetzt und exportiert habe. Huch?
Dieser Händler ist erschreckend effizient: ich hatte eigentlich gedacht, ich hätte alle Preise sorgfältig abgeklappert (daher ja auch der Überdruß), aber denkste &dansh; die automatische Suche fördert Gelegenheiten zutage, an die ich nicht mal gedacht hätte. Dabei ist nicht mal ein ausgedehntes Satellitennetzwerk erforderlich, schon mit vier Sektoren kann sich der Händler geraume Zeit beschäftigen ohne daß der Gewinn pro Fahrt spürbar leidet.


004  $PageID = 1002
Der systematische Vergleich aller Handelsmöglichkeiten ist potentiell ''sehr'' rechenintensiv, weshalb ich den Händler jetzt fest auf Sprungweite=1 festgenagelt habe. Außerdem würden höhere Distanzen einen Sprungantrieb erfordern; dazu muß er sich einen Vorrat an EZ für den Eigenbedarf anlegen und ggf ergänzen usw usf -- wobei es mir sehr fraglich erscheint, ob die Gewinne bei höherer Sprungweite noch signifikant steigen würden.
005 
006  * Created by Schnobs, July 2007
007  * Automatic Satellite Deployment, startup script
008 
009  if $SatType == 0
010    $SatType = Navigationssatellit
011  else
012    $SatType = Erweiterter Satellit
013  end
014 
015  * Andockerlaubnis am Basislager
016 
017  if not [THIS] -> is docking allowed at $Camp
018    play sample 1248
019    write to player logbook: printf: pageid=$PageID textid=1, $Camp, null, null, null, null
020    return null
021  end
022 
023  * sind schon Satelliten im Kofferraum
024  if not [THIS] -> get amount of ware $SatType in cargo bay
025  * aha. Ist denn wenigstens genug Platz
026    if not [THIS] -> get free amount of ware $SatType in cargo bay
027    play sample 1253
028    write to player logbook: printf: pageid=$PageID textid=2, $SatType, null, null, null, null
029    return null
030    end
031  end
032 
033  * ----ab hier werden die Sektoren durchgegangen----
034  * erstmal ein paar variablen
035  * wie gross ist das Universum
036  $uniX = get max sectors in x direction
037  $uniY = get max sectors in y direction
038 
039  * und wo bin ich gerade
040  $CampSector = $Camp -> get sector
041  $homeX = $CampSector -> get universe x index
042  $homeY = $CampSector -> get universe y index
043  $SectorList =  array alloc: size=0
044 
045 
046  * kleineren bereich abstecken...
047 
048  $minX = $homeX - $Range
049  skip if $minX >= 0
050    $minX = 0
051  $maxX = $homeX + $Range
052  skip if $maxX <= $uniX
053    $maxX = $uniX
054 
055  $minY = $homeY - $Range
056  skip if $minY >= 0
057    $minY = 0
058  $maxY = $homeY + $Range
059  skip if $maxY <= $uniY
060    $maxY = $uniY
061 
062  * und jetzt fuer min max XY pruefen...
063 
064  $x = $minX
065  while $x <= $maxX
066    $y = $minY
067    while $y <= $maxY
068    $tempSec = get sector from universe index: x=$x, y=$y
069    $tempdist = get jumps from sector $CampSector to sector $tempSec
070    $known = $tempSec -> is sector known by the player
071    $nmy = [THIS] -> is $tempSec a enemy
072    if $tempdist <= $Range AND $known == [TRUE] AND $nmy == [FALSE]
073     
074  * Sektor dem Array hinzufuegen
075      skip if not  is datatyp[ $tempSec ] == DATATYP_SECTOR
076      append $tempSec to array $SectorList
077     
078  * ende der eigentlichen tests
079    end
080   
081  * y hochsetzen, y-Schleife beenden
082    inc $y =
083    end
084   
085  * Ende der x-Schleife
086    inc $x =
087  end
088 
089  * an dieser Stelle sollte eine Sektorenliste vorliege
090  * nun die Liste ins Log schreiben
091 
092 
093  $i = 1
094  $numSectors =  size of array $SectorList
095  $tempSec = $SectorList[0]
096  $msg = $tempSec
097  while $i < $numSectors
098    $tempSec = $SectorList[$i]
099    $msg = $msg + ', ' + $tempSec
100    inc $i =
101  end
102 
103  write to player logbook: printf: pageid=$PageID textid=3, $SatType, $Camp, $msg, null, null
104 
105  * erstmal zum Basislager
106 @ = [THIS] -> call script 'lib.xi.nav' :  Target=$Camp  Range=null  Sector Position=null
107 
108  * variablen exportieren un das eigentliche skript aufrufen.
109  [THIS] -> set local variable: name=$SectorList value=$SectorList
110  [THIS] -> set local variable: name=$SatType value=$SatType
111 @ = [THIS] -> call script 'plugin.satdrop.main' :  Basislager=$Camp  Nav. oder Erw. satellit=$SatType
112  return null


===plugin.satdrop.main===
Es gibt keine Sprachdatei oder Befehle. Gestartet wird die Software aus dem Skript-Editor, alle Nachrichten sind hart kodiert.


Klappert die Sektoren im Array ab und sucht nach Satelliten. Falls keiner da ist, fliegt es los und stellt einen auf. Falls keine Satelliten (mehr) an Bord sind, wird das Nachschub-Skript aufgerufen.
==Modifizierte Handelsbefehle==


'''Ich hatte bei den bisherigen Tests noch nie Satelliten an Bord. Ich kann bisher nur sagen, daß dieses Skript erfolgreich das Nachschub-Skript aufruft -- und dort ist was faul.'''
Meine derzeitige Baustelle. So etwas habe ich schonmal gemacht, bin aber überzeugt, daß es noch besser geht.
Die Befehle sollen in den "Zusätlichen Schiffskommandos" liegen; insgesamt gibt es drei Befehle, aber man kann leider nur max. zwei Kommandos gleichzeitig setzten. Schade eigentlich.


===Handle naheliegend===
Normalwerweise sucht der Händler den meistbietenden Abnehmer; mit dieser Modifikation findet er den nächstgelegenen, der noch mindestens den eingestellten Preis bietet. Frühere Erfahrungen zeigen, daß das sehr sinnvoll sein kann: die Gewinne sinken ein wenig, aber man kann sich oft den zweiten Frachter sparen.


===Warte auf Ladung===
    * 1: Camp , Var/Station , 'Basislager'
Nur für Verkäufer: das Schiff wird erst losfliegen, wenn sein Laderaum gefüllt ist. Wozu ständig mit halbleerem Laderaum durch die Gegend gondeln?
    * 2: SatType , Var/Ware , 'Nav. oder Erw. satellit'
Source Text
001  $textID = get global variable: name=$textID.satdrop
002  $pageID = get global variable: name=$pageID.satdrop
003  load text: id=$textID
004  $pageID = 1002
005 
006  * dies ist eine Endlos-Schleife
007  while [TRUE]
008  START:
009  * Sektorenliste aktualisieren
010    $SectorList = [THIS] -> get local variable: name=$SectorList
011   
012  * sind ueberhaupt Satelliten an Bord
013  * nicht vergessen, alles ausser 0 ist wahr...
014    while [THIS] -> get amount of ware $SatType in cargo bay
015   
016   
017    $i.sec = 0
018    $sector.count =  size of array $SectorList
019    while $i.sec < $sector.count
020      $tempSec = $SectorList[$i.sec]
021     
022  * falls wir keinen Nav.Sat finden...
023      skip if  find ship: sector=$tempSec class or type=Navigationssatellit race=Player flags=null refobj=null maxdist=null maxnum=null refpos=null
024  * und auch keinen Erw.Sat...
025      skip if  find ship: sector=$tempSec class or type=Erweiterter Satellit race=Player flags=null refobj=null maxdist=null maxnum=null refpos=null
026  * sofort aus der Schleife ausbrechen.
027      break
028     
029     
030  * wenn wir bis hier kommen, ist ein Satellit vorhanden.
031  * deshalb wird tempSec geloescht, i hochgesetzt, naechster Sektor bitte.
032      $tempSec = null
033      inc $i.sec =
034 @    = wait randomly from 0 to 500 ms
035    end
036   
037   
038  * wenn tempSec einen Wert hat, wurde oben kein Sat gefunden...
039    if  is datatyp[ $tempSec ] == [SECTOR]
040     
041  * lib.xi.nav erwartet ein array x,y,z,sektor
042  * range ist keine sprungweite, sondern die abweichungvon xyz
043      $sat.x = 0
044      $sat.y = 30000
045      $sat.z = 0
046      $secpos =  array alloc: size=4
047      $secpos[0] = $sat.x
048      $secpos[1] = $sat.y
049      $secpos[2] = $sat.z
050      $secpos[3] = $tempSec
051 @    = [THIS] -> call script 'lib.xi.nav' :  Target=null  Range=300  Sector Position=$secpos
052     
053  * warentyp - schiffstyp
054      $sat.shiptype = Erweiterter Satellit
055      skip if $SatType == Erweiterter Satellit
056      $sat.shiptype = Navigationssatellit
057     
058  * sat im laderaum vernichten
059      = [THIS] -> add -1 units of $SatType
060  * sat im weltall erzeugen
061      $whats.this =  create ship: type=$sat.shiptype owner=Player addto=$tempSec x=$sat.x y=$sat.y z=$sat.z
062     
063  * und zurueck auf los. Wir schauen uns die restlichen
064  * Sektoren an, noch bevor wir nach hause fliegen.
065 @    = wait randomly from 0 to 500 ms
066      goto label START
067    end
068   
069   
070  * wenn wir hier ankommen, sind alle Sektoren geprueft
071  * und es fehlt nirgends ein Satellit.
072  * wenn wir im Raum sind, ab nach Hause
073    if not [THIS] -> is docked
074 @    = [THIS] -> call script 'lib.xi.nav' :  Target=$Camp  Range=null  Sector Position=null
075  * andernfalls 5min aussetzen
076    else
077 @    = wait 300000 ms
078    end
079  * In jedem fall machen wir eine kurze Pause
080 @  = wait randomly from 0 to 500 ms
081    end
082   
083  * wenn wir diesen punkt erreichen, sind die Satelliten alle
084 @  = [THIS] -> call script 'plugin.satdrop.buy' :  Ware=$SatType  maxprice=null  Basislager=$Camp
085  end
086  return null
===plugin.satdrop.buy===


Soll Satelliten nachkaufen. Klappt nicht.
===Abweichende Sprungweite===
Selbsterklärend.


Dieses Skript ist zu 90% von den "Manuellen Handelsbefehlen" der Xai Corporation abgekupfert.
==Autom. Bergbau==
    * 1: Arg1 , Value , 'Ware'
    * 2: Arg2 , Value , 'maxprice'
    * 3: Camp , Var/Station , 'Basislager'
Source Text
001  * Created by Xai Corporation
002  *
003  * ---------------------------------------
004  * Find best buy
005  * - Arg1-Ware, Arg2-MaxPrice, Arg3-Max-Jumps
006  *  -  set defaults if not already set
007  $textID = get global variable: name=$textID.satdrop
008  load text: id=$textID
009  $pageID = 1002
010 
011 
012 
013  if not $Arg1
014    return null
015  else if not  is datatyp[ $Arg1 ] == DATATYP_WARE
016    return null
017  end
018  if not $Arg2
019    $Arg2 = get max price of ware $Arg1
020  else if not  is datatyp[ $Arg2 ] == DATATYP_INT
021    $Arg2 = get max price of ware $Arg1
022  end
023 
024  $price.avg = get average price of ware $Arg1
025 
026  $in.cargo = [THIS] -> get amount of ware $Arg1 in cargo bay
027  $failed.attempt = 0
028  $gametime.start = playing time
029 
030  while $in.cargo == 0
031   
032  *  -  get  sectors in range
033    enable signal/interrupt handling: [FALSE]
034    $sector.list = [THIS] -> get local variable: name=$SectorList


XI berechnet hier eine Sektorenliste (array) nach ihren eigenen Regeln. Den ganzen Plumquatsch habe ich abgeschnitten und will stattdessen mein eigenes Array nachladen. Wenn ich den Debugger über dieses Skript laufen lasse, zeigt er mir für $sector.list ''DATATYP_NULL, null, (0)'' -- ich habe jetzt schon ein dutzend mal geprüft, das Start-Skript exportiert das Array und im main-Skript wird es auch erfolgreich geladen.
Die "große" Variante dieses Skripts soll den Bergbau vollständig automatisieren; es handelt sich um mein erstes großes Projekt, und das merkt man. Definitiv nicht reif für eine Veröffentlichung.


035    $sector.list.num =  size of array $sector.list
Als Ableger ist eine "kleine" Version entstanden: das Geschützturm-Skript erzeugt am Ort des zerstörten Asteroiden eine Navigationsbake. Erzsammler lassen sich nicht von treibenden Frachtcontainern ablenken, sie fliegen gezielt die Baken an und sammeln nur Minerale. Mehrere Sammler kommen sich nicht in die quere. Wenn der Laderaum voll ist, schalten sie ''erkennbar'' in den Bereitschaftsmodus, so daß man volle Frachter schon in der Besitztümerliste erkennt.
036  *  - get best price from sectors in range
037    $best.price = get max price of ware $Arg1
038    while $sector.list.num
039    dec $sector.list.num =
040    $sector = $sector.list[$sector.list.num]
041    if $Arg2 > $price.avg
042      $station =  find station: product $Arg1 with best price:  max.price=$price.avg, amount=null, max.jumps=0, startsector=$sector, trader=[THIS]
043      skip if $station
044      $station =  find station sells: resource $Arg1 with best price: max.price=$Arg2, amount=null, max.jumps=0, startsector=$sector, trader=[THIS]
045    end
046    skip if $station
047      $station =  find station: product $Arg1 with best price:  max.price=$Arg2, amount=null, max.jumps=0, startsector=$sector, trader=[THIS]
048  *  -  set station as best if price is lowest
049    if $station
050      $station.isEnemy = [THIS] -> is $station a enemy
051      if $Arg3 < 3 OR ! $station.isEnemy
052      $range = get jumps from sector [SECTOR] to sector $sector
053      $price = $station -> get price of ware $Arg1
054      if $best.range > $range OR $price < $best.price
055        $best.price = $price
056        $Arg2 = $best.price
057        $best.station = $station
058        $best.range = $range
059      end
060  * trust me this is needed for line 59
061      $station = null
062      end
063    end
064   
065    end
066    $station = $best.station
067    $ware = $Arg1
068   
069  * set Display
070    [THIS] -> set destination to $station
071    [THIS] -> set wanted ware to $ware
072    [THIS] -> set command: COMMAND_GET_WARE  target=$ware target2=null par1=null par2=null
073    set script command: COMMAND_SIGN_MTC_BEST_BUY
074   
075  * fly to station
076    $station.name = sprintf: fmt='%s', $station, null, null, null, null
077    while not $arrived
078 @  $arrived = [THIS] -> call script 'lib.xi.nav' :  Target=$station  Range=null  Sector Position=null
079 @  = wait 300 ms
080    end
081   
082  * check we have arrived
083    if [DOCKEDAT] == $station
084 @  = [THIS] -> call script 'lib.xi.trade' :  Command='buy'  Ware=$ware  Quantity=null
085    end
086   
087  * .........................................
088  * an dieser Stelle sollten wir wieder Satelliten haben
089  * .........................................
090   
091  * nirgends angedockt bedeutet Probleme
092    skip if [THIS] -> is docked
093 @  = [THIS] -> call script 'lib.xi.nav' :  Target=$Camp  Range=null  Sector Position=null
094   
095   
096    $in.cargo = [THIS] -> get amount of ware $Arg1 in cargo bay
097   
098   
099  * doch noch keine satelliten bekommen...
100  * alle stunde nachricht an den spieler und weiter versuchen
101    if $in.cargo == 0
102    inc $failed.attempt =
103    if $failed.attempt >= 12
104      $gametime.now = playing time
105      $gametime.passed = ( $gametime.now - $gametime.start ) mod 60
106      write to player logbook: printf: pageid=1002 textid=4, $gametime.passed, $ware, null, null, null
107      $failed.attempt = 0
108    end
109 @  = wait 300000 ms
110    end
111  end
112  return null

Aktuelle Version vom 24. Januar 2008, 17:54 Uhr

Hier ein paar Skripte, die ich mir so im Laufe der Zeit geschrieben habe. Bei Interesse findet ihr in den Wiki-Menüs am linken Rand die Funktion "Email an diesen Benutzer".

Kleine Helferlein

Geschützturmbefehl für den Bergbau

Im Standard-Skript "Greife mein Ziel an" (!turret.attacktarget.std) findet sich folgendes:

012       if not [THIS] -> is $victim a enemy
013        $victim = null

Damit soll verhindert werden, daß die Kanzel das Feuer auf neutrale und befreundete Schiffe und Stationen eröffnet. Eigentlich ist das ja ganz sinnvoll. Nur sind Asteroiden prinzipiell neutral und ändern ihre Meinung auch nicht, wenn man sie beschießt. Eine kleine Änderung am Skript prüft zusätzlich, ob das Ziel ein Asteroid und die Waffe ein Mobiles Bohrsystem ist.

Nun kann sich der Bergbauingeneur ganz auf die Steuerung des Schiffes konzentrieren, und muß nicht länger in die Heckkanzel umsteigen.

Landecomputer für die KI

Alle mit Landecomputer ausgestatteten Schiffe benutzen ihn auch.

Mehr Fairness beim Völkerrang

Die Flotten der Völker sind offensichtlich überfordert und schaffen es nicht, die Sicherheit in ihren Sektoren zu gewährleisten. Da ist der Spieler gefragt... und mit den Patroullienkommandos aus dem Bonuspack ist das ja durchaus zu schaffen. Nur: wo bleibt der Dank?

Wenn eines meiner Schiffe Völkerbesitz beschädigt, werde ich dafür persönlich zur Rechenschaft gezogen. Das gleichzeitig zahlreiche Patroullien in meinem Namen und auf meine Rechnung für Sicherheit sorgen, wird hingegen von niemandem gewürdigt. Das hat mir dermaßen Gestunken, daß ich da was unternommen habe.

Jetzt bekomme ich den vollen Völkerrang für Abschüsse durch eigenes Personal. Die Prämie muß ich mir mit dem Piloten teilen, schließlich hat er seinen Kopf hingehalten.


Autom. Satellitenverteiler

Funktionsumfang

oder
Was geht und was nicht geht

Dies ist ein sehr schlichtes Skript, um in einem bestimmten Bereich Satelliten aufzustellen. Das Schiff plaziert Satelliten in allen Sektoren des Einsatzgebietes, und ersetzt verloren gegangene. Die erforderlichen Satelliten werden (ebenfalls innerhalb des Einsatzgebietes) günstigst eingekauft.

Dieses Skript richtet sich an den aufstrebenden Jungunternehmer: der Funktionsumfang ist bescheiden, mit Problemen kann es nicht umgehen. Dafür entstehen auch keine weiteren Kosten, keine Gebühr pro aufgestelltem Satellit oder sowas. Ständig Satelliten zu ersetzen verursacht schon genug laufende Kosten.

Bedienung:
Bei Start wird man gebeten, eine Station auszuwählen: das Basislager. Dies ist keine Heimatbasis im eigentlichen Sinne, sondern lediglich der Parkplatz, den das Schiff anfliegt, wenn es sonst nichts zu tun hat. Insofern tut es jede Station, auf der man andocken kann.

Weiterhin wird man gefragt, welche Art von Satellit man verteilen will: E = Erweitert, alle anderen Eingaben = Navigationssatellit.

Zu guter letzt soll man noch eine Sprungweite angeben. Der Ausgangspunkt ist der Sektor, in dem sich das Basislager befindet. Das Einsatzgebiet wird aus der Sprungweite in Verbindung mit den Freund/Feind-Einstellungen berechnet, dadurch kann man das Einsatzgebiet sinnvoll abgrenzen. Beispiel: Basislager ist die Handelsstation in Argon Prime, Sprungweite ist 7, alle außer den Argonen sind Feinde. Ergebnis: das Einsatzgebiet sind die sog. "Argonischen Kernsektoren".

VORSICHT: Die Rassen haben ja mehr als ein Gebiet. Wenn man die Sprungweite zu hoch einstellt, landen Sektoren aus mehreren Gebieten in der Liste. Das kann erwünscht sein, aber auf jeden Fall sind die Wege lang und u.U. führen Sie durch einen Xenonsektor oder dergleichen...

Die Liste der Sektoren wird bei Programmstart berechnet und dann gespeichert; es ließe sich also mit relativ wenig Aufwand ein Skript basteln, das einzelne Sektoren zur Liste hinzufügt oder daraus entfernt. Wenn man die F/F-Einstellungen später ändert, hat das KEINE Auswirkungen auf den Einsatzbereich!

Was geschieht:
Alle fünf Mizuras werden die Sektoren im Einsatzbereich abgeklopft. Wenn sich in einem Sektor kein Spieler-Satellit befindet, fliegt das Schiff hin und plaziert einen Satelliten in der Mitte des Sektors deutlich oberhalb der Ekliptik. Es kann mehrere Satelliten hintereinander aufstellen, ohne jedesmal zum Basislager zurückzukehren.

Wenn ihm die Satelliten ausgehen, versucht es innerhalb des Einsatzgebietes neue zu beschaffen. So billig wie möglich zwar, aber erforderlichenfalls werden Spitzenpreise gezahlt. Falls das aus welchem Grund auch immer nicht klappt: Kein Geld auf dem Spielerkonto? Keine Station im Einsatzgebiet handelt mit den erforderlichen Satelliten? Keine Andockerlaubnis irgendwo? Das Skript kennt das alles nicht. Es weiß nur daß immer noch keine Satelliten geladen hat, wartet ein paar Mizuras und versucht es erneut. Wenn es über längere Zeit keine Satelliten einkaufen kann, wird ca. einmal pro Stunde eine Nachricht an den Spieler geschickt, während das Schiff es einfach immer weiter versucht.

Also, nochmal zum mitschreiben: das Skript ist schlau genug, ohne Satelliten gar nicht erst zu starten. Und das ist die einzige Intelligenz, die es hat. Andere Probleme werden nicht einmal erkannt.


Der (fast) perfekte Händler

...funktioniert (von außen gesehen) ähnlich wie die Handelssoftware Mk3, nur viel besser. Denn dieser Händler Vergleicht systematisch alle Handelsgelegenheiten und entscheidet sich für den besten Auftrag, unter Berücksichtigung von Laderaum und Spielerkonto. Bezahlt wird er in CPU-Zyklen.

Anders als die Uni-Händler (oder Fabrikfrachter) kann dieser Händler nur die Preise der Sektoren abfragen, die der Spieler auch "sehen" kann. Er macht also nichts, was man nicht auch selbst tun könnte, und ist in dieser Hinsicht ausgesprochen fair. Geschrieben habe ich dieses Skript als ich (mal wieder) ein neues Spiel angefangen habe, des ständigen Preisvergleichs aber schnell überdrüssig wurde.

Dieser Händler ist erschreckend effizient: ich hatte eigentlich gedacht, ich hätte alle Preise sorgfältig abgeklappert (daher ja auch der Überdruß), aber denkste &dansh; die automatische Suche fördert Gelegenheiten zutage, an die ich nicht mal gedacht hätte. Dabei ist nicht mal ein ausgedehntes Satellitennetzwerk erforderlich, schon mit vier Sektoren kann sich der Händler geraume Zeit beschäftigen ohne daß der Gewinn pro Fahrt spürbar leidet.

Der systematische Vergleich aller Handelsmöglichkeiten ist potentiell sehr rechenintensiv, weshalb ich den Händler jetzt fest auf Sprungweite=1 festgenagelt habe. Außerdem würden höhere Distanzen einen Sprungantrieb erfordern; dazu muß er sich einen Vorrat an EZ für den Eigenbedarf anlegen und ggf ergänzen usw usf -- wobei es mir sehr fraglich erscheint, ob die Gewinne bei höherer Sprungweite noch signifikant steigen würden.

Es gibt keine Sprachdatei oder Befehle. Gestartet wird die Software aus dem Skript-Editor, alle Nachrichten sind hart kodiert.

Modifizierte Handelsbefehle

Meine derzeitige Baustelle. So etwas habe ich schonmal gemacht, bin aber überzeugt, daß es noch besser geht. Die Befehle sollen in den "Zusätlichen Schiffskommandos" liegen; insgesamt gibt es drei Befehle, aber man kann leider nur max. zwei Kommandos gleichzeitig setzten. Schade eigentlich.

Handle naheliegend

Normalwerweise sucht der Händler den meistbietenden Abnehmer; mit dieser Modifikation findet er den nächstgelegenen, der noch mindestens den eingestellten Preis bietet. Frühere Erfahrungen zeigen, daß das sehr sinnvoll sein kann: die Gewinne sinken ein wenig, aber man kann sich oft den zweiten Frachter sparen.

Warte auf Ladung

Nur für Verkäufer: das Schiff wird erst losfliegen, wenn sein Laderaum gefüllt ist. Wozu ständig mit halbleerem Laderaum durch die Gegend gondeln?

Abweichende Sprungweite

Selbsterklärend.

Autom. Bergbau

Die "große" Variante dieses Skripts soll den Bergbau vollständig automatisieren; es handelt sich um mein erstes großes Projekt, und das merkt man. Definitiv nicht reif für eine Veröffentlichung.

Als Ableger ist eine "kleine" Version entstanden: das Geschützturm-Skript erzeugt am Ort des zerstörten Asteroiden eine Navigationsbake. Erzsammler lassen sich nicht von treibenden Frachtcontainern ablenken, sie fliegen gezielt die Baken an und sammeln nur Minerale. Mehrere Sammler kommen sich nicht in die quere. Wenn der Laderaum voll ist, schalten sie erkennbar in den Bereitschaftsmodus, so daß man volle Frachter schon in der Besitztümerliste erkennt.