XRWS           Eż   §  Eext_01.cat ext_01.dat aiscripts/SMT.trade.findtraderun.player.xml 17183 1443986698 7b8fa8fdaf458033835973c0e81f9d63
aiscripts/trade.ship.xml 505 1443986655 61637d13e6112117b3c1d32c40931834
<?xml version="1.0" encoding="iso-8859-1" ?>
<aiscript name="SMT.trade.findtraderun.player" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="aiscripts.xsd" version="1">
  <params>
    <param name="warelist" />
    <param name="range" />
    <!--TODO: Support sellrange and buyrange for station working trade ships-->
    <param name="sellrange" default="null" comment="TODO"/>
    <param name="buyrange" default="null" comment="TODO"/>
    <param name="debugchance" default="0"/>
    <param name="debugchance2" default="0"/>
  </params>
  <init>
    <set_command_action commandaction="commandaction.searchingtrades" />
  </init>
  <attention min="unknown">
    <actions>

      <!-- set up initial state for trade runs -->
      <label name="start" />
      <set_value name="$buyoffer" exact="null" />
      <set_value name="$selloffer" exact="null" />
      <set_value name="$currentcargo" exact="this.ship.cargo.list" />

      <!-- strip fuel cells for own need from the list -->
      <do_if value="not $warelist.indexof.{ware.fuelcells}">
        <set_value name="$fuelindex" exact="$currentcargo.indexof.{ware.fuelcells}" />
        <do_if value="$fuelindex">
          <remove_value name="$currentcargo.{$fuelindex}" />
        </do_if>
      </do_if>
      <do_else>
        <!-- TODO: fuel trade ship needs to keep some for own use and the rest for trading -->
      </do_else>

      <debug_text text="player.age + ' finding trade offer; range: ' + $range.knownname" chance="$debugchance" />
      <debug_text text="player.age + ' current cargo: ' + $currentcargo" chance="$debugchance" />
      <debug_text text="player.age + ' commander: ' + this.ship.commander.knownname" chance="$debugchance" />

      <label name="find trade run" />
      <!-- try to find a buy offer for wares in our cargo first -->
      <do_if value="$currentcargo.count gt 0">
        <!-- in case it was resources for our station, wait until we can deliver them -->
        <debug_text text="player.age + ' checking if we can sell our current cargo to our homebase'" chance="$debugchance" />
        <find_buy_offer tradepartner="this.ship" buyer="this.ship.commander" wares="$currentcargo" result="$buyoffer">
          <amount min="1" />
        </find_buy_offer>
        <do_if value="$buyoffer.available">
          <debug_text text="'we have cargo on board that our homebase needs: %1 in %2 needs %3 %4'.[$buyoffer.buyer.knownname, $buyoffer.buyer.zone.knownname, $buyoffer.offeramount.{this}, $buyoffer.ware.name]" chance="$debugchance"/>
          <resume label="finish" />
        </do_if>
        <do_else>
          <!-- in case it was wares that our homebase does not need, shop around the range to find another buyer -->
          <!-- find a buy offer that matches our cargo, proceeds will now go to our new commander -->
          <debug_text text="player.age + ' checking if we can sell our current cargo somewhere else'" chance="$debugchance" />
          <do_all exact="2" counter="$pass">
            <do_all exact="$currentcargo.count" counter="$i" reverse="1">
              <set_value name="$currentware" exact="$currentcargo.{$i}" />
              <do_if value="this.ship.commander.resources.{$currentware}.exists">
                <!-- don't sell potential resources for our homebase to someone else, just keep them. We will be able to deliver them later -->
                <remove_value name="$currentcargo.{$i}"/>
                <continue />
              </do_if>

              <do_if value="$pass == 1">
                <find_buy_offer tradepartner="this.ship" wares="$currentware" space="$range" result="$buyoffer" >
                  <match_buyer class="class.ship_xl" comment="try and find/prefer build platforms" />
                </find_buy_offer>
                <do_if value="$buyoffer.exists">
                  <debug_text text="'builder ship trade run found: %1 in %2 needs %3 %4'.[$buyoffer.buyer.knownname, $buyoffer.buyer.zone.knownname, $buyoffer.offeramount.{this}, $buyoffer.ware.name]" chance="$debugchance"/>
                  <resume label="finish" />
                </do_if>
                <wait min="3s" max="5s" sinceversion="1"/>
              </do_if>
              <do_else>
                <set_value name="$minbuyprice" exact="$currentware.minprice" />
                <do_if value="this.ship.commander.products.{$currentware}.exists">
                  <find_sell_offer seller="this.ship.commander" wares="$currentware" result="$homebaseselloffer">
                    <amount min="1" />
                  </find_sell_offer>
                  <do_if value="$homebaseselloffer.available">
                    <!-- we don't want to make a loss when selling off products from our homebase, otherwise just try and dump the goods -->
                    <set_value name="$minbuyprice" exact="$homebaseselloffer.unitprice" />
                  </do_if>
                  <do_else>
                    <set_value name="$minbuyprice" exact="$currentware.averageprice" />
                  </do_else>
                </do_if>
                <find_buy_offer tradepartner="this.ship" wares="$currentware" space="$range" result="$buyoffers" multiple="true">
                  <match_buyer>
                    <match negate="true" class="class.ship_xl" />
                  </match_buyer>
                  <offeramount min="this.ship.cargo.{$currentware}.count * 0.25f" entity="this" />
                  <price min="$minbuyprice" />
                </find_buy_offer>
                <debug_text text="player.age + ' found %1 buyoffers for at least %2 %3 in %4'.[$buyoffers.count, this.ship.cargo.{$currentware}.count * 0.25f, $currentware, $range.knownname]" chance="$debugchance" />
                <set_value name="$buyoffer" exact="null" />
                <do_while value="$buyoffers.count gt 0">
                  <set_value name="$buyidx" min="1" max="$buyoffers.count" />
                  <set_value name="$buyoffer" exact="$buyoffers.{$buyidx}" />
                  <do_if value="$buyoffer.buyer.owner == this.owner">
                    <break />
                  </do_if>
                  <remove_value name="$buyoffers.{$buyidx}" />
                </do_while>
                <do_if value="$buyoffer.exists">
                  <debug_text text="'we have cargo on board that our homebase does not need, but we can sell it in the allowed range: %1 in %2 needs %3 %4'.[$buyoffer.buyer.knownname, $buyoffer.buyer.zone.knownname, $buyoffer.offeramount.{this}, $buyoffer.ware.name]" chance="$debugchance"/>
                  <resume label="finish" />
                </do_if>
                <wait min="10s" max="20s" sinceversion="1"/>
              </do_else>
            </do_all>
          </do_all>
        </do_else>
      </do_if>

      <!-- update the wares we deal with for a new trade run - ensure that we don't miss any wares if the list has changed due to the homebase being expanded -->
      <do_if value="this.ship.commander.isoperational">
        <set_value name="$homebase" exact="this.ship.commander" />
        <set_value name="$resources" exact="$homebase.resources.list" />
        <set_value name="$products" exact="$homebase.products.list" />
        <evaluate_ammo_storage object="$homebase" wares="$ammowares" type="missile" />
        <do_all exact="$resources.count" counter="$i">
          <set_value name="$ware" exact="$resources.{$i}" />
          <do_if value="this.ship.cargo.{$ware}.max gt 0">
            <do_if value="$warelist.indexof.{$ware}" exact="0">
              <append_to_list name="$warelist" exact="$ware" />
            </do_if>
          </do_if>
        </do_all>
        <do_all exact="$products.count" counter="$i">
          <set_value name="$ware" exact="$products.{$i}" />
          <do_if value="this.ship.cargo.{$ware}.max gt 0">
            <do_if value="$warelist.indexof.{$ware}" exact="0">
              <append_to_list name="$warelist" exact="$ware" />
            </do_if>
          </do_if>
        </do_all>
        <do_all exact="$ammowares.count" counter="$i">
          <set_value name="$ware" exact="$ammowares.{$i}" />
          <do_if value="this.ship.cargo.{$ware}.max gt 0">
            <do_if value="$warelist.indexof.{$ware}" exact="0">
              <append_to_list name="$warelist" exact="$ware" />
            </do_if>
          </do_if>
        </do_all>

        <debug_text text="'updating warelist on %1(%2) to transport %3'.[this.ship.knownname, this.ship, $warelist]" chance="$debugchance" />
        <remove_value name="$homebase" />
        <remove_value name="$ammowares" />
        <remove_value name="$products" />
        <remove_value name="$resources" />
        <remove_value name="$ware" />
      </do_if>

      <debug_text text="player.age + ' checking if we can sell products from our station somewhere'" chance="$debugchance" />
      <find_sell_offer tradepartner="this.ship" seller="this.ship.commander" wares="$warelist" result="$selloffers" multiple="true">
        <amount min="1" />
      </find_sell_offer>
      <do_if value="$selloffers.count gt 0">
        <!-- find a buy offer that matches one of our sell offers -->
        <!-- try to sell off the wares that we have the most of first, sort by relativeprice to avoid weirdness with intermediate wares -->
        <sort_trades name="$selloffers" tradelist="$selloffers" sorter="relativeprice" />
        <do_all exact="$selloffers.count" counter="$i">
		    <set_value name="$so" exact="$selloffers.{$i}" />
            <debug_text text="player.age + ' SELLOFFER INFO:\n\'%1\' sells %2 units of %3 for a total price of %4 Cr.'.[$so.seller.knownname, $so.offeramount.{this}, $so.ware.name, $so.price/1Cr]" chance="$debugchance"/>
            <do_if value="@$selloffers.{$i}.restriction.faction">
              <!-- if there is a faction restriction for this ware, don't look for buyers of a different faction! -->
              <find_buy_offer tradepartner="this.ship" wares="$selloffers.{$i}.ware" space="$range" result="$buyoffers"  multiple="true">
                <match_buyer owner="$selloffers.{$i}.restriction.faction">
                  <match negate="true" class="class.ship_xl" />
                </match_buyer>
                <price min="$selloffers.{$i}.unitprice" />
              </find_buy_offer>
            </do_if>
            <do_else>
              <find_buy_offer tradepartner="this.ship" wares="$selloffers.{$i}.ware" space="$range" result="$buyoffers"  multiple="true">
                <match_buyer>
                  <match negate="true" class="class.ship_xl" />
                </match_buyer>
                <price min="$selloffers.{$i}.unitprice" />
              </find_buy_offer>
            </do_else>
            <debug_text text="player.age + ' Found %1 buy offers'.[$buyoffers.count]" chance="$debugchance"/>
            <do_if value="$buyoffers.count gt 0">
			  <!-- Find best offer-->
              <set_value name="$buyoffer" exact="null" />
			  <set_value name="$profit" exact="0" />
              <do_all exact="$buyoffers.count" counter="$j">
			    <set_value name="$tmpbuyoffer" exact="$buyoffers.{$j}" />
				<set_value name="$tmpdistance" exact="$selloffers.{$i}.seller.distanceto.{$tmpbuyoffer.buyer}" />
				<set_value name="$tmpamount" exact="$tmpbuyoffer.offeramount.{this}" />
				<do_if value="$tmpamount gt this.ship.cargo.{$tmpbuyoffer.ware}.free">
				  <set_value name="$tmpamount" exact="this.ship.cargo.{$tmpbuyoffer.ware}.free" />
				</do_if>
				
				<set_value name="$tmpprofit" exact="($tmpamount * $tmpbuyoffer.unitprice)f / ($tmpdistance)f" />

                <debug_text text="player.age + ' TMP BUYOFFER INFO:\n\'%1\' buys %2 (desires: %5) units of %3 for a total price of %4 Cr. Distance: %6 Profit = %7'.[$tmpbuyoffer.buyer.knownname, $tmpamount, $tmpbuyoffer.ware.name, ($tmpamount * $tmpbuyoffer.unitprice)/1Cr, $tmpbuyoffer.amount, $tmpdistance, $tmpprofit]" chance="$debugchance"/>

				<do_if value="$tmpprofit gt $profit">
                  <set_value name="$buyoffer" exact="$tmpbuyoffer" />
			      <set_value name="$profit" exact="$tmpprofit" />
				</do_if>  
			  </do_all>
              <set_value name="$selloffer" exact="$selloffers.{$i}" />
              <resume label="finish" />
            </do_if>
            <wait min="10s" max="20s"/>
        </do_all>
      </do_if>

      <debug_text text="player.age + ' checking if we can buy resources for our station somewhere'" chance="$debugchance" />
      <find_buy_offer tradepartner="this.ship" buyer="this.ship.commander" wares="$warelist" result="$buyoffers" multiple="true">
        <amount min="1" />
      </find_buy_offer>
      <do_if value="$buyoffers.count gt 0">
        <!-- find a sell offer that matches one of our buy offers -->
        <!-- build table with priorities, making primary resources more "urgent" than secondaries or ammo offers -->
        <set_value name="$offertable" exact="table[]" />
        <do_all exact="$buyoffers.count" counter="$i">
          <set_value name="$offer" exact="$buyoffers.{$i}" />
          <set_value name="$offertable.{$offer}" exact="$offer.stocklevel + (0.8 * this.ship.commander.resources.{$offer.ware}.primary)" />
        </do_all>
        <!-- we now use the list of offers which has been sorted by the priority values -->
        <set_value name="$buyoffers" exact="$offertable.keys.sorted" />
        <!-- $table.keys.sorted gives us the listed sorted by values from lowest to highest, so we need to iterate in reverse -->
        <do_all exact="$buyoffers.count" counter="$i" reverse="true">
          <do_if value="@$buyoffers.{$i}.restriction.faction">
            <!-- if there is a faction restriction for this ware, don't look for sellers of a different faction! -->
            <find_sell_offer tradepartner="this.ship" wares="$buyoffers.{$i}.ware" space="$range" result="$selloffer">
              <match_seller owner="$buyoffers.{$i}.restriction.faction" />
            </find_sell_offer>
          </do_if>
          <do_else>
            <find_sell_offer tradepartner="this.ship" wares="$buyoffers.{$i}.ware" space="$range" result="$selloffer" />
          </do_else>
          <do_if value="$selloffer.exists">
            <set_value name="$buyoffer" exact="$buyoffers.{$i}" />
            <resume label="finish" />
          </do_if>
          <debug_text text="'waiting'" chance="$debugchance"/>
          <wait min="10s" max="20s"/>
        </do_all>
      </do_if>

      <!-- can't find anything good at the moment... wait a while, then check again -->
      <debug_text text="player.age + ' no good trade offer found, waiting for a while before checking again'" chance="$debugchance" />
      <debug_text text="player.age + ' no good trade offer found. \'%1\'(job: \'%5\'), commander: \'%2\', buyoffers: \'%3\', selloffers: \'%4\''.[this.ship.knownname, this.ship.commander.knownname, $buyoffers, $selloffers, this.ship.job]" chance="1002" />
      <do_if value="@this.ship.commanderentity.$config_subordinate_range">
        <do_if value="$range != this.ship.commanderentity.$config_subordinate_range">
          <set_value name="$range" exact="this.ship.commanderentity.$config_subordinate_range"/>
        </do_if>
      </do_if>
      <set_value name="$idletime" min="30s" max="90s"/>
      <run_script name="'move.idle'">
        <param name="TimeOut" value="$idletime" />
      </run_script>
      <resume label="start" />

      <label name="finish" />
      <do_if value="$buyoffer.exists">
        <debug_text text="player.age + ' BUYOFFER INFO:\n\'%1\' buys %2 (desires: %5) units of %3 for a total price of %4 Cr.'.[$buyoffer.buyer.knownname, $buyoffer.offeramount.{this}, $buyoffer.ware.name, $buyoffer.price/1Cr, $buyoffer.amount]" chance="$debugchance" />
      </do_if>
      <do_if value="$selloffer.exists">
        <debug_text text="player.age + ' SELLOFFER INFO:\n\'%1\' sells %2 units of %3 for a total price of %4 Cr.'.[$selloffer.seller.knownname, $selloffer.offeramount.{this}, $selloffer.ware.name, $selloffer.price/1Cr]" chance="$debugchance" />
      </do_if>

      <!-- TODO: if we find that traders buy too much of a ware, only fill a fraction of the cargo space with any one ware, so that we'll still have space for others left (only if the basket contains more than one ware) -->
      <!--<set_value name="$totalcargospace" exact="this.ship.cargo.{$ware}.max" />
      <set_value name="$freecargospace" exact="this.ship.cargo.{$ware}.free" />
      <set_value name="$amount" />
      <debug_text text="'Amount that will be traded: ' + $amount" chance="$debugchance" />
      <retval name="amount" value="$amount" />-->

      <return>
        <retval name="buyoffer" value="$buyoffer" />
        <retval name="selloffer" value="$selloffer" />
      </return>

    </actions>
  </attention>
</aiscript>
<?xml version="1.0" encoding="utf-8"?> 

 <diff xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > 
  <replace sel="//set_value[@exact=&quot;'trade.findtraderun'&quot;]"> 
     <do_if value="1">
       <do_if value="this.ship.commander.isplayerowned">
	     <set_value name="$traderunscript" exact="'STM.trade.findtraderun.player'" />
       </do_if>
	   <do_else>
	     <set_value name="$traderunscript" exact="'trade.findtraderun'" />
	   </do_else>
	 </do_if>  
   </replace>
 </diff><?xml version="1.0" encoding="utf-8"?>
<!-- Station Manager Trading Fix v0.10 -->
<content id="" name="" description="" version="10" author="keeper" date="2015-10-04" lastupdate="">
  <!-- Requires minimum game version 3.60 -->
  <dependency version="360"/>
</content>
