Benutzer:Schnobs/Skripte

Aus X-Lexikon
Zur Navigation springenZur Suche springen

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 der Plan. Kommentare sind herzlich willkommen.


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. Die Satelliten und das Schiff sind schon teuer genug.


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. 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".

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!

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.

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

Funktion: übernimmt die Benutzereingabe. Klappert alle Sektoren ab und schreibt sie in ein array Schickt das Schiff zum Basislager exportiert die notwendigen variablen startet das eigentliche Skript

Arguments

    * 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, obwohl ich oben 1002 gesetzt und exportiert habe. Huch?

004   $PageID = 1002
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

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.

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.


    * 1: Camp , Var/Station , 'Basislager'
    * 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.

Dieses Skript ist zu 90% von den "Manuellen Handelsbefehlen" der Xai Corporation abgekupfert.

    * 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.

035    $sector.list.num =  size of array $sector.list
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